Is it possible to use compiler tracing to detect when a function is called from generated code?

I’m working on a library that uses compiler tracing to detect calls to @moduledoc false and @doc false modules/functions. But if code was generated in a macro within a dependency I do not want to generate a warning for that call/reference even if that code is calling a module that would typically be private.

Here is an example of a macro that creates a function that calls a module (ExampleDep.Private) that is @moduledoc false but should not generate a warning from your application (PrivCheckExample):

defmodule ExampleDep.PubMacros do
  ...
  defmacro expand_funcs do
    quote location: :keep, unquote: false do
      def good_func do
        ExampleDep.Private.add(1, 2)
      end
    end
  end
  ...
end

I’m trying to disambiguate the :alias_reference check first. Here is all the data that I am receiving:

ref: {:alias_reference, [line: 13, counter: {PrivCheckExample, 3}, alias: false],
 ExampleDep.Private}
env: #Macro.Env<
  aliases: [],
  context: nil,
  context_modules: [PrivCheckExample],
  file: "lib/example_dep/pub_macros.ex",
  function: {:good_func, 0},
  functions: [{Kernel, [!=: 2, !==: 2, *: 2, ...]}],
  lexical_tracker: #PID<0.179.0>,
  line: 36,
  macro_aliases: [],
  macros: [{Kernel, ...}],
  module: PrivCheckExample,
  requires: [...],
  ...
>

Currently the only possibility that I see is that the file path in the Macro.Env is relative rather absolute, and the file name doesn’t match the current module (but since the file name could be anything that is not reliable). Can I depend on the fact that the file path is not absolute to know that the call was generated within a macro?

No, unfortunately that’s not possible today. The file path in Macro.Env doesn’t guarantee it either, as it only changes when using location: :keep.

1 Like

I get around macros without location: :keep by not checking them (if there’s a :remote_macro call at the same line in the file then errors on that line are ignored).

Could I say that a relative path in Macro.Env indicates that location: :keep was used? Maybe as a heuristic I could ignore those as well.

For my tool I’m trying to avoid any false positives, but false negatives are okay (since it appears impossible to account for them in an automated tool).