Problem with super calls
bartblast opened this issue · comments
I'm trying to run:
$ mix beam.file InheritMod --elixir
using an example from Elixir docs https://hexdocs.pm/elixir/1.12/Kernel.html#defoverridable/1-example
(see DefaultMod and InheritMod)
Apparently, there is a problem with super calls, I get the following error:
** (SyntaxError) nofile:2:28: syntax error before: '('
|
2 | defp test (overridable 1)(x, y) do
| ^
(elixir 1.14.3) lib/code.ex:776: Code.format_string!/2
(beam_file 0.4.0) lib/beam_file.ex:925: BeamFile.to_code/2
(beam_file 0.4.0) lib/beam_file.ex:494: BeamFile.elixir_code/2
(beam_file 0.4.0) lib/mix/tasks/beam.file.ex:35: Mix.Tasks.Beam.File.output/1
(mix 1.14.3) lib/mix/task.ex:421: anonymous fn/3 in Mix.Task.run_task/4
(mix 1.14.3) lib/mix/cli.ex:84: Mix.CLI.run_task/2
I suspect converting string function names to double quoted atoms should solve the issue.
Thanks a lot. I will take a look.
Hi @bartblast I have released a new version. BeamFile.elixir_code(InheritMod)
runs now but unfortunately the returned code is not compileable.
Hey @NickNeck, thanks for looking into that! I believe this doesn't work, because "super" keyword needs to be expanded to the actual function name.
This is the code generated in the 0.4.1 fix which doesn't compile:
defmodule Elixir.InheritMod do
defp unquote(:"test (overridable 1)")(x, y) do
:erlang.+(x, y)
end
def test(x, y) do
:erlang.+(:erlang.*(x, y), super(x, y))
end
end
And this should work:
defmodule Elixir.InheritMod do
defp unquote(:"test (overridable 1)")(x, y) do
:erlang.+(x, y)
end
def test(x, y) do
:erlang.+(:erlang.*(x, y), unquote(:"test (overridable 1)")(x, y))
end
end
@bartblast thanks again. I have tried again.
Hey @NickNeck, unfortunately, I found a similar issue with function names consisting of symbols only, such as operator functions, e.g. see: https://github.com/elixir-lang/elixir/blob/a64d42f5d3cb6c32752af9d3312897e8cd5bb7ec/lib/elixir/lib/bitwise.ex#L137
I believe a fix should be very similar.
Also, I created a small pull request that goes through all Elixir standard library modules and tests whether their code can be generated correctly: #6