vscode-elixir-ls icon indicating copy to clipboard operation
vscode-elixir-ls copied to clipboard

Go-to-definition & hover lost when using dynamic module calls via Application.get_env/3

Open Ruhshan opened this issue 7 months ago • 3 comments

I’ve noticed that ElixirLS navigation and hover only work when I call modules directly, but break as soon as I switch to a dynamic lookup via Application.get_env/3.

Direct calls (works)

defmodule TaskProcessor.Events do
  alias TaskProcessor.Segments
  alias TaskProcessor.Events.Queue.Oban,         as: EventsQueue
  alias TaskProcessor.Events.Persistance.Ecto,   as: Repo

  def enqueue_create_event(event_id) when is_integer(event_id) and event_id > 0 do
    EventsQueue.enqueue_create_event(event_id)
  end

  def enqueue_create_event(bad_event_id), do: {:error, {:invalid_event_id, bad_event_id}}

  def process_event(%{event_id: id, isCreated: true}) do
    case Repo.fetch_with_segments(id) do
      :not_found -> {:error, :not_found}
      {:ok, %{date: date, segments: segs}} ->
        Segments.schedule_segments(segs, id, date)
    end
  end
end

  • Cmd+Click on EventsQueue.enqueue_create_event/1 or Repo.fetch_with_segments/1 jumps to the implementation.
  • Hover shows the function signature.

Dynamic calls (Not working, or am i not doing right ?)

defmodule TaskProcessor.Events.Impl do
  @behaviour TaskProcessor.Events.Behavior

  alias TaskProcessor.Segments

  @impl true
  @spec enqueue_create_event(any()) :: {:ok, Oban.Job.t()} | {:error, any()}
  def enqueue_create_event(event_id) when is_integer(event_id) and event_id > 0 do
    queue_impl().enqueue_create_event(event_id)
  end

  def enqueue_create_event(bad_event_id), do: {:error, {:invalid_event_id, bad_event_id}}

  @impl true
  def process_event(%{event_id: id, isCreated: true}) do
    case repo_impl().fetch_with_segments(id) do
      :not_found -> {:error, :not_found}
      {:ok, %{date: date, segments: segs}} ->
        Segments.schedule_segments(segs, id, date)
    end
  end

  defp queue_impl do
    Application.get_env(:task_processor, :events_queue, TaskProcessor.Events.Queue.Oban)
  end

  defp repo_impl do
    Application.get_env(:task_processor, :events_repo,  TaskProcessor.Events.Persistance.Ecto)
  end
end
  • Cmd+Click on queue_impl().enqueue_create_event/1 or repo_impl().fetch_with_segments/1 does nothing.
  • Hover shows nothing

Environment

- ElixirLS version: 0.28.0
- Elixir version: 1.18.4
- Erlang/OTP version: 28
- Macbook M1 

Is there any way to configure ElixirLS (or leverage Dialyzer/Elixir compiler hints) so that go-to-definition and hover info work for modules resolved at runtime via Application.get_env/3? I need this functionality so that I can dynamically inject mocks during tests using the Mox library.

Thank you!

Ruhshan avatar Jun 22 '25 12:06 Ruhshan

I tried to refactor it to use Application.compile_env/3. But stil doesn't works.

Image

Ruhshan avatar Jun 22 '25 19:06 Ruhshan

Update:

Installed elixir tools, that contains next-ls. Now I can use go to definition on @repo.fetch_with_segments.

I’m wondering, if next-ls can do it, elixir-ls which is more mature supposed to do it too.

Ruhshan avatar Jun 22 '25 20:06 Ruhshan

ElixirLS is conservative in evaluating user code during code intelligence. See related https://github.com/elixir-lsp/elixir_sense/issues/161. The basic compile_env scenario should work. Can you provide a code snippet that reproduces it?

lukaszsamson avatar Oct 23 '25 21:10 lukaszsamson