Skip to content

Commit

Permalink
feat(definitions): macros (#81)
Browse files Browse the repository at this point in the history
  • Loading branch information
mhanberg authored Jul 3, 2023
1 parent 1314754 commit 1d3b022
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 16 deletions.
3 changes: 2 additions & 1 deletion lib/next_ls/definition.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ defmodule NextLS.Definition do
]
)

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

case ref do
[ref] ->
Expand Down
36 changes: 22 additions & 14 deletions priv/monkey/_next_ls_private_compiler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,34 @@ defmodule NextLSPrivate.Tracer do
:ok
end

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

Process.send(
parent,
{{:tracer, :local_function},
%{
meta: meta,
func: func,
arity: arity,
file: env.file,
module: module
}},
[]
)
if type == :remote_macro && meta[:closing][:line] != meta[:line] do
# this is the case that a macro is getting expanded from inside
# another macro expansion
:noop
else
Process.send(
parent,
{{:tracer, :local_function},
%{
meta: meta,
func: func,
arity: arity,
file: env.file,
module: module
}},
[]
)
end

:ok
end

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

Process.send(
Expand Down
174 changes: 173 additions & 1 deletion test/next_ls_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ defmodule NextLSTest do
end
end

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

Expand Down Expand Up @@ -629,6 +629,178 @@ defmodule NextLSTest do
end
end

describe "macro go to definition" do
setup %{cwd: cwd} do
remote = Path.join(cwd, "lib/remote.ex")

File.write!(remote, """
defmodule Remote do
defmacro bang!() do
quote do
"‼️"
end
end
end
""")

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

File.write!(imported, """
defmodule Imported do
defmacro boom() do
quote do
"💣"
end
end
end
""")

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

File.write!(bar, """
defmodule Foo do
require Remote
import Imported
defmacrop process() do
quote location: :keep do
boom()
:ok
end
end
def run() do
Remote.bang!()
boom()
process()
end
end
""")

[bar: bar, imported: imported, remote: remote]
end

setup :with_lsp

test "go to local macro definition", %{client: client, bar: bar} do
assert :ok ==
notify(client, %{
method: "initialized",
jsonrpc: "2.0",
params: %{}
})

assert_notification "window/logMessage", %{"message" => "[NextLS] Runtime ready..."}
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}

uri = uri(bar)

request(client, %{
method: "textDocument/definition",
id: 4,
jsonrpc: "2.0",
params: %{
position: %{line: 14, character: 6},
textDocument: %{uri: uri}
}
})

assert_result 4, %{
"range" => %{
"start" => %{
"line" => 4,
"character" => 0
},
"end" => %{
"line" => 4,
"character" => 0
}
},
"uri" => ^uri
}
end

test "go to imported macro definition", %{client: client, bar: bar, imported: imported} do
assert :ok ==
notify(client, %{
method: "initialized",
jsonrpc: "2.0",
params: %{}
})

assert_notification "window/logMessage", %{"message" => "[NextLS] Runtime ready..."}
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}

uri = uri(bar)

request(client, %{
method: "textDocument/definition",
id: 4,
jsonrpc: "2.0",
params: %{
position: %{line: 13, character: 5},
textDocument: %{uri: uri}
}
})

uri = uri(imported)

assert_result 4, %{
"range" => %{
"start" => %{
"line" => 1,
"character" => 0
},
"end" => %{
"line" => 1,
"character" => 0
}
},
"uri" => ^uri
}
end

test "go to remote macro definition", %{client: client, bar: bar, remote: remote} do
assert :ok ==
notify(client, %{
method: "initialized",
jsonrpc: "2.0",
params: %{}
})

assert_notification "window/logMessage", %{"message" => "[NextLS] Runtime ready..."}
assert_notification "window/logMessage", %{"message" => "[NextLS] Compiled!"}

uri = uri(bar)

request(client, %{
method: "textDocument/definition",
id: 4,
jsonrpc: "2.0",
params: %{
position: %{line: 12, character: 13},
textDocument: %{uri: uri}
}
})

uri = uri(remote)

assert_result 4, %{
"range" => %{
"start" => %{
"line" => 1,
"character" => 0
},
"end" => %{
"line" => 1,
"character" => 0
}
},
"uri" => ^uri
}
end
end

defp with_lsp(%{tmp_dir: tmp_dir}) do
root_path = Path.absname(tmp_dir)

Expand Down

0 comments on commit 1d3b022

Please sign in to comment.