-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The spec ... doesn't match the function name/arity
for generated code
#150
Comments
After investigation: {:function, 2, :rollback, 1,
[
{:clause, 2, [{:var, 2, :_@1}], [],
[
{:call, 2,
{:remote, 2, {:atom, 2, Ecto.Repo.Transaction}, {:atom, 2, :rollback}},
[{:call, 2, {:atom, 2, :get_dynamic_repo}, []}, {:var, 2, :_@1}]}
]}
]}, |
Just added #162 with a simplified test that isolates the problem. Looking a bit deeper into this, here is what I have found:
(However, this might not be right ... if I replace calls to It seems like in the current implementation, we don't have sufficient information to determine whether code is generated or not. We just use the Erlang AST from defmodule GeneratingCode do
defmacro __using__(_) do
quote do
@spec wrong_ret() :: atom()
def wrong_ret() do
1234
end
end
end
end
defmodule GeneratedCode do
use GeneratingCode
@spec wrong_ret2() :: atom()
def wrong_ret2() do
1234
end
end And here's what the AST looks like to Gradient: iex(1)> Gradient.ElixirFileUtils.get_forms("test/examples/_build/Elixir.GeneratedCode.beam")
{:ok,
[
[
... (attributes and __info__ function) ...
{:function, 13, :wrong_ret, 0, [{:clause, 13, [], [], [{:integer, 13, 1234}]}]},
{:function, 16, :wrong_ret2, 0, [{:clause, 16, [], [], [{:integer, 16, 1234}]}]}
]
]} As you can see above, the function Inside I believe the best solution is to change the way that we're getting the AST to include the Elixir debug info as well. The above AST, fetched with :beam_lib.chunks(path, [:abstract_code]) But if we change it to what's used in :beam_lib.chunks(path, [:debug_info]) then we get a more interesting representation: iex(2)> Gradient.Debug.elixir_ast('test/examples/_build/Elixir.GeneratedCode.beam')
{:ok,
%{
...
definitions: [
{{:wrong_ret2, 0}, :def, [line: 16], [{[line: 16], [], [], 1234}]},
{{:wrong_ret, 0}, :def, [line: 13, context: GeneratingCode],
[{[line: 13, context: GeneratingCode], [], [], 1234}]}
],
...
}} Notice above that the What do you think @luk-pau-es @erszcz? A couple of questions specifically:
|
If you generate a simple Phoenix app with
mix phx.new
, add Gradient as a dependency, and then runmix gradient
, you get these errors (among others). For an example, see this PR: #149The spec referred to is generated at compile time by a
use
statement. Usinglib/simple_phoenix_app_web/views/layout_view.ex
as an example, here's the code in that actual file:And here's the code that
use SimplePhoenixAppWeb, :view
generates:In the quoted code, the spec correctly comes right before the function. But when I decompile the
LayoutView
module (viaGradient.Debug.print_erlang(SimplePhoenixAppWeb.LayoutView)
), the spec is placed at the beginning of the file, before the__info__
function definition. I believe that's why it gives the error.I think the way to fix this would be to get the Elixir AST separately from the compiled bytecode so we could check if the function is generated, and in that case, allow the specs to be out of order.
The text was updated successfully, but these errors were encountered: