hrzndhrn / beam_file

BeamFile - A peek into the BEAM file

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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