Skip to content

Commit

Permalink
fix(completions): completions inside alias/import/require special for…
Browse files Browse the repository at this point in the history
…ms (#422)

Closes #421
  • Loading branch information
mhanberg committed Apr 17, 2024
1 parent 1bb590e commit d62809e
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 18 deletions.
52 changes: 35 additions & 17 deletions priv/monkey/_next_ls_private_compiler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1213,38 +1213,56 @@ if Version.match?(System.version(), ">= 1.17.0-dev") do
expand({form, meta, [arg, []]}, state, env)
end

defp expand({:alias, meta, [arg, opts]}, state, env) do
defp expand({:alias, meta, [arg, opts]} = node, state, env) do
{arg, state, env} = expand(arg, state, env)
{opts, state, env} = expand_directive_opts(opts, state, env)

# An actual compiler would raise if the alias fails.
case Macro.Env.define_alias(env, meta, arg, [trace: false] ++ opts) do
{:ok, env} -> {arg, state, env}
{:error, _} -> {arg, state, env}
case arg do
{:__aliases__, _, _} ->
# An actual compiler would raise if the alias fails.
case Macro.Env.define_alias(env, meta, arg, [trace: false] ++ opts) do
{:ok, env} -> {arg, state, env}
{:error, _} -> {arg, state, env}
end

_ ->
{node, state, env}
end
end

defp expand({:require, meta, [arg, opts]}, state, env) do
defp expand({:require, meta, [arg, opts]} = node, state, env) do
{arg, state, env} = expand(arg, state, env)
{opts, state, env} = expand_directive_opts(opts, state, env)

# An actual compiler would raise if the module is not defined or if the require fails.
case Macro.Env.define_require(env, meta, arg, [trace: false] ++ opts) do
{:ok, env} -> {arg, state, env}
{:error, _} -> {arg, state, env}
case arg do
{:__aliases__, _, _} ->
# An actual compiler would raise if the module is not defined or if the require fails.
case Macro.Env.define_require(env, meta, arg, [trace: false] ++ opts) do
{:ok, env} -> {arg, state, env}
{:error, _} -> {arg, state, env}
end

_ ->
{node, state, env}
end
end

defp expand({:import, meta, [arg, opts]}, state, env) do
defp expand({:import, meta, [arg, opts]} = node, state, env) do
{arg, state, env} = expand(arg, state, env)
{opts, state, env} = expand_directive_opts(opts, state, env)

# An actual compiler would raise if the module is not defined or if the import fails.
with true <- is_atom(arg) and Code.ensure_loaded?(arg),
{:ok, env} <- Macro.Env.define_import(env, meta, arg, [trace: false] ++ opts) do
{arg, state, env}
else
_ -> {arg, state, env}
case arg do
{:__aliases__, _, _} ->
# An actual compiler would raise if the module is not defined or if the import fails.
with true <- is_atom(arg) and Code.ensure_loaded?(arg),
{:ok, env} <- Macro.Env.define_import(env, meta, arg, [trace: false] ++ opts) do
{arg, state, env}
else
_ -> {arg, state, env}
end

_ ->
{node, state, env}
end
end

Expand Down
53 changes: 52 additions & 1 deletion test/next_ls/completions_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ defmodule NextLS.CompletionsTest do
end
""")

baz = Path.join(cwd, "my_proj/lib/baz.ex")

File.write!(baz, """
defmodule Foo.Bar.Baz do
def run() do
:ok
end
end
""")

[foo: foo, cwd: cwd]
end

Expand Down Expand Up @@ -285,7 +295,7 @@ defmodule NextLS.CompletionsTest do
}
}

assert_result 2, [_, _] = results
assert_result 2, [_, _, _] = results
results
end)

Expand All @@ -300,6 +310,14 @@ defmodule NextLS.CompletionsTest do
"label" => "bar.ex"
} in results

assert %{
"data" => nil,
"documentation" => "",
"insertText" => "baz.ex",
"kind" => 17,
"label" => "baz.ex"
} in results

assert %{
"data" => nil,
"documentation" => "",
Expand Down Expand Up @@ -342,4 +360,37 @@ defmodule NextLS.CompletionsTest do
}
]
end

test "inside alias special form", %{client: client, foo: foo} do
uri = uri(foo)

did_open(client, foo, """
defmodule Foo do
alias Foo.Bar.
def run() do
:ok
end
end
""")

request client, %{
method: "textDocument/completion",
id: 2,
jsonrpc: "2.0",
params: %{
textDocument: %{
uri: uri
},
position: %{
line: 1,
character: 16
}
}
}

assert_result 2, [
%{"data" => _, "documentation" => _, "insertText" => "Baz", "kind" => 9, "label" => "Baz"}
]
end
end

0 comments on commit d62809e

Please sign in to comment.