Skip to content

Commit 424dccb

Browse files
committed
Fix LSP compatibility - textDocument/didChange version is the number after all changes applied
This was broken since the original code drop (or may be an artefact of LSP 2.0) Fixes #1024
1 parent 5d0ed74 commit 424dccb

File tree

5 files changed

+52
-56
lines changed

5 files changed

+52
-56
lines changed

apps/language_server/lib/language_server/parser.ex

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ defmodule ElixirLS.LanguageServer.Parser do
5858
end
5959

6060
def handle_cast({:parse_with_debounce, uri, source_file}, state) do
61+
# TODO check source_file.language_id
6162
state = if String.ends_with?(uri, [".ex", ".exs", ".eex"]) do
6263
state = update_in(state.debounce_refs[uri], fn old_ref ->
6364
if old_ref do

apps/language_server/lib/language_server/server.ex

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ defmodule ElixirLS.LanguageServer.Server do
528528
state
529529
end
530530

531-
defp handle_notification(did_open(uri, _language_id, version, text), state = %__MODULE__{}) do
531+
defp handle_notification(did_open(uri, language_id, version, text), state = %__MODULE__{}) do
532532
if Map.has_key?(state.source_files, uri) do
533533
# An open notification must not be sent more than once without a corresponding
534534
# close notification send before
@@ -551,7 +551,7 @@ defmodule ElixirLS.LanguageServer.Server do
551551
Logger.error("File not valid on open:\n#{inspect(text)}")
552552
end
553553

554-
source_file = %SourceFile{text: text, version: version}
554+
source_file = %SourceFile{text: text, version: version, language_id: language_id}
555555

556556
Parser.parse_with_debounce(uri, source_file)
557557

@@ -593,6 +593,8 @@ defmodule ElixirLS.LanguageServer.Server do
593593
else
594594
state =
595595
update_in(state.source_files[uri], fn source_file ->
596+
# LSP 3.17: The version number points to the version after all provided content changes have
597+
# been applied
596598
updated_source_file =
597599
%SourceFile{source_file | version: version, dirty?: true}
598600
|> SourceFile.apply_content_changes(content_changes)

apps/language_server/lib/language_server/source_file.ex

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule ElixirLS.LanguageServer.SourceFile do
22
import ElixirLS.LanguageServer.Protocol
33
require Logger
44

5-
defstruct [:text, :version, dirty?: false]
5+
defstruct [:text, :version, :language_id, dirty?: false]
66

77
@endings ["\r\n", "\r", "\n"]
88

@@ -54,12 +54,6 @@ defmodule ElixirLS.LanguageServer.SourceFile do
5454
put_in(source_file.text, new_text)
5555
end
5656

57-
source_file =
58-
update_in(source_file.version, fn
59-
v when is_integer(v) -> v + 1
60-
_ -> 1
61-
end)
62-
6357
apply_content_changes(source_file, rest)
6458
end
6559

apps/language_server/test/server_test.exs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,8 @@ defmodule ElixirLS.LanguageServer.ServerTest do
527527

528528
assert_receive notification("textDocument/publishDiagnostics", %{
529529
"uri" => ^uri,
530-
"diagnostics" => [diagnostic]
530+
"diagnostics" => [diagnostic],
531+
"version" => 1
531532
}),
532533
1000
533534

@@ -550,14 +551,15 @@ defmodule ElixirLS.LanguageServer.ServerTest do
550551

551552
state = :sys.get_state(server)
552553

553-
assert %SourceFile{dirty?: false, text: ^code, version: 1} =
554+
assert %SourceFile{dirty?: false, text: ^code, language_id: "elixir", version: 1} =
554555
Server.get_source_file(state, uri)
555556

556557
# Code.with_diagnostics is broken on elixir < 1.15.3
557558
if Version.match?(System.version(), ">= 1.15.3") do
558559
assert_receive notification("textDocument/publishDiagnostics", %{
559560
"uri" => ^uri,
560-
"diagnostics" => [diagnostic]
561+
"diagnostics" => [diagnostic],
562+
"version" => 1
561563
}),
562564
1000
563565

@@ -810,11 +812,12 @@ defmodule ElixirLS.LanguageServer.ServerTest do
810812
}),
811813
1000
812814

813-
Server.receive_packet(server, did_change(uri, 1, content_changes))
815+
Server.receive_packet(server, did_change(uri, 2, content_changes))
814816

815817
assert_receive notification("textDocument/publishDiagnostics", %{
816818
"uri" => ^uri,
817-
"diagnostics" => [_]
819+
"diagnostics" => [_],
820+
"version" => 2
818821
}),
819822
1000
820823

@@ -846,24 +849,26 @@ defmodule ElixirLS.LanguageServer.ServerTest do
846849
)
847850

848851
fake_initialize(server)
849-
Server.receive_packet(server, did_open(uri, "elixir", 1, code))
852+
Server.receive_packet(server, did_open(uri, "elixir", 0, code))
850853

851854
assert_receive notification("textDocument/publishDiagnostics", %{
852855
"uri" => ^uri,
853-
"diagnostics" => [_]
856+
"diagnostics" => [_],
857+
"version" => 0
854858
}),
855859
1000
856860

857861
Server.receive_packet(server, did_change(uri, 1, content_changes))
858862

859863
assert_receive notification("textDocument/publishDiagnostics", %{
860864
"uri" => ^uri,
861-
"diagnostics" => []
865+
"diagnostics" => [],
866+
"version" => 1
862867
}),
863868
1000
864869

865870
state = :sys.get_state(server)
866-
assert %SourceFile{dirty?: true, version: 2} = Server.get_source_file(state, uri)
871+
assert %SourceFile{dirty?: true, version: 1} = Server.get_source_file(state, uri)
867872

868873
wait_until_compiled(server)
869874
end)

0 commit comments

Comments
 (0)