Skip to content

Commit

Permalink
Fixes and improvements around text synchronisation (#411)
Browse files Browse the repository at this point in the history
* Purge consolidated protocols before compilation

Fixes #395

* move to dialyzer_test.exs

* dialyzer_enabled? is already asserted at call site

* add argument type assertions

* return invalid_param when handling a request involving not open uri

* add tests for text synchronization

fixes some issues when certain sequence of notifications would create nil entries in source_files map

* warn when cancelling unknown request

* fix difference in watched extensions

* add tests to workspace/didChangeWatchedFiles

fix some consistency issues:
dirty? flag not updated when file modified outside (no didSave)
rebuild not triggered when opened dirty file modified outside

* add tests for SourceFile.apply_content_changes

based on https://github.com/microsoft/vscode-languageserver-node
fixes a few edge cases when dealing with invalid ranges

* add test

* add utf test

* add test

fix full_range invalid when last line with unicode

* fix apply_content_changes not preserving windows line endings

* wip

* do not warn if consolidation path does not exist

* fix tests

* return invalid_request

* handle invalid uri in async requests

* return invalid_request for not matched commands

* handle client request errors

* run formatter

* rename

* Refactor implementation of SourceFile.lines_with_endings

The previous implementation did not have any bugs (that I saw), but I
did find it more difficult to read and understand. I expect performance
to be comparable.

For more comprehensive testing I have added StreamData which adds
property-based testing. We can probably use that in other portions of
the code base as well.

* Update apps/language_server/test/source_file_test.exs

Co-authored-by: Jason Axelson <axelson@users.noreply.github.com>

* run formatter

* add disclaimer

* combine lines_with_endings test cases

Co-authored-by: Jason Axelson <jason.axelson@gmail.com>
Co-authored-by: Jason Axelson <axelson@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 24, 2020
1 parent 7c27bce commit 0851d87
Show file tree
Hide file tree
Showing 14 changed files with 1,436 additions and 173 deletions.
4 changes: 4 additions & 0 deletions apps/language_server/lib/language_server/build.ex
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,10 @@ defmodule ElixirLS.LanguageServer.Build do
with {:ok, beams} <- File.ls(path) do
Enum.map(beams, &(&1 |> Path.rootname(".beam") |> String.to_atom() |> purge_module()))
else
{:error, :enoent} ->
# consolidation_path does not exist
:ok

{:error, reason} ->
JsonRpc.show_message(
:warning,
Expand Down
8 changes: 6 additions & 2 deletions apps/language_server/lib/language_server/mix_shell.ex
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@ defmodule ElixirLS.LanguageServer.MixShell do
])

case response do
{:ok, %{"result" => result}} -> result
_ -> true
{:ok, %{"result" => result}} ->
result

other ->
error("[ElixirLS] unexpected client response #{inspect(other)}, assuming yes")
true
end
else
Mix.Shell.IO.yes?(message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand do

alias ElixirLS.LanguageServer.{JsonRpc, SourceFile}
import ElixirLS.LanguageServer.Protocol
alias ElixirLS.LanguageServer.Server

@default_target_line_length 98

def execute("spec:" <> _, args, source_files) do
def execute("spec:" <> _, args, state) do
[
%{
"uri" => uri,
Expand All @@ -23,7 +24,9 @@ defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand do
mod = String.to_atom(mod)
fun = String.to_atom(fun)

cur_text = source_files[uri].text
source_file = Server.get_source_file(state, uri)

cur_text = source_file.text

# In case line has changed since this suggestion was generated, look for the function's current
# line number and fall back to the previous line number if we can't guess the new one
Expand Down Expand Up @@ -67,15 +70,27 @@ defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand do
"#{indentation}@spec #{spec}\n"
end

JsonRpc.send_request("workspace/applyEdit", %{
"label" => "Add @spec to #{mod}.#{fun}/#{arity}",
"edit" => %{
"changes" => %{
uri => [%{"range" => range(line - 1, 0, line - 1, 0), "newText" => formatted}]
edit_result =
JsonRpc.send_request("workspace/applyEdit", %{
"label" => "Add @spec to #{mod}.#{fun}/#{arity}",
"edit" => %{
"changes" => %{
uri => [%{"range" => range(line - 1, 0, line - 1, 0), "newText" => formatted}]
}
}
}
})
})

case edit_result do
{:ok, %{"applied" => true}} ->
{:ok, nil}

other ->
{:error, :server_error,
"cannot insert spec, workspace/applyEdit returned #{inspect(other)}"}
end
end

{:ok, nil}
def execute(_command, _args, _state) do
{:error, :invalid_request, nil}
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule ElixirLS.LanguageServer.Providers.Formatting do
function_exported?(Code, :format_string!, 2)
end

def format(source_file, uri, project_dir) do
def format(%SourceFile{} = source_file, uri, project_dir) do
if can_format?(uri, project_dir) do
case SourceFile.formatter_opts(uri) do
{:ok, opts} ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ defmodule ElixirLS.LanguageServer.Providers.OnTypeFormatting do
alias ElixirLS.LanguageServer.SourceFile
import ElixirLS.LanguageServer.Protocol

def format(source_file, line, character, "\n", _options) do
def format(%SourceFile{} = source_file, line, character, "\n", _options) do
lines = SourceFile.lines(source_file)
prev_line = Enum.at(lines, line - 1)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
defmodule ElixirLS.LanguageServer.Providers.SignatureHelp do
alias ElixirLS.LanguageServer.SourceFile

def signature(source_file, line, character) do
def signature(%SourceFile{} = source_file, line, character) do
response =
case ElixirSense.signature(source_file.text, line + 1, character + 1) do
%{active_param: active_param, signatures: signatures} ->
Expand Down
Loading

0 comments on commit 0851d87

Please sign in to comment.