Skip to content

Commit 88dc456

Browse files
authored
fix: better handling of native<->lsp conversions (#34)
* fix: handle shutdown request conversion * fix: convert completion item tags * fix: supress errors caused by code actions triggered before we try to start the engine * chore: update elixir_sense
1 parent 8e57be4 commit 88dc456

File tree

9 files changed

+60
-28
lines changed

9 files changed

+60
-28
lines changed

apps/engine/mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ defmodule Engine.MixProject do
4444
Mix.Credo.dependency(),
4545
Mix.Dialyzer.dependency(),
4646
{:elixir_sense,
47-
github: "elixir-lsp/elixir_sense", ref: "73ce7e0d239342fb9527d7ba567203e77dbb9b25"},
47+
github: "elixir-lsp/elixir_sense", ref: "e3ddc403554050221a2fd19a10a896fa7525bc02"},
4848
{:forge, path: "../forge", env: Mix.env()},
4949
{:gen_lsp, "~> 0.11"},
5050
{:patch, "~> 0.15", only: [:dev, :test], optional: true, runtime: false},

apps/engine/mix.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"},
66
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
77
"dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"},
8-
"elixir_sense": {:git, "https://github.com/elixir-lsp/elixir_sense.git", "73ce7e0d239342fb9527d7ba567203e77dbb9b25", [ref: "73ce7e0d239342fb9527d7ba567203e77dbb9b25"]},
8+
"elixir_sense": {:git, "https://github.com/elixir-lsp/elixir_sense.git", "e3ddc403554050221a2fd19a10a896fa7525bc02", [ref: "e3ddc403554050221a2fd19a10a896fa7525bc02"]},
99
"erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"},
1010
"file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"},
1111
"gen_lsp": {:hex, :gen_lsp, "0.11.0", "9eda4d2fcaff94d9b3062e322fcf524c176db1502f584a3cff6135088b46084b", [: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", "d67c20650a5290a02f7bac53083ac4487d3c6b461f35a8b14c5d2d7638c20d26"},

apps/expert/lib/expert.ex

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -84,30 +84,39 @@ defmodule Expert do
8484
def handle_request(request, lsp) do
8585
state = assigns(lsp).state
8686

87-
with {:ok, handler} <- fetch_handler(request),
88-
{:ok, request} <- Convert.to_native(request),
89-
{:ok, response} <- handler.handle(request, state.configuration),
90-
{:ok, response} <- Expert.Protocol.Convert.to_lsp(response) do
91-
{:reply, response, lsp}
87+
if state.engine_initialized? do
88+
with {:ok, handler} <- fetch_handler(request),
89+
{:ok, request} <- Convert.to_native(request),
90+
{:ok, response} <- handler.handle(request, state.configuration),
91+
{:ok, response} <- Expert.Protocol.Convert.to_lsp(response) do
92+
{:reply, response, lsp}
93+
else
94+
{:error, {:unhandled, _}} ->
95+
Logger.info("Unhandled request: #{request.method}")
96+
97+
{:reply,
98+
%GenLSP.ErrorResponse{
99+
code: GenLSP.Enumerations.ErrorCodes.method_not_found(),
100+
message: "Method not found"
101+
}, lsp}
102+
103+
error ->
104+
message = "Failed to handle #{request.method}, #{inspect(error)}"
105+
Logger.error(message)
106+
107+
{:reply,
108+
%GenLSP.ErrorResponse{
109+
code: GenLSP.Enumerations.ErrorCodes.internal_error(),
110+
message: message
111+
}, lsp}
112+
end
92113
else
93-
{:error, {:unhandled, _}} ->
94-
Logger.info("Unhandled request: #{request.method}")
95-
96-
{:reply,
97-
%GenLSP.ErrorResponse{
98-
code: GenLSP.Enumerations.ErrorCodes.method_not_found(),
99-
message: "Method not found"
100-
}, lsp}
101-
102-
error ->
103-
message = "Failed to handle #{request.method}, #{inspect(error)}"
104-
Logger.error(message)
114+
GenLSP.warning(
115+
lsp,
116+
"Received request #{request.method} before engine was initialized. Ignoring."
117+
)
105118

106-
{:reply,
107-
%GenLSP.ErrorResponse{
108-
code: GenLSP.Enumerations.ErrorCodes.internal_error(),
109-
message: message
110-
}, lsp}
119+
{:noreply, lsp}
111120
end
112121
end
113122

@@ -155,6 +164,18 @@ defmodule Expert do
155164
end
156165
end
157166

167+
def handle_info(:engine_initialized, lsp) do
168+
state = assigns(lsp).state
169+
170+
new_state = %State{state | engine_initialized?: true}
171+
172+
lsp = assign(lsp, state: new_state)
173+
174+
Logger.info("Engine initialized")
175+
176+
{:noreply, lsp}
177+
end
178+
158179
def handle_info(:default_config, lsp) do
159180
state = assigns(lsp).state
160181

apps/expert/lib/expert/application.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ defmodule Expert.Application do
1919
{Task.Supervisor, name: :expert_task_queue},
2020
{GenLSP.Buffer, name: Expert.Buffer},
2121
{Expert,
22+
name: Expert,
2223
buffer: Expert.Buffer,
2324
task_supervisor: :expert_task_queue,
2425
dynamic_supervisor: Expert.DynamicSupervisor,

apps/expert/lib/expert/code_intelligence/completion/translations/callable.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ defmodule Expert.CodeIntelligence.Completion.Translations.Callable do
4444

4545
tags =
4646
if Map.get(callable.metadata, :deprecated) do
47-
[:deprecated]
47+
[GenLSP.Enumerations.CompletionItemTag.deprecated()]
4848
end
4949

5050
kind =

apps/expert/lib/expert/protocol/convert.ex

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,9 @@ defmodule Expert.Protocol.Convert do
2929
{:ok, %{original_request | params: updated_request}}
3030
end
3131
end
32+
33+
def to_native(%GenLSP.Requests.Shutdown{} = request) do
34+
# Special case for shutdown requests, which don't have a params field
35+
{:ok, request}
36+
end
3237
end

apps/expert/lib/expert/state.ex

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ defmodule Expert.State do
1616

1717
defstruct configuration: nil,
1818
initialized?: false,
19+
engine_initialized?: false,
1920
shutdown_received?: false,
2021
in_flight_requests: %{}
2122

@@ -54,7 +55,10 @@ defmodule Expert.State do
5455

5556
response = initialize_result()
5657

57-
Task.start_link(fn -> Project.Supervisor.start(config.project) end)
58+
Task.Supervisor.start_child(:expert_task_queue, fn ->
59+
Project.Supervisor.start(config.project)
60+
send(Expert, :engine_initialized)
61+
end)
5862

5963
{:ok, response, new_state}
6064
end

apps/expert/mix.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"credo": {:hex, :credo, "1.7.12", "9e3c20463de4b5f3f23721527fcaf16722ec815e70ff6c60b86412c695d426c1", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "8493d45c656c5427d9c729235b99d498bd133421f3e0a683e5c1b561471291e5"},
55
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
66
"dialyxir": {:hex, :dialyxir, "1.4.5", "ca1571ac18e0f88d4ab245f0b60fa31ff1b12cbae2b11bd25d207f865e8ae78a", [:mix], [{:erlex, ">= 0.2.7", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "b0fb08bb8107c750db5c0b324fa2df5ceaa0f9307690ee3c1f6ba5b9eb5d35c3"},
7-
"elixir_sense": {:git, "https://github.com/elixir-lsp/elixir_sense.git", "73ce7e0d239342fb9527d7ba567203e77dbb9b25", [ref: "73ce7e0d239342fb9527d7ba567203e77dbb9b25"]},
7+
"elixir_sense": {:git, "https://github.com/elixir-lsp/elixir_sense.git", "e3ddc403554050221a2fd19a10a896fa7525bc02", [ref: "e3ddc403554050221a2fd19a10a896fa7525bc02"]},
88
"erlex": {:hex, :erlex, "0.2.7", "810e8725f96ab74d17aac676e748627a07bc87eb950d2b83acd29dc047a30595", [:mix], [], "hexpm", "3ed95f79d1a844c3f6bf0cea61e0d5612a42ce56da9c03f01df538685365efb0"},
99
"file_system": {:hex, :file_system, "1.1.0", "08d232062284546c6c34426997dd7ef6ec9f8bbd090eb91780283c9016840e8f", [:mix], [], "hexpm", "bfcf81244f416871f2a2e15c1b515287faa5db9c6bcf290222206d120b3d43f6"},
1010
"gen_lsp": {:hex, :gen_lsp, "0.11.0", "9eda4d2fcaff94d9b3062e322fcf524c176db1502f584a3cff6135088b46084b", [: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", "d67c20650a5290a02f7bac53083ac4487d3c6b461f35a8b14c5d2d7638c20d26"},

apps/expert/test/expert/code_intelligence/completion/translations/function_test.exs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ defmodule Expert.CodeIntelligence.Completion.Translations.FunctionTest do
1212
|> fetch_completion("filter_map")
1313

1414
assert completion.label
15-
assert [:deprecated] = completion.tags
15+
expected_tag = GenLSP.Enumerations.CompletionItemTag.deprecated()
16+
assert [^expected_tag] = completion.tags
1617
end
1718

1819
test "bang functions are sorted after non-bang functions", %{project: project} do

0 commit comments

Comments
 (0)