Skip to content

Commit 1d3b022

Browse files
authored
feat(definitions): macros (#81)
1 parent 1314754 commit 1d3b022

File tree

3 files changed

+197
-16
lines changed

3 files changed

+197
-16
lines changed

Diff for: lib/next_ls/definition.ex

+2-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ defmodule NextLS.Definition do
1313
]
1414
)
1515

16-
:dets.traverse(dets_symbol_table, fn x -> {:continue, x} end)
16+
# :dets.traverse(dets_symbol_table, fn x -> {:continue, x} end) |> dbg
17+
# :dets.traverse(dets_ref_table, fn x -> {:continue, x} end) |> dbg
1718

1819
case ref do
1920
[ref] ->

Diff for: priv/monkey/_next_ls_private_compiler.ex

+22-14
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,34 @@ defmodule NextLSPrivate.Tracer do
33
:ok
44
end
55

6-
def trace({:remote_function, meta, module, func, arity}, env) do
6+
def trace({type, meta, module, func, arity}, env)
7+
when type in [:remote_function, :remote_macro, :imported_macro] and
8+
module not in [:elixir_def, :elixir_utils, Kernel, Enum] do
79
parent = "NEXTLS_PARENT_PID" |> System.get_env() |> Base.decode64!() |> :erlang.binary_to_term()
810

9-
Process.send(
10-
parent,
11-
{{:tracer, :local_function},
12-
%{
13-
meta: meta,
14-
func: func,
15-
arity: arity,
16-
file: env.file,
17-
module: module
18-
}},
19-
[]
20-
)
11+
if type == :remote_macro && meta[:closing][:line] != meta[:line] do
12+
# this is the case that a macro is getting expanded from inside
13+
# another macro expansion
14+
:noop
15+
else
16+
Process.send(
17+
parent,
18+
{{:tracer, :local_function},
19+
%{
20+
meta: meta,
21+
func: func,
22+
arity: arity,
23+
file: env.file,
24+
module: module
25+
}},
26+
[]
27+
)
28+
end
2129

2230
:ok
2331
end
2432

25-
def trace({:local_function, meta, func, arity}, env) do
33+
def trace({type, meta, func, arity}, env) when type in [:local_function, :local_macro] do
2634
parent = "NEXTLS_PARENT_PID" |> System.get_env() |> Base.decode64!() |> :erlang.binary_to_term()
2735

2836
Process.send(

Diff for: test/next_ls_test.exs

+173-1
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ defmodule NextLSTest do
466466
end
467467
end
468468

469-
describe "two" do
469+
describe "function go to definition" do
470470
setup %{cwd: cwd} do
471471
remote = Path.join(cwd, "lib/remote.ex")
472472

@@ -629,6 +629,178 @@ defmodule NextLSTest do
629629
end
630630
end
631631

632+
describe "macro go to definition" do
633+
setup %{cwd: cwd} do
634+
remote = Path.join(cwd, "lib/remote.ex")
635+
636+
File.write!(remote, """
637+
defmodule Remote do
638+
defmacro bang!() do
639+
quote do
640+
"‼️"
641+
end
642+
end
643+
end
644+
""")
645+
646+
imported = Path.join(cwd, "lib/imported.ex")
647+
648+
File.write!(imported, """
649+
defmodule Imported do
650+
defmacro boom() do
651+
quote do
652+
"💣"
653+
end
654+
end
655+
end
656+
""")
657+
658+
bar = Path.join(cwd, "lib/bar.ex")
659+
660+
File.write!(bar, """
661+
defmodule Foo do
662+
require Remote
663+
import Imported
664+
665+
defmacrop process() do
666+
quote location: :keep do
667+
boom()
668+
:ok
669+
end
670+
end
671+
672+
def run() do
673+
Remote.bang!()
674+
boom()
675+
process()
676+
end
677+
end
678+
""")
679+
680+
[bar: bar, imported: imported, remote: remote]
681+
end
682+
683+
setup :with_lsp
684+
685+
test "go to local macro definition", %{client: client, bar: bar} do
686+
assert :ok ==
687+
notify(client, %{
688+
method: "initialized",
689+
jsonrpc: "2.0",
690+
params: %{}
691+
})
692+
693+
assert_notification "window/logMessage", %{"message" => "[NextLS] Runtime ready..."}
694+
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
695+
696+
uri = uri(bar)
697+
698+
request(client, %{
699+
method: "textDocument/definition",
700+
id: 4,
701+
jsonrpc: "2.0",
702+
params: %{
703+
position: %{line: 14, character: 6},
704+
textDocument: %{uri: uri}
705+
}
706+
})
707+
708+
assert_result 4, %{
709+
"range" => %{
710+
"start" => %{
711+
"line" => 4,
712+
"character" => 0
713+
},
714+
"end" => %{
715+
"line" => 4,
716+
"character" => 0
717+
}
718+
},
719+
"uri" => ^uri
720+
}
721+
end
722+
723+
test "go to imported macro definition", %{client: client, bar: bar, imported: imported} do
724+
assert :ok ==
725+
notify(client, %{
726+
method: "initialized",
727+
jsonrpc: "2.0",
728+
params: %{}
729+
})
730+
731+
assert_notification "window/logMessage", %{"message" => "[NextLS] Runtime ready..."}
732+
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
733+
734+
uri = uri(bar)
735+
736+
request(client, %{
737+
method: "textDocument/definition",
738+
id: 4,
739+
jsonrpc: "2.0",
740+
params: %{
741+
position: %{line: 13, character: 5},
742+
textDocument: %{uri: uri}
743+
}
744+
})
745+
746+
uri = uri(imported)
747+
748+
assert_result 4, %{
749+
"range" => %{
750+
"start" => %{
751+
"line" => 1,
752+
"character" => 0
753+
},
754+
"end" => %{
755+
"line" => 1,
756+
"character" => 0
757+
}
758+
},
759+
"uri" => ^uri
760+
}
761+
end
762+
763+
test "go to remote macro definition", %{client: client, bar: bar, remote: remote} do
764+
assert :ok ==
765+
notify(client, %{
766+
method: "initialized",
767+
jsonrpc: "2.0",
768+
params: %{}
769+
})
770+
771+
assert_notification "window/logMessage", %{"message" => "[NextLS] Runtime ready..."}
772+
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}
773+
774+
uri = uri(bar)
775+
776+
request(client, %{
777+
method: "textDocument/definition",
778+
id: 4,
779+
jsonrpc: "2.0",
780+
params: %{
781+
position: %{line: 12, character: 13},
782+
textDocument: %{uri: uri}
783+
}
784+
})
785+
786+
uri = uri(remote)
787+
788+
assert_result 4, %{
789+
"range" => %{
790+
"start" => %{
791+
"line" => 1,
792+
"character" => 0
793+
},
794+
"end" => %{
795+
"line" => 1,
796+
"character" => 0
797+
}
798+
},
799+
"uri" => ^uri
800+
}
801+
end
802+
end
803+
632804
defp with_lsp(%{tmp_dir: tmp_dir}) do
633805
root_path = Path.absname(tmp_dir)
634806

0 commit comments

Comments
 (0)