From 42ae2cad769f82b70ba6bd38b91963b9dca59e01 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 | 4 ++ priv/monkey/_next_ls_private_compiler.ex | 11 +++- 4 files changed, 68 insertions(+), 22 deletions(-) diff --git a/lib/next_ls.ex b/lib/next_ls.ex index 4ce70445..cf040803 100644 --- a/lib/next_ls.ex +++ b/lib/next_ls.ex @@ -129,7 +129,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 64ec9626..b6b88ad2 100644 --- a/lib/next_ls/runtime/sidecar.ex +++ b/lib/next_ls/runtime/sidecar.ex @@ -28,7 +28,11 @@ defmodule NextLS.Runtime.Sidecar do def handle_info({{:tracer, :start}, filename}, state) do DB.clean_references(state.db, filename) + {: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 e382a96e..fe784e47 100644 --- a/priv/monkey/_next_ls_private_compiler.ex +++ b/priv/monkey/_next_ls_private_compiler.ex @@ -84,7 +84,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 @@ -111,7 +112,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( @@ -163,6 +164,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