Skip to content

Commit

Permalink
fix: reap symbols when file is deleted (#127)
Browse files Browse the repository at this point in the history
  • Loading branch information
mhanberg authored Jul 28, 2023
1 parent 88a7f3a commit 9517615
Show file tree
Hide file tree
Showing 7 changed files with 195 additions and 76 deletions.
43 changes: 43 additions & 0 deletions lib/next_ls.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ defmodule NextLS do
alias GenLSP.Notifications.TextDocumentDidChange
alias GenLSP.Notifications.TextDocumentDidOpen
alias GenLSP.Notifications.TextDocumentDidSave
alias GenLSP.Notifications.WorkspaceDidChangeWatchedFiles
alias GenLSP.Notifications.WorkspaceDidChangeWorkspaceFolders
alias GenLSP.Requests.Initialize
alias GenLSP.Requests.Shutdown
alias GenLSP.Requests.TextDocumentDefinition
alias GenLSP.Requests.TextDocumentDocumentSymbol
alias GenLSP.Requests.TextDocumentFormatting
alias GenLSP.Requests.WorkspaceSymbol
alias GenLSP.Structures.DidChangeWatchedFilesParams
alias GenLSP.Structures.DidChangeWorkspaceFoldersParams
alias GenLSP.Structures.DidOpenTextDocumentParams
alias GenLSP.Structures.InitializeParams
Expand Down Expand Up @@ -283,6 +285,25 @@ defmodule NextLS do
)
end

nil =
GenLSP.request(lsp, %GenLSP.Requests.ClientRegisterCapability{
id: System.unique_integer([:positive]),
params: %GenLSP.Structures.RegistrationParams{
registrations: [
%GenLSP.Structures.Registration{
id: "file-watching",
method: "workspace/didChangeWatchedFiles",
register_options: %GenLSP.Structures.DidChangeWatchedFilesRegistrationOptions{
watchers:
for ext <- ~W|ex exs leex eex heex sface| do
%GenLSP.Structures.FileSystemWatcher{kind: 7, glob_pattern: "**/*.#{ext}"}
end
}
}
]
}
})

GenLSP.log(lsp, "[NextLS] Booting runtimes...")

for %{uri: uri, name: name} <- lsp.assigns.workspace_folders do
Expand Down Expand Up @@ -435,6 +456,28 @@ defmodule NextLS do
{:noreply, lsp}
end

def handle_notification(%WorkspaceDidChangeWatchedFiles{params: %DidChangeWatchedFilesParams{changes: changes}}, lsp) do
type = GenLSP.Enumerations.FileChangeType.deleted()

# TODO
# ✅ delete from documents
# ✅ delete all references that occur in this file
# ✅ delete all symbols from that file
lsp =
for %{type: ^type, uri: uri} <- changes, reduce: lsp do
lsp ->
dispatch(lsp.assigns.registry, :symbol_tables, fn entries ->
for {pid, _} <- entries do
SymbolTable.remove(pid, uri)
end
end)

update_in(lsp.assigns.documents, &Map.drop(&1, [uri]))
end

{:noreply, lsp}
end

def handle_notification(%Exit{}, lsp) do
System.halt(lsp.assigns.exit_code)

Expand Down
1 change: 1 addition & 0 deletions lib/next_ls/document_symbol.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule NextLS.DocumentSymbol do
@moduledoc false

alias GenLSP.Structures.DocumentSymbol
alias GenLSP.Structures.Position
alias GenLSP.Structures.Range
Expand Down
14 changes: 14 additions & 0 deletions lib/next_ls/symbol_table.ex
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ defmodule NextLS.SymbolTable do
}
end

@type uri :: String.t()

def start_link(args) do
GenServer.start_link(__MODULE__, Keyword.take(args, [:path, :workspace, :registry]), Keyword.take(args, [:name]))
end
Expand All @@ -26,6 +28,9 @@ defmodule NextLS.SymbolTable do
@spec put_reference(pid() | atom(), map()) :: :ok
def put_reference(server, reference), do: GenServer.cast(server, {:put_reference, reference})

@spec remove(pid() | atom(), uri()) :: :ok
def remove(server, uri), do: GenServer.cast(server, {:remove, uri})

@spec symbols(pid() | atom()) :: list(struct())
def symbols(server), do: GenServer.call(server, :symbols)

Expand Down Expand Up @@ -170,4 +175,13 @@ defmodule NextLS.SymbolTable do

{:noreply, state}
end

def handle_cast({:remove, uri}, %{table: symbol_table, reference_table: reference_table} = state) do
file = URI.parse(uri).path

:dets.select_delete(symbol_table, [{{:_, %{file: :"$1"}}, [], [{:==, :"$1", file}]}])
:dets.select_delete(reference_table, [{{{:"$1", :_}, :_}, [], [{:==, :"$1", file}]}])

{:noreply, state}
end
end
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ defmodule NextLS.MixProject do
# Run "mix help deps" to learn about dependencies.
defp deps do
[
{:gen_lsp, "~> 0.4"},
{:gen_lsp, "~> 0.5"},
{:styler, "~> 0.8", only: :dev},
{:ex_doc, ">= 0.0.0", only: :dev},
{:dialyxir, ">= 0.0.0", only: [:dev, :test], runtime: false}
Expand Down
4 changes: 2 additions & 2 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
"earmark_parser": {:hex, :earmark_parser, "1.4.32", "fa739a0ecfa34493de19426681b23f6814573faee95dfd4b4aafe15a7b5b32c6", [:mix], [], "hexpm", "b8b0dd77d60373e77a3d7e8afa598f325e49e8663a51bcc2b88ef41838cca755"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"ex_doc": {:hex, :ex_doc, "0.29.4", "6257ecbb20c7396b1fe5accd55b7b0d23f44b6aa18017b415cb4c2b91d997729", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2c6699a737ae46cb61e4ed012af931b57b699643b24dabe2400a8168414bc4f5"},
"gen_lsp": {:hex, :gen_lsp, "0.4.0", "e07e3c35890ae91ee624c5e2e888cef70bb046a8884b09675c33233d19d2ec1d", [:mix], [{:jason, "~> 1.3", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:schematic, "~> 0.2", [hex: :schematic, repo: "hexpm", optional: false]}, {:typed_struct, "~> 0.3.0", [hex: :typed_struct, repo: "hexpm", optional: false]}], "hexpm", "71e7ecd1295a9ba8c07659bc2241d3839ac97d5b1ffc0a86b8a2e08b09609079"},
"gen_lsp": {:hex, :gen_lsp, "0.5.0", "463d25c2b81f64b95667e1e6fa9bf2a4ed00896f5e9abe2965bc50edeebae747", [:mix], [{:jason, "~> 1.3", [hex: :jason, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.5 or ~> 1.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:schematic, "~> 0.2.1", [hex: :schematic, repo: "hexpm", optional: false]}, {:typed_struct, "~> 0.3.0", [hex: :typed_struct, repo: "hexpm", optional: false]}], "hexpm", "6d40e2315bd2206cb0e40e93c5d58b28ab15787214fea1066f6561df783ef7c9"},
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
"nimble_options": {:hex, :nimble_options, "1.0.2", "92098a74df0072ff37d0c12ace58574d26880e522c22801437151a159392270e", [:mix], [], "hexpm", "fd12a8db2021036ce12a309f26f564ec367373265b53e25403f0ee697380f1b8"},
"nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"},
"schematic": {:hex, :schematic, "0.2.0", "ac710efbd98b8f4b3d137f8ebac6f9a17da917bb4d1296b487ac4157fb74c806", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d4bc93bac2e7d04869fd6ced9df82c092c154fc648677512bc7c75d9a2655be3"},
"schematic": {:hex, :schematic, "0.2.1", "0b091df94146fd15a0a343d1bd179a6c5a58562527746dadd09477311698dbb1", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "0b255d65921e38006138201cd4263fd8bb807d9dfc511074615cd264a571b3b1"},
"styler": {:hex, :styler, "0.8.1", "f3c0f65023e4bfbf7e7aa752d128b8475fdabfd30f96ee7314b84480cc56e788", [:mix], [], "hexpm", "1aa48d3aa689a639289af3d8254d40e068e98c083d6e5e3d1a695e71a147b344"},
"telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"},
"typed_struct": {:hex, :typed_struct, "0.3.0", "939789e3c1dca39d7170c87f729127469d1315dcf99fee8e152bb774b17e7ff7", [:mix], [], "hexpm", "c50bd5c3a61fe4e198a8504f939be3d3c85903b382bde4865579bc23111d1b6d"},
Expand Down
9 changes: 8 additions & 1 deletion priv/monkey/_next_ls_private_compiler.ex
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,14 @@ defmodule :_next_ls_private_compiler do
# --no-compile, so nothing was compiled, but the
# task was not re-enabled it seems
Mix.Task.rerun("deps.loadpaths")
Mix.Task.rerun("compile", ["--no-protocol-consolidation", "--return-errors", "--tracer", "NextLSPrivate.Tracer"])

Mix.Task.rerun("compile", [
"--ignore-module-conflict",
"--no-protocol-consolidation",
"--return-errors",
"--tracer",
"NextLSPrivate.Tracer"
])
rescue
e -> {:error, e}
end
Expand Down
Loading

0 comments on commit 9517615

Please sign in to comment.