From 990237891aabd949c1a281ef9506d9a04bf094f3 Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Sat, 5 Aug 2023 11:21:59 -0400 Subject: [PATCH] feat: go to definition when aliases modules --- lib/next_ls.ex | 7 ++- lib/next_ls/definition.ex | 68 +++++++++++++++++------- lib/next_ls/runtime/sidecar.ex | 6 +++ priv/monkey/_next_ls_private_compiler.ex | 11 +++- 4 files changed, 70 insertions(+), 22 deletions(-) diff --git a/lib/next_ls.ex b/lib/next_ls.ex index 4b9f1cf0..057f8123 100644 --- a/lib/next_ls.ex +++ b/lib/next_ls.ex @@ -127,7 +127,12 @@ defmodule NextLS do result = dispatch(lsp.assigns.registry, :databases, fn entries -> for {pid, _} <- entries do - case Definition.fetch(URI.parse(uri).path, {position.line + 1, position.character + 1}, pid) do + case Definition.fetch( + URI.parse(uri).path, + {position.line + 1, position.character + 1}, + pid, + Enum.join(lsp.assigns.documents[uri], "\n") + ) do nil -> nil diff --git a/lib/next_ls/definition.ex b/lib/next_ls/definition.ex index 4dc304f0..e86af354 100644 --- a/lib/next_ls/definition.ex +++ b/lib/next_ls/definition.ex @@ -4,24 +4,16 @@ defmodule NextLS.Definition do alias NextLS.DB - def fetch(file, {line, col}, db) do - with [[_pk, identifier, _arity, _file, type, module, _start_l, _start_c, _end_l, _end_c | _]] <- - DB.query( - db, - ~Q""" - SELECT - * - FROM - 'references' AS refs - WHERE - refs.file = ? - AND ? BETWEEN refs.start_line AND refs.end_line - AND ? BETWEEN refs.start_column AND refs.end_column - ORDER BY refs.id asc - LIMIT 1; - """, - [file, line, col] - ) do + def fetch(file, {line, col}, db, text) do + reference = + with nil <- fetch_from_db(db, {file, line, col}), + nil <- fetch_from_context(text, {line, col}) do + nil + end + + dbg(reference) + + with %{identifier: identifier, type: type, module: module} <- reference do query = ~Q""" SELECT @@ -50,7 +42,45 @@ defmodule NextLS.Definition do else nil end - else + end + end + + defp fetch_from_db(db, {file, line, col}) do + rows = + DB.query( + db, + ~Q""" + SELECT + * + FROM + 'references' AS refs + WHERE + refs.file = ? + AND refs.start_line <= ? + AND ? <= refs.end_line + AND refs.start_column <= ? + AND ? <= refs.end_column + ORDER BY refs.id asc + LIMIT 1; + """, + [file, line, line, col, col] + ) + + case rows do + [[_pk, identifier, _arity, _file, type, module, _start_l, _start_c, _end_l, _end_c | _]] -> + %{identifier: identifier, type: type, module: module} + + [] -> + nil + end + end + + defp fetch_from_context(text, {line, col}) do + case Code.Fragment.surround_context(text, {line, col}) do + %{context: {:alias, alias}} -> + module = to_string(alias) + %{identifier: module, type: "alias", module: module} + _ -> nil end diff --git a/lib/next_ls/runtime/sidecar.ex b/lib/next_ls/runtime/sidecar.ex index c0b0d062..1361726c 100644 --- a/lib/next_ls/runtime/sidecar.ex +++ b/lib/next_ls/runtime/sidecar.ex @@ -25,4 +25,10 @@ defmodule NextLS.Runtime.Sidecar do {:noreply, state} end + + def handle_info({{:tracer, :dbg}, payload}, state) do + dbg(payload) + + {:noreply, state} + end end diff --git a/priv/monkey/_next_ls_private_compiler.ex b/priv/monkey/_next_ls_private_compiler.ex index 63e59164..4ba12798 100644 --- a/priv/monkey/_next_ls_private_compiler.ex +++ b/priv/monkey/_next_ls_private_compiler.ex @@ -78,7 +78,8 @@ defmodule NextLSPrivate.Tracer do :ok end - def trace({type, meta, module, func, arity}, env) when type in [:remote_function, :remote_macro, :imported_macro] do + def trace({type, meta, module, func, arity} = it, env) + when type in [:remote_function, :remote_macro, :imported_macro] do parent = parent_pid() if type == :remote_macro && meta[:closing][:line] != meta[:line] do @@ -105,7 +106,7 @@ defmodule NextLSPrivate.Tracer do :ok end - def trace({type, meta, func, arity}, env) when type in [:local_function, :local_macro] do + def trace({type, meta, func, arity} = it, env) when type in [:local_function, :local_macro] do parent = parent_pid() Process.send( @@ -157,6 +158,12 @@ defmodule NextLSPrivate.Tracer do :ok end + def trace(it, env) do + parent = parent_pid() + Process.send(parent, {{:tracer, :dbg}, {it, env.aliases}}, []) + :ok + end + def trace(_event, _env) do :ok end