Skip to content

Commit d62809e

Browse files
authored
fix(completions): completions inside alias/import/require special forms (#422)
Closes #421
1 parent 1bb590e commit d62809e

File tree

2 files changed

+87
-18
lines changed

2 files changed

+87
-18
lines changed

priv/monkey/_next_ls_private_compiler.ex

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1213,38 +1213,56 @@ if Version.match?(System.version(), ">= 1.17.0-dev") do
12131213
expand({form, meta, [arg, []]}, state, env)
12141214
end
12151215

1216-
defp expand({:alias, meta, [arg, opts]}, state, env) do
1216+
defp expand({:alias, meta, [arg, opts]} = node, state, env) do
12171217
{arg, state, env} = expand(arg, state, env)
12181218
{opts, state, env} = expand_directive_opts(opts, state, env)
12191219

1220-
# An actual compiler would raise if the alias fails.
1221-
case Macro.Env.define_alias(env, meta, arg, [trace: false] ++ opts) do
1222-
{:ok, env} -> {arg, state, env}
1223-
{:error, _} -> {arg, state, env}
1220+
case arg do
1221+
{:__aliases__, _, _} ->
1222+
# An actual compiler would raise if the alias fails.
1223+
case Macro.Env.define_alias(env, meta, arg, [trace: false] ++ opts) do
1224+
{:ok, env} -> {arg, state, env}
1225+
{:error, _} -> {arg, state, env}
1226+
end
1227+
1228+
_ ->
1229+
{node, state, env}
12241230
end
12251231
end
12261232

1227-
defp expand({:require, meta, [arg, opts]}, state, env) do
1233+
defp expand({:require, meta, [arg, opts]} = node, state, env) do
12281234
{arg, state, env} = expand(arg, state, env)
12291235
{opts, state, env} = expand_directive_opts(opts, state, env)
12301236

1231-
# An actual compiler would raise if the module is not defined or if the require fails.
1232-
case Macro.Env.define_require(env, meta, arg, [trace: false] ++ opts) do
1233-
{:ok, env} -> {arg, state, env}
1234-
{:error, _} -> {arg, state, env}
1237+
case arg do
1238+
{:__aliases__, _, _} ->
1239+
# An actual compiler would raise if the module is not defined or if the require fails.
1240+
case Macro.Env.define_require(env, meta, arg, [trace: false] ++ opts) do
1241+
{:ok, env} -> {arg, state, env}
1242+
{:error, _} -> {arg, state, env}
1243+
end
1244+
1245+
_ ->
1246+
{node, state, env}
12351247
end
12361248
end
12371249

1238-
defp expand({:import, meta, [arg, opts]}, state, env) do
1250+
defp expand({:import, meta, [arg, opts]} = node, state, env) do
12391251
{arg, state, env} = expand(arg, state, env)
12401252
{opts, state, env} = expand_directive_opts(opts, state, env)
12411253

1242-
# An actual compiler would raise if the module is not defined or if the import fails.
1243-
with true <- is_atom(arg) and Code.ensure_loaded?(arg),
1244-
{:ok, env} <- Macro.Env.define_import(env, meta, arg, [trace: false] ++ opts) do
1245-
{arg, state, env}
1246-
else
1247-
_ -> {arg, state, env}
1254+
case arg do
1255+
{:__aliases__, _, _} ->
1256+
# An actual compiler would raise if the module is not defined or if the import fails.
1257+
with true <- is_atom(arg) and Code.ensure_loaded?(arg),
1258+
{:ok, env} <- Macro.Env.define_import(env, meta, arg, [trace: false] ++ opts) do
1259+
{arg, state, env}
1260+
else
1261+
_ -> {arg, state, env}
1262+
end
1263+
1264+
_ ->
1265+
{node, state, env}
12481266
end
12491267
end
12501268

test/next_ls/completions_test.exs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ defmodule NextLS.CompletionsTest do
3131
end
3232
""")
3333

34+
baz = Path.join(cwd, "my_proj/lib/baz.ex")
35+
36+
File.write!(baz, """
37+
defmodule Foo.Bar.Baz do
38+
def run() do
39+
:ok
40+
end
41+
end
42+
""")
43+
3444
[foo: foo, cwd: cwd]
3545
end
3646

@@ -285,7 +295,7 @@ defmodule NextLS.CompletionsTest do
285295
}
286296
}
287297

288-
assert_result 2, [_, _] = results
298+
assert_result 2, [_, _, _] = results
289299
results
290300
end)
291301

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

313+
assert %{
314+
"data" => nil,
315+
"documentation" => "",
316+
"insertText" => "baz.ex",
317+
"kind" => 17,
318+
"label" => "baz.ex"
319+
} in results
320+
303321
assert %{
304322
"data" => nil,
305323
"documentation" => "",
@@ -342,4 +360,37 @@ defmodule NextLS.CompletionsTest do
342360
}
343361
]
344362
end
363+
364+
test "inside alias special form", %{client: client, foo: foo} do
365+
uri = uri(foo)
366+
367+
did_open(client, foo, """
368+
defmodule Foo do
369+
alias Foo.Bar.
370+
371+
def run() do
372+
:ok
373+
end
374+
end
375+
""")
376+
377+
request client, %{
378+
method: "textDocument/completion",
379+
id: 2,
380+
jsonrpc: "2.0",
381+
params: %{
382+
textDocument: %{
383+
uri: uri
384+
},
385+
position: %{
386+
line: 1,
387+
character: 16
388+
}
389+
}
390+
}
391+
392+
assert_result 2, [
393+
%{"data" => _, "documentation" => _, "insertText" => "Baz", "kind" => 9, "label" => "Baz"}
394+
]
395+
end
345396
end

0 commit comments

Comments
 (0)