Skip to content

Commit

Permalink
Async parse (#1045)
Browse files Browse the repository at this point in the history
* debounce parse made async

* extract common function

* don't go through the server for not parsable documents

* use common code path for calls with and without position

* handle immediate requests asynchronously

* store refs and respond on async process down

* cleanup error codes

:parse_error is reserved for invalid JSON-RPC requests and not LSP errors

* improve LSP compatibility - fill error.data on initialize error

* include version in key

* enqueue parsing requests to the same uri

* fix a few edge cases
  • Loading branch information
lukaszsamson committed Jan 1, 2024
1 parent 4edc564 commit 460d553
Show file tree
Hide file tree
Showing 7 changed files with 291 additions and 156 deletions.
38 changes: 33 additions & 5 deletions apps/language_server/lib/language_server/json_rpc.ex
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,20 @@ defmodule ElixirLS.LanguageServer.JsonRpc do
end
end

defmacro error_response(id, code, message, data) do
quote do
%{
"error" => %{
"code" => unquote(code),
"message" => unquote(message),
"data" => unquote(data)
},
"id" => unquote(id),
"jsonrpc" => "2.0"
}
end
end

## Utils

def notify(method, params) do
Expand All @@ -77,9 +91,14 @@ defmodule ElixirLS.LanguageServer.JsonRpc do
WireProtocol.send(response(id, result))
end

def respond_with_error(id, type, message \\ nil) do
def respond_with_error(id, type, message \\ nil, data \\ nil) do
{code, default_message} = error_code_and_message(type)
WireProtocol.send(error_response(id, code, message || default_message))

if data do
WireProtocol.send(error_response(id, code, message || default_message, data))
else
WireProtocol.send(error_response(id, code, message || default_message))
end
end

def show_message(type, message) do
Expand Down Expand Up @@ -226,16 +245,25 @@ defmodule ElixirLS.LanguageServer.JsonRpc do
end
end

# https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#errorCodes

# Defined by JSON-RPC
defp error_code_and_message(:parse_error), do: {-32700, "Parse error"}
defp error_code_and_message(:invalid_request), do: {-32600, "Invalid Request"}
defp error_code_and_message(:method_not_found), do: {-32601, "Method not found"}
defp error_code_and_message(:invalid_params), do: {-32602, "Invalid params"}
defp error_code_and_message(:internal_error), do: {-32603, "Internal error"}
defp error_code_and_message(:server_error), do: {-32000, "Server error"}

# -32099 - -32000 - JSON-RPC reserved error codes
# No LSP error codes should be defined between the start and end range.
# For backwards compatibility the `ServerNotInitialized` and the `UnknownErrorCode`
# are left in the range.
defp error_code_and_message(:server_not_initialized), do: {-32002, "Server not initialized"}
defp error_code_and_message(:unknown_error_code), do: {-32001, "Unknown error code"}

defp error_code_and_message(:request_cancelled), do: {-32800, "Request cancelled"}
# -32899 - -32800 - LSP reserved error codes
defp error_code_and_message(:request_failed), do: {-32803, "Request cancelled"}
defp error_code_and_message(:server_cancelled), do: {-32802, "Server cancelled"}
defp error_code_and_message(:content_modified), do: {-32801, "Content modified"}
defp error_code_and_message(:code_lens_error), do: {-32900, "Error while building code lenses"}
defp error_code_and_message(:request_cancelled), do: {-32800, "Request cancelled"}
end
Loading

0 comments on commit 460d553

Please sign in to comment.