hrzndhrn / beam_file

BeamFile - A peek into the BEAM file

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Invalid AST and generated code for comprehensions

bartblast opened this issue · comments

It looks like the "into" key is misplaced in the elixir_quoted/1 output AST for comprehensions which in turn may be responsible for invalid code generated by elixir_code/1.

Example:

defmodule MyModule do
  def my_fun do
    for n <- [1, 2, 3], into: [], do: n * n
  end
end

(notice I included "into" explicitly in the comprehension example, because it is added anyway by BeamFile)

iex> quote do for n <- [1, 2, 3], into: [], do: n * n end
{:for, [],
 [
   {:<-, [],
    [
      {:n, [if_undefined: :apply, context: Elixir, imports: [{0, IEx.Helpers}]],
       Elixir},
      [1, 2, 3]
    ]},
   [
     into: [],
     do: {:*, [context: Elixir, imports: [{2, Kernel}]],
      [
        {:n,
         [if_undefined: :apply, context: Elixir, imports: [{0, IEx.Helpers}]],
         Elixir},
        {:n,
         [if_undefined: :apply, context: Elixir, imports: [{0, IEx.Helpers}]],
         Elixir}
      ]}
   ]
 ]}

but in the elixir_quoted/1 result, the "into" key is after the "do" key:

iex> BeamFile.elixir_quoted(MyModule)
{:ok,
 {:defmodule, [context: Elixir, import: Kernel],
  [
    {:__aliases__, [alias: false], [MyModule]},
    [
      do: {:__block__, [],
       [
         {:def, [line: 2],
          [
            {:my_fun, [], Elixir},
            [
              do: {:for, [line: 3],
               [
                 {:<-, [line: 3], [{:n, [version: 0, line: 3], nil}, [1, 2, 3]]},
                 [
                   do: {{:., [line: 3], [:erlang, :*]}, [line: 3],
                    [
                      {:n, [version: 0, line: 3], nil},
                      {:n, [version: 0, line: 3], nil}
                    ]},
                   into: []
                 ]
               ]}
            ]
          ]}
       ]}
    ]
  ]}}

Also, the code generated by elixir_code/1 seems to be invalid as well (notice the strange "into" block):

defmodule Elixir.MyModule do
  def my_fun do
    for n <- [1, 2, 3] do
      :erlang.*(n, n)
    into
      []
    end
  end
end

Good catch. Thanks for reporting. I will take a look.