From c48c1dfcaebe90d1a52ed61fcd798e7e75f6da50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 17 Aug 2021 17:30:41 +0200 Subject: [PATCH 1/2] Add mix xref trace that shows all deps for a given file --- lib/elixir/lib/code.ex | 4 +- lib/elixir/lib/kernel.ex | 38 ++-- lib/elixir/lib/macro.ex | 2 +- lib/elixir/lib/map_set.ex | 1 + lib/elixir/src/elixir_aliases.erl | 10 +- lib/elixir/src/elixir_compiler.erl | 14 +- lib/elixir/src/elixir_expand.erl | 3 +- .../elixir/kernel/lexical_tracker_test.exs | 44 ++++ lib/mix/lib/mix/tasks/xref.ex | 204 ++++++++++++++++-- lib/mix/test/mix/tasks/xref_test.exs | 116 +++++++++- 10 files changed, 395 insertions(+), 41 deletions(-) diff --git a/lib/elixir/lib/code.ex b/lib/elixir/lib/code.ex index ad7d63ef80c..8a1cfaf06a0 100644 --- a/lib/elixir/lib/code.ex +++ b/lib/elixir/lib/code.ex @@ -1264,8 +1264,8 @@ defmodule Code do @doc """ Stores all given compilation options. - To store individual options, see `put_compiler_option/2`. - For a description of all options, see `put_compiler_option/2`. + To store individual options and for a description of all + options, see `put_compiler_option/2`. ## Examples diff --git a/lib/elixir/lib/kernel.ex b/lib/elixir/lib/kernel.ex index 1f820bc2738..b12b38e60e5 100644 --- a/lib/elixir/lib/kernel.ex +++ b/lib/elixir/lib/kernel.ex @@ -4488,19 +4488,13 @@ defmodule Kernel do defmacro defmodule(alias, do: block) do env = __CALLER__ - boot? = bootstrapped?(Macro) - - expanded = - case boot? do - true -> Macro.expand(alias, env) - false -> alias - end + expanded = expand_module_alias(alias, env) {expanded, with_alias} = - case boot? and is_atom(expanded) do + case is_atom(expanded) do true -> # Expand the module considering the current environment/nesting - {full, old, new} = expand_module(alias, expanded, env) + {full, old, new} = alias_defmodule(alias, expanded, env) meta = [defined: full, context: env.module] ++ alias_meta(alias) {full, {:alias, meta, [old, [as: new, warn: false]]}} @@ -4540,16 +4534,34 @@ defmodule Kernel do defp alias_meta({:__aliases__, meta, _}), do: meta defp alias_meta(_), do: [] + # We don't want to trace :alias_reference since we are defining the alias + defp expand_module_alias({:__aliases__, _, _} = original, env) do + case :elixir_aliases.expand_or_concat(original, env) do + receiver when is_atom(receiver) -> + receiver + + aliases -> + aliases = :lists.map(&Macro.expand(&1, env), aliases) + + case :lists.all(&is_atom/1, aliases) do + true -> :elixir_aliases.concat(aliases) + false -> original + end + end + end + + defp expand_module_alias(other, env), do: Macro.expand(other, env) + # defmodule Elixir.Alias - defp expand_module({:__aliases__, _, [:"Elixir", _ | _]}, module, _env), + defp alias_defmodule({:__aliases__, _, [:"Elixir", _ | _]}, module, _env), do: {module, module, nil} # defmodule Alias in root - defp expand_module({:__aliases__, _, _}, module, %{module: nil}), + defp alias_defmodule({:__aliases__, _, _}, module, %{module: nil}), do: {module, module, nil} # defmodule Alias nested - defp expand_module({:__aliases__, _, [h | t]}, _module, env) when is_atom(h) do + defp alias_defmodule({:__aliases__, _, [h | t]}, _module, env) when is_atom(h) do module = :elixir_aliases.concat([env.module, h]) alias = String.to_atom("Elixir." <> Atom.to_string(h)) @@ -4560,7 +4572,7 @@ defmodule Kernel do end # defmodule _ - defp expand_module(_raw, module, _env) do + defp alias_defmodule(_raw, module, _env) do {module, module, nil} end diff --git a/lib/elixir/lib/macro.ex b/lib/elixir/lib/macro.ex index 39ce6214e69..8fe3e611127 100644 --- a/lib/elixir/lib/macro.ex +++ b/lib/elixir/lib/macro.ex @@ -1475,7 +1475,7 @@ defmodule Macro do end defp do_expand_once({:__aliases__, meta, _} = original, env) do - case :elixir_aliases.expand(original, env) do + case :elixir_aliases.expand_or_concat(original, env) do receiver when is_atom(receiver) -> :elixir_env.trace({:alias_reference, meta, receiver}, env) {receiver, true} diff --git a/lib/elixir/lib/map_set.ex b/lib/elixir/lib/map_set.ex index ff66c755105..3d38b4396d7 100644 --- a/lib/elixir/lib/map_set.ex +++ b/lib/elixir/lib/map_set.ex @@ -402,6 +402,7 @@ defmodule MapSet do end defimpl Collectable do + # TODO: Optimize into an empty mapset by using :maps.from_keys/2 on Erlang/OTP 24+ def into(map_set) do fun = fn list, {:cont, x} -> [{x, []} | list] diff --git a/lib/elixir/src/elixir_aliases.erl b/lib/elixir/src/elixir_aliases.erl index 796f22ec552..6480606b069 100644 --- a/lib/elixir/src/elixir_aliases.erl +++ b/lib/elixir/src/elixir_aliases.erl @@ -1,6 +1,6 @@ -module(elixir_aliases). -export([inspect/1, last/1, concat/1, safe_concat/1, format_error/1, - ensure_loaded/3, expand/2, store/5]). + ensure_loaded/3, expand/2, expand_or_concat/2, store/5]). -include("elixir.hrl"). inspect(Atom) when is_atom(Atom) -> @@ -75,6 +75,14 @@ expand({'__aliases__', Meta, [H | T]}, Aliases, E) when is_atom(H) -> expand({'__aliases__', _Meta, List}, _Aliases, _E) -> List. +%% Expands or concat if possible. + +expand_or_concat(Aliases, E) -> + case expand(Aliases, E) of + [H | T] when is_atom(H) -> concat([H | T]); + AtomOrList -> AtomOrList + end. + %% Ensure a module is loaded before its usage. ensure_loaded(_Meta, 'Elixir.Kernel', _E) -> ok; diff --git a/lib/elixir/src/elixir_compiler.erl b/lib/elixir/src/elixir_compiler.erl index 30982e89fec..e49bd5ab0a6 100644 --- a/lib/elixir/src/elixir_compiler.erl +++ b/lib/elixir/src/elixir_compiler.erl @@ -115,12 +115,24 @@ fast_compile({'__block__', _, Exprs}, E) -> lists:foldl(fun(Expr, _) -> fast_compile(Expr, E) end, nil, Exprs); fast_compile({defmodule, Meta, [Mod, [{do, TailBlock}]]}, NoLineE) -> E = NoLineE#{line := ?line(Meta)}, + Block = {'__block__', Meta, [ {'=', Meta, [{result, Meta, ?MODULE}, TailBlock]}, {{'.', Meta, [elixir_utils, noop]}, Meta, []}, {result, Meta, ?MODULE} ]}, - Expanded = 'Elixir.Macro':expand(Mod, E), + + Expanded = case Mod of + {'__aliases__', _, _} -> + case elixir_aliases:expand_or_concat(Mod, E) of + Receiver when is_atom(Receiver) -> Receiver; + _ -> 'Elixir.Macro':expand(Mod, E) + end; + + _ -> + 'Elixir.Macro':expand(Mod, E) + end, + elixir_module:compile(Expanded, Block, [], E). %% Bootstrapper diff --git a/lib/elixir/src/elixir_expand.erl b/lib/elixir/src/elixir_expand.erl index eb645367132..f34f9d76962 100644 --- a/lib/elixir/src/elixir_expand.erl +++ b/lib/elixir/src/elixir_expand.erl @@ -982,7 +982,7 @@ expand_without_aliases_report(Other, S, E) -> expand(Other, S, E). expand_aliases({'__aliases__', Meta, _} = Alias, S, E, Report) -> - case elixir_aliases:expand(Alias, E) of + case elixir_aliases:expand_or_concat(Alias, E) of Receiver when is_atom(Receiver) -> Report andalso elixir_env:trace({alias_reference, Meta, Receiver}, E), {Receiver, S, E}; @@ -995,6 +995,7 @@ expand_aliases({'__aliases__', Meta, _} = Alias, S, E, Report) -> Receiver = elixir_aliases:concat(EAliases), Report andalso elixir_env:trace({alias_reference, Meta, Receiver}, E), {Receiver, SA, EA}; + false -> form_error(Meta, E, ?MODULE, {invalid_alias, Alias}) end diff --git a/lib/elixir/test/elixir/kernel/lexical_tracker_test.exs b/lib/elixir/test/elixir/kernel/lexical_tracker_test.exs index 8ca79775792..cca4efd9394 100644 --- a/lib/elixir/test/elixir/kernel/lexical_tracker_test.exs +++ b/lib/elixir/test/elixir/kernel/lexical_tracker_test.exs @@ -209,10 +209,41 @@ defmodule Kernel.LexicalTrackerTest do refute String in runtime end + test "structs are exports or compile time" do + {{compile, exports, runtime, _}, _binding} = + Code.eval_string(""" + defmodule Kernel.LexicalTrackerTest.StructRuntime do + def expand, do: %URI{} + Kernel.LexicalTracker.references(__ENV__.lexical_tracker) + end |> elem(3) + """) + + refute URI in compile + assert URI in exports + assert URI in runtime + + {{compile, exports, runtime, _}, _binding} = + Code.eval_string(""" + defmodule Kernel.LexicalTrackerTest.StructCompile do + _ = %URI{} + Kernel.LexicalTracker.references(__ENV__.lexical_tracker) + end |> elem(3) + """) + + assert URI in compile + assert URI in exports + refute URI in runtime + end + test "Macro.struct! adds an export dependency" do {{compile, exports, runtime, _}, _binding} = Code.eval_string(""" defmodule Kernel.LexicalTrackerTest.MacroStruct do + # We do not use the alias because it would be a compile time + # dependency. The alias may happen in practice, which is the + # mechanism to make this expansion become a compile-time one. + # However, in some cases, such as typespecs, we don't necessarily + # want the compile-time dependency to happen. Macro.struct!(:"Elixir.URI", __ENV__) Kernel.LexicalTracker.references(__ENV__.lexical_tracker) end |> elem(3) @@ -237,5 +268,18 @@ defmodule Kernel.LexicalTrackerTest do refute URI in exports assert URI in runtime end + + test "defmodule does not add a compile dependency" do + {{compile, exports, runtime, _}, _binding} = + Code.eval_string(""" + defmodule Kernel.LexicalTrackerTest.Defmodule do + Kernel.LexicalTracker.references(__ENV__.lexical_tracker) + end |> elem(3) + """) + + refute Kernel.LexicalTrackerTest.Defmodule in compile + refute Kernel.LexicalTrackerTest.Defmodule in exports + refute Kernel.LexicalTrackerTest.Defmodule in runtime + end end end diff --git a/lib/mix/lib/mix/tasks/xref.ex b/lib/mix/lib/mix/tasks/xref.ex index 337930e5095..524cca33fd1 100644 --- a/lib/mix/lib/mix/tasks/xref.ex +++ b/lib/mix/lib/mix/tasks/xref.ex @@ -20,12 +20,50 @@ defmodule Mix.Tasks.Xref do This task is automatically reenabled, so you can print information multiple times in the same Mix invocation. - ## mix xref callers CALLEE + ## mix xref callers MODULE Prints all callers of the given `MODULE`. Example: $ mix xref callers MyMod + ## mix xref trace FILE + + Compiles the given file listing all dependencies within the same app. + It includes the type and line for each one. Example: + + $ mix xref trace lib/my_app/router.ex + + The `--label` option may be given to keep only certain traces: + + $ mix xref trace lib/my_app/router.ex --label compile + + ### Example + + Imagine the given file lib/b.ex: + + defmodule B do + import A + A.macro() + macro() + A.fun() + fun() + def calls_macro, do: A.macro() + def calls_fun, do: A.fun() + def calls_struct, do: %A{} + end + + `mix xref trace` will print: + + lib/b.ex:2: require A (export) + lib/b.ex:3: call A.macro/0 (compile) + lib/b.ex:4: import A.macro/0 (compile) + lib/b.ex:5: call A.fun/0 (compile) + lib/b.ex:6: call A.fun/0 (compile) + lib/b.ex:6: import A.fun/0 (compile) + lib/b.ex:7: call A.macro/0 (compile) + lib/b.ex:8: call A.fun/0 (runtime) + lib/b.ex:9: struct A (export) + ## mix xref graph Prints a file dependency graph where an edge from `A` to `B` indicates @@ -175,7 +213,8 @@ defmodule Mix.Tasks.Xref do another module, the caller module has to be recompiled whenever the callee changes. Compile-time dependencies are typically added when using macros or when invoking functions in the module body (outside - of functions). + of functions). You can list all dependencies in a file by running + `mix xref trace path/to/file.ex`. Exports dependencies are compile time dependencies on the module API, namely structs and its public definitions. For example, if you import @@ -221,7 +260,6 @@ defmodule Mix.Tasks.Xref do """ @switches [ - abort_if_any: :boolean, archives_check: :boolean, compile: :boolean, deps_check: :boolean, @@ -245,11 +283,14 @@ defmodule Mix.Tasks.Xref do {opts, args} = OptionParser.parse!(args, strict: @switches) case args do - ["callers", callee] -> - callers(callee, opts) + ["callers", module] -> + handle_callers(module, opts) + + ["trace", file] -> + handle_trace(file, opts) ["graph"] -> - graph(opts) + handle_graph(opts) # TODO: Remove on v2.0 ["deprecated"] -> @@ -396,8 +437,8 @@ defmodule Mix.Tasks.Xref do ## Modes - defp callers(callee, opts) do - module = parse_callee(callee) + defp handle_callers(module, opts) do + module = parse_module(module) file_callers = for source <- sources(opts), @@ -411,26 +452,49 @@ defmodule Mix.Tasks.Xref do check_failure(:references, length(file_callers), opts[:fail_above]) end - defp check_failure(found, count, max_count) - when not is_nil(max_count) and count > max_count do - Mix.raise("Too many #{found} (found: #{count}, permitted: #{max_count})") - end + defp handle_trace(file, opts) do + set = + for app <- apps(opts), + modules = Application.spec(app, :modules), + module <- modules, + into: MapSet.new(), + do: module - defp check_failure(_, _, _) do - :ok + old = Code.compiler_options(ignore_module_conflict: true, tracers: [__MODULE__]) + ets = :ets.new(__MODULE__, [:named_table, :duplicate_bag, :public]) + :ets.insert(ets, [{:config, set, trace_label(opts[:label])}]) + + try do + Code.compile_file(file) + else + _ -> + :ets.delete(ets, :modules) + + traces = + try do + print_traces(Enum.sort(:ets.lookup_element(__MODULE__, :entry, 2))) + rescue + _ -> [] + end + + check_failure(:traces, length(traces), opts[:fail_above]) + after + :ets.delete(ets) + Code.compiler_options(old) + end end - defp graph(opts) do + defp handle_graph(opts) do {direct_filter, transitive_filter} = label_filter(opts[:label]) write_graph(file_references(direct_filter, opts), transitive_filter, opts) end ## Callers - defp parse_callee(callee) do - case Mix.Utils.parse_mfa(callee) do + defp parse_module(module) do + case Mix.Utils.parse_mfa(module) do {:ok, [module]} -> module - _ -> Mix.raise("xref callers MODULE expects a MODULE, got: " <> callee) + _ -> Mix.raise("xref callers MODULE expects a MODULE, got: " <> module) end end @@ -443,6 +507,84 @@ defmodule Mix.Tasks.Xref do end end + ## Trace + + @doc false + def trace({:require, meta, module, _opts}, env), + do: add_trace(:export, :require, module, module, meta, env) + + def trace({:struct_expansion, meta, module, _keys}, env), + do: add_trace(:export, :struct, module, module, meta, env) + + def trace({:alias_reference, meta, module}, env) when env.module != module, + do: add_trace(mode(env), :alias, module, module, meta, env) + + def trace({:remote_function, meta, module, function, arity}, env), + do: add_trace(mode(env), :call, module, {module, function, arity}, meta, env) + + def trace({:remote_macro, meta, module, function, arity}, env), + do: add_trace(:compile, :call, module, {module, function, arity}, meta, env) + + def trace({:imported_function, meta, module, function, arity}, env), + do: add_trace(mode(env), :import, module, {module, function, arity}, meta, env) + + def trace({:imported_macro, meta, module, function, arity}, env), + do: add_trace(:compile, :import, module, {module, function, arity}, meta, env) + + def trace(_event, _env), + do: :ok + + defp mode(%{function: nil}), do: :compile + defp mode(_), do: :runtime + + defp add_trace(mode, type, module, module_or_mfa, meta, env) do + [{:config, modules, label}] = :ets.lookup(__MODULE__, :config) + + if module in modules and (label == nil or mode == label) do + line = meta[:line] || env.line + :ets.insert(__MODULE__, {:entry, {env.file, line, module_or_mfa, mode, type}}) + end + + :ok + end + + defp print_traces(entries) do + # We don't want to show aliases if there is an entry of the same type + non_aliases = + for {_file, _line, module_or_mfa, mode, type} <- entries, + type != :alias, + into: %{}, + do: {{trace_module(module_or_mfa), mode}, []} + + shell = Mix.shell() + + for {file, line, module_or_mfa, mode, type} <- entries, + type != :alias or not Map.has_key?(non_aliases, {module_or_mfa, mode}) do + shell.info([ + Exception.format_file_line(Path.relative_to_cwd(file), line), + ?\s, + Atom.to_string(type), + ?\s, + format_module_or_mfa(module_or_mfa), + " (#{mode})" + ]) + + :ok + end + end + + defp trace_label(nil), do: nil + defp trace_label("compile"), do: :compile + defp trace_label("export"), do: :export + defp trace_label("runtime"), do: :runtime + defp trace_label(other), do: Mix.raise("Unknown --label #{other} in mix xref trace") + + defp trace_module({m, _, _}), do: m + defp trace_module(m), do: m + + defp format_module_or_mfa({m, f, a}), do: Exception.format_mfa(m, f, a) + defp format_module_or_mfa(m), do: inspect(m) + ## Graph defp excluded(opts) do @@ -457,7 +599,7 @@ defmodule Mix.Tasks.Xref do defp label_filter("runtime"), do: {:all, nil} defp label_filter("compile-connected"), do: {:all, :compile_connected} defp label_filter("compile-direct"), do: {:compile, :all} - defp label_filter(other), do: Mix.raise("Unknown --label #{other}") + defp label_filter(other), do: Mix.raise("Unknown --label #{other} in mix xref graph") defp file_references(filter, opts) do module_sources = @@ -601,7 +743,7 @@ defmodule Mix.Tasks.Xref do {:references, count_references(file_references)} other -> - Mix.raise("Unknown --format #{other}") + Mix.raise("Unknown --format #{other} in mix xref graph") end check_failure(found, count, opts[:fail_above]) @@ -799,6 +941,19 @@ defmodule Mix.Tasks.Xref do do: source end + defp apps(opts) do + siblings = + if opts[:include_siblings] do + for %{scm: Mix.SCM.Path, opts: opts, app: app} <- Mix.Dep.cached(), + opts[:in_umbrella], + do: app + else + [] + end + + [Mix.Project.config()[:app] | siblings] + end + defp manifests(opts) do siblings = if opts[:include_siblings] do @@ -811,4 +966,13 @@ defmodule Mix.Tasks.Xref do [Path.join(Mix.Project.manifest_path(), @manifest) | siblings] end + + defp check_failure(found, count, max_count) + when not is_nil(max_count) and count > max_count do + Mix.raise("Too many #{found} (found: #{count}, permitted: #{max_count})") + end + + defp check_failure(_, _, _) do + :ok + end end diff --git a/lib/mix/test/mix/tasks/xref_test.exs b/lib/mix/test/mix/tasks/xref_test.exs index b5f8b52d01d..c0dc8cea4c9 100644 --- a/lib/mix/test/mix/tasks/xref_test.exs +++ b/lib/mix/test/mix/tasks/xref_test.exs @@ -226,6 +226,118 @@ defmodule Mix.Tasks.XrefTest do end end + describe "mix xref trace FILE" do + test "shows labelled traces" do + files = %{ + "lib/a.ex" => ~S""" + defmodule A do + defstruct [:foo, :bar] + defmacro macro, do: :ok + def fun, do: :ok + end + """, + "lib/b.ex" => ~S""" + defmodule B do + import A + A.macro() + macro() + A.fun() + fun() + def calls_macro, do: A.macro() + def calls_fun, do: A.fun() + def calls_struct, do: %A{} + end + """ + } + + output = """ + Compiling 2 files (.ex) + Generated sample app + lib/b.ex:2: require A (export) + lib/b.ex:3: call A.macro/0 (compile) + lib/b.ex:4: import A.macro/0 (compile) + lib/b.ex:5: call A.fun/0 (compile) + lib/b.ex:6: call A.fun/0 (compile) + lib/b.ex:6: import A.fun/0 (compile) + lib/b.ex:7: call A.macro/0 (compile) + lib/b.ex:8: call A.fun/0 (runtime) + lib/b.ex:9: struct A (export) + """ + + assert_trace("lib/b.ex", files, output) + end + + test "filters per label" do + files = %{ + "lib/a.ex" => ~S""" + defmodule A do + defmacro macro, do: :ok + def fun, do: :ok + end + """, + "lib/b.ex" => ~S""" + defmodule B do + require A + def calls_macro, do: A.macro() + def calls_fun, do: A.fun() + end + """ + } + + output = """ + Compiling 2 files (.ex) + Generated sample app + lib/b.ex:3: call A.macro/0 (compile) + """ + + assert_trace(~w[--label compile], "lib/b.ex", files, output) + end + + test "fails if above limit per label" do + files = %{ + "lib/a.ex" => ~S""" + defmodule A do + defmacro macro, do: :ok + def fun, do: :ok + end + """, + "lib/b.ex" => ~S""" + defmodule B do + require A + def calls_macro, do: A.macro() + def calls_fun, do: A.fun() + end + """ + } + + output = """ + Compiling 2 files (.ex) + Generated sample app + lib/b.ex:3: call A.macro/0 (compile) + """ + + message = "Too many traces (found: 1, permitted: 0)" + + assert_raise Mix.Error, message, fn -> + assert_trace(~w[--label compile --fail-above 0], "lib/b.ex", files, output) + end + end + + defp assert_trace(opts \\ [], file, files, expected) do + in_fixture("no_mixfile", fn -> + for {file, contents} <- files do + File.write!(file, contents) + end + + capture_io(:stderr, fn -> + assert Mix.Task.run("xref", opts ++ ["trace", file]) == :ok + end) + + assert ^expected = receive_until_no_messages([]) + end) + end + end + describe "mix xref graph" do test "basic usage" do assert_graph(""" @@ -304,13 +416,13 @@ defmodule Mix.Tasks.XrefTest do end test "unknown label" do - assert_raise Mix.Error, "Unknown --label bad", fn -> + assert_raise Mix.Error, "Unknown --label bad in mix xref graph", fn -> assert_graph(["--label", "bad"], "") end end test "unknown format" do - assert_raise Mix.Error, "Unknown --format bad", fn -> + assert_raise Mix.Error, "Unknown --format bad in mix xref graph", fn -> assert_graph(["--format", "bad"], "") end end From f3ece01dab66a236af3980608135ed3cffc445d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 17 Aug 2021 17:52:10 +0200 Subject: [PATCH 2/2] Fix tracing --- lib/elixir/src/elixir_module.erl | 1 - lib/elixir/test/elixir/kernel/tracers_test.exs | 2 -- lib/mix/test/mix/tasks/compile.elixir_test.exs | 12 ++++++------ 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/elixir/src/elixir_module.erl b/lib/elixir/src/elixir_module.erl index 975e3427d61..7bf24b1246f 100644 --- a/lib/elixir/src/elixir_module.erl +++ b/lib/elixir/src/elixir_module.erl @@ -103,7 +103,6 @@ compile(Line, Module, Block, Vars, E) -> try put_compiler_modules([Module | CompilerModules]), - elixir_env:trace({defmodule, [{line, Line}]}, E), {Result, NE} = eval_form(Line, Module, DataBag, Block, Vars, E), CheckerInfo = get(elixir_checker_info), diff --git a/lib/elixir/test/elixir/kernel/tracers_test.exs b/lib/elixir/test/elixir/kernel/tracers_test.exs index ff128c8d0ac..e38757a8322 100644 --- a/lib/elixir/test/elixir/kernel/tracers_test.exs +++ b/lib/elixir/test/elixir/kernel/tracers_test.exs @@ -134,8 +134,6 @@ defmodule Kernel.TracersTest do end """) - assert_receive {{:defmodule, _meta}, %{module: Sample}} - assert_receive {{:local_macro, meta, :foo, 1}, _} assert meta[:line] == 4 assert meta[:column] == 21 diff --git a/lib/mix/test/mix/tasks/compile.elixir_test.exs b/lib/mix/test/mix/tasks/compile.elixir_test.exs index 03646b0d8df..d7487f05263 100644 --- a/lib/mix/test/mix/tasks/compile.elixir_test.exs +++ b/lib/mix/test/mix/tasks/compile.elixir_test.exs @@ -10,8 +10,8 @@ defmodule Mix.Tasks.Compile.ElixirTest do :ok end - def trace(event, _e) do - send(__MODULE__, event) + def trace(event, env) do + send(__MODULE__, {event, env}) :ok end @@ -50,8 +50,8 @@ defmodule Mix.Tasks.Compile.ElixirTest do in_fixture("no_mixfile", fn -> Mix.Tasks.Compile.Elixir.run(["--tracer", "Mix.Tasks.Compile.ElixirTest"]) - assert_received {:alias_reference, _meta, A} - assert_received {:alias_reference, _meta, B} + assert_received {{:on_module, _, :none}, %{module: A}} + assert_received {{:on_module, _, :none}, %{module: B}} end) after Code.put_compiler_option(:tracers, []) @@ -63,8 +63,8 @@ defmodule Mix.Tasks.Compile.ElixirTest do in_fixture("no_mixfile", fn -> Mix.Tasks.Compile.Elixir.run([]) - assert_received {:alias_reference, _meta, A} - assert_received {:alias_reference, _meta, B} + assert_received {{:on_module, _, :none}, %{module: A}} + assert_received {{:on_module, _, :none}, %{module: B}} end) after Code.put_compiler_option(:tracers, [])