diff --git a/Cargo.lock b/Cargo.lock index bcc7728efebb5..5578d46216cc8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1237,6 +1237,17 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" +[[package]] +name = "gen-lsp-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4552cb20fa322e0ebc35c2bbbe3eed8ace907bbcedc92aace7a325c9064b80b" +dependencies = [ + "serde", + "serde_json", + "url", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -1976,18 +1987,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "lsp-types" -version = "0.95.1" -source = "git+https://github.com/astral-sh/lsp-types.git?rev=e15db0593f0ecbbd80599c3f5880e4bf5da1ca0c#e15db0593f0ecbbd80599c3f5880e4bf5da1ca0c" -dependencies = [ - "bitflags 1.3.2", - "serde", - "serde_json", - "serde_repr", - "url", -] - [[package]] name = "manyhow" version = "0.11.4" @@ -3494,12 +3493,12 @@ dependencies = [ "anyhow", "crossbeam", "dunce", + "gen-lsp-types", "ignore", "insta", "jod-thread", "libc", "lsp-server", - "lsp-types", "regex", "ruff_db", "ruff_diagnostics", @@ -3825,17 +3824,6 @@ dependencies = [ "zmij", ] -[[package]] -name = "serde_repr" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "serde_spanned" version = "1.1.1" @@ -4713,11 +4701,11 @@ dependencies = [ "bitflags 2.11.0", "crossbeam", "dunce", + "gen-lsp-types", "insta", "jod-thread", "libc", "lsp-server", - "lsp-types", "regex", "ruff_db", "ruff_diagnostics", diff --git a/Cargo.toml b/Cargo.toml index 065969b8257ce..14b3f4445ad93 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -129,9 +129,7 @@ libc = { version = "0.2.153" } libcst = { version = "1.8.4", default-features = false } log = { version = "0.4.17" } lsp-server = { version = "0.7.6" } -lsp-types = { git = "https://github.com/astral-sh/lsp-types.git", rev = "e15db0593f0ecbbd80599c3f5880e4bf5da1ca0c", features = [ - "proposed", -] } +lsp-types = { package = "gen-lsp-types", version = "0.5.0", features = ["url"] } matchit = { version = "0.9.0" } memchr = { version = "2.7.1" } mimalloc = { version = "0.1.39" } diff --git a/crates/ruff_linter/resources/test/fixtures/isort/line_ending_crlf.py b/crates/ruff_linter/resources/test/fixtures/isort/line_ending_crlf.py index 82aa39c4057f5..31dd8666b8951 100644 --- a/crates/ruff_linter/resources/test/fixtures/isort/line_ending_crlf.py +++ b/crates/ruff_linter/resources/test/fixtures/isort/line_ending_crlf.py @@ -1,2 +1,2 @@ -from long_module_name import member_one, member_two, member_three, member_four, member_five - +from long_module_name import member_one, member_two, member_three, member_four, member_five + diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W391_2.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W391_2.py index a45c7a1cf0b66..c8274542ce95a 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W391_2.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W391_2.py @@ -1,17 +1,17 @@ -# Windows style -def foo() -> None: - pass - - -def bar() -> None: - pass - - - -if __name__ == '__main__': - foo() - bar() - - - - +# Windows style +def foo() -> None: + pass + + +def bar() -> None: + pass + + + +if __name__ == '__main__': + foo() + bar() + + + + diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W391_3.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W391_3.py index 151b1a248c1de..df2759f0d5548 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W391_3.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W391_3.py @@ -1,13 +1,13 @@ -# Windows style -def foo() -> None: - pass - - -def bar() -> None: - pass - - - -if __name__ == '__main__': - foo() - bar() +# Windows style +def foo() -> None: + pass + + +def bar() -> None: + pass + + + +if __name__ == '__main__': + foo() + bar() diff --git a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_1.py b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_1.py index c29b7d53ec741..378d4fea4fa8a 100644 --- a/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_1.py +++ b/crates/ruff_linter/resources/test/fixtures/pycodestyle/W605_1.py @@ -1,137 +1,137 @@ -# Same as `W605_0.py` but using f-strings and t-strings instead. - -#: W605:1:10 -regex = f'\.png$' - -#: W605:2:1 -regex = f''' -\.png$ -''' - -#: W605:2:6 -f( - f'\_' -) - -#: W605:4:6 -f""" -multi-line -literal -with \_ somewhere -in the middle -""" - -#: W605:1:38 -value = f'new line\nand invalid escape \_ here' - - -#: Okay -regex = fr'\.png$' -regex = f'\\.png$' -regex = fr''' -\.png$ -''' -regex = fr''' -\\.png$ -''' -s = f'\\' -regex = f'\w' # noqa -regex = f''' -\w -''' # noqa - -regex = f'\\\_' -value = f'\{{1}}' -value = f'\{1}' -value = f'{1:\}' -value = f"{f"\{1}"}" -value = rf"{f"\{1}"}" - -# Okay -value = rf'\{{1}}' -value = rf'\{1}' -value = rf'{1:\}' -value = f"{rf"\{1}"}" - -# Regression tests for https://github.com/astral-sh/ruff/issues/10434 -f"{{}}+-\d" -f"\n{{}}+-\d+" -f"\n{{}}�+-\d+" - -# See https://github.com/astral-sh/ruff/issues/11491 -total = 10 -ok = 7 -incomplete = 3 -s = f"TOTAL: {total}\nOK: {ok}\INCOMPLETE: {incomplete}\n" - -# Debug text (should trigger) -t = f"{'\InHere'=}" - - - -#: W605:1:10 -regex = t'\.png$' - -#: W605:2:1 -regex = t''' -\.png$ -''' - -#: W605:2:6 -f( - t'\_' -) - -#: W605:4:6 -t""" -multi-line -literal -with \_ somewhere -in the middle -""" - -#: W605:1:38 -value = t'new line\nand invalid escape \_ here' - - -#: Okay -regex = fr'\.png$' -regex = t'\\.png$' -regex = fr''' -\.png$ -''' -regex = fr''' -\\.png$ -''' -s = t'\\' -regex = t'\w' # noqa -regex = t''' -\w -''' # noqa - -regex = t'\\\_' -value = t'\{{1}}' -value = t'\{1}' -value = t'{1:\}' -value = t"{t"\{1}"}" -value = rt"{t"\{1}"}" - -# Okay -value = rt'\{{1}}' -value = rt'\{1}' -value = rt'{1:\}' -value = t"{rt"\{1}"}" - -# Regression tests for https://github.com/astral-sh/ruff/issues/10434 -t"{{}}+-\d" -t"\n{{}}+-\d+" -t"\n{{}}�+-\d+" - -# See https://github.com/astral-sh/ruff/issues/11491 -total = 10 -ok = 7 -incomplete = 3 -s = t"TOTAL: {total}\nOK: {ok}\INCOMPLETE: {incomplete}\n" - -# Debug text (should trigger) -t = t"{'\InHere'=}" +# Same as `W605_0.py` but using f-strings and t-strings instead. + +#: W605:1:10 +regex = f'\.png$' + +#: W605:2:1 +regex = f''' +\.png$ +''' + +#: W605:2:6 +f( + f'\_' +) + +#: W605:4:6 +f""" +multi-line +literal +with \_ somewhere +in the middle +""" + +#: W605:1:38 +value = f'new line\nand invalid escape \_ here' + + +#: Okay +regex = fr'\.png$' +regex = f'\\.png$' +regex = fr''' +\.png$ +''' +regex = fr''' +\\.png$ +''' +s = f'\\' +regex = f'\w' # noqa +regex = f''' +\w +''' # noqa + +regex = f'\\\_' +value = f'\{{1}}' +value = f'\{1}' +value = f'{1:\}' +value = f"{f"\{1}"}" +value = rf"{f"\{1}"}" + +# Okay +value = rf'\{{1}}' +value = rf'\{1}' +value = rf'{1:\}' +value = f"{rf"\{1}"}" + +# Regression tests for https://github.com/astral-sh/ruff/issues/10434 +f"{{}}+-\d" +f"\n{{}}+-\d+" +f"\n{{}}�+-\d+" + +# See https://github.com/astral-sh/ruff/issues/11491 +total = 10 +ok = 7 +incomplete = 3 +s = f"TOTAL: {total}\nOK: {ok}\INCOMPLETE: {incomplete}\n" + +# Debug text (should trigger) +t = f"{'\InHere'=}" + + + +#: W605:1:10 +regex = t'\.png$' + +#: W605:2:1 +regex = t''' +\.png$ +''' + +#: W605:2:6 +f( + t'\_' +) + +#: W605:4:6 +t""" +multi-line +literal +with \_ somewhere +in the middle +""" + +#: W605:1:38 +value = t'new line\nand invalid escape \_ here' + + +#: Okay +regex = fr'\.png$' +regex = t'\\.png$' +regex = fr''' +\.png$ +''' +regex = fr''' +\\.png$ +''' +s = t'\\' +regex = t'\w' # noqa +regex = t''' +\w +''' # noqa + +regex = t'\\\_' +value = t'\{{1}}' +value = t'\{1}' +value = t'{1:\}' +value = t"{t"\{1}"}" +value = rt"{t"\{1}"}" + +# Okay +value = rt'\{{1}}' +value = rt'\{1}' +value = rt'{1:\}' +value = t"{rt"\{1}"}" + +# Regression tests for https://github.com/astral-sh/ruff/issues/10434 +t"{{}}+-\d" +t"\n{{}}+-\d+" +t"\n{{}}�+-\d+" + +# See https://github.com/astral-sh/ruff/issues/11491 +total = 10 +ok = 7 +incomplete = 3 +s = t"TOTAL: {total}\nOK: {ok}\INCOMPLETE: {incomplete}\n" + +# Debug text (should trigger) +t = t"{'\InHere'=}" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/carriage_return/.editorconfig b/crates/ruff_python_formatter/resources/test/fixtures/ruff/carriage_return/.editorconfig index cafa748cf3f88..ac00203513837 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/carriage_return/.editorconfig +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/carriage_return/.editorconfig @@ -1,2 +1,2 @@ -[*.py] -end_of_line = crlf +[*.py] +end_of_line = crlf diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/carriage_return/.gitattributes b/crates/ruff_python_formatter/resources/test/fixtures/ruff/carriage_return/.gitattributes index 0c42f3cc294d6..9bb7c1d910361 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/carriage_return/.gitattributes +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/carriage_return/.gitattributes @@ -1 +1 @@ -* text=auto eol=crlf +* text=auto eol=crlf diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/carriage_return/string.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/carriage_return/string.py index 45f9dacc386f0..ba6a0f0c3321a 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/carriage_return/string.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/carriage_return/string.py @@ -1,6 +1,6 @@ -'This string will not include \ -backslashes or newline characters.' - -"""Multiline -String \" -""" +'This string will not include \ +backslashes or newline characters.' + +"""Multiline +String \" +""" diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_crlf.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_crlf.py index 05cc97963f21e..15b28a18e0e75 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_crlf.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_crlf.py @@ -1,9 +1,9 @@ -def doctest_line_ending(): - """ - Do cool stuff. - >>> def foo( x ): - ... print( x ) - ... - ... print( x ) - """ - pass +def doctest_line_ending(): + """ + Do cool stuff. + >>> def foo( x ): + ... print( x ) + ... + ... print( x ) + """ + pass diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/f-string-carriage-return-newline.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/f-string-carriage-return-newline.py index 1ddc0eee67393..0239ede9393f0 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/f-string-carriage-return-newline.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/f-string-carriage-return-newline.py @@ -1,8 +1,8 @@ -# Regression test for https://github.com/astral-sh/ruff/issues/18667 -f"{ -1= -}" - -t"{ -1= -}" +# Regression test for https://github.com/astral-sh/ruff/issues/18667 +f"{ +1= +}" + +t"{ +1= +}" diff --git a/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_crlf.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_crlf.py.snap index 3cd2fe42ac7c5..3f9a0bde34737 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_crlf.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@docstring_code_examples_crlf.py.snap @@ -1,45 +1,45 @@ ---- -source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_crlf.py ---- -## Input -```python -def doctest_line_ending(): - """ - Do cool stuff. - >>> def foo( x ): - ... print( x ) - ... - ... print( x ) - """ - pass -``` - -## Outputs -### Output 1 -``` -indent-style = space -line-width = 88 -indent-width = 4 -quote-style = Double -line-ending = CarriageReturnLineFeed -magic-trailing-comma = Respect -docstring-code = Enabled -docstring-code-line-width = "dynamic" -preview = Disabled -target_version = 3.10 -source_type = Python -nested-string-quote-style = alternating -``` - -```python -def doctest_line_ending(): - """ - Do cool stuff. - >>> def foo(x): - ... print(x) - ... - ... print(x) - """ - pass -``` +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/docstring_code_examples_crlf.py +--- +## Input +```python +def doctest_line_ending(): + """ + Do cool stuff. + >>> def foo( x ): + ... print( x ) + ... + ... print( x ) + """ + pass +``` + +## Outputs +### Output 1 +``` +indent-style = space +line-width = 88 +indent-width = 4 +quote-style = Double +line-ending = CarriageReturnLineFeed +magic-trailing-comma = Respect +docstring-code = Enabled +docstring-code-line-width = "dynamic" +preview = Disabled +target_version = 3.10 +source_type = Python +nested-string-quote-style = alternating +``` + +```python +def doctest_line_ending(): + """ + Do cool stuff. + >>> def foo(x): + ... print(x) + ... + ... print(x) + """ + pass +``` diff --git a/crates/ruff_python_formatter/tests/snapshots/format@f-string-carriage-return-newline.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@f-string-carriage-return-newline.py.snap index c24f246a5e687..7d57399a6cf71 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@f-string-carriage-return-newline.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@f-string-carriage-return-newline.py.snap @@ -1,27 +1,27 @@ ---- -source: crates/ruff_python_formatter/tests/fixtures.rs -input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/f-string-carriage-return-newline.py ---- -## Input -```python -# Regression test for https://github.com/astral-sh/ruff/issues/18667 -f"{ -1= -}" - -t"{ -1= -}" -``` - -## Output -```python -# Regression test for https://github.com/astral-sh/ruff/issues/18667 -f"{ -1= -}" - -t"{ -1= -}" -``` +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/f-string-carriage-return-newline.py +--- +## Input +```python +# Regression test for https://github.com/astral-sh/ruff/issues/18667 +f"{ +1= +}" + +t"{ +1= +}" +``` + +## Output +```python +# Regression test for https://github.com/astral-sh/ruff/issues/18667 +f"{ +1= +}" + +t"{ +1= +}" +``` diff --git a/crates/ruff_python_parser/resources/invalid/re_lex_logical_token_windows_eol.py b/crates/ruff_python_parser/resources/invalid/re_lex_logical_token_windows_eol.py index e59a3af014a59..18e6e791bdf7a 100644 --- a/crates/ruff_python_parser/resources/invalid/re_lex_logical_token_windows_eol.py +++ b/crates/ruff_python_parser/resources/invalid/re_lex_logical_token_windows_eol.py @@ -1,3 +1,3 @@ -if call(foo, [a, b - def bar(): - pass +if call(foo, [a, b + def bar(): + pass diff --git a/crates/ruff_python_parser/resources/invalid/re_lexing/line_continuation_windows_eol.py b/crates/ruff_python_parser/resources/invalid/re_lexing/line_continuation_windows_eol.py index f2848adfc5583..3224dc983a0bc 100644 --- a/crates/ruff_python_parser/resources/invalid/re_lexing/line_continuation_windows_eol.py +++ b/crates/ruff_python_parser/resources/invalid/re_lexing/line_continuation_windows_eol.py @@ -1,4 +1,4 @@ -call(a, b, # comment \ - -def bar(): +call(a, b, # comment \ + +def bar(): pass \ No newline at end of file diff --git a/crates/ruff_server/src/edit.rs b/crates/ruff_server/src/edit.rs index 1cad80a5b494a..0e77a9808cd8e 100644 --- a/crates/ruff_server/src/edit.rs +++ b/crates/ruff_server/src/edit.rs @@ -7,7 +7,7 @@ mod text_document; use std::collections::HashMap; -use lsp_types::{PositionEncodingKind, Url}; +use lsp_types::{DocumentChange, PositionEncodingKind, TextDocumentIdentifier, Uri as Url}; pub(crate) use notebook::NotebookDocument; pub(crate) use range::{NotebookRange, RangeExt, ToRangeExt}; pub(crate) use replacement::Replacement; @@ -137,7 +137,7 @@ impl WorkspaceEditTracker { Self::DocumentChanges(document_edits) => { if document_edits .iter() - .any(|document| document.text_document.uri == uri) + .any(|document| document.text_document.text_document_identifier.uri == uri) { return Err(anyhow::anyhow!( "Attempted to add edits for a document that was already edited" @@ -145,11 +145,11 @@ impl WorkspaceEditTracker { } document_edits.push(lsp_types::TextDocumentEdit { text_document: lsp_types::OptionalVersionedTextDocumentIdentifier { - uri, + text_document_identifier: TextDocumentIdentifier { uri }, // TODO(jane): Re-enable versioned edits after investigating whether it could work with notebook cells version: None, }, - edits: edits.into_iter().map(lsp_types::OneOf::Left).collect(), + edits: edits.into_iter().map(lsp_types::Edit::TextEdit).collect(), }); Ok(()) } @@ -175,10 +175,15 @@ impl WorkspaceEditTracker { pub(crate) fn into_workspace_edit(self) -> lsp_types::WorkspaceEdit { match self { Self::DocumentChanges(document_edits) => lsp_types::WorkspaceEdit { - document_changes: Some(lsp_types::DocumentChanges::Edits(document_edits)), + document_changes: Some( + document_edits + .into_iter() + .map(DocumentChange::TextDocumentEdit) + .collect(), + ), ..Default::default() }, - Self::Changes(changes) => lsp_types::WorkspaceEdit::new(changes), + Self::Changes(changes) => lsp_types::WorkspaceEdit::new(Some(changes), None, None), } } } diff --git a/crates/ruff_server/src/edit/notebook.rs b/crates/ruff_server/src/edit/notebook.rs index fa4ac89b43dcc..9fef280e4e4e5 100644 --- a/crates/ruff_server/src/edit/notebook.rs +++ b/crates/ruff_server/src/edit/notebook.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use anyhow::Ok; use lsp_types::NotebookCellKind; use ruff_notebook::CellMetadata; @@ -17,13 +19,13 @@ pub(crate) struct NotebookDocument { metadata: ruff_notebook::RawNotebookMetadata, version: DocumentVersion, // Used to quickly find the index of a cell for a given URL. - cell_index: FxHashMap, + cell_index: FxHashMap, } /// A single cell within a notebook, which has text contents represented as a `TextDocument`. #[derive(Clone, Debug)] struct NotebookCell { - url: lsp_types::Url, + url: lsp_types::Uri, kind: NotebookCellKind, document: TextDocument, } @@ -32,7 +34,7 @@ impl NotebookDocument { pub(crate) fn new( version: DocumentVersion, cells: Vec, - metadata: serde_json::Map, + metadata: HashMap, cell_documents: Vec, ) -> crate::Result { let mut cell_contents: FxHashMap<_, _> = cell_documents @@ -51,7 +53,7 @@ impl NotebookDocument { Ok(Self { version, cell_index: Self::make_cell_index(cells.as_slice()), - metadata: serde_json::from_value(serde_json::Value::Object(metadata))?, + metadata: serde_json::from_value(serde_json::to_value(metadata)?)?, cells, }) } @@ -97,14 +99,14 @@ impl NotebookDocument { pub(crate) fn update( &mut self, - cells: Option, - metadata_change: Option>, + cells: Option, + metadata_change: Option>, version: DocumentVersion, encoding: PositionEncoding, ) -> crate::Result<()> { self.version = version; - if let Some(lsp_types::NotebookDocumentCellChange { + if let Some(lsp_types::NotebookDocumentCellChanges { structure, data, text_content, @@ -178,7 +180,9 @@ impl NotebookDocument { if let Some(content_changes) = text_content { for content_change in content_changes { - if let Some(cell) = self.cell_by_uri_mut(&content_change.document.uri) { + if let Some(cell) = + self.cell_by_uri_mut(&content_change.document.text_document_identifier.uri) + { cell.document .apply_changes(content_change.changes, version, encoding); } @@ -187,7 +191,7 @@ impl NotebookDocument { } if let Some(metadata_change) = metadata_change { - self.metadata = serde_json::from_value(serde_json::Value::Object(metadata_change))?; + self.metadata = serde_json::from_value(serde_json::to_value(metadata_change)?)?; } Ok(()) @@ -199,27 +203,27 @@ impl NotebookDocument { } /// Get the URI for a cell by its index within the cell array. - pub(crate) fn cell_uri_by_index(&self, index: CellId) -> Option<&lsp_types::Url> { + pub(crate) fn cell_uri_by_index(&self, index: CellId) -> Option<&lsp_types::Uri> { self.cells.get(index).map(|cell| &cell.url) } /// Get the text document representing the contents of a cell by the cell URI. - pub(crate) fn cell_document_by_uri(&self, uri: &lsp_types::Url) -> Option<&TextDocument> { + pub(crate) fn cell_document_by_uri(&self, uri: &lsp_types::Uri) -> Option<&TextDocument> { self.cells .get(*self.cell_index.get(uri)?) .map(|cell| &cell.document) } /// Returns a list of cell URIs in the order they appear in the array. - pub(crate) fn urls(&self) -> impl Iterator { + pub(crate) fn urls(&self) -> impl Iterator { self.cells.iter().map(|cell| &cell.url) } - fn cell_by_uri_mut(&mut self, uri: &lsp_types::Url) -> Option<&mut NotebookCell> { + fn cell_by_uri_mut(&mut self, uri: &lsp_types::Uri) -> Option<&mut NotebookCell> { self.cells.get_mut(*self.cell_index.get(uri)?) } - fn make_cell_index(cells: &[NotebookCell]) -> FxHashMap { + fn make_cell_index(cells: &[NotebookCell]) -> FxHashMap { let mut index = FxHashMap::with_capacity_and_hasher(cells.len(), FxBuildHasher); for (i, cell) in cells.iter().enumerate() { index.insert(cell.url.clone(), i); @@ -244,6 +248,10 @@ impl NotebookCell { #[cfg(test)] mod tests { + use std::collections::HashMap; + + use lsp_types::LanguageKind; + use super::NotebookDocument; enum TestCellContent { @@ -252,8 +260,8 @@ mod tests { Code(String), } - fn create_test_url(index: usize) -> lsp_types::Url { - lsp_types::Url::parse(&format!("cell:/test.ipynb#{index}")).unwrap() + fn create_test_url(index: usize) -> lsp_types::Uri { + lsp_types::Uri::parse(&format!("cell:/test.ipynb#{index}")).unwrap() } fn create_test_notebook(test_cells: Vec) -> NotebookDocument { @@ -272,7 +280,7 @@ mod tests { }); cell_documents.push(lsp_types::TextDocumentItem { uri: url, - language_id: "markdown".to_owned(), + language_id: LanguageKind::new("markdown"), version: 0, text: content, }); @@ -286,7 +294,7 @@ mod tests { }); cell_documents.push(lsp_types::TextDocumentItem { uri: url, - language_id: "python".to_owned(), + language_id: LanguageKind::new("python"), version: 0, text: content, }); @@ -294,7 +302,7 @@ mod tests { } } - NotebookDocument::new(0, cells, serde_json::Map::default(), cell_documents).unwrap() + NotebookDocument::new(0, cells, HashMap::default(), cell_documents).unwrap() } /// This test case checks that for a notebook with three code cells, when the client sends a @@ -312,7 +320,7 @@ mod tests { notebook .update( - Some(lsp_types::NotebookDocumentCellChange { + Some(lsp_types::NotebookDocumentCellChanges { structure: Some(lsp_types::NotebookDocumentCellChangeStructure { array: lsp_types::NotebookCellArrayChange { start: 0, diff --git a/crates/ruff_server/src/edit/text_document.rs b/crates/ruff_server/src/edit/text_document.rs index b78f1c031c368..a8dce44a903e3 100644 --- a/crates/ruff_server/src/edit/text_document.rs +++ b/crates/ruff_server/src/edit/text_document.rs @@ -1,4 +1,7 @@ -use lsp_types::TextDocumentContentChangeEvent; +use lsp_types::{ + TextDocumentContentChangeEvent, TextDocumentContentChangePartial, + TextDocumentContentChangeWholeDocument, +}; use ruff_source_file::LineIndex; use crate::PositionEncoding; @@ -85,9 +88,9 @@ impl TextDocument { encoding: PositionEncoding, ) { if let [ - lsp_types::TextDocumentContentChangeEvent { - range: None, text, .. - }, + TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { text }, + ), ] = changes.as_slice() { tracing::debug!("Fast path - replacing entire document"); @@ -101,21 +104,21 @@ impl TextDocument { let mut new_contents = self.contents().to_string(); let mut active_index = self.index().clone(); - for TextDocumentContentChangeEvent { - range, - text: change, - .. - } in changes - { - if let Some(range) = range { - let range = range.to_text_range(&new_contents, &active_index, encoding); - - new_contents.replace_range( - usize::from(range.start())..usize::from(range.end()), - &change, - ); - } else { - new_contents = change; + for change in changes { + match change { + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { range, text, .. }, + ) => { + let range = range.to_text_range(&new_contents, &active_index, encoding); + + new_contents + .replace_range(usize::from(range.start())..usize::from(range.end()), &text); + } + TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { text }, + ) => { + new_contents = text; + } } active_index = LineIndex::from_source_text(&new_contents); @@ -156,7 +159,7 @@ impl TextDocument { #[cfg(test)] mod tests { use crate::{PositionEncoding, TextDocument}; - use lsp_types::{Position, TextDocumentContentChangeEvent}; + use lsp_types::{Position, TextDocumentContentChangeEvent, TextDocumentContentChangePartial}; #[test] fn redo_edit() { @@ -179,30 +182,27 @@ def interface(): // Add an `s`, remove it again (back to the original code), and then re-add the `s` document.apply_changes( vec![ - TextDocumentContentChangeEvent { - range: Some(lsp_types::Range::new( - Position::new(9, 7), - Position::new(9, 7), - )), - range_length: Some(0), - text: "s".to_string(), - }, - TextDocumentContentChangeEvent { - range: Some(lsp_types::Range::new( - Position::new(9, 7), - Position::new(9, 8), - )), - range_length: Some(1), - text: String::new(), - }, - TextDocumentContentChangeEvent { - range: Some(lsp_types::Range::new( - Position::new(9, 7), - Position::new(9, 7), - )), - range_length: Some(0), - text: "s".to_string(), - }, + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: lsp_types::Range::new(Position::new(9, 7), Position::new(9, 7)), + text: "s".to_string(), + ..Default::default() + }, + ), + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: lsp_types::Range::new(Position::new(9, 7), Position::new(9, 8)), + text: String::new(), + ..Default::default() + }, + ), + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: lsp_types::Range::new(Position::new(9, 7), Position::new(9, 7)), + text: "s".to_string(), + ..Default::default() + }, + ), ], 1, PositionEncoding::UTF16, diff --git a/crates/ruff_server/src/fix.rs b/crates/ruff_server/src/fix.rs index 8af1e97f7d3d1..ae2054976e53d 100644 --- a/crates/ruff_server/src/fix.rs +++ b/crates/ruff_server/src/fix.rs @@ -20,7 +20,7 @@ use ruff_source_file::LineIndex; /// A simultaneous fix made across a single text document or among an arbitrary /// number of notebook cells. -pub(crate) type Fixes = FxHashMap>; +pub(crate) type Fixes = FxHashMap>; pub(crate) fn fix_all( query: &DocumentQuery, diff --git a/crates/ruff_server/src/lint.rs b/crates/ruff_server/src/lint.rs index c53971841f7eb..2d9859d66946f 100644 --- a/crates/ruff_server/src/lint.rs +++ b/crates/ruff_server/src/lint.rs @@ -62,7 +62,7 @@ pub(crate) struct DiagnosticFix { } /// A series of diagnostics across a single text document or an arbitrary number of notebook cells. -pub(crate) type DiagnosticsMap = FxHashMap>; +pub(crate) type DiagnosticsMap = FxHashMap>; pub(crate) fn check( query: &DocumentQuery, @@ -302,10 +302,10 @@ fn to_lsp_diagnostic( } else { ( match diagnostic.severity() { - ruff_db::diagnostic::Severity::Info => lsp_types::DiagnosticSeverity::INFORMATION, - ruff_db::diagnostic::Severity::Warning => lsp_types::DiagnosticSeverity::WARNING, - ruff_db::diagnostic::Severity::Error => lsp_types::DiagnosticSeverity::ERROR, - ruff_db::diagnostic::Severity::Fatal => lsp_types::DiagnosticSeverity::ERROR, + ruff_db::diagnostic::Severity::Info => lsp_types::DiagnosticSeverity::Information, + ruff_db::diagnostic::Severity::Warning => lsp_types::DiagnosticSeverity::Warning, + ruff_db::diagnostic::Severity::Error => lsp_types::DiagnosticSeverity::Error, + ruff_db::diagnostic::Severity::Fatal => lsp_types::DiagnosticSeverity::Error, }, diagnostic.secondary_code_or_id().to_string(), ) @@ -317,10 +317,10 @@ fn to_lsp_diagnostic( range, severity: Some(severity), tags: tags(diagnostic), - code: Some(lsp_types::NumberOrString::String(code)), + code: Some(lsp_types::Code::String(code)), code_description: diagnostic.documentation_url().and_then(|url| { Some(lsp_types::CodeDescription { - href: lsp_types::Url::parse(url).ok()?, + href: lsp_types::Uri::parse(url).ok()?, }) }), source: Some(DIAGNOSTIC_NAME.into()), @@ -350,8 +350,8 @@ fn severity(code: &str) -> lsp_types::DiagnosticSeverity { match code { // F821: undefined name // E902: IOError - "F821" | "E902" => lsp_types::DiagnosticSeverity::ERROR, - _ => lsp_types::DiagnosticSeverity::WARNING, + "F821" | "E902" => lsp_types::DiagnosticSeverity::Error, + _ => lsp_types::DiagnosticSeverity::Warning, } } @@ -360,10 +360,10 @@ fn tags(diagnostic: &Diagnostic) -> Option> { tags.iter() .map(|tag| match tag { ruff_db::diagnostic::DiagnosticTag::Unnecessary => { - lsp_types::DiagnosticTag::UNNECESSARY + lsp_types::DiagnosticTag::Unnecessary } ruff_db::diagnostic::DiagnosticTag::Deprecated => { - lsp_types::DiagnosticTag::DEPRECATED + lsp_types::DiagnosticTag::Deprecated } }) .collect() diff --git a/crates/ruff_server/src/server.rs b/crates/ruff_server/src/server.rs index cb819187c9689..189204e1ff759 100644 --- a/crates/ruff_server/src/server.rs +++ b/crates/ruff_server/src/server.rs @@ -4,6 +4,9 @@ use lsp_server::Connection; use lsp_types as types; use lsp_types::InitializeParams; use lsp_types::MessageType; +use lsp_types::NotebookCellLanguage; +use lsp_types::NotebookDocumentFilterWithCells; +use lsp_types::WorkspaceFoldersInitializeParams; use std::num::NonZeroUsize; use std::panic::PanicHookInfo; use std::str::FromStr; @@ -12,11 +15,7 @@ use types::ClientCapabilities; use types::CodeActionKind; use types::CodeActionOptions; use types::DiagnosticOptions; -use types::NotebookCellSelector; use types::NotebookDocumentSyncOptions; -use types::NotebookSelector; -use types::OneOf; -use types::TextDocumentSyncCapability; use types::TextDocumentSyncKind; use types::TextDocumentSyncOptions; use types::WorkDoneProgressOptions; @@ -73,7 +72,8 @@ impl Server { let InitializeParams { initialization_options, - workspace_folders, + workspace_folders_initialize_params: + WorkspaceFoldersInitializeParams { workspace_folders }, .. } = init_params; @@ -153,7 +153,7 @@ impl Server { fn server_capabilities(position_encoding: PositionEncoding) -> types::ServerCapabilities { types::ServerCapabilities { position_encoding: Some(position_encoding.into()), - code_action_provider: Some(types::CodeActionProviderCapability::Options( + code_action_provider: Some( CodeActionOptions { code_action_kinds: Some( SupportedCodeAction::all() @@ -164,18 +164,21 @@ impl Server { work_done_progress: Some(true), }, resolve_provider: Some(true), - }, - )), - workspace: Some(types::WorkspaceServerCapabilities { + documentation: None, + } + .into(), + ), + workspace: Some(types::WorkspaceOptions { workspace_folders: Some(WorkspaceFoldersServerCapabilities { supported: Some(true), - change_notifications: Some(OneOf::Left(true)), + change_notifications: Some(true.into()), }), file_operations: None, + text_document_content: None, }), - document_formatting_provider: Some(OneOf::Left(true)), - document_range_formatting_provider: Some(OneOf::Left(true)), - diagnostic_provider: Some(types::DiagnosticServerCapabilities::Options( + document_formatting_provider: Some(true.into()), + document_range_formatting_provider: Some(true.into()), + diagnostic_provider: Some( DiagnosticOptions { identifier: Some(crate::DIAGNOSTIC_NAME.into()), // multi-file analysis could change this @@ -184,8 +187,9 @@ impl Server { work_done_progress_options: WorkDoneProgressOptions { work_done_progress: Some(true), }, - }, - )), + } + .into(), + ), execute_command_provider: Some(types::ExecuteCommandOptions { commands: SupportedCommand::all() .map(|command| command.identifier().to_string()) @@ -194,26 +198,31 @@ impl Server { work_done_progress: Some(false), }, }), - hover_provider: Some(types::HoverProviderCapability::Simple(true)), - notebook_document_sync: Some(types::OneOf::Left(NotebookDocumentSyncOptions { - save: Some(false), - notebook_selector: [NotebookSelector::ByCells { - notebook: None, - cells: vec![NotebookCellSelector { - language: "python".to_string(), - }], - }] - .to_vec(), - })), - text_document_sync: Some(TextDocumentSyncCapability::Options( + hover_provider: Some(true.into()), + notebook_document_sync: Some( + NotebookDocumentSyncOptions { + save: Some(false), + notebook_selector: [NotebookDocumentFilterWithCells { + notebook: None, + cells: vec![NotebookCellLanguage { + language: "python".to_string(), + }], + } + .into()] + .to_vec(), + } + .into(), + ), + text_document_sync: Some( TextDocumentSyncOptions { open_close: Some(true), - change: Some(TextDocumentSyncKind::INCREMENTAL), + change: Some(TextDocumentSyncKind::Incremental), will_save: Some(false), will_save_wait_until: Some(false), - ..Default::default() - }, - )), + save: None, + } + .into(), + ), ..Default::default() } } @@ -246,7 +255,7 @@ impl SupportedCodeAction { /// Returns the LSP code action kind that map to this code action. fn to_kind(self) -> CodeActionKind { match self { - Self::QuickFix => CodeActionKind::QUICKFIX, + Self::QuickFix => CodeActionKind::QuickFix, Self::SourceFixAll => crate::SOURCE_FIX_ALL_RUFF, Self::SourceOrganizeImports => crate::SOURCE_ORGANIZE_IMPORTS_RUFF, Self::NotebookSourceFixAll => crate::NOTEBOOK_SOURCE_FIX_ALL_RUFF, @@ -360,7 +369,7 @@ impl ServerPanicHookHandler { client .show_message( "The Ruff language server exited with a panic. See the logs for more details.", - MessageType::ERROR, + MessageType::Error, ) .ok(); } diff --git a/crates/ruff_server/src/server/api.rs b/crates/ruff_server/src/server/api.rs index 42007c10d8029..4ac66b05dc391 100644 --- a/crates/ruff_server/src/server/api.rs +++ b/crates/ruff_server/src/server/api.rs @@ -2,7 +2,7 @@ use std::panic::UnwindSafe; use anyhow::anyhow; use lsp_server::{self as server, RequestId}; -use lsp_types::{notification::Notification, request::Request}; +use lsp_types::{LspNotificationMethod, LspRequestMethod, Notification, Request}; use notifications as notification; use requests as request; @@ -33,7 +33,7 @@ use super::{Result, schedule::BackgroundSchedule}; /// that is of type [`lsp_types::Url`]. macro_rules! define_document_url { ($params:ident: &$p:ty) => { - fn document_url($params: &$p) -> std::borrow::Cow<'_, lsp_types::Url> { + fn document_url($params: &$p) -> std::borrow::Cow<'_, lsp_types::Uri> { std::borrow::Cow::Borrowed(&$params.text_document.uri) } }; @@ -50,7 +50,7 @@ use define_document_url; pub(super) fn request(req: server::Request) -> Task { let id = req.id.clone(); - match req.method.as_str() { + match LspRequestMethod::from(req.method.clone()) { request::CodeActions::METHOD => { background_request_task::(req, BackgroundSchedule::Worker) } @@ -70,7 +70,7 @@ pub(super) fn request(req: server::Request) -> Task { request::Hover::METHOD => { background_request_task::(req, BackgroundSchedule::Worker) } - lsp_types::request::Shutdown::METHOD => sync_request_task::(req), + lsp_types::ShutdownRequest::METHOD => sync_request_task::(req), method => { tracing::warn!("Received request {method} which does not have a handler"); let result: Result<()> = Err(Error::new( @@ -101,7 +101,7 @@ pub(super) fn request(req: server::Request) -> Task { } pub(super) fn notification(notif: server::Notification) -> Task { - match notif.method.as_str() { + match LspNotificationMethod::from(notif.method.clone()) { notification::DidChange::METHOD => { sync_notification_task::(notif) } @@ -125,10 +125,10 @@ pub(super) fn notification(notif: server::Notification) -> Task { notification::DidCloseNotebook::METHOD => { sync_notification_task::(notif) } - lsp_types::notification::Cancel::METHOD => { + lsp_types::CancelNotification::METHOD => { sync_notification_task::(notif) } - lsp_types::notification::SetTrace::METHOD => { + lsp_types::SetTraceNotification::METHOD => { tracing::trace!("Ignoring `setTrace` notification"); return Task::nothing(); } @@ -153,7 +153,7 @@ where { let (id, params) = cast_request::(req)?; Ok(Task::sync(move |session, client: &Client| { - let _span = tracing::debug_span!("request", %id, method = R::METHOD).entered(); + let _span = tracing::debug_span!("request", %id, method = R::METHOD.as_str()).entered(); let result = R::run(session, client, params); respond::(&id, result, client); })) @@ -183,7 +183,7 @@ where }; Box::new(move |client| { - let _span = tracing::debug_span!("request", %id, method = R::METHOD).entered(); + let _span = tracing::debug_span!("request", %id, method = R::METHOD.as_str()).entered(); // Test again if the request was cancelled since it was scheduled on the background task // and, if so, return early @@ -237,7 +237,7 @@ where fn sync_notification_task(notif: server::Notification) -> Result { let (id, params) = cast_notification::(notif)?; Ok(Task::sync(move |session, client| { - let _span = tracing::debug_span!("notification", method = N::METHOD).entered(); + let _span = tracing::debug_span!("notification", method = N::METHOD.as_str()).entered(); if let Err(err) = N::run(session, client, params) { tracing::error!("An error occurred while running {id}: {err}"); client @@ -266,7 +266,7 @@ where return Box::new(|_| {}); }; Box::new(move |client| { - let _span = tracing::debug_span!("notification", method = N::METHOD).entered(); + let _span = tracing::debug_span!("notification", method = N::METHOD.as_str()).entered(); let result = match std::panic::catch_unwind(|| N::run_with_snapshot(snapshot, client, params)) { @@ -311,7 +311,7 @@ where <::RequestType as Request>::Params: UnwindSafe, { request - .extract(Req::METHOD) + .extract(Req::METHOD.as_str()) .map_err(|err| match err { json_err @ server::ExtractError::JsonError { .. } => { anyhow::anyhow!("JSON parsing failure:\n{json_err}") @@ -354,7 +354,7 @@ fn respond_silent_error(id: RequestId, client: &Client, error: lsp_server::Respo fn cast_notification( notification: server::Notification, ) -> Result<( - &'static str, + LspNotificationMethod, <::NotificationType as Notification>::Params, )> where @@ -363,7 +363,7 @@ where Ok(( N::METHOD, notification - .extract(N::METHOD) + .extract(N::METHOD.as_str()) .map_err(|err| match err { json_err @ server::ExtractError::JsonError { .. } => { anyhow::anyhow!("JSON parsing failure:\n{json_err}") diff --git a/crates/ruff_server/src/server/api/diagnostics.rs b/crates/ruff_server/src/server/api/diagnostics.rs index 6f8efe47e83b4..dab14f2f1f598 100644 --- a/crates/ruff_server/src/server/api/diagnostics.rs +++ b/crates/ruff_server/src/server/api/diagnostics.rs @@ -24,7 +24,7 @@ pub(super) fn publish_diagnostics_for_document( ) -> crate::server::Result<()> { for (uri, diagnostics) in generate_diagnostics(snapshot) { client - .send_notification::( + .send_notification::( lsp_types::PublishDiagnosticsParams { uri, diagnostics, @@ -42,7 +42,7 @@ pub(super) fn clear_diagnostics_for_document( client: &Client, ) -> crate::server::Result<()> { client - .send_notification::( + .send_notification::( lsp_types::PublishDiagnosticsParams { uri: query.make_key().into_url(), diagnostics: vec![], diff --git a/crates/ruff_server/src/server/api/notifications/cancel.rs b/crates/ruff_server/src/server/api/notifications/cancel.rs index 85553866783de..6d64da3e5570d 100644 --- a/crates/ruff_server/src/server/api/notifications/cancel.rs +++ b/crates/ruff_server/src/server/api/notifications/cancel.rs @@ -1,6 +1,6 @@ use lsp_server::RequestId; +use lsp_types::CancelNotification; use lsp_types::CancelParams; -use lsp_types::notification::Cancel; use crate::server::Result; use crate::server::api::traits::{NotificationHandler, SyncNotificationHandler}; @@ -9,14 +9,14 @@ use crate::session::{Client, Session}; pub(crate) struct CancelNotificationHandler; impl NotificationHandler for CancelNotificationHandler { - type NotificationType = Cancel; + type NotificationType = CancelNotification; } impl SyncNotificationHandler for CancelNotificationHandler { fn run(session: &mut Session, client: &Client, params: CancelParams) -> Result<()> { let id: RequestId = match params.id { - lsp_types::NumberOrString::Number(id) => id.into(), - lsp_types::NumberOrString::String(id) => id.into(), + lsp_types::Id::Int(id) => id.into(), + lsp_types::Id::String(id) => id.into(), }; let _ = client.cancel(session, id); diff --git a/crates/ruff_server/src/server/api/notifications/did_change.rs b/crates/ruff_server/src/server/api/notifications/did_change.rs index 8e77cb593fadf..d66b4daba8dda 100644 --- a/crates/ruff_server/src/server/api/notifications/did_change.rs +++ b/crates/ruff_server/src/server/api/notifications/did_change.rs @@ -3,13 +3,12 @@ use crate::server::api::LSPResult; use crate::server::api::diagnostics::publish_diagnostics_for_document; use crate::session::{Client, Session}; use lsp_server::ErrorCode; -use lsp_types as types; -use lsp_types::notification as notif; +use lsp_types::{self as types, DidChangeTextDocumentNotification, TextDocumentIdentifier}; pub(crate) struct DidChange; impl super::NotificationHandler for DidChange { - type NotificationType = notif::DidChangeTextDocument; + type NotificationType = DidChangeTextDocumentNotification; } impl super::SyncNotificationHandler for DidChange { @@ -19,7 +18,7 @@ impl super::SyncNotificationHandler for DidChange { types::DidChangeTextDocumentParams { text_document: types::VersionedTextDocumentIdentifier { - uri, + text_document_identifier: TextDocumentIdentifier { uri }, version: new_version, }, content_changes, diff --git a/crates/ruff_server/src/server/api/notifications/did_change_configuration.rs b/crates/ruff_server/src/server/api/notifications/did_change_configuration.rs index 34982ec65659e..57493d228ffef 100644 --- a/crates/ruff_server/src/server/api/notifications/did_change_configuration.rs +++ b/crates/ruff_server/src/server/api/notifications/did_change_configuration.rs @@ -1,12 +1,11 @@ use crate::server::Result; use crate::session::{Client, Session}; -use lsp_types as types; -use lsp_types::notification as notif; +use lsp_types::{self as types, DidChangeConfigurationNotification}; pub(crate) struct DidChangeConfiguration; impl super::NotificationHandler for DidChangeConfiguration { - type NotificationType = notif::DidChangeConfiguration; + type NotificationType = DidChangeConfigurationNotification; } impl super::SyncNotificationHandler for DidChangeConfiguration { diff --git a/crates/ruff_server/src/server/api/notifications/did_change_notebook.rs b/crates/ruff_server/src/server/api/notifications/did_change_notebook.rs index d092ccacb8528..fb0cad1833e88 100644 --- a/crates/ruff_server/src/server/api/notifications/did_change_notebook.rs +++ b/crates/ruff_server/src/server/api/notifications/did_change_notebook.rs @@ -3,13 +3,12 @@ use crate::server::api::LSPResult; use crate::server::api::diagnostics::publish_diagnostics_for_document; use crate::session::{Client, Session}; use lsp_server::ErrorCode; -use lsp_types as types; -use lsp_types::notification as notif; +use lsp_types::{self as types, DidChangeNotebookDocumentNotification}; pub(crate) struct DidChangeNotebook; impl super::NotificationHandler for DidChangeNotebook { - type NotificationType = notif::DidChangeNotebookDocument; + type NotificationType = DidChangeNotebookDocumentNotification; } impl super::SyncNotificationHandler for DidChangeNotebook { diff --git a/crates/ruff_server/src/server/api/notifications/did_change_watched_files.rs b/crates/ruff_server/src/server/api/notifications/did_change_watched_files.rs index bc97231411dd1..ea3bd6dc1107a 100644 --- a/crates/ruff_server/src/server/api/notifications/did_change_watched_files.rs +++ b/crates/ruff_server/src/server/api/notifications/did_change_watched_files.rs @@ -2,13 +2,12 @@ use crate::server::Result; use crate::server::api::LSPResult; use crate::server::api::diagnostics::publish_diagnostics_for_document; use crate::session::{Client, Session}; -use lsp_types as types; -use lsp_types::notification as notif; +use lsp_types::{self as types, DidChangeWatchedFilesNotification}; pub(crate) struct DidChangeWatchedFiles; impl super::NotificationHandler for DidChangeWatchedFiles { - type NotificationType = notif::DidChangeWatchedFiles; + type NotificationType = DidChangeWatchedFilesNotification; } impl super::SyncNotificationHandler for DidChangeWatchedFiles { @@ -22,11 +21,7 @@ impl super::SyncNotificationHandler for DidChangeWatchedFiles { if !params.changes.is_empty() { if session.resolved_client_capabilities().workspace_refresh { client - .send_request::( - session, - (), - |_, ()| (), - ) + .send_request::(session, (), |_, ()| ()) .with_failure_code(lsp_server::ErrorCode::InternalError)?; } else { // publish diagnostics for text documents diff --git a/crates/ruff_server/src/server/api/notifications/did_change_workspace.rs b/crates/ruff_server/src/server/api/notifications/did_change_workspace.rs index a121d1b2b4e96..06562f9fb5d8d 100644 --- a/crates/ruff_server/src/server/api/notifications/did_change_workspace.rs +++ b/crates/ruff_server/src/server/api/notifications/did_change_workspace.rs @@ -1,13 +1,12 @@ use crate::server::Result; use crate::server::api::LSPResult; use crate::session::{Client, Session}; -use lsp_types as types; -use lsp_types::notification as notif; +use lsp_types::{self as types, DidChangeWorkspaceFoldersNotification}; pub(crate) struct DidChangeWorkspace; impl super::NotificationHandler for DidChangeWorkspace { - type NotificationType = notif::DidChangeWorkspaceFolders; + type NotificationType = DidChangeWorkspaceFoldersNotification; } impl super::SyncNotificationHandler for DidChangeWorkspace { diff --git a/crates/ruff_server/src/server/api/notifications/did_close.rs b/crates/ruff_server/src/server/api/notifications/did_close.rs index a3075a4846b87..672b9b21ec297 100644 --- a/crates/ruff_server/src/server/api/notifications/did_close.rs +++ b/crates/ruff_server/src/server/api/notifications/did_close.rs @@ -2,13 +2,12 @@ use crate::server::Result; use crate::server::api::LSPResult; use crate::server::api::diagnostics::clear_diagnostics_for_document; use crate::session::{Client, Session}; -use lsp_types as types; -use lsp_types::notification as notif; +use lsp_types::{self as types, DidCloseTextDocumentNotification}; pub(crate) struct DidClose; impl super::NotificationHandler for DidClose { - type NotificationType = notif::DidCloseTextDocument; + type NotificationType = DidCloseTextDocumentNotification; } impl super::SyncNotificationHandler for DidClose { diff --git a/crates/ruff_server/src/server/api/notifications/did_close_notebook.rs b/crates/ruff_server/src/server/api/notifications/did_close_notebook.rs index b70993b5e1225..38dbe00422552 100644 --- a/crates/ruff_server/src/server/api/notifications/did_close_notebook.rs +++ b/crates/ruff_server/src/server/api/notifications/did_close_notebook.rs @@ -1,13 +1,12 @@ use crate::server::Result; use crate::server::api::LSPResult; use crate::session::{Client, Session}; -use lsp_types::notification as notif; -use lsp_types::{self as types, NotebookDocumentIdentifier}; +use lsp_types::{self as types, DidCloseNotebookDocumentNotification, NotebookDocumentIdentifier}; pub(crate) struct DidCloseNotebook; impl super::NotificationHandler for DidCloseNotebook { - type NotificationType = notif::DidCloseNotebookDocument; + type NotificationType = DidCloseNotebookDocumentNotification; } impl super::SyncNotificationHandler for DidCloseNotebook { diff --git a/crates/ruff_server/src/server/api/notifications/did_open.rs b/crates/ruff_server/src/server/api/notifications/did_open.rs index 41a6fb6cf8d13..4de8dc0ee56f1 100644 --- a/crates/ruff_server/src/server/api/notifications/did_open.rs +++ b/crates/ruff_server/src/server/api/notifications/did_open.rs @@ -3,13 +3,12 @@ use crate::server::Result; use crate::server::api::LSPResult; use crate::server::api::diagnostics::publish_diagnostics_for_document; use crate::session::{Client, Session}; -use lsp_types as types; -use lsp_types::notification as notif; +use lsp_types::{self as types, DidOpenTextDocumentNotification}; pub(crate) struct DidOpen; impl super::NotificationHandler for DidOpen { - type NotificationType = notif::DidOpenTextDocument; + type NotificationType = DidOpenTextDocumentNotification; } impl super::SyncNotificationHandler for DidOpen { @@ -26,7 +25,7 @@ impl super::SyncNotificationHandler for DidOpen { }, }: types::DidOpenTextDocumentParams, ) -> Result<()> { - let document = TextDocument::new(text, version).with_language_id(&language_id); + let document = TextDocument::new(text, version).with_language_id(language_id.as_str()); session.open_text_document(uri.clone(), document); diff --git a/crates/ruff_server/src/server/api/notifications/did_open_notebook.rs b/crates/ruff_server/src/server/api/notifications/did_open_notebook.rs index a75e88ecc5398..6ac24e18bcdc7 100644 --- a/crates/ruff_server/src/server/api/notifications/did_open_notebook.rs +++ b/crates/ruff_server/src/server/api/notifications/did_open_notebook.rs @@ -4,13 +4,12 @@ use crate::server::api::LSPResult; use crate::server::api::diagnostics::publish_diagnostics_for_document; use crate::session::{Client, Session}; use lsp_server::ErrorCode; -use lsp_types as types; -use lsp_types::notification as notif; +use lsp_types::{self as types, DidOpenNotebookDocumentNotification}; pub(crate) struct DidOpenNotebook; impl super::NotificationHandler for DidOpenNotebook { - type NotificationType = notif::DidOpenNotebookDocument; + type NotificationType = DidOpenNotebookDocumentNotification; } impl super::SyncNotificationHandler for DidOpenNotebook { diff --git a/crates/ruff_server/src/server/api/requests/code_action.rs b/crates/ruff_server/src/server/api/requests/code_action.rs index 9dae18563b84d..1b39280a76d48 100644 --- a/crates/ruff_server/src/server/api/requests/code_action.rs +++ b/crates/ruff_server/src/server/api/requests/code_action.rs @@ -1,8 +1,8 @@ use lsp_server::ErrorCode; -use lsp_types::{self as types, request as req}; +use lsp_types::{self as types, CodeActionRequest, CodeActionResponse}; use ruff_python_ast::SourceType; use rustc_hash::FxHashSet; -use types::{CodeActionKind, CodeActionOrCommand}; +use types::CodeActionKind; use crate::DIAGNOSTIC_NAME; use crate::edit::WorkspaceEditTracker; @@ -18,7 +18,7 @@ use super::code_action_resolve::{resolve_edit_for_fix_all, resolve_edit_for_orga pub(crate) struct CodeActions; impl super::RequestHandler for CodeActions { - type RequestType = req::CodeActionRequest; + type RequestType = CodeActionRequest; } impl super::BackgroundDocumentRequestHandler for CodeActions { @@ -27,8 +27,8 @@ impl super::BackgroundDocumentRequestHandler for CodeActions { snapshot: DocumentSnapshot, _client: &Client, params: types::CodeActionParams, - ) -> Result> { - let mut response: types::CodeActionResponse = types::CodeActionResponse::default(); + ) -> Result>> { + let mut response = Vec::new(); let query = snapshot.query(); @@ -116,7 +116,7 @@ impl super::BackgroundDocumentRequestHandler for CodeActions { fn quick_fix( snapshot: &DocumentSnapshot, fixes: &[DiagnosticFix], -) -> crate::Result> { +) -> crate::Result> { let document = snapshot.query(); fixes @@ -133,9 +133,9 @@ fn quick_fix( fix.edits.clone(), )?; - Ok(types::CodeActionOrCommand::CodeAction(types::CodeAction { + Ok(CodeActionResponse::CodeAction(types::CodeAction { title: format!("{DIAGNOSTIC_NAME} ({}): {}", fix.code, fix.title), - kind: Some(types::CodeActionKind::QUICKFIX), + kind: Some(types::CodeActionKind::QuickFix), edit: Some(tracker.into_workspace_edit()), diagnostics: Some(vec![fix.fixed_diagnostic.clone()]), data: Some( @@ -147,7 +147,7 @@ fn quick_fix( .collect() } -fn noqa_comments(snapshot: &DocumentSnapshot, fixes: &[DiagnosticFix]) -> Vec { +fn noqa_comments(snapshot: &DocumentSnapshot, fixes: &[DiagnosticFix]) -> Vec { fixes .iter() .filter_map(|fix| { @@ -163,9 +163,9 @@ fn noqa_comments(snapshot: &DocumentSnapshot, fixes: &[DiagnosticFix]) -> Vec Vec crate::Result { +fn fix_all(snapshot: &DocumentSnapshot) -> crate::Result { let document = snapshot.query(); let (edit, data) = if snapshot @@ -204,7 +204,7 @@ fn fix_all(snapshot: &DocumentSnapshot) -> crate::Result { ) }; - Ok(CodeActionOrCommand::CodeAction(types::CodeAction { + Ok(CodeActionResponse::CodeAction(types::CodeAction { title: format!("{DIAGNOSTIC_NAME}: Fix all auto-fixable problems"), kind: Some(crate::SOURCE_FIX_ALL_RUFF), edit, @@ -213,7 +213,7 @@ fn fix_all(snapshot: &DocumentSnapshot) -> crate::Result { })) } -fn notebook_fix_all(snapshot: &DocumentSnapshot) -> crate::Result { +fn notebook_fix_all(snapshot: &DocumentSnapshot) -> crate::Result { let document = snapshot.query(); let (edit, data) = if snapshot @@ -239,7 +239,7 @@ fn notebook_fix_all(snapshot: &DocumentSnapshot) -> crate::Result crate::Result crate::Result { +fn organize_imports(snapshot: &DocumentSnapshot) -> crate::Result { let document = snapshot.query(); let (edit, data) = if snapshot @@ -274,7 +274,7 @@ fn organize_imports(snapshot: &DocumentSnapshot) -> crate::Result crate::Result crate::Result { +fn notebook_organize_imports(snapshot: &DocumentSnapshot) -> crate::Result { let document = snapshot.query(); let (edit, data) = if snapshot @@ -309,7 +309,7 @@ fn notebook_organize_imports(snapshot: &DocumentSnapshot) -> crate::Result Cow<'_, types::Url> { - let uri: lsp_types::Url = serde_json::from_value(params.data.clone().unwrap_or_default()) + fn document_url(params: &types::CodeAction) -> Cow<'_, types::Uri> { + let uri: lsp_types::Uri = serde_json::from_value(params.data.clone().unwrap_or_default()) .expect("code actions should have a URI in their data fields"); Cow::Owned(uri) } diff --git a/crates/ruff_server/src/server/api/requests/diagnostic.rs b/crates/ruff_server/src/server/api/requests/diagnostic.rs index 5315ea931bc05..9efcf5d480705 100644 --- a/crates/ruff_server/src/server/api/requests/diagnostic.rs +++ b/crates/ruff_server/src/server/api/requests/diagnostic.rs @@ -1,16 +1,13 @@ use crate::server::api::diagnostics::generate_diagnostics; use crate::session::DocumentSnapshot; use crate::{server::Result, session::Client}; -use lsp_types::{self as types, request as req}; -use types::{ - DocumentDiagnosticReportResult, FullDocumentDiagnosticReport, - RelatedFullDocumentDiagnosticReport, -}; +use lsp_types::{self as types, DocumentDiagnosticReport, DocumentDiagnosticRequest}; +use types::{FullDocumentDiagnosticReport, RelatedFullDocumentDiagnosticReport}; pub(crate) struct DocumentDiagnostic; impl super::RequestHandler for DocumentDiagnostic { - type RequestType = req::DocumentDiagnosticRequest; + type RequestType = DocumentDiagnosticRequest; } impl super::BackgroundDocumentRequestHandler for DocumentDiagnostic { @@ -19,22 +16,24 @@ impl super::BackgroundDocumentRequestHandler for DocumentDiagnostic { snapshot: DocumentSnapshot, _client: &Client, _params: types::DocumentDiagnosticParams, - ) -> Result { - Ok(DocumentDiagnosticReportResult::Report( - types::DocumentDiagnosticReport::Full(RelatedFullDocumentDiagnosticReport { - related_documents: None, - full_document_diagnostic_report: FullDocumentDiagnosticReport { - // TODO(jane): eventually this will be important for caching diagnostic information. - result_id: None, - // Pull diagnostic requests are only called for text documents. - // Since diagnostic requests generate - items: generate_diagnostics(&snapshot) - .into_iter() - .next() - .map(|(_, diagnostics)| diagnostics) - .unwrap_or_default(), + ) -> Result { + Ok( + DocumentDiagnosticReport::RelatedFullDocumentDiagnosticReport( + RelatedFullDocumentDiagnosticReport { + related_documents: None, + full_document_diagnostic_report: FullDocumentDiagnosticReport { + // TODO(jane): eventually this will be important for caching diagnostic information. + result_id: None, + // Pull diagnostic requests are only called for text documents. + // Since diagnostic requests generate + items: generate_diagnostics(&snapshot) + .into_iter() + .next() + .map(|(_, diagnostics)| diagnostics) + .unwrap_or_default(), + }, }, - }), - )) + ), + ) } } diff --git a/crates/ruff_server/src/server/api/requests/execute_command.rs b/crates/ruff_server/src/server/api/requests/execute_command.rs index 632a196ab91c8..0a959787c6cd2 100644 --- a/crates/ruff_server/src/server/api/requests/execute_command.rs +++ b/crates/ruff_server/src/server/api/requests/execute_command.rs @@ -8,14 +8,16 @@ use crate::session::{Client, Session}; use crate::{DIAGNOSTIC_NAME, DocumentKey}; use crate::{edit::DocumentVersion, server}; use lsp_server::ErrorCode; -use lsp_types::{self as types, TextDocumentIdentifier, request as req}; +use lsp_types::{ + self as types, ApplyWorkspaceEditRequest, ExecuteCommandRequest, TextDocumentIdentifier, +}; use serde::Deserialize; pub(crate) struct ExecuteCommand; #[derive(Deserialize)] struct Argument { - uri: types::Url, + uri: types::Uri, version: DocumentVersion, } @@ -31,7 +33,7 @@ struct DebugCommandArgument { } impl super::RequestHandler for ExecuteCommand { - type RequestType = req::ExecuteCommand; + type RequestType = ExecuteCommandRequest; } impl super::SyncRequestHandler for ExecuteCommand { @@ -48,7 +50,10 @@ impl super::SyncRequestHandler for ExecuteCommand { // provided but we could expand this to consider all *open* documents. let argument: DebugCommandArgument = params.arguments.into_iter().next().map_or_else( || Ok(DebugCommandArgument::default()), - |value| serde_json::from_value(value).with_failure_code(ErrorCode::InvalidParams), + |value| { + serde_json::from_value(serde_json::Value::Array(value)) + .with_failure_code(ErrorCode::InvalidParams) + }, )?; return Ok(Some(serde_json::Value::String( debug_information(session, argument.text_document) @@ -64,7 +69,10 @@ impl super::SyncRequestHandler for ExecuteCommand { let mut arguments: Vec = params .arguments .into_iter() - .map(|value| serde_json::from_value(value).with_failure_code(ErrorCode::InvalidParams)) + .map(|value| { + serde_json::from_value(serde_json::Value::Array(value)) + .with_failure_code(ErrorCode::InvalidParams) + }) .collect::>()?; arguments.sort_by(|a, b| a.uri.cmp(&b.uri)); @@ -130,11 +138,12 @@ fn apply_edit( label: &str, edit: types::WorkspaceEdit, ) -> crate::Result<()> { - client.send_request::( + client.send_request::( session, types::ApplyWorkspaceEditParams { label: Some(format!("{DIAGNOSTIC_NAME}: {label}")), edit, + metadata: None, }, move |client, response| { if !response.applied { @@ -216,3 +225,4 @@ config_path = {config_path:?} Ok(buffer) } + diff --git a/crates/ruff_server/src/server/api/requests/format.rs b/crates/ruff_server/src/server/api/requests/format.rs index d747f27d3e76c..346b5933080dc 100644 --- a/crates/ruff_server/src/server/api/requests/format.rs +++ b/crates/ruff_server/src/server/api/requests/format.rs @@ -1,5 +1,5 @@ use anyhow::Context; -use lsp_types::{self as types, request as req}; +use lsp_types::{self as types, DocumentFormattingRequest}; use types::TextEdit; use ruff_source_file::LineIndex; @@ -16,7 +16,7 @@ use crate::{PositionEncoding, TextDocument}; pub(crate) struct Format; impl super::RequestHandler for Format { - type RequestType = req::Formatting; + type RequestType = DocumentFormattingRequest; } impl super::BackgroundDocumentRequestHandler for Format { diff --git a/crates/ruff_server/src/server/api/requests/format_range.rs b/crates/ruff_server/src/server/api/requests/format_range.rs index 5f2d0b58f94a8..48b7614506596 100644 --- a/crates/ruff_server/src/server/api/requests/format_range.rs +++ b/crates/ruff_server/src/server/api/requests/format_range.rs @@ -1,5 +1,5 @@ use anyhow::Context; -use lsp_types::{self as types, Range, request as req}; +use lsp_types::{self as types, DocumentRangeFormattingRequest, Range}; use crate::edit::{RangeExt, ToRangeExt}; use crate::resolve::is_document_excluded_for_formatting; @@ -11,7 +11,7 @@ use crate::{PositionEncoding, TextDocument}; pub(crate) struct FormatRange; impl super::RequestHandler for FormatRange { - type RequestType = req::RangeFormatting; + type RequestType = DocumentRangeFormattingRequest; } impl super::BackgroundDocumentRequestHandler for FormatRange { diff --git a/crates/ruff_server/src/server/api/requests/hover.rs b/crates/ruff_server/src/server/api/requests/hover.rs index ea4492ad212f4..67f08f4fe6c29 100644 --- a/crates/ruff_server/src/server/api/requests/hover.rs +++ b/crates/ruff_server/src/server/api/requests/hover.rs @@ -1,7 +1,7 @@ use crate::server::Result; use crate::session::{Client, DocumentSnapshot}; use anyhow::Context; -use lsp_types::{self as types, request as req}; +use lsp_types::{self as types, HoverRequest}; use regex::Regex; use ruff_linter::FixAvailability; use ruff_linter::registry::{Linter, Rule, RuleNamespace}; @@ -12,11 +12,11 @@ use std::fmt::Write; pub(crate) struct Hover; impl super::RequestHandler for Hover { - type RequestType = req::HoverRequest; + type RequestType = HoverRequest; } impl super::BackgroundDocumentRequestHandler for Hover { - fn document_url(params: &types::HoverParams) -> std::borrow::Cow<'_, lsp_types::Url> { + fn document_url(params: &types::HoverParams) -> std::borrow::Cow<'_, lsp_types::Uri> { std::borrow::Cow::Borrowed(¶ms.text_document_position_params.text_document.uri) } fn run_with_snapshot( @@ -78,10 +78,11 @@ pub(crate) fn hover( }; let hover = types::Hover { - contents: types::HoverContents::Markup(types::MarkupContent { + contents: types::MarkupContent { kind: types::MarkupKind::Markdown, value: output, - }), + } + .into(), range: None, }; diff --git a/crates/ruff_server/src/server/api/requests/shutdown.rs b/crates/ruff_server/src/server/api/requests/shutdown.rs index 5ec89c79329cd..98b4469a84ce1 100644 --- a/crates/ruff_server/src/server/api/requests/shutdown.rs +++ b/crates/ruff_server/src/server/api/requests/shutdown.rs @@ -5,7 +5,7 @@ use crate::session::Client; pub(crate) struct ShutdownHandler; impl RequestHandler for ShutdownHandler { - type RequestType = lsp_types::request::Shutdown; + type RequestType = lsp_types::ShutdownRequest; } impl SyncRequestHandler for ShutdownHandler { diff --git a/crates/ruff_server/src/server/api/traits.rs b/crates/ruff_server/src/server/api/traits.rs index ef0dc88d9937a..ae695247b74e1 100644 --- a/crates/ruff_server/src/server/api/traits.rs +++ b/crates/ruff_server/src/server/api/traits.rs @@ -29,13 +29,15 @@ use crate::session::{Client, DocumentSnapshot, Session}; -use lsp_types::notification::Notification as LSPNotification; -use lsp_types::request::Request; +use lsp_types::LspNotificationMethod; +use lsp_types::LspRequestMethod; +use lsp_types::Notification as LSPNotification; +use lsp_types::Request; /// A supertrait for any server request handler. pub(super) trait RequestHandler { type RequestType: Request; - const METHOD: &'static str = <::RequestType as Request>::METHOD; + const METHOD: LspRequestMethod = <::RequestType as Request>::METHOD; } /// A request handler that needs mutable access to the session. @@ -62,7 +64,7 @@ pub(super) trait BackgroundDocumentRequestHandler: RequestHandler { /// [`define_document_url`]: super::define_document_url fn document_url( params: &<::RequestType as Request>::Params, - ) -> std::borrow::Cow<'_, lsp_types::Url>; + ) -> std::borrow::Cow<'_, lsp_types::Uri>; fn run_with_snapshot( snapshot: DocumentSnapshot, @@ -74,7 +76,7 @@ pub(super) trait BackgroundDocumentRequestHandler: RequestHandler { /// A supertrait for any server notification handler. pub(super) trait NotificationHandler { type NotificationType: LSPNotification; - const METHOD: &'static str = + const METHOD: LspNotificationMethod = <::NotificationType as LSPNotification>::METHOD; } @@ -100,7 +102,7 @@ pub(super) trait BackgroundDocumentNotificationHandler: NotificationHandler { /// [`define_document_url`]: super::define_document_url fn document_url( params: &<::NotificationType as LSPNotification>::Params, - ) -> std::borrow::Cow<'_, lsp_types::Url>; + ) -> std::borrow::Cow<'_, lsp_types::Uri>; fn run_with_snapshot( snapshot: DocumentSnapshot, diff --git a/crates/ruff_server/src/server/main_loop.rs b/crates/ruff_server/src/server/main_loop.rs index 00d1ee5d32e2d..370e84c7f1416 100644 --- a/crates/ruff_server/src/server/main_loop.rs +++ b/crates/ruff_server/src/server/main_loop.rs @@ -2,8 +2,7 @@ use anyhow::anyhow; use crossbeam::select; use lsp_server::Message; use lsp_types::{ - self as types, DidChangeWatchedFilesRegistrationOptions, FileSystemWatcher, - notification::Notification as _, + self as types, DidChangeWatchedFilesRegistrationOptions, FileSystemWatcher, Notification as _, }; use crate::{ @@ -61,7 +60,7 @@ impl Server { api::request(req) } Message::Notification(notification) => { - if notification.method == lsp_types::notification::Exit::METHOD { + if notification.method == lsp_types::ExitNotification::METHOD.as_str() { if !self.session.is_shutdown_requested() { return Err(anyhow!( "Received exit notification before a shutdown request" @@ -156,17 +155,19 @@ impl Server { serde_json::to_value(DidChangeWatchedFilesRegistrationOptions { watchers: vec![ FileSystemWatcher { - glob_pattern: types::GlobPattern::String( + glob_pattern: types::GlobPattern::Pattern( "**/.ruff.toml".into(), ), kind: None, }, FileSystemWatcher { - glob_pattern: types::GlobPattern::String("**/ruff.toml".into()), + glob_pattern: types::GlobPattern::Pattern( + "**/ruff.toml".into(), + ), kind: None, }, FileSystemWatcher { - glob_pattern: types::GlobPattern::String( + glob_pattern: types::GlobPattern::Pattern( "**/pyproject.toml".into(), ), kind: None, @@ -182,7 +183,7 @@ impl Server { tracing::info!("Configuration file watcher successfully registered"); }; - if let Err(err) = client.send_request::( + if let Err(err) = client.send_request::( &self.session, params, response_handler, diff --git a/crates/ruff_server/src/session.rs b/crates/ruff_server/src/session.rs index 6bbd6718bb66a..497b48329866a 100644 --- a/crates/ruff_server/src/session.rs +++ b/crates/ruff_server/src/session.rs @@ -1,9 +1,10 @@ //! Data model, state management, and configuration resolution. +use std::collections::HashMap; use std::path::Path; use std::sync::Arc; -use lsp_types::{ClientCapabilities, FileEvent, NotebookDocumentCellChange, Url}; +use lsp_types::{ClientCapabilities, FileEvent, NotebookDocumentCellChanges, Uri as Url}; use settings::ClientSettings; use crate::edit::{DocumentKey, DocumentVersion, NotebookDocument}; @@ -108,12 +109,12 @@ impl Session { } /// Iterates over the LSP URLs for all open text documents. These URLs are valid file paths. - pub(super) fn text_document_urls(&self) -> impl Iterator + '_ { + pub(super) fn text_document_urls(&self) -> impl Iterator + '_ { self.index.text_document_urls() } /// Iterates over the LSP URLs for all open notebook documents. These URLs are valid file paths. - pub(super) fn notebook_document_urls(&self) -> impl Iterator + '_ { + pub(super) fn notebook_document_urls(&self) -> impl Iterator + '_ { self.index.notebook_document_urls() } @@ -140,8 +141,8 @@ impl Session { pub(crate) fn update_notebook_document( &mut self, key: &DocumentKey, - cells: Option, - metadata: Option>, + cells: Option, + metadata: Option>, version: DocumentVersion, ) -> crate::Result<()> { let encoding = self.encoding(); diff --git a/crates/ruff_server/src/session/client.rs b/crates/ruff_server/src/session/client.rs index e90c001e09345..f5600a71454ac 100644 --- a/crates/ruff_server/src/session/client.rs +++ b/crates/ruff_server/src/session/client.rs @@ -46,11 +46,11 @@ impl Client { response_handler: impl FnOnce(&Client, R::Result) + Send + 'static, ) -> crate::Result<()> where - R: lsp_types::request::Request, + R: lsp_types::Request, { let response_handler = Box::new(move |client: &Client, response: lsp_server::Response| { let _span = - tracing::debug_span!("client_response", id=%response.id, method = R::METHOD) + tracing::debug_span!("client_response", id=%response.id, method = R::METHOD.as_str()) .entered(); match (response.error, response.result) { @@ -110,7 +110,7 @@ impl Client { /// Sends a notification to the client. pub(crate) fn send_notification(&self, params: N::Params) -> crate::Result<()> where - N: lsp_types::notification::Notification, + N: lsp_types::Notification, { let method = N::METHOD.to_string(); @@ -190,12 +190,10 @@ impl Client { message: impl Display, message_type: lsp_types::MessageType, ) -> crate::Result<()> { - self.send_notification::( - lsp_types::ShowMessageParams { - typ: message_type, - message: message.to_string(), - }, - ) + self.send_notification::(lsp_types::ShowMessageParams { + kind: message_type, + message: message.to_string(), + }) } /// Sends a request to display a warning to the client with a formatted message. The warning is @@ -203,7 +201,7 @@ impl Client { /// /// Logs an error if the message could not be sent. pub(crate) fn show_warning_message(&self, message: impl Display) { - let result = self.show_message(message, lsp_types::MessageType::WARNING); + let result = self.show_message(message, lsp_types::MessageType::Warning); if let Err(err) = result { tracing::error!("Failed to send warning message to the client: {err}"); @@ -215,7 +213,7 @@ impl Client { /// /// Logs an error if the message could not be sent. pub(crate) fn show_error_message(&self, message: impl Display) { - let result = self.show_message(message, lsp_types::MessageType::ERROR); + let result = self.show_message(message, lsp_types::MessageType::Error); if let Err(err) = result { tracing::error!("Failed to send error message to the client: {err}"); diff --git a/crates/ruff_server/src/session/index.rs b/crates/ruff_server/src/session/index.rs index 9084df2e43581..b0055aab60ed3 100644 --- a/crates/ruff_server/src/session/index.rs +++ b/crates/ruff_server/src/session/index.rs @@ -1,10 +1,11 @@ use std::borrow::Cow; +use std::collections::HashMap; use std::ops::{Deref, DerefMut}; use std::path::PathBuf; use std::{collections::BTreeMap, path::Path, sync::Arc}; use anyhow::anyhow; -use lsp_types::{FileEvent, Url}; +use lsp_types::{FileEvent, Uri as Url}; use rustc_hash::{FxHashMap, FxHashSet}; use thiserror::Error; @@ -141,8 +142,8 @@ impl Index { pub(super) fn update_notebook_document( &mut self, key: &DocumentKey, - cells: Option, - metadata: Option>, + cells: Option, + metadata: Option>, new_version: DocumentVersion, encoding: PositionEncoding, ) -> crate::Result<()> { diff --git a/crates/ruff_server/src/session/options.rs b/crates/ruff_server/src/session/options.rs index 97aa0bf60e1af..419dbe063e6a1 100644 --- a/crates/ruff_server/src/session/options.rs +++ b/crates/ruff_server/src/session/options.rs @@ -1,6 +1,6 @@ use std::{path::PathBuf, str::FromStr as _}; -use lsp_types::Url; +use lsp_types::Uri as Url; use rustc_hash::FxHashMap; use serde::Deserialize; use serde_json::{Map, Value}; diff --git a/crates/ruff_server/src/workspace.rs b/crates/ruff_server/src/workspace.rs index 8f3cea1873a0f..f25cf940958a8 100644 --- a/crates/ruff_server/src/workspace.rs +++ b/crates/ruff_server/src/workspace.rs @@ -1,6 +1,6 @@ use std::ops::Deref; -use lsp_types::{Url, WorkspaceFolder}; +use lsp_types::{Uri as Url, WorkspaceFolders}; use thiserror::Error; use crate::session::{ClientOptions, WorkspaceOptionsMap}; @@ -12,7 +12,7 @@ impl Workspaces { /// Create the workspaces from the provided workspace folders as provided by the client during /// initialization. pub(crate) fn from_workspace_folders( - workspace_folders: Option>, + workspace_folders: Option, mut workspace_options: WorkspaceOptionsMap, ) -> std::result::Result { let mut client_options_for_url = |url: &Url| { @@ -25,27 +25,34 @@ impl Workspaces { }) }; - let workspaces = - if let Some(folders) = workspace_folders.filter(|folders| !folders.is_empty()) { - folders - .into_iter() - .map(|folder| { - let options = client_options_for_url(&folder.uri); - Workspace::new(folder.uri).with_options(options) - }) - .collect() + let workspaces = if let Some(folders) = workspace_folders.and_then(|folders| { + if let WorkspaceFolders::WorkspaceFolderList(folders) = folders + && !folders.is_empty() + { + Some(folders) } else { - let current_dir = std::env::current_dir().map_err(WorkspacesError::Io)?; - tracing::info!( - "No workspace(s) were provided during initialization. \ + None + } + }) { + folders + .into_iter() + .map(|folder| { + let options = client_options_for_url(&folder.uri); + Workspace::new(folder.uri).with_options(options) + }) + .collect() + } else { + let current_dir = std::env::current_dir().map_err(WorkspacesError::Io)?; + tracing::info!( + "No workspace(s) were provided during initialization. \ Using the current working directory as a default workspace: {}", - current_dir.display() - ); - let uri = Url::from_file_path(current_dir) - .map_err(|()| WorkspacesError::InvalidCurrentDir)?; - let options = client_options_for_url(&uri); - vec![Workspace::default(uri).with_options(options)] - }; + current_dir.display() + ); + let uri = Url::from_file_path(current_dir) + .map_err(|()| WorkspacesError::InvalidCurrentDir)?; + let options = client_options_for_url(&uri); + vec![Workspace::default(uri).with_options(options)] + }; Ok(Workspaces(workspaces)) } diff --git a/crates/ruff_server/tests/document.rs b/crates/ruff_server/tests/document.rs index 46ab37f917244..5eb53977cd9ff 100644 --- a/crates/ruff_server/tests/document.rs +++ b/crates/ruff_server/tests/document.rs @@ -1,6 +1,8 @@ const PANDAS_HTML_SRC: &str = include_str!("../resources/test/fixtures/pandas_html.py"); -use lsp_types::{Position, Range, TextDocumentContentChangeEvent}; +use lsp_types::{ + Position, Range, TextDocumentContentChangeEvent, TextDocumentContentChangePartial, +}; use ruff_server::{PositionEncoding, TextDocument}; #[test] @@ -8,76 +10,86 @@ fn delete_lines_pandas_html() { let mut document = TextDocument::new(PANDAS_HTML_SRC.to_string(), 1); let changes = vec![ - TextDocumentContentChangeEvent { - range: Some(Range { - start: Position { - line: 79, - character: 0, + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: Range { + start: Position { + line: 79, + character: 0, + }, + end: Position { + line: 91, + character: 67, + }, }, - end: Position { - line: 91, - character: 67, + text: String::new(), + ..Default::default() + }, + ), + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: Range { + start: Position { + line: 81, + character: 4, + }, + end: Position { + line: 81, + character: 36, + }, }, - }), - range_length: Some(388), - text: String::new(), - }, - TextDocumentContentChangeEvent { - range: Some(Range { - start: Position { - line: 81, - character: 4, + text: "p".into(), + ..Default::default() + }, + ), + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: Range { + start: Position { + line: 81, + character: 5, + }, + end: Position { + line: 81, + character: 5, + }, }, - end: Position { - line: 81, - character: 36, + text: "a".into(), + ..Default::default() + }, + ), + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: Range { + start: Position { + line: 81, + character: 6, + }, + end: Position { + line: 81, + character: 6, + }, }, - }), - range_length: Some(32), - text: "p".into(), - }, - TextDocumentContentChangeEvent { - range: Some(Range { - start: Position { - line: 81, - character: 5, + text: "s".into(), + ..Default::default() + }, + ), + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: Range { + start: Position { + line: 81, + character: 7, + }, + end: Position { + line: 81, + character: 7, + }, }, - end: Position { - line: 81, - character: 5, - }, - }), - range_length: Some(0), - text: "a".into(), - }, - TextDocumentContentChangeEvent { - range: Some(Range { - start: Position { - line: 81, - character: 6, - }, - end: Position { - line: 81, - character: 6, - }, - }), - range_length: Some(0), - text: "s".into(), - }, - TextDocumentContentChangeEvent { - range: Some(Range { - start: Position { - line: 81, - character: 7, - }, - end: Position { - line: 81, - character: 7, - }, - }), - range_length: Some(0), - text: "s".into(), - }, + text: "s".into(), + ..Default::default() + }, + ), ]; for (version, change) in (2..).zip(changes) { diff --git a/crates/ruff_server/tests/e2e/custom_extension.rs b/crates/ruff_server/tests/e2e/custom_extension.rs index a67d51a66ef55..3d9ebad71404f 100644 --- a/crates/ruff_server/tests/e2e/custom_extension.rs +++ b/crates/ruff_server/tests/e2e/custom_extension.rs @@ -92,8 +92,8 @@ fn lint_custom_extension_mapped_to_markdown_emits_no_diagnostics() -> Result<()> diagnostics, @r#" { - "kind": "full", - "items": [] + "items": [], + "kind": "full" } "# ); diff --git a/crates/ruff_server/tests/e2e/main.rs b/crates/ruff_server/tests/e2e/main.rs index 65db9e9d450f7..1bec02bf86613 100644 --- a/crates/ruff_server/tests/e2e/main.rs +++ b/crates/ruff_server/tests/e2e/main.rs @@ -43,24 +43,26 @@ use anyhow::{Context, Result, anyhow}; use crossbeam::channel::RecvTimeoutError; use insta::internals::SettingsBindDropGuard; use lsp_server::{Connection, Message, RequestId, Response, ResponseError}; -use lsp_types::notification::{ - DidChangeTextDocument, DidChangeWatchedFiles, DidChangeWorkspaceFolders, DidCloseTextDocument, - DidOpenTextDocument, Exit, Initialized, Notification, -}; -use lsp_types::request::{ - CodeActionRequest, DocumentDiagnosticRequest, HoverRequest, Initialize, Request, Shutdown, -}; use lsp_types::{ ClientCapabilities, CodeActionContext, CodeActionParams, CodeActionResponse, DiagnosticClientCapabilities, DidChangeTextDocumentParams, DidChangeWatchedFilesParams, DidChangeWorkspaceFoldersParams, DidCloseTextDocumentParams, DidOpenTextDocumentParams, - DocumentDiagnosticParams, DocumentDiagnosticReportResult, FileEvent, Hover, HoverParams, - InitializeParams, InitializeResult, InitializedParams, NumberOrString, PartialResultParams, - Position, PublishDiagnosticsClientCapabilities, Range, TextDocumentClientCapabilities, + DocumentDiagnosticParams, DocumentDiagnosticReport, FileEvent, Hover, HoverParams, + InitializeParams, InitializeResult, InitializedParams, PartialResultParams, Position, + PublishDiagnosticsClientCapabilities, Range, TextDocumentClientCapabilities, TextDocumentContentChangeEvent, TextDocumentIdentifier, TextDocumentItem, - TextDocumentPositionParams, TextEdit, Url, VersionedTextDocumentIdentifier, - WorkDoneProgressParams, WorkspaceClientCapabilities, WorkspaceFolder, - WorkspaceFoldersChangeEvent, + TextDocumentPositionParams, TextEdit, Uri as Url, VersionedTextDocumentIdentifier, + WorkDoneProgressParams, WorkspaceClientCapabilities, WorkspaceFolder, WorkspaceFolders, + WorkspaceFoldersChangeEvent, WorkspaceFoldersInitializeParams, +}; +use lsp_types::{ + CodeActionRequest, DocumentDiagnosticRequest, HoverRequest, InitializeRequest, Request, + ShutdownRequest, +}; +use lsp_types::{ + DidChangeTextDocumentNotification, DidChangeWatchedFilesNotification, + DidChangeWorkspaceFoldersNotification, DidCloseTextDocumentNotification, + DidOpenTextDocumentNotification, ExitNotification, InitializedNotification, Notification, }; use ruff_server::{ConnectionInitializer, LogLevel, Server, init_logging}; use rustc_hash::FxHashMap; @@ -245,14 +247,16 @@ impl TestServer { ) -> Self { let init_params = InitializeParams { capabilities, - workspace_folders: Some(workspace_folders), + workspace_folders_initialize_params: WorkspaceFoldersInitializeParams { + workspace_folders: Some(WorkspaceFolders::WorkspaceFolderList(workspace_folders)), + }, initialization_options, ..Default::default() }; - let init_request_id = self.send_request::(init_params); - self.initialize_response = Some(self.await_response::(&init_request_id)); - self.send_notification::(InitializedParams {}); + let init_request_id = self.send_request::(init_params); + self.initialize_response = Some(self.await_response::(&init_request_id)); + self.send_notification::(InitializedParams {}); self } @@ -331,7 +335,7 @@ impl TestServer { R: Request, { // Track if an Exit notification is being sent - if R::METHOD == lsp_types::request::Shutdown::METHOD { + if R::METHOD == lsp_types::ShutdownRequest::METHOD { self.shutdown_requested = true; } @@ -483,7 +487,7 @@ impl TestServer { let notification = self .notifications .iter() - .position(|notification| N::METHOD == notification.method) + .position(|notification| N::METHOD.as_str() == notification.method) .and_then(|index| self.notifications.remove(index)); if let Some(notification) = notification { let params = serde_json::from_value(notification.params)?; @@ -504,12 +508,12 @@ impl TestServer { pub(crate) fn collect_publish_diagnostic_notifications( &mut self, count: usize, - ) -> BTreeMap> { + ) -> BTreeMap> { let mut results = BTreeMap::default(); for _ in 0..count { let notification = - self.await_notification::(); + self.await_notification::(); if let Some(existing) = results.insert(notification.uri.clone(), notification.diagnostics) @@ -571,7 +575,7 @@ impl TestServer { let request = self .requests .iter() - .position(|request| R::METHOD == request.method) + .position(|request| R::METHOD.as_str() == request.method) .and_then(|index| self.requests.remove(index)); if let Some(request) = request { let params = serde_json::from_value(request.params)?; @@ -653,10 +657,10 @@ impl TestServer { #[expect(dead_code)] pub(crate) fn cancel(&mut self, request_id: &RequestId) { let id_string = request_id.to_string(); - self.send_notification::(lsp_types::CancelParams { + self.send_notification::(lsp_types::CancelParams { id: match id_string.parse() { - Ok(id) => NumberOrString::Number(id), - Err(_) => NumberOrString::String(id_string), + Ok(id) => lsp_types::Id::Int(id), + Err(_) => lsp_types::Id::String(id_string), }, }); } @@ -711,12 +715,12 @@ impl TestServer { let params = DidOpenTextDocumentParams { text_document: TextDocumentItem { uri: self.file_uri(path), - language_id: language_id.to_string(), + language_id: language_id.to_string().into(), version, text: content.as_ref().to_string(), }, }; - self.send_notification::(params); + self.send_notification::(params); } /// Send a `textDocument/didChange` notification with the given content changes @@ -729,12 +733,14 @@ impl TestServer { ) { let params = DidChangeTextDocumentParams { text_document: VersionedTextDocumentIdentifier { - uri: self.file_uri(path), + text_document_identifier: TextDocumentIdentifier { + uri: self.file_uri(path), + }, version, }, content_changes: changes, }; - self.send_notification::(params); + self.send_notification::(params); } /// Send a `textDocument/didClose` notification @@ -745,14 +751,14 @@ impl TestServer { uri: self.file_uri(path), }, }; - self.send_notification::(params); + self.send_notification::(params); } /// Send a `workspace/didChangeWatchedFiles` notification with the given file events #[expect(dead_code)] pub(crate) fn did_change_watched_files(&mut self, events: Vec) { let params = DidChangeWatchedFilesParams { changes: events }; - self.send_notification::(params); + self.send_notification::(params); } /// Send a `workspace/didChangeWorkspaceFolders` notification with the given added/removed @@ -786,7 +792,7 @@ impl TestServer { .collect(), }, }; - self.send_notification::(params); + self.send_notification::(params); } /// Send a `textDocument/diagnostic` request for the document at the given path. @@ -794,7 +800,7 @@ impl TestServer { &mut self, path: impl AsRef, previous_result_id: Option, - ) -> DocumentDiagnosticReportResult { + ) -> DocumentDiagnosticReport { let params = DocumentDiagnosticParams { text_document: TextDocumentIdentifier { uri: self.file_uri(path), @@ -829,7 +835,7 @@ impl TestServer { /// Send a `textDocument/formatting` request for the document at the given path. pub(crate) fn format_request(&mut self, path: impl AsRef) -> Option> { - let id = self.send_request::( + let id = self.send_request::( lsp_types::DocumentFormattingParams { text_document: TextDocumentIdentifier { uri: self.file_uri(path), @@ -839,7 +845,7 @@ impl TestServer { }, ); - self.await_response::(&id) + self.await_response::(&id) } /// Send a `textDocument/rangeFormatting` request for the document at the given path. @@ -848,7 +854,7 @@ impl TestServer { path: impl AsRef, range: Range, ) -> Option> { - let id = self.send_request::( + let id = self.send_request::( lsp_types::DocumentRangeFormattingParams { text_document: TextDocumentIdentifier { uri: self.file_uri(path), @@ -858,7 +864,7 @@ impl TestServer { work_done_progress_params: WorkDoneProgressParams::default(), }, ); - self.await_response::(&id) + self.await_response::(&id) } /// Send a `textDocument/codeAction` request for the document at the given path. @@ -866,7 +872,7 @@ impl TestServer { &mut self, path: impl AsRef, diagnostics: Vec, - ) -> Option { + ) -> Option> { let params = CodeActionParams { text_document: TextDocumentIdentifier { uri: self.file_uri(path), @@ -913,10 +919,10 @@ impl Drop for TestServer { // The `server_thread` could be `None` if the server exited unexpectedly or panicked or if // it dropped the client connection. let shutdown_error = if self.server_thread.is_some() && !self.shutdown_requested { - let shutdown_id = self.send_request::(()); - match self.try_await_response::(&shutdown_id, None) { + let shutdown_id = self.send_request::(()); + match self.try_await_response::(&shutdown_id, None) { Ok(()) => { - self.send_notification::(()); + self.send_notification::(()); None } @@ -1086,6 +1092,7 @@ impl TestServerBuilder { .get_or_insert_default() .publish_diagnostics .get_or_insert_default() + .diagnostics_capabilities .related_information = Some(enabled); self } diff --git a/crates/ruff_server/tests/e2e/notebook.rs b/crates/ruff_server/tests/e2e/notebook.rs index 5948127426871..c3120a62790b1 100644 --- a/crates/ruff_server/tests/e2e/notebook.rs +++ b/crates/ruff_server/tests/e2e/notebook.rs @@ -2,12 +2,15 @@ use std::path::{Path, PathBuf}; use anyhow::Result; use insta::assert_json_snapshot; -use lsp_types::notification::{DidChangeNotebookDocument, DidOpenNotebookDocument}; use lsp_types::{ - DidChangeNotebookDocumentParams, DidOpenNotebookDocumentParams, LSPObject, NotebookDocument, - NotebookDocumentCellChange, NotebookDocumentChangeEvent, NotebookDocumentChangeTextContent, - Position, Range, TextDocumentContentChangeEvent, TextDocumentItem, - VersionedNotebookDocumentIdentifier, VersionedTextDocumentIdentifier, + DidChangeNotebookDocumentNotification, DidOpenNotebookDocumentNotification, + NotebookDocumentCellContentChanges, TextDocumentContentChangePartial, TextDocumentIdentifier, +}; +use lsp_types::{ + DidChangeNotebookDocumentParams, DidOpenNotebookDocumentParams, LspObject, NotebookDocument, + NotebookDocumentCellChanges, NotebookDocumentChangeEvent, Position, Range, + TextDocumentContentChangeEvent, TextDocumentItem, VersionedNotebookDocumentIdentifier, + VersionedTextDocumentIdentifier, }; use ruff_notebook::SourceValue; @@ -17,8 +20,8 @@ const NOTEBOOK_FIXTURE_PATH: &str = "resources/test/fixtures/tensorflow_test_not struct NotebookChange { version: i32, - metadata: Option, - updated_cells: NotebookDocumentCellChange, + metadata: Option, + updated_cells: NotebookDocumentCellChanges, } #[test] @@ -37,114 +40,130 @@ fn super_resolution_overview() -> Result<()> { let notebook_uri = notebook_document.uri.clone(); let cell_count = cell_text_documents.len(); - server.send_notification::(DidOpenNotebookDocumentParams { - notebook_document, - cell_text_documents, - }); + server.send_notification::( + DidOpenNotebookDocumentParams { + notebook_document, + cell_text_documents, + }, + ); let diagnostics = server.collect_publish_diagnostic_notifications(cell_count); assert_json_snapshot!("super_resolution_overview_open", diagnostics); - let changes = [NotebookChange { - version: 0, - metadata: None, - updated_cells: NotebookDocumentCellChange { - structure: None, - data: None, - text_content: Some(vec![NotebookDocumentChangeTextContent { - document: VersionedTextDocumentIdentifier { - uri: make_cell_uri(&fixture_path, 5), - version: 2, - }, - changes: vec![ - TextDocumentContentChangeEvent { - range: Some(Range { - start: Position { - line: 18, - character: 61, - }, - end: Position { - line: 18, - character: 62, - }, - }), - range_length: Some(1), - text: "\"".to_string(), + let changes = [ + NotebookChange { + version: 0, + metadata: None, + updated_cells: NotebookDocumentCellChanges { + structure: None, + data: None, + text_content: Some(vec![NotebookDocumentCellContentChanges { + document: VersionedTextDocumentIdentifier { + text_document_identifier: TextDocumentIdentifier { + uri: make_cell_uri(&fixture_path, 5), + }, + version: 2, }, - TextDocumentContentChangeEvent { - range: Some(Range { - start: Position { - line: 18, - character: 55, + changes: vec![ + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: Range { + start: Position { + line: 18, + character: 61, + }, + end: Position { + line: 18, + character: 62, + }, + }, + text: "\"".to_string(), + ..Default::default() }, - end: Position { - line: 18, - character: 56, + ), + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: Range { + start: Position { + line: 18, + character: 55, + }, + end: Position { + line: 18, + character: 56, + }, + }, + text: "\"".to_string(), + ..Default::default() }, - }), - range_length: Some(1), - text: "\"".to_string(), - }, - TextDocumentContentChangeEvent { - range: Some(Range { - start: Position { - line: 14, - character: 46, + ), + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: Range { + start: Position { + line: 14, + character: 46, + }, + end: Position { + line: 14, + character: 47, + }, + }, + text: "\"".to_string(), + ..Default::default() }, - end: Position { - line: 14, - character: 47, + ), + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: Range { + start: Position { + line: 14, + character: 40, + }, + end: Position { + line: 14, + character: 41, + }, + }, + text: "\"".to_string(), + ..Default::default() }, - }), - range_length: Some(1), - text: "\"".to_string(), + ), + ], + }]), + }, + }, + NotebookChange { + version: 1, + metadata: None, + updated_cells: NotebookDocumentCellChanges { + structure: None, + data: None, + text_content: Some(vec![NotebookDocumentCellContentChanges { + document: VersionedTextDocumentIdentifier { + text_document_identifier: TextDocumentIdentifier { + uri: make_cell_uri(&fixture_path, 4), + }, + version: 2, }, - TextDocumentContentChangeEvent { - range: Some(Range { + changes: vec![TextDocumentContentChangeEvent::TextDocumentContentChangePartial(TextDocumentContentChangePartial { + range: Range { start: Position { - line: 14, - character: 40, + line: 0, + character: 0, }, end: Position { - line: 14, - character: 41, + line: 0, + character: 181, }, - }), - range_length: Some(1), - text: "\"".to_string(), - }, - ], - }]), - }, - }, - NotebookChange { - version: 1, - metadata: None, - updated_cells: NotebookDocumentCellChange { - structure: None, - data: None, - text_content: Some(vec![NotebookDocumentChangeTextContent { - document: VersionedTextDocumentIdentifier { - uri: make_cell_uri(&fixture_path, 4), - version: 2, - }, - changes: vec![TextDocumentContentChangeEvent { - range: Some(Range { - start: Position { - line: 0, - character: 0, }, - end: Position { - line: 0, - character: 181, - }, - }), - range_length: Some(181), - text: "test_img_path = tf.keras.utils.get_file(\n \"lr.jpg\",\n \"https://raw.githubusercontent.com/tensorflow/examples/master/lite/examples/super_resolution/android/app/src/main/assets/lr-1.jpg\",\n)".to_string(), - }], - }]), + text: "test_img_path = tf.keras.utils.get_file(\n \"lr.jpg\",\n \"https://raw.githubusercontent.com/tensorflow/examples/master/lite/examples/super_resolution/android/app/src/main/assets/lr-1.jpg\",\n)".to_string(), + ..Default::default() + })], + }]), + }, }, - }]; + ]; let mut final_diagnostics = None; @@ -154,16 +173,18 @@ fn super_resolution_overview() -> Result<()> { updated_cells, } in changes { - server.send_notification::(DidChangeNotebookDocumentParams { - notebook_document: VersionedNotebookDocumentIdentifier { - uri: notebook_uri.clone(), - version, - }, - change: NotebookDocumentChangeEvent { - metadata, - cells: Some(updated_cells), + server.send_notification::( + DidChangeNotebookDocumentParams { + notebook_document: VersionedNotebookDocumentIdentifier { + uri: notebook_uri.clone(), + version, + }, + change: NotebookDocumentChangeEvent { + metadata, + cells: Some(updated_cells), + }, }, - }); + ); final_diagnostics = Some(server.collect_publish_diagnostic_notifications(cell_count)); } @@ -191,10 +212,12 @@ fn notebook_without_ipynb_extension() -> Result<()> { create_lsp_notebook(&fixture_path, workspace_dir.join("notebook.py"))?; let cell_count = cell_text_documents.len(); - server.send_notification::(DidOpenNotebookDocumentParams { - notebook_document, - cell_text_documents, - }); + server.send_notification::( + DidOpenNotebookDocumentParams { + notebook_document, + cell_text_documents, + }, + ); let diagnostics = server.collect_publish_diagnostic_notifications(cell_count); assert_json_snapshot!("notebook_without_ipynb_extension_open", diagnostics); @@ -213,7 +236,7 @@ fn create_lsp_notebook( open_uri_path: PathBuf, ) -> Result<(NotebookDocument, Vec)> { let notebook = ruff_notebook::Notebook::from_path(file_path)?; - let notebook_uri = lsp_types::Url::from_file_path(open_uri_path).unwrap(); + let notebook_uri = lsp_types::Uri::from_file_path(open_uri_path).unwrap(); let mut cells = Vec::new(); let mut cell_text_documents = Vec::new(); @@ -242,8 +265,8 @@ fn create_lsp_notebook( )) } -fn make_cell_uri(path: &Path, index: usize) -> lsp_types::Url { - lsp_types::Url::parse(&format!( +fn make_cell_uri(path: &Path, index: usize) -> lsp_types::Uri { + lsp_types::Uri::parse(&format!( "notebook-cell:///Users/test/notebooks/{}.ipynb?cell={index}", path.file_name().unwrap().to_string_lossy() )) @@ -252,7 +275,7 @@ fn make_cell_uri(path: &Path, index: usize) -> lsp_types::Url { fn cell_to_lsp_cell( cell: &ruff_notebook::Cell, - cell_uri: lsp_types::Url, + cell_uri: lsp_types::Uri, ) -> Result<(lsp_types::NotebookCell, TextDocumentItem)> { let contents = match cell.source() { SourceValue::String(string) => string.clone(), @@ -260,7 +283,7 @@ fn cell_to_lsp_cell( }; let metadata = match serde_json::to_value(cell.metadata())? { serde_json::Value::Null => None, - serde_json::Value::Object(metadata) => Some(metadata), + metadata @ serde_json::Value::Object(_) => Some(serde_json::from_value(metadata)?), _ => anyhow::bail!("Notebook cell metadata was not an object"), }; Ok(( @@ -274,6 +297,6 @@ fn cell_to_lsp_cell( metadata, execution_summary: None, }, - TextDocumentItem::new(cell_uri, "python".to_string(), 0, contents), + TextDocumentItem::new(cell_uri, lsp_types::LanguageKind::Python, 0, contents), )) } diff --git a/crates/ruff_server/tests/e2e/workspace.rs b/crates/ruff_server/tests/e2e/workspace.rs index dad0965aa2001..c151819ad129d 100644 --- a/crates/ruff_server/tests/e2e/workspace.rs +++ b/crates/ruff_server/tests/e2e/workspace.rs @@ -30,8 +30,8 @@ ignore = ["F401"] diagnostics, @r#" { - "kind": "full", - "items": [] + "items": [], + "kind": "full" } "# ); @@ -40,7 +40,6 @@ ignore = ["F401"] external_diagnostics, @r#" { - "kind": "full", "items": [ { "range": { @@ -96,7 +95,8 @@ ignore = ["F401"] "title": "Remove unused import: `os`" } } - ] + ], + "kind": "full" } "# ); diff --git a/crates/ty_server/src/capabilities.rs b/crates/ty_server/src/capabilities.rs index 46f0a5f3761ee..2d98a6b78b5f2 100644 --- a/crates/ty_server/src/capabilities.rs +++ b/crates/ty_server/src/capabilities.rs @@ -1,12 +1,9 @@ use lsp_types::{ self as types, ClientCapabilities, CodeActionKind, CodeActionOptions, CompletionOptions, - DeclarationCapability, DiagnosticOptions, DiagnosticServerCapabilities, - HoverProviderCapability, InlayHintOptions, InlayHintServerCapabilities, MarkupKind, - NotebookCellSelector, NotebookSelector, OneOf, RenameOptions, SelectionRangeProviderCapability, - SemanticTokensFullOptions, SemanticTokensLegend, SemanticTokensOptions, - SemanticTokensServerCapabilities, ServerCapabilities, SignatureHelpOptions, - TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions, - TypeDefinitionProviderCapability, WorkDoneProgressOptions, + DiagnosticOptions, DiagnosticProvider, InlayHintOptions, MarkupKind, NotebookCellLanguage, + NotebookDocumentFilterWithCells, NotebookSelector, RenameOptions, SemanticTokensLegend, + SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncKind, + TextDocumentSyncOptions, WorkDoneProgressOptions, }; use std::str::FromStr; @@ -230,7 +227,11 @@ impl ResolvedClientCapabilities { if let Some(publish_diagnostics) = text_document.and_then(|text_document| text_document.publish_diagnostics.as_ref()) { - if publish_diagnostics.related_information == Some(true) { + if publish_diagnostics + .diagnostics_capabilities + .related_information + == Some(true) + { flags |= Self::DIAGNOSTIC_RELATED_INFORMATION; } } @@ -379,19 +380,20 @@ pub(crate) fn server_capabilities( None } else { // Otherwise, we always advertise support for workspace and pull diagnostics. - Some(DiagnosticServerCapabilities::Options( + Some(DiagnosticProvider::DiagnosticOptions( server_diagnostic_options(true), )) }; ServerCapabilities { position_encoding: Some(position_encoding.into()), - code_action_provider: Some(types::CodeActionProviderCapability::Options( + code_action_provider: Some( CodeActionOptions { - code_action_kinds: Some(vec![CodeActionKind::QUICKFIX]), + code_action_kinds: Some(vec![CodeActionKind::QuickFix]), ..CodeActionOptions::default() - }, - )), + } + .into(), + ), execute_command_provider: Some(types::ExecuteCommandOptions { commands: SupportedCommand::all() @@ -403,29 +405,28 @@ pub(crate) fn server_capabilities( }), diagnostic_provider, - text_document_sync: Some(TextDocumentSyncCapability::Options( + text_document_sync: Some( TextDocumentSyncOptions { open_close: Some(true), - change: Some(TextDocumentSyncKind::INCREMENTAL), + change: Some(TextDocumentSyncKind::Incremental), ..Default::default() - }, - )), - type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)), - definition_provider: Some(OneOf::Left(true)), - declaration_provider: Some(DeclarationCapability::Simple(true)), - references_provider: Some(OneOf::Left(true)), - rename_provider: Some(OneOf::Right(server_rename_options())), - document_highlight_provider: Some(OneOf::Left(true)), - hover_provider: Some(HoverProviderCapability::Simple(true)), + } + .into(), + ), + type_definition_provider: Some(true.into()), + definition_provider: Some(true.into()), + declaration_provider: Some(true.into()), + references_provider: Some(true.into()), + rename_provider: Some(server_rename_options().into()), + document_highlight_provider: Some(true.into()), + hover_provider: Some(true.into()), signature_help_provider: Some(SignatureHelpOptions { trigger_characters: Some(vec!["(".to_string(), ",".to_string()]), retrigger_characters: Some(vec![")".to_string()]), work_done_progress_options: WorkDoneProgressOptions::default(), }), - inlay_hint_provider: Some(OneOf::Right(InlayHintServerCapabilities::Options( - InlayHintOptions::default(), - ))), - semantic_tokens_provider: Some(SemanticTokensServerCapabilities::SemanticTokensOptions( + inlay_hint_provider: Some(InlayHintOptions::default().into()), + semantic_tokens_provider: Some( SemanticTokensOptions { work_done_progress_options: WorkDoneProgressOptions::default(), legend: SemanticTokensLegend { @@ -438,38 +439,44 @@ pub(crate) fn server_capabilities( .map(|&s| s.into()) .collect(), }, - range: Some(true), - full: Some(SemanticTokensFullOptions::Bool(true)), - }, - )), + range: Some(true.into()), + full: Some(true.into()), + } + .into(), + ), completion_provider: Some(CompletionOptions { trigger_characters: Some(vec!['.'.to_string()]), ..Default::default() }), - selection_range_provider: Some(SelectionRangeProviderCapability::Simple(true)), - folding_range_provider: Some(types::FoldingRangeProviderCapability::Simple(true)), - document_symbol_provider: Some(OneOf::Left(true)), - workspace_symbol_provider: Some(OneOf::Left(true)), - notebook_document_sync: Some(OneOf::Left(lsp_types::NotebookDocumentSyncOptions { - save: Some(false), - notebook_selector: [NotebookSelector::ByCells { - notebook: None, - cells: vec![NotebookCellSelector { - language: "python".to_string(), - }], - }] - .to_vec(), - })), - workspace: Some(lsp_types::WorkspaceServerCapabilities { + selection_range_provider: Some(true.into()), + folding_range_provider: Some(true.into()), + document_symbol_provider: Some(true.into()), + workspace_symbol_provider: Some(true.into()), + notebook_document_sync: Some( + lsp_types::NotebookDocumentSyncOptions { + save: Some(false), + notebook_selector: [NotebookSelector::NotebookDocumentFilterWithCells( + NotebookDocumentFilterWithCells { + notebook: None, + cells: vec![NotebookCellLanguage { + language: "python".to_string(), + }], + }, + )] + .to_vec(), + } + .into(), + ), + workspace: Some(lsp_types::WorkspaceOptions { workspace_folders: Some(lsp_types::WorkspaceFoldersServerCapabilities { // N.B. It seems this is purely informational: // https://github.com/microsoft/language-server-protocol/issues/1720#issuecomment-1514732305 supported: Some(true), - change_notifications: Some(OneOf::Left(true)), + change_notifications: Some(true.into()), }), ..Default::default() }), - type_hierarchy_provider: Some(OneOf::Left(true)), + type_hierarchy_provider: Some(true.into()), ..Default::default() } } diff --git a/crates/ty_server/src/document.rs b/crates/ty_server/src/document.rs index ce66018a96312..c135eed8bbdee 100644 --- a/crates/ty_server/src/document.rs +++ b/crates/ty_server/src/document.rs @@ -5,7 +5,7 @@ mod notebook; mod range; mod text_document; -use lsp_types::{PositionEncodingKind, Url}; +use lsp_types::{PositionEncodingKind, Uri as Url}; use ruff_db::system::{SystemPathBuf, SystemVirtualPath, SystemVirtualPathBuf}; use crate::system::AnySystemPath; diff --git a/crates/ty_server/src/document/notebook.rs b/crates/ty_server/src/document/notebook.rs index f3f485c942655..ed9d663a74146 100644 --- a/crates/ty_server/src/document/notebook.rs +++ b/crates/ty_server/src/document/notebook.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use lsp_types::NotebookCellKind; use ruff_notebook::CellMetadata; use ruff_source_file::OneIndexed; @@ -13,12 +15,12 @@ use crate::session::index::Index; /// [`super::TextDocument`]s (they can be looked up by the Cell's URL). #[derive(Clone, Debug)] pub struct NotebookDocument { - url: lsp_types::Url, + url: lsp_types::Uri, cells: Vec, metadata: ruff_notebook::RawNotebookMetadata, version: DocumentVersion, /// Map from Cell URL to their index in `cells` - cell_index: FxHashMap, + cell_index: FxHashMap, } /// The metadata of a single cell within a notebook. @@ -34,17 +36,17 @@ struct NotebookCell { /// > cells and can therefore be used to uniquely identify a notebook cell /// > or the cell’s text document. /// > - url: lsp_types::Url, + url: lsp_types::Uri, kind: NotebookCellKind, execution_summary: Option, } impl NotebookDocument { pub fn new( - url: lsp_types::Url, + url: lsp_types::Uri, notebook_version: DocumentVersion, cells: Vec, - metadata: serde_json::Map, + metadata: HashMap, ) -> crate::Result { let cells: Vec<_> = cells.into_iter().map(NotebookCell::new).collect(); let index = cells @@ -58,11 +60,11 @@ impl NotebookDocument { url, version: notebook_version, cells, - metadata: serde_json::from_value(serde_json::Value::Object(metadata))?, + metadata: serde_json::from_value(serde_json::to_value(metadata)?)?, }) } - pub(crate) fn url(&self) -> &lsp_types::Url { + pub(crate) fn url(&self) -> &lsp_types::Uri { &self.url } @@ -125,7 +127,7 @@ impl NotebookDocument { &mut self, array: lsp_types::NotebookCellArrayChange, updated_cells: Vec, - metadata_change: Option>, + metadata_change: Option>, version: DocumentVersion, ) -> crate::Result<()> { self.version = version; @@ -159,7 +161,7 @@ impl NotebookDocument { } if let Some(metadata_change) = metadata_change { - self.metadata = serde_json::from_value(serde_json::Value::Object(metadata_change))?; + self.metadata = serde_json::from_value(serde_json::to_value(metadata_change)?)?; } Ok(()) @@ -171,18 +173,18 @@ impl NotebookDocument { } /// Get the URI for a cell by its index within the cell array. - pub(crate) fn cell_uri_by_index(&self, index: OneIndexed) -> Option<&lsp_types::Url> { + pub(crate) fn cell_uri_by_index(&self, index: OneIndexed) -> Option<&lsp_types::Uri> { self.cells .get(index.to_zero_indexed()) .map(|cell| &cell.url) } /// Returns a list of cell URIs in the order they appear in the array. - pub(crate) fn cell_urls(&self) -> impl Iterator { + pub(crate) fn cell_urls(&self) -> impl Iterator { self.cells.iter().map(|cell| &cell.url) } - pub(crate) fn cell_index_by_uri(&self, cell_url: &lsp_types::Url) -> Option { + pub(crate) fn cell_index_by_uri(&self, cell_url: &lsp_types::Uri) -> Option { Some(OneIndexed::from_zero_indexed( self.cell_index.get(cell_url).copied()?, )) diff --git a/crates/ty_server/src/document/range.rs b/crates/ty_server/src/document/range.rs index 190428bbc1173..ad565e6cec3a4 100644 --- a/crates/ty_server/src/document/range.rs +++ b/crates/ty_server/src/document/range.rs @@ -14,7 +14,7 @@ pub(crate) struct LspRange { range: lsp_types::Range, /// The URI of this range's text document - uri: Option, + uri: Option, } impl LspRange { @@ -55,7 +55,7 @@ pub(crate) struct LspPosition { position: lsp_types::Position, /// The URI of this range's text document - uri: Option, + uri: Option, } impl LspPosition { @@ -72,7 +72,7 @@ impl LspPosition { /// Returns the uri of the text document this position belongs to. #[expect(unused)] - pub(crate) fn uri(&self) -> Option<&lsp_types::Url> { + pub(crate) fn uri(&self) -> Option<&lsp_types::Uri> { self.uri.as_ref() } } @@ -87,7 +87,7 @@ pub(crate) trait RangeExt { &self, db: &dyn Db, file: File, - url: &lsp_types::Url, + url: &lsp_types::Uri, encoding: PositionEncoding, ) -> Option; } @@ -97,7 +97,7 @@ impl RangeExt for lsp_types::Range { &self, db: &dyn Db, file: File, - url: &lsp_types::Url, + url: &lsp_types::Uri, encoding: PositionEncoding, ) -> Option { let start = self.start.to_text_size(db, file, url, encoding)?; @@ -121,7 +121,7 @@ pub(crate) trait PositionExt { &self, db: &dyn Db, file: File, - url: &lsp_types::Url, + url: &lsp_types::Uri, encoding: PositionEncoding, ) -> Option; } @@ -131,7 +131,7 @@ impl PositionExt for lsp_types::Position { &self, db: &dyn Db, file: File, - url: &lsp_types::Url, + url: &lsp_types::Uri, encoding: PositionEncoding, ) -> Option { let source = source_text(db, file); diff --git a/crates/ty_server/src/document/text_document.rs b/crates/ty_server/src/document/text_document.rs index 90a07185a30fc..5ac85bb250270 100644 --- a/crates/ty_server/src/document/text_document.rs +++ b/crates/ty_server/src/document/text_document.rs @@ -1,4 +1,7 @@ -use lsp_types::{TextDocumentContentChangeEvent, Url}; +use lsp_types::{ + LanguageKind, TextDocumentContentChangeEvent, TextDocumentContentChangePartial, + TextDocumentContentChangeWholeDocument, Uri as Url, +}; use ruff_source_file::LineIndex; use crate::PositionEncoding; @@ -36,17 +39,22 @@ pub enum LanguageId { Other, } -impl From<&str> for LanguageId { - fn from(language_id: &str) -> Self { +impl From for LanguageId { + fn from(language_id: LanguageKind) -> Self { match language_id { - "python" => Self::Python, + LanguageKind::Python => Self::Python, _ => Self::Other, } } } impl TextDocument { - pub fn new(url: Url, contents: String, version: DocumentVersion, language_id: &str) -> Self { + pub fn new( + url: Url, + contents: String, + version: DocumentVersion, + language_id: LanguageKind, + ) -> Self { Self { url, contents, @@ -93,9 +101,9 @@ impl TextDocument { encoding: PositionEncoding, ) { if let [ - lsp_types::TextDocumentContentChangeEvent { - range: None, text, .. - }, + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { text }, + ), ] = changes.as_slice() { tracing::debug!("Fast path - replacing entire document"); @@ -109,21 +117,22 @@ impl TextDocument { let mut new_contents = self.contents().to_string(); let mut active_index = LineIndex::from_source_text(&new_contents); - for TextDocumentContentChangeEvent { - range, - text: change, - .. - } in changes - { - if let Some(range) = range { - let range = lsp_range_to_text_range(range, &new_contents, &active_index, encoding); - - new_contents.replace_range( - usize::from(range.start())..usize::from(range.end()), - &change, - ); - } else { - new_contents = change; + for change in changes { + match change { + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { range, text, .. }, + ) => { + let range = + lsp_range_to_text_range(range, &new_contents, &active_index, encoding); + + new_contents + .replace_range(usize::from(range.start())..usize::from(range.end()), &text); + } + TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { text }, + ) => { + new_contents = text; + } } active_index = LineIndex::from_source_text(&new_contents); @@ -152,7 +161,10 @@ impl TextDocument { #[cfg(test)] mod tests { use crate::{PositionEncoding, TextDocument}; - use lsp_types::{Position, TextDocumentContentChangeEvent, Url}; + use lsp_types::{ + LanguageKind, Position, TextDocumentContentChangeEvent, TextDocumentContentChangePartial, + Uri as Url, + }; #[test] fn redo_edit() { @@ -171,36 +183,33 @@ def interface(): "# .to_string(), 0, - "python", + LanguageKind::Python, ); // Add an `s`, remove it again (back to the original code), and then re-add the `s` document.apply_changes( vec![ - TextDocumentContentChangeEvent { - range: Some(lsp_types::Range::new( - Position::new(9, 7), - Position::new(9, 7), - )), - range_length: Some(0), - text: "s".to_string(), - }, - TextDocumentContentChangeEvent { - range: Some(lsp_types::Range::new( - Position::new(9, 7), - Position::new(9, 8), - )), - range_length: Some(1), - text: String::new(), - }, - TextDocumentContentChangeEvent { - range: Some(lsp_types::Range::new( - Position::new(9, 7), - Position::new(9, 7), - )), - range_length: Some(0), - text: "s".to_string(), - }, + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: lsp_types::Range::new(Position::new(9, 7), Position::new(9, 7)), + text: "s".to_string(), + ..Default::default() + }, + ), + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: lsp_types::Range::new(Position::new(9, 7), Position::new(9, 8)), + text: String::new(), + ..Default::default() + }, + ), + TextDocumentContentChangeEvent::TextDocumentContentChangePartial( + TextDocumentContentChangePartial { + range: lsp_types::Range::new(Position::new(9, 7), Position::new(9, 7)), + text: "s".to_string(), + ..Default::default() + }, + ), ], 1, PositionEncoding::UTF16, diff --git a/crates/ty_server/src/lib.rs b/crates/ty_server/src/lib.rs index fe7ba186c6fbe..96e4ef5f7f8c1 100644 --- a/crates/ty_server/src/lib.rs +++ b/crates/ty_server/src/lib.rs @@ -6,7 +6,7 @@ use ruff_db::system::{OsSystem, SystemPathBuf}; use crate::db::Db; pub use crate::logging::{LogLevel, init_logging}; -pub use crate::server::{PartialWorkspaceProgress, PartialWorkspaceProgressParams, Server}; +pub use crate::server::Server; pub use crate::session::{ClientOptions, DiagnosticMode, GlobalOptions, WorkspaceOptions}; pub use document::{NotebookDocument, PositionEncoding, TextDocument}; pub(crate) use session::Session; diff --git a/crates/ty_server/src/server.rs b/crates/ty_server/src/server.rs index 0d952c99d188c..1f34ec0cffbef 100644 --- a/crates/ty_server/src/server.rs +++ b/crates/ty_server/src/server.rs @@ -6,7 +6,10 @@ use crate::capabilities::{ResolvedClientCapabilities, server_capabilities}; use crate::session::{ClientName, InitializationOptions, Session, warn_about_unknown_options}; use anyhow::Context; use lsp_server::Connection; -use lsp_types::{ClientCapabilities, InitializeParams, MessageType, Url}; +use lsp_types::{ + ClientCapabilities, InitializeParams, MessageType, Uri as Url, WorkspaceFolders, + WorkspaceFoldersInitializeParams, +}; use ruff_db::system::System; use std::num::NonZeroUsize; use std::panic::{PanicHookInfo, RefUnwindSafe}; @@ -24,7 +27,6 @@ pub(crate) use main_loop::{ Action, ConnectionSender, Event, MainLoopReceiver, MainLoopSender, SendRequest, }; pub(crate) type Result = std::result::Result; -pub use api::{PartialWorkspaceProgress, PartialWorkspaceProgressParams}; pub struct Server { connection: Connection, @@ -46,7 +48,8 @@ impl Server { let InitializeParams { initialization_options, capabilities: client_capabilities, - workspace_folders, + workspace_folders_initialize_params: + WorkspaceFoldersInitializeParams { workspace_folders }, client_info, .. } = serde_json::from_value(init_value) @@ -103,7 +106,15 @@ impl Server { // Get workspace URLs without settings - settings will come from workspace/configuration let workspace_urls = workspace_folders - .filter(|folders| !folders.is_empty()) + .and_then(|folders| { + if let WorkspaceFolders::WorkspaceFolderList(folders) = folders + && !folders.is_empty() + { + Some(folders) + } else { + None + } + }) .map(|folders| { folders .into_iter() @@ -207,7 +218,7 @@ impl ServerPanicHookHandler { if let Some(client) = hook_client.upgrade() { client.show_message( "The ty language server exited with a panic. See the logs for more details.", - MessageType::ERROR, + MessageType::Error, ); } })); diff --git a/crates/ty_server/src/server/api.rs b/crates/ty_server/src/server/api.rs index 74637f3775a0c..0d515d8f6f72d 100644 --- a/crates/ty_server/src/server/api.rs +++ b/crates/ty_server/src/server/api.rs @@ -3,8 +3,8 @@ use crate::session::Session; use anyhow::anyhow; use lsp_server as server; use lsp_server::{ErrorCode, RequestId}; -use lsp_types::notification::Notification; -use lsp_types::request::Request; +use lsp_types::{LspNotificationMethod, Notification}; +use lsp_types::{LspRequestMethod, Request}; use std::panic::{AssertUnwindSafe, UnwindSafe}; mod diagnostics; @@ -19,7 +19,6 @@ use self::traits::{NotificationHandler, RequestHandler}; use super::{Result, schedule::BackgroundSchedule}; use crate::session::client::Client; pub(crate) use diagnostics::publish_settings_diagnostics; -pub use requests::{PartialWorkspaceProgress, PartialWorkspaceProgressParams}; use ruff_db::panic::PanicError; /// Processes a request from the client to the server. @@ -31,7 +30,7 @@ use ruff_db::panic::PanicError; pub(super) fn request(req: server::Request) -> Task { let id = req.id.clone(); - match req.method.as_str() { + match LspRequestMethod::from(req.method.clone()) { requests::ExecuteCommand::METHOD => sync_request_task::(req), requests::CodeActionRequestHandler::METHOD => background_document_request_task::< requests::CodeActionRequestHandler, @@ -125,7 +124,7 @@ pub(super) fn request(req: server::Request) -> Task { >( req, BackgroundSchedule::Worker ), - lsp_types::request::Shutdown::METHOD => sync_request_task::(req), + lsp_types::ShutdownRequest::METHOD => sync_request_task::(req), method => { tracing::warn!("Received request {method} which does not have a handler"); @@ -161,7 +160,7 @@ pub(super) fn request(req: server::Request) -> Task { } pub(super) fn notification(notif: server::Notification) -> Task { - match notif.method.as_str() { + match LspNotificationMethod::from(notif.method.clone()) { notifications::DidCloseTextDocumentHandler::METHOD => { sync_notification_task::(notif) } @@ -186,10 +185,10 @@ pub(super) fn notification(notif: server::Notification) -> Task { notifications::DidChangeWorkspaceFoldersHandler::METHOD => { sync_notification_task::(notif) } - lsp_types::notification::Cancel::METHOD => { + lsp_types::CancelNotification::METHOD => { sync_notification_task::(notif) } - lsp_types::notification::SetTrace::METHOD => { + lsp_types::SetTraceNotification::METHOD => { tracing::trace!("Ignoring `setTrace` notification"); return Task::nothing(); } @@ -218,7 +217,7 @@ where { let (id, params) = cast_request::(req)?; Ok(Task::sync(move |session, client: &Client| { - let _span = tracing::debug_span!("request", %id, method = R::METHOD).entered(); + let _span = tracing::debug_span!("request", %id, method = R::METHOD.as_str()).entered(); let result = R::run(session, client, params); respond::(&id, result, client, session.client_name().log_guidance()); })) @@ -247,7 +246,7 @@ where let log_guidance = snapshot.0.client_name().log_guidance(); Box::new(move |client| { - let _span = tracing::debug_span!("request", %id, method = R::METHOD).entered(); + let _span = tracing::debug_span!("request", %id, method = R::METHOD.as_str()).entered(); // Test again if the request was cancelled since it was scheduled on the background task // and, if so, return early @@ -315,7 +314,7 @@ where let log_guidance = document.client_name().log_guidance(); Box::new(move |client| { - let _span = tracing::debug_span!("request", %id, method = R::METHOD).entered(); + let _span = tracing::debug_span!("request", %id, method = R::METHOD.as_str()).entered(); // Test again if the request was cancelled since it was scheduled on the background task // and, if so, return early @@ -386,7 +385,7 @@ fn sync_notification_task( ) -> Result { let (id, params) = cast_notification::(notif)?; Ok(Task::sync(move |session, client| { - let _span = tracing::debug_span!("notification", method = N::METHOD).entered(); + let _span = tracing::debug_span!("notification", method = N::METHOD.as_str()).entered(); if let Err(err) = N::run(session, client, params) { tracing::error!("An error occurred while running {id}: {err}"); client.show_error_message(format!( @@ -427,7 +426,7 @@ where let log_guidance = snapshot.client_name().log_guidance(); Box::new(move |client| { - let _span = tracing::debug_span!("notification", method = N::METHOD).entered(); + let _span = tracing::debug_span!("notification", method = N::METHOD.as_str()).entered(); let result = match ruff_db::panic::catch_unwind(|| { N::run_with_snapshot(snapshot, client, params) @@ -463,7 +462,7 @@ where <::RequestType as Request>::Params: UnwindSafe, { request - .extract(Req::METHOD) + .extract(Req::METHOD.as_str()) .map_err(|err| match err { json_err @ server::ExtractError::JsonError { .. } => { anyhow::anyhow!("JSON parsing failure:\n{json_err}") @@ -503,7 +502,7 @@ fn respond_silent_error(id: RequestId, client: &Client, error: lsp_server::Respo fn cast_notification( notification: server::Notification, ) -> Result<( - &'static str, + LspNotificationMethod, <::NotificationType as Notification>::Params, )> where @@ -512,7 +511,7 @@ where Ok(( N::METHOD, notification - .extract(N::METHOD) + .extract(N::METHOD.as_str()) .map_err(|err| match err { json_err @ server::ExtractError::JsonError { .. } => { anyhow::anyhow!("JSON parsing failure:\n{json_err}") diff --git a/crates/ty_server/src/server/api/diagnostics.rs b/crates/ty_server/src/server/api/diagnostics.rs index fe282ca35eaaa..65f302da70ac5 100644 --- a/crates/ty_server/src/server/api/diagnostics.rs +++ b/crates/ty_server/src/server/api/diagnostics.rs @@ -2,10 +2,10 @@ use std::collections::HashMap; use std::fmt::Write as _; use std::hash::{DefaultHasher, Hash as _, Hasher as _}; -use lsp_types::notification::PublishDiagnostics; +use lsp_types::{Code, PublishDiagnosticsNotification}; use lsp_types::{ CodeDescription, Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity, DiagnosticTag, - NumberOrString, PublishDiagnosticsParams, Url, + PublishDiagnosticsParams, Uri as Url, }; use ruff_diagnostics::Applicability; use ruff_text_size::Ranged; @@ -209,7 +209,7 @@ pub(super) fn publish_diagnostics(document: &DocumentHandle, session: &Session, // Sends a notification to the client with the diagnostics for the document. let publish_diagnostics_notification = |uri: Url, diagnostics: Vec| { - client.send_notification::(PublishDiagnosticsParams { + client.send_notification::(PublishDiagnosticsParams { uri, diagnostics, version: Some(document.version()), @@ -323,7 +323,7 @@ pub(crate) fn publish_settings_diagnostics( }) .collect::>(); - client.send_notification::(PublishDiagnosticsParams { + client.send_notification::(PublishDiagnosticsParams { uri: url, diagnostics: lsp_diagnostics, version: None, @@ -381,13 +381,13 @@ fn unnecessary_hint_to_lsp_diagnostic( url, Diagnostic { range: range.local_range(), - severity: Some(DiagnosticSeverity::HINT), + severity: Some(DiagnosticSeverity::Hint), code: None, code_description: None, source: Some(DIAGNOSTIC_NAME.into()), message: hint.message(), related_information: None, - tags: Some(vec![DiagnosticTag::UNNECESSARY]), + tags: Some(vec![DiagnosticTag::Unnecessary]), data: None, }, )) @@ -401,7 +401,7 @@ pub(super) fn to_lsp_diagnostic( encoding: PositionEncoding, client_capabilities: ResolvedClientCapabilities, global_settings: &GlobalSettings, -) -> Option<(Option, Diagnostic)> { +) -> Option<(Option, Diagnostic)> { if diagnostic.is_invalid_syntax() && !global_settings.show_syntax_errors() { return None; } @@ -423,9 +423,9 @@ pub(super) fn to_lsp_diagnostic( }; let severity = match diagnostic.severity() { - Severity::Info => DiagnosticSeverity::INFORMATION, - Severity::Warning => DiagnosticSeverity::WARNING, - Severity::Error | Severity::Fatal => DiagnosticSeverity::ERROR, + Severity::Info => DiagnosticSeverity::Information, + Severity::Warning => DiagnosticSeverity::Warning, + Severity::Error | Severity::Fatal => DiagnosticSeverity::Error, }; let tags = diagnostic @@ -433,8 +433,8 @@ pub(super) fn to_lsp_diagnostic( .map(|tags| { tags.iter() .map(|tag| match tag { - ruff_db::diagnostic::DiagnosticTag::Unnecessary => DiagnosticTag::UNNECESSARY, - ruff_db::diagnostic::DiagnosticTag::Deprecated => DiagnosticTag::DEPRECATED, + ruff_db::diagnostic::DiagnosticTag::Unnecessary => DiagnosticTag::Unnecessary, + ruff_db::diagnostic::DiagnosticTag::Deprecated => DiagnosticTag::Deprecated, }) .collect::>() }) @@ -518,7 +518,7 @@ pub(super) fn to_lsp_diagnostic( range, severity: Some(severity), tags, - code: Some(NumberOrString::String(diagnostic.id().to_string())), + code: Some(Code::String(diagnostic.id().to_string())), code_description, source: Some(DIAGNOSTIC_NAME.into()), message, diff --git a/crates/ty_server/src/server/api/notifications/cancel.rs b/crates/ty_server/src/server/api/notifications/cancel.rs index c8f7199e75807..e01453cc37027 100644 --- a/crates/ty_server/src/server/api/notifications/cancel.rs +++ b/crates/ty_server/src/server/api/notifications/cancel.rs @@ -1,6 +1,6 @@ use lsp_server::RequestId; +use lsp_types::CancelNotification; use lsp_types::CancelParams; -use lsp_types::notification::Cancel; use crate::server::Result; use crate::server::api::traits::{NotificationHandler, SyncNotificationHandler}; @@ -10,14 +10,14 @@ use crate::session::client::Client; pub(crate) struct CancelNotificationHandler; impl NotificationHandler for CancelNotificationHandler { - type NotificationType = Cancel; + type NotificationType = CancelNotification; } impl SyncNotificationHandler for CancelNotificationHandler { fn run(session: &mut Session, client: &Client, params: CancelParams) -> Result<()> { let id: RequestId = match params.id { - lsp_types::NumberOrString::Number(id) => id.into(), - lsp_types::NumberOrString::String(id) => id.into(), + lsp_types::Id::Int(id) => id.into(), + lsp_types::Id::String(id) => id.into(), }; client.cancel(session, id); diff --git a/crates/ty_server/src/server/api/notifications/did_change.rs b/crates/ty_server/src/server/api/notifications/did_change.rs index ef0631f772294..84daa070ccd45 100644 --- a/crates/ty_server/src/server/api/notifications/did_change.rs +++ b/crates/ty_server/src/server/api/notifications/did_change.rs @@ -1,6 +1,8 @@ use lsp_server::ErrorCode; -use lsp_types::notification::DidChangeTextDocument; -use lsp_types::{DidChangeTextDocumentParams, VersionedTextDocumentIdentifier}; +use lsp_types::{ + DidChangeTextDocumentNotification, DidChangeTextDocumentParams, TextDocumentIdentifier, + VersionedTextDocumentIdentifier, +}; use crate::server::Result; use crate::server::api::LSPResult; @@ -12,7 +14,7 @@ use crate::session::client::Client; pub(crate) struct DidChangeTextDocumentHandler; impl NotificationHandler for DidChangeTextDocumentHandler { - type NotificationType = DidChangeTextDocument; + type NotificationType = DidChangeTextDocumentNotification; } impl SyncNotificationHandler for DidChangeTextDocumentHandler { @@ -22,7 +24,11 @@ impl SyncNotificationHandler for DidChangeTextDocumentHandler { params: DidChangeTextDocumentParams, ) -> Result<()> { let DidChangeTextDocumentParams { - text_document: VersionedTextDocumentIdentifier { uri, version }, + text_document: + VersionedTextDocumentIdentifier { + text_document_identifier: TextDocumentIdentifier { uri }, + version, + }, content_changes, } = params; diff --git a/crates/ty_server/src/server/api/notifications/did_change_notebook.rs b/crates/ty_server/src/server/api/notifications/did_change_notebook.rs index 36490412b3413..9dba97ae0816d 100644 --- a/crates/ty_server/src/server/api/notifications/did_change_notebook.rs +++ b/crates/ty_server/src/server/api/notifications/did_change_notebook.rs @@ -1,6 +1,5 @@ use lsp_server::ErrorCode; -use lsp_types as types; -use lsp_types::notification as notif; +use lsp_types::{self as types, DidChangeNotebookDocumentNotification}; use crate::server::Result; use crate::server::api::LSPResult; @@ -12,7 +11,7 @@ use crate::session::client::Client; pub(crate) struct DidChangeNotebookHandler; impl NotificationHandler for DidChangeNotebookHandler { - type NotificationType = notif::DidChangeNotebookDocument; + type NotificationType = DidChangeNotebookDocumentNotification; } impl SyncNotificationHandler for DidChangeNotebookHandler { diff --git a/crates/ty_server/src/server/api/notifications/did_change_watched_files.rs b/crates/ty_server/src/server/api/notifications/did_change_watched_files.rs index 5b1547a17ed5c..d4b97496ff374 100644 --- a/crates/ty_server/src/server/api/notifications/did_change_watched_files.rs +++ b/crates/ty_server/src/server/api/notifications/did_change_watched_files.rs @@ -7,8 +7,8 @@ use crate::server::api::traits::{NotificationHandler, SyncNotificationHandler}; use crate::session::Session; use crate::session::client::Client; use crate::system::AnySystemPath; -use lsp_types as types; -use lsp_types::{FileChangeType, notification as notif}; +use lsp_types::FileChangeType; +use lsp_types::{self as types, DidChangeWatchedFilesNotification}; use ruff_db::system::SystemPathBuf; use ty_project::Db as _; use ty_project::watch::{ChangeEvent, ChangedKind, CreatedKind, DeletedKind}; @@ -16,7 +16,7 @@ use ty_project::watch::{ChangeEvent, ChangedKind, CreatedKind, DeletedKind}; pub(crate) struct DidChangeWatchedFiles; impl NotificationHandler for DidChangeWatchedFiles { - type NotificationType = notif::DidChangeWatchedFiles; + type NotificationType = DidChangeWatchedFilesNotification; } impl SyncNotificationHandler for DidChangeWatchedFiles { @@ -38,26 +38,19 @@ impl SyncNotificationHandler for DidChangeWatchedFiles { } }; - let change_event = match change.typ { - FileChangeType::CREATED => ChangeEvent::Created { + let change_event = match change.kind { + FileChangeType::Created => ChangeEvent::Created { path: system_path, kind: CreatedKind::Any, }, - FileChangeType::CHANGED => ChangeEvent::Changed { + FileChangeType::Changed => ChangeEvent::Changed { path: system_path, kind: ChangedKind::Any, }, - FileChangeType::DELETED => ChangeEvent::Deleted { + FileChangeType::Deleted => ChangeEvent::Deleted { path: system_path, kind: DeletedKind::Any, }, - _ => { - tracing::debug!( - "Ignoring unsupported change event type: `{:?}` for {system_path}", - change.typ - ); - continue; - } }; changes.push(change_event); @@ -82,11 +75,7 @@ impl SyncNotificationHandler for DidChangeWatchedFiles { let client_capabilities = session.client_capabilities(); if client_capabilities.supports_workspace_diagnostic_refresh() { - client.send_request::( - session, - (), - |_, ()| {}, - ); + client.send_request::(session, (), |_, ()| {}); } else { for key in session.text_document_handles() { publish_diagnostics_if_needed(&key, session, client); @@ -94,7 +83,7 @@ impl SyncNotificationHandler for DidChangeWatchedFiles { } if client_capabilities.supports_inlay_hint_refresh() { - client.send_request::(session, (), |_, ()| {}); + client.send_request::(session, (), |_, ()| {}); } Ok(()) diff --git a/crates/ty_server/src/server/api/notifications/did_change_workspace_folders.rs b/crates/ty_server/src/server/api/notifications/did_change_workspace_folders.rs index 0c27123019dab..9034aa82f9af4 100644 --- a/crates/ty_server/src/server/api/notifications/did_change_workspace_folders.rs +++ b/crates/ty_server/src/server/api/notifications/did_change_workspace_folders.rs @@ -1,5 +1,4 @@ -use lsp_types as types; -use lsp_types::notification as notif; +use lsp_types::{self as types, DidChangeWorkspaceFoldersNotification}; use crate::server::Result; use crate::server::api::traits::{NotificationHandler, SyncNotificationHandler}; @@ -9,7 +8,7 @@ use crate::session::client::Client; pub(crate) struct DidChangeWorkspaceFoldersHandler; impl NotificationHandler for DidChangeWorkspaceFoldersHandler { - type NotificationType = notif::DidChangeWorkspaceFolders; + type NotificationType = DidChangeWorkspaceFoldersNotification; } impl SyncNotificationHandler for DidChangeWorkspaceFoldersHandler { diff --git a/crates/ty_server/src/server/api/notifications/did_close.rs b/crates/ty_server/src/server/api/notifications/did_close.rs index c7a2930e49284..0804ac9282b77 100644 --- a/crates/ty_server/src/server/api/notifications/did_close.rs +++ b/crates/ty_server/src/server/api/notifications/did_close.rs @@ -1,5 +1,5 @@ use lsp_server::ErrorCode; -use lsp_types::notification::DidCloseTextDocument; +use lsp_types::DidCloseTextDocumentNotification; use lsp_types::{DidCloseTextDocumentParams, TextDocumentIdentifier}; use crate::server::Result; @@ -11,7 +11,7 @@ use crate::session::client::Client; pub(crate) struct DidCloseTextDocumentHandler; impl NotificationHandler for DidCloseTextDocumentHandler { - type NotificationType = DidCloseTextDocument; + type NotificationType = DidCloseTextDocumentNotification; } impl SyncNotificationHandler for DidCloseTextDocumentHandler { diff --git a/crates/ty_server/src/server/api/notifications/did_close_notebook.rs b/crates/ty_server/src/server/api/notifications/did_close_notebook.rs index 887a70c3974d1..9d9838d69136c 100644 --- a/crates/ty_server/src/server/api/notifications/did_close_notebook.rs +++ b/crates/ty_server/src/server/api/notifications/did_close_notebook.rs @@ -1,5 +1,7 @@ -use lsp_types::notification::DidCloseNotebookDocument; -use lsp_types::{DidCloseNotebookDocumentParams, NotebookDocumentIdentifier}; +use lsp_types::{ + DidCloseNotebookDocumentNotification, DidCloseNotebookDocumentParams, + NotebookDocumentIdentifier, +}; use crate::server::Result; use crate::server::api::LSPResult; @@ -10,7 +12,7 @@ use crate::session::client::Client; pub(crate) struct DidCloseNotebookHandler; impl NotificationHandler for DidCloseNotebookHandler { - type NotificationType = DidCloseNotebookDocument; + type NotificationType = DidCloseNotebookDocumentNotification; } impl SyncNotificationHandler for DidCloseNotebookHandler { diff --git a/crates/ty_server/src/server/api/notifications/did_open.rs b/crates/ty_server/src/server/api/notifications/did_open.rs index bef5c1cc4a462..3c67363209ab6 100644 --- a/crates/ty_server/src/server/api/notifications/did_open.rs +++ b/crates/ty_server/src/server/api/notifications/did_open.rs @@ -1,5 +1,4 @@ -use lsp_types::notification::DidOpenTextDocument; -use lsp_types::{DidOpenTextDocumentParams, TextDocumentItem}; +use lsp_types::{DidOpenTextDocumentNotification, DidOpenTextDocumentParams, TextDocumentItem}; use crate::TextDocument; use crate::server::Result; @@ -11,7 +10,7 @@ use crate::session::client::Client; pub(crate) struct DidOpenTextDocumentHandler; impl NotificationHandler for DidOpenTextDocumentHandler { - type NotificationType = DidOpenTextDocument; + type NotificationType = DidOpenTextDocumentNotification; } impl SyncNotificationHandler for DidOpenTextDocumentHandler { @@ -30,7 +29,7 @@ impl SyncNotificationHandler for DidOpenTextDocumentHandler { }, } = params; - let text_doc = TextDocument::new(uri, text, version, &language_id); + let text_doc = TextDocument::new(uri, text, version, language_id); let document = session.open_text_document(text_doc); publish_diagnostics_if_needed(&document, session, client); diff --git a/crates/ty_server/src/server/api/notifications/did_open_notebook.rs b/crates/ty_server/src/server/api/notifications/did_open_notebook.rs index d34a60a9425a2..c76a1bbfe4795 100644 --- a/crates/ty_server/src/server/api/notifications/did_open_notebook.rs +++ b/crates/ty_server/src/server/api/notifications/did_open_notebook.rs @@ -1,6 +1,5 @@ use lsp_server::ErrorCode; -use lsp_types::DidOpenNotebookDocumentParams; -use lsp_types::notification::DidOpenNotebookDocument; +use lsp_types::{DidOpenNotebookDocumentNotification, DidOpenNotebookDocumentParams}; use crate::TextDocument; use crate::document::NotebookDocument; @@ -14,7 +13,7 @@ use crate::session::client::Client; pub(crate) struct DidOpenNotebookHandler; impl NotificationHandler for DidOpenNotebookHandler { - type NotificationType = DidOpenNotebookDocument; + type NotificationType = DidOpenNotebookDocumentNotification; } impl SyncNotificationHandler for DidOpenNotebookHandler { @@ -40,7 +39,7 @@ impl SyncNotificationHandler for DidOpenNotebookHandler { for cell in params.cell_text_documents { let cell_document = - TextDocument::new(cell.uri, cell.text, cell.version, &cell.language_id) + TextDocument::new(cell.uri, cell.text, cell.version, cell.language_id) .with_notebook(notebook_path.clone()); session.open_text_document(cell_document); } diff --git a/crates/ty_server/src/server/api/requests.rs b/crates/ty_server/src/server/api/requests.rs index ceae1f3a677a9..6317eae4745f6 100644 --- a/crates/ty_server/src/server/api/requests.rs +++ b/crates/ty_server/src/server/api/requests.rs @@ -63,5 +63,3 @@ pub(super) use type_hierarchy_subtypes::TypeHierarchySubtypesRequestHandler; pub(super) use type_hierarchy_supertypes::TypeHierarchySupertypesRequestHandler; pub(super) use workspace_diagnostic::WorkspaceDiagnosticRequestHandler; pub(super) use workspace_symbols::WorkspaceSymbolRequestHandler; - -pub use workspace_diagnostic::{PartialWorkspaceProgress, PartialWorkspaceProgressParams}; diff --git a/crates/ty_server/src/server/api/requests/code_action.rs b/crates/ty_server/src/server/api/requests/code_action.rs index 77cb9dcd1c2f8..67cbcbeec87dc 100644 --- a/crates/ty_server/src/server/api/requests/code_action.rs +++ b/crates/ty_server/src/server/api/requests/code_action.rs @@ -1,13 +1,13 @@ use std::borrow::Cow; use std::collections::HashMap; -use lsp_types::{self as types, NumberOrString, TextEdit, Url, request as req}; +use lsp_types::{self as types, Code, CodeActionRequest, CodeActionResponse, TextEdit, Uri as Url}; use ruff_db::files::File; use ruff_diagnostics::Edit; use ruff_text_size::Ranged; use ty_ide::code_actions; use ty_project::ProjectDatabase; -use types::{CodeActionKind, CodeActionOrCommand}; +use types::CodeActionKind; use crate::db::Db; use crate::document::{RangeExt, ToRangeExt}; @@ -22,7 +22,7 @@ use crate::{DIAGNOSTIC_NAME, PositionEncoding}; pub(crate) struct CodeActionRequestHandler; impl RequestHandler for CodeActionRequestHandler { - type RequestType = req::CodeActionRequest; + type RequestType = CodeActionRequest; } impl BackgroundDocumentRequestHandler for CodeActionRequestHandler { @@ -35,7 +35,7 @@ impl BackgroundDocumentRequestHandler for CodeActionRequestHandler { snapshot: &DocumentSnapshot, _client: &Client, params: types::CodeActionParams, - ) -> Result> { + ) -> Result>> { let diagnostics = params.context.diagnostics; let Some(file) = snapshot.to_notebook_or_file(db) else { @@ -57,9 +57,9 @@ impl BackgroundDocumentRequestHandler for CodeActionRequestHandler { } }; - actions.push(CodeActionOrCommand::CodeAction(lsp_types::CodeAction { + actions.push(CodeActionResponse::CodeAction(lsp_types::CodeAction { title: data.fix_title, - kind: Some(CodeActionKind::QUICKFIX), + kind: Some(CodeActionKind::QuickFix), diagnostics: Some(vec![diagnostic.clone()]), edit: Some(lsp_types::WorkspaceEdit { changes: Some(data.edits), @@ -70,6 +70,7 @@ impl BackgroundDocumentRequestHandler for CodeActionRequestHandler { command: None, disabled: None, data: None, + tags: None, })); } @@ -80,13 +81,13 @@ impl BackgroundDocumentRequestHandler for CodeActionRequestHandler { // which is dubious when you're in the middle of resolving symbols. let url = snapshot.url(); let encoding = snapshot.encoding(); - if let Some(NumberOrString::String(diagnostic_id)) = &diagnostic.code + if let Some(Code::String(diagnostic_id)) = &diagnostic.code && let Some(range) = diagnostic.range.to_text_range(db, file, url, encoding) { for action in code_actions(db, file, range, diagnostic_id) { - actions.push(CodeActionOrCommand::CodeAction(lsp_types::CodeAction { + actions.push(CodeActionResponse::CodeAction(lsp_types::CodeAction { title: action.title, - kind: Some(CodeActionKind::QUICKFIX), + kind: Some(CodeActionKind::QuickFix), diagnostics: Some(vec![diagnostic.clone()]), edit: Some(lsp_types::WorkspaceEdit { changes: to_lsp_edits(db, file, encoding, action.edits), @@ -97,6 +98,7 @@ impl BackgroundDocumentRequestHandler for CodeActionRequestHandler { command: None, disabled: None, data: None, + tags: None, })); } } diff --git a/crates/ty_server/src/server/api/requests/completion.rs b/crates/ty_server/src/server/api/requests/completion.rs index 4c88e3cfda48c..b46895d749a55 100644 --- a/crates/ty_server/src/server/api/requests/completion.rs +++ b/crates/ty_server/src/server/api/requests/completion.rs @@ -1,10 +1,10 @@ use std::borrow::Cow; use std::time::Instant; -use lsp_types::request::Completion; +use lsp_types::CompletionRequest; use lsp_types::{ CompletionItem, CompletionItemKind, CompletionItemLabelDetails, CompletionList, - CompletionParams, CompletionResponse, Documentation, TextEdit, Url, + CompletionParams, CompletionResponse, Documentation, TextEdit, Uri as Url, }; use ruff_source_file::OneIndexed; use ruff_text_size::Ranged; @@ -21,12 +21,12 @@ use crate::session::client::Client; pub(crate) struct CompletionRequestHandler; impl RequestHandler for CompletionRequestHandler { - type RequestType = Completion; + type RequestType = CompletionRequest; } impl BackgroundDocumentRequestHandler for CompletionRequestHandler { fn document_url(params: &CompletionParams) -> Cow<'_, Url> { - Cow::Borrowed(¶ms.text_document_position.text_document.uri) + Cow::Borrowed(¶ms.text_document_position_params.text_document.uri) } fn run_with_snapshot( @@ -48,7 +48,7 @@ impl BackgroundDocumentRequestHandler for CompletionRequestHandler { return Ok(None); }; - let Some(offset) = params.text_document_position.position.to_text_size( + let Some(offset) = params.text_document_position_params.position.to_text_size( db, file, snapshot.url(), @@ -131,9 +131,11 @@ impl BackgroundDocumentRequestHandler for CompletionRequestHandler { }) .collect(); let len = items.len(); - let response = CompletionResponse::List(CompletionList { + let response = CompletionResponse::CompletionList(CompletionList { is_incomplete: true, items, + item_defaults: None, + apply_kind: None, }); tracing::debug!( "Completions request returned {len} suggestions in {elapsed:?}", @@ -154,30 +156,30 @@ fn ty_kind_to_lsp_kind(kind: CompletionKind) -> CompletionItemKind { // ref https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#completionItemKind match kind { - Text => CompletionItemKind::TEXT, - Method => CompletionItemKind::METHOD, - Function => CompletionItemKind::FUNCTION, - Constructor => CompletionItemKind::CONSTRUCTOR, - Field => CompletionItemKind::FIELD, - Variable => CompletionItemKind::VARIABLE, - Class => CompletionItemKind::CLASS, - Interface => CompletionItemKind::INTERFACE, - Module => CompletionItemKind::MODULE, - Property => CompletionItemKind::PROPERTY, - Unit => CompletionItemKind::UNIT, - Value => CompletionItemKind::VALUE, - Enum => CompletionItemKind::ENUM, - Keyword => CompletionItemKind::KEYWORD, - Snippet => CompletionItemKind::SNIPPET, - Color => CompletionItemKind::COLOR, - File => CompletionItemKind::FILE, - Reference => CompletionItemKind::REFERENCE, - Folder => CompletionItemKind::FOLDER, - EnumMember => CompletionItemKind::ENUM_MEMBER, - Constant => CompletionItemKind::CONSTANT, - Struct => CompletionItemKind::STRUCT, - Event => CompletionItemKind::EVENT, - Operator => CompletionItemKind::OPERATOR, - TypeParameter => CompletionItemKind::TYPE_PARAMETER, + Text => CompletionItemKind::Text, + Method => CompletionItemKind::Method, + Function => CompletionItemKind::Function, + Constructor => CompletionItemKind::Constructor, + Field => CompletionItemKind::Field, + Variable => CompletionItemKind::Variable, + Class => CompletionItemKind::Class, + Interface => CompletionItemKind::Interface, + Module => CompletionItemKind::Module, + Property => CompletionItemKind::Property, + Unit => CompletionItemKind::Unit, + Value => CompletionItemKind::Value, + Enum => CompletionItemKind::Enum, + Keyword => CompletionItemKind::Keyword, + Snippet => CompletionItemKind::Snippet, + Color => CompletionItemKind::Color, + File => CompletionItemKind::File, + Reference => CompletionItemKind::Reference, + Folder => CompletionItemKind::Folder, + EnumMember => CompletionItemKind::EnumMember, + Constant => CompletionItemKind::Constant, + Struct => CompletionItemKind::Struct, + Event => CompletionItemKind::Event, + Operator => CompletionItemKind::Operator, + TypeParameter => CompletionItemKind::TypeParameter, } } diff --git a/crates/ty_server/src/server/api/requests/diagnostic.rs b/crates/ty_server/src/server/api/requests/diagnostic.rs index 3ccc6864e96a6..b84dbae407c02 100644 --- a/crates/ty_server/src/server/api/requests/diagnostic.rs +++ b/crates/ty_server/src/server/api/requests/diagnostic.rs @@ -1,10 +1,10 @@ use std::borrow::Cow; -use lsp_types::request::DocumentDiagnosticRequest; +use lsp_types::DocumentDiagnosticRequest; use lsp_types::{ - DocumentDiagnosticParams, DocumentDiagnosticReport, DocumentDiagnosticReportResult, - FullDocumentDiagnosticReport, RelatedFullDocumentDiagnosticReport, - RelatedUnchangedDocumentDiagnosticReport, UnchangedDocumentDiagnosticReport, Url, + DocumentDiagnosticParams, DocumentDiagnosticReport, FullDocumentDiagnosticReport, + RelatedFullDocumentDiagnosticReport, RelatedUnchangedDocumentDiagnosticReport, + UnchangedDocumentDiagnosticReport, Uri as Url, }; use crate::server::Result; @@ -32,34 +32,31 @@ impl BackgroundDocumentRequestHandler for DocumentDiagnosticRequestHandler { snapshot: &DocumentSnapshot, _client: &Client, params: DocumentDiagnosticParams, - ) -> Result { + ) -> Result { if snapshot.global_settings().diagnostic_mode().is_off() { - return Ok(DocumentDiagnosticReportResult::Report( - DocumentDiagnosticReport::Full(RelatedFullDocumentDiagnosticReport::default()), - )); + return Ok(RelatedFullDocumentDiagnosticReport::default().into()); } let diagnostics = compute_diagnostics(db, snapshot.document(), snapshot.encoding()); let Some(diagnostics) = diagnostics else { - return Ok(DocumentDiagnosticReportResult::Report( - DocumentDiagnosticReport::Full(RelatedFullDocumentDiagnosticReport::default()), - )); + return Ok(RelatedFullDocumentDiagnosticReport::default().into()); }; let result_id = diagnostics.result_id(); let report = match result_id { Some(new_id) if Some(&new_id) == params.previous_result_id.as_ref() => { - DocumentDiagnosticReport::Unchanged(RelatedUnchangedDocumentDiagnosticReport { + RelatedUnchangedDocumentDiagnosticReport { related_documents: None, unchanged_document_diagnostic_report: UnchangedDocumentDiagnosticReport { result_id: new_id, }, - }) + } + .into() } new_id => { - DocumentDiagnosticReport::Full(RelatedFullDocumentDiagnosticReport { + RelatedFullDocumentDiagnosticReport { related_documents: None, full_document_diagnostic_report: FullDocumentDiagnosticReport { result_id: new_id, @@ -73,11 +70,12 @@ impl BackgroundDocumentRequestHandler for DocumentDiagnosticRequestHandler { ) .expect_text_document(), }, - }) + } + .into() } }; - Ok(DocumentDiagnosticReportResult::Report(report)) + Ok(report) } } diff --git a/crates/ty_server/src/server/api/requests/doc_highlights.rs b/crates/ty_server/src/server/api/requests/doc_highlights.rs index 72500e907c991..e30e81ca20ac6 100644 --- a/crates/ty_server/src/server/api/requests/doc_highlights.rs +++ b/crates/ty_server/src/server/api/requests/doc_highlights.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; -use lsp_types::request::DocumentHighlightRequest; -use lsp_types::{DocumentHighlight, DocumentHighlightKind, DocumentHighlightParams, Url}; +use lsp_types::DocumentHighlightRequest; +use lsp_types::{DocumentHighlight, DocumentHighlightKind, DocumentHighlightParams, Uri as Url}; use ty_ide::{ReferenceKind, document_highlights}; use ty_project::ProjectDatabase; @@ -62,9 +62,9 @@ impl BackgroundDocumentRequestHandler for DocumentHighlightRequestHandler { .local_range(); let kind = match target.kind() { - ReferenceKind::Read => Some(DocumentHighlightKind::READ), - ReferenceKind::Write => Some(DocumentHighlightKind::WRITE), - ReferenceKind::Other => Some(DocumentHighlightKind::TEXT), + ReferenceKind::Read => Some(DocumentHighlightKind::Read), + ReferenceKind::Write => Some(DocumentHighlightKind::Write), + ReferenceKind::Other => Some(DocumentHighlightKind::Text), }; Some(DocumentHighlight { range, kind }) diff --git a/crates/ty_server/src/server/api/requests/document_symbols.rs b/crates/ty_server/src/server/api/requests/document_symbols.rs index 2f7719b2ac3af..a05873fea6819 100644 --- a/crates/ty_server/src/server/api/requests/document_symbols.rs +++ b/crates/ty_server/src/server/api/requests/document_symbols.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; -use lsp_types::request::DocumentSymbolRequest; -use lsp_types::{DocumentSymbol, DocumentSymbolParams, SymbolInformation, Url}; +use lsp_types::DocumentSymbolRequest; +use lsp_types::{DocumentSymbol, DocumentSymbolParams, Uri as Url}; use ruff_db::files::File; use ty_ide::{HierarchicalSymbols, SymbolId, SymbolInfo, document_symbols}; use ty_project::ProjectDatabase; @@ -55,7 +55,7 @@ impl BackgroundDocumentRequestHandler for DocumentSymbolRequestHandler { if supports_hierarchical { let symbols = symbols.to_hierarchical(); - let lsp_symbols: Vec = symbols + let lsp_symbols = symbols .iter() .filter_map(|(id, symbol)| { convert_to_lsp_document_symbol( @@ -69,17 +69,21 @@ impl BackgroundDocumentRequestHandler for DocumentSymbolRequestHandler { }) .collect(); - Ok(Some(lsp_types::DocumentSymbolResponse::Nested(lsp_symbols))) + Ok(Some(lsp_types::DocumentSymbolResponse::DocumentSymbolList( + lsp_symbols, + ))) } else { // Return flattened symbols as SymbolInformation - let lsp_symbols: Vec = symbols + let lsp_symbols = symbols .iter() .filter_map(|(_, symbol)| { convert_to_lsp_symbol_information(db, file, symbol, snapshot.encoding()) }) .collect(); - Ok(Some(lsp_types::DocumentSymbolResponse::Flat(lsp_symbols))) + Ok(Some( + lsp_types::DocumentSymbolResponse::SymbolInformationList(lsp_symbols), + )) } } } diff --git a/crates/ty_server/src/server/api/requests/execute_command.rs b/crates/ty_server/src/server/api/requests/execute_command.rs index 8c0c0f90761ff..d8a56c1b07aa9 100644 --- a/crates/ty_server/src/server/api/requests/execute_command.rs +++ b/crates/ty_server/src/server/api/requests/execute_command.rs @@ -6,7 +6,8 @@ use crate::server::api::traits::SyncRequestHandler; use crate::session::Session; use crate::session::client::Client; use lsp_server::ErrorCode; -use lsp_types::{self as types, request as req}; +use lsp_types::ExecuteCommandRequest; +use lsp_types::{self as types}; use std::fmt::Write; use std::str::FromStr; use ty_project::Db as _; @@ -14,7 +15,7 @@ use ty_project::Db as _; pub(crate) struct ExecuteCommand; impl RequestHandler for ExecuteCommand { - type RequestType = req::ExecuteCommand; + type RequestType = ExecuteCommandRequest; } impl SyncRequestHandler for ExecuteCommand { diff --git a/crates/ty_server/src/server/api/requests/folding_range.rs b/crates/ty_server/src/server/api/requests/folding_range.rs index a360afb4e6fc1..95a50b57f15b4 100644 --- a/crates/ty_server/src/server/api/requests/folding_range.rs +++ b/crates/ty_server/src/server/api/requests/folding_range.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; -use lsp_types::request::FoldingRangeRequest; -use lsp_types::{FoldingRange, FoldingRangeKind, FoldingRangeParams, Url}; +use lsp_types::FoldingRangeRequest; +use lsp_types::{FoldingRange, FoldingRangeKind, FoldingRangeParams, Uri as Url}; use ruff_db::source::source_text; use ruff_text_size::TextRange; use ty_ide::folding_ranges; diff --git a/crates/ty_server/src/server/api/requests/goto_declaration.rs b/crates/ty_server/src/server/api/requests/goto_declaration.rs index 397a7dcef8e82..1e94694ca4158 100644 --- a/crates/ty_server/src/server/api/requests/goto_declaration.rs +++ b/crates/ty_server/src/server/api/requests/goto_declaration.rs @@ -1,7 +1,6 @@ use std::borrow::Cow; -use lsp_types::request::{GotoDeclaration, GotoDeclarationParams}; -use lsp_types::{GotoDefinitionResponse, Url}; +use lsp_types::{DeclarationParams, DeclarationRequest, DeclarationResponse, Uri as Url}; use ty_ide::goto_declaration; use ty_project::ProjectDatabase; @@ -15,11 +14,11 @@ use crate::session::client::Client; pub(crate) struct GotoDeclarationRequestHandler; impl RequestHandler for GotoDeclarationRequestHandler { - type RequestType = GotoDeclaration; + type RequestType = DeclarationRequest; } impl BackgroundDocumentRequestHandler for GotoDeclarationRequestHandler { - fn document_url(params: &GotoDeclarationParams) -> Cow<'_, Url> { + fn document_url(params: &DeclarationParams) -> Cow<'_, Url> { Cow::Borrowed(¶ms.text_document_position_params.text_document.uri) } @@ -27,8 +26,8 @@ impl BackgroundDocumentRequestHandler for GotoDeclarationRequestHandler { db: &ProjectDatabase, snapshot: &DocumentSnapshot, _client: &Client, - params: GotoDeclarationParams, - ) -> crate::server::Result> { + params: DeclarationParams, + ) -> crate::server::Result> { if snapshot .workspace_settings() .is_language_services_disabled() @@ -63,14 +62,14 @@ impl BackgroundDocumentRequestHandler for GotoDeclarationRequestHandler { .filter_map(|target| target.to_link(db, src, snapshot.encoding())) .collect(); - Ok(Some(GotoDefinitionResponse::Link(links))) + Ok(Some(links.into())) } else { let locations: Vec<_> = ranged .into_iter() .filter_map(|target| target.to_location(db, snapshot.encoding())) .collect(); - Ok(Some(GotoDefinitionResponse::Array(locations))) + Ok(Some(DeclarationResponse::Declaration(locations.into()))) } } } diff --git a/crates/ty_server/src/server/api/requests/goto_definition.rs b/crates/ty_server/src/server/api/requests/goto_definition.rs index de468b781862c..9b4a424fc83c4 100644 --- a/crates/ty_server/src/server/api/requests/goto_definition.rs +++ b/crates/ty_server/src/server/api/requests/goto_definition.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; -use lsp_types::request::GotoDefinition; -use lsp_types::{GotoDefinitionParams, GotoDefinitionResponse, Url}; +use lsp_types::DefinitionRequest; +use lsp_types::{DefinitionParams, DefinitionResponse, Uri as Url}; use ty_ide::goto_definition; use ty_project::ProjectDatabase; @@ -15,11 +15,11 @@ use crate::session::client::Client; pub(crate) struct GotoDefinitionRequestHandler; impl RequestHandler for GotoDefinitionRequestHandler { - type RequestType = GotoDefinition; + type RequestType = DefinitionRequest; } impl BackgroundDocumentRequestHandler for GotoDefinitionRequestHandler { - fn document_url(params: &GotoDefinitionParams) -> Cow<'_, Url> { + fn document_url(params: &DefinitionParams) -> Cow<'_, Url> { Cow::Borrowed(¶ms.text_document_position_params.text_document.uri) } @@ -27,8 +27,8 @@ impl BackgroundDocumentRequestHandler for GotoDefinitionRequestHandler { db: &ProjectDatabase, snapshot: &DocumentSnapshot, _client: &Client, - params: GotoDefinitionParams, - ) -> crate::server::Result> { + params: DefinitionParams, + ) -> crate::server::Result> { if snapshot .workspace_settings() .is_language_services_disabled() @@ -63,14 +63,14 @@ impl BackgroundDocumentRequestHandler for GotoDefinitionRequestHandler { .filter_map(|target| target.to_link(db, src, snapshot.encoding())) .collect(); - Ok(Some(GotoDefinitionResponse::Link(links))) + Ok(Some(links.into())) } else { let locations: Vec<_> = ranged .into_iter() .filter_map(|target| target.to_location(db, snapshot.encoding())) .collect(); - Ok(Some(GotoDefinitionResponse::Array(locations))) + Ok(Some(DefinitionResponse::Definition(locations.into()))) } } } diff --git a/crates/ty_server/src/server/api/requests/goto_type_definition.rs b/crates/ty_server/src/server/api/requests/goto_type_definition.rs index cab7290f88d29..2574e7385067b 100644 --- a/crates/ty_server/src/server/api/requests/goto_type_definition.rs +++ b/crates/ty_server/src/server/api/requests/goto_type_definition.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; -use lsp_types::request::{GotoTypeDefinition, GotoTypeDefinitionParams}; -use lsp_types::{GotoDefinitionResponse, Url}; +use lsp_types::{TypeDefinitionParams, TypeDefinitionRequest}; +use lsp_types::{TypeDefinitionResponse, Uri as Url}; use ty_ide::goto_type_definition; use ty_project::ProjectDatabase; @@ -15,11 +15,11 @@ use crate::session::client::Client; pub(crate) struct GotoTypeDefinitionRequestHandler; impl RequestHandler for GotoTypeDefinitionRequestHandler { - type RequestType = GotoTypeDefinition; + type RequestType = TypeDefinitionRequest; } impl BackgroundDocumentRequestHandler for GotoTypeDefinitionRequestHandler { - fn document_url(params: &GotoTypeDefinitionParams) -> Cow<'_, Url> { + fn document_url(params: &TypeDefinitionParams) -> Cow<'_, Url> { Cow::Borrowed(¶ms.text_document_position_params.text_document.uri) } @@ -27,8 +27,8 @@ impl BackgroundDocumentRequestHandler for GotoTypeDefinitionRequestHandler { db: &ProjectDatabase, snapshot: &DocumentSnapshot, _client: &Client, - params: GotoTypeDefinitionParams, - ) -> crate::server::Result> { + params: TypeDefinitionParams, + ) -> crate::server::Result> { if snapshot .workspace_settings() .is_language_services_disabled() @@ -63,14 +63,14 @@ impl BackgroundDocumentRequestHandler for GotoTypeDefinitionRequestHandler { .filter_map(|target| target.to_link(db, src, snapshot.encoding())) .collect(); - Ok(Some(GotoDefinitionResponse::Link(links))) + Ok(Some(links.into())) } else { let locations: Vec<_> = ranged .into_iter() .filter_map(|target| target.to_location(db, snapshot.encoding())) .collect(); - Ok(Some(GotoDefinitionResponse::Array(locations))) + Ok(Some(TypeDefinitionResponse::Definition(locations.into()))) } } } diff --git a/crates/ty_server/src/server/api/requests/hover.rs b/crates/ty_server/src/server/api/requests/hover.rs index 3c37b3d5811ad..fcb0b12f5adde 100644 --- a/crates/ty_server/src/server/api/requests/hover.rs +++ b/crates/ty_server/src/server/api/requests/hover.rs @@ -6,8 +6,8 @@ use crate::server::api::traits::{ }; use crate::session::DocumentSnapshot; use crate::session::client::Client; -use lsp_types::request::HoverRequest; -use lsp_types::{HoverContents, HoverParams, MarkupContent, Url}; +use lsp_types::HoverRequest; +use lsp_types::{HoverParams, MarkupContent, Uri as Url}; use ty_ide::{MarkupKind, hover}; use ty_project::ProjectDatabase; @@ -64,10 +64,11 @@ impl BackgroundDocumentRequestHandler for HoverRequestHandler { let contents = range_info.display(db, markup_kind).to_string(); Ok(Some(lsp_types::Hover { - contents: HoverContents::Markup(MarkupContent { + contents: MarkupContent { kind: lsp_markup_kind, value: contents, - }), + } + .into(), range: range_info .file_range() .to_lsp_range(db, snapshot.encoding()) diff --git a/crates/ty_server/src/server/api/requests/inlay_hints.rs b/crates/ty_server/src/server/api/requests/inlay_hints.rs index 14ae7249b2153..cb066bf7d361a 100644 --- a/crates/ty_server/src/server/api/requests/inlay_hints.rs +++ b/crates/ty_server/src/server/api/requests/inlay_hints.rs @@ -1,8 +1,8 @@ use std::borrow::Cow; use std::time::Instant; -use lsp_types::request::InlayHintRequest; -use lsp_types::{InlayHintParams, Url}; +use lsp_types::InlayHintRequest; +use lsp_types::{InlayHintParams, Uri as Url}; use ruff_db::files::File; use ty_ide::{InlayHintKind, InlayHintLabel, InlayHintTextEdit, inlay_hints}; use ty_project::ProjectDatabase; @@ -93,8 +93,8 @@ impl RetriableRequestHandler for InlayHintRequestHandler {} fn inlay_hint_kind(inlay_hint_kind: &InlayHintKind) -> lsp_types::InlayHintKind { match inlay_hint_kind { - InlayHintKind::Type => lsp_types::InlayHintKind::TYPE, - InlayHintKind::CallArgumentName => lsp_types::InlayHintKind::PARAMETER, + InlayHintKind::Type => lsp_types::InlayHintKind::Type, + InlayHintKind::CallArgumentName => lsp_types::InlayHintKind::Parameter, } } @@ -102,7 +102,7 @@ fn inlay_hint_label( inlay_hint_label: &InlayHintLabel, db: &ProjectDatabase, encoding: PositionEncoding, -) -> lsp_types::InlayHintLabel { +) -> lsp_types::Label { let mut label_parts = Vec::new(); for part in inlay_hint_label.parts() { label_parts.push(lsp_types::InlayHintLabelPart { @@ -114,7 +114,7 @@ fn inlay_hint_label( command: None, }); } - lsp_types::InlayHintLabel::LabelParts(label_parts) + lsp_types::Label::InlayHintLabelPartList(label_parts) } fn inlay_hint_text_edit( diff --git a/crates/ty_server/src/server/api/requests/prepare_rename.rs b/crates/ty_server/src/server/api/requests/prepare_rename.rs index 2fd82282018dc..827e2979a44ee 100644 --- a/crates/ty_server/src/server/api/requests/prepare_rename.rs +++ b/crates/ty_server/src/server/api/requests/prepare_rename.rs @@ -1,7 +1,6 @@ use std::borrow::Cow; -use lsp_types::request::PrepareRenameRequest; -use lsp_types::{PrepareRenameResponse, TextDocumentPositionParams, Url}; +use lsp_types::{PrepareRenameParams, PrepareRenameRequest, PrepareRenameResult, Uri as Url}; use ty_ide::can_rename; use ty_project::ProjectDatabase; @@ -19,16 +18,16 @@ impl RequestHandler for PrepareRenameRequestHandler { } impl BackgroundDocumentRequestHandler for PrepareRenameRequestHandler { - fn document_url(params: &TextDocumentPositionParams) -> Cow<'_, Url> { - Cow::Borrowed(¶ms.text_document.uri) + fn document_url(params: &PrepareRenameParams) -> Cow<'_, Url> { + Cow::Borrowed(¶ms.text_document_position_params.text_document.uri) } fn run_with_snapshot( db: &ProjectDatabase, snapshot: &DocumentSnapshot, _client: &Client, - params: TextDocumentPositionParams, - ) -> crate::server::Result> { + params: PrepareRenameParams, + ) -> crate::server::Result> { if snapshot .workspace_settings() .is_language_services_disabled() @@ -40,11 +39,12 @@ impl BackgroundDocumentRequestHandler for PrepareRenameRequestHandler { return Ok(None); }; - let Some(offset) = - params - .position - .to_text_size(db, file, snapshot.url(), snapshot.encoding()) - else { + let Some(offset) = params.text_document_position_params.position.to_text_size( + db, + file, + snapshot.url(), + snapshot.encoding(), + ) else { return Ok(None); }; @@ -59,7 +59,7 @@ impl BackgroundDocumentRequestHandler for PrepareRenameRequestHandler { return Ok(None); }; - Ok(Some(PrepareRenameResponse::Range(lsp_range))) + Ok(Some(lsp_range.into())) } } diff --git a/crates/ty_server/src/server/api/requests/prepare_type_hierarchy.rs b/crates/ty_server/src/server/api/requests/prepare_type_hierarchy.rs index a680f8a95886f..b0d760ce57baf 100644 --- a/crates/ty_server/src/server/api/requests/prepare_type_hierarchy.rs +++ b/crates/ty_server/src/server/api/requests/prepare_type_hierarchy.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; -use lsp_types::request::TypeHierarchyPrepare; -use lsp_types::{TypeHierarchyItem, TypeHierarchyPrepareParams, Url}; +use lsp_types::TypeHierarchyPrepareRequest; +use lsp_types::{TypeHierarchyItem, TypeHierarchyPrepareParams, Uri as Url}; use ty_project::ProjectDatabase; use crate::document::PositionExt; @@ -24,7 +24,7 @@ use crate::session::client::Client; pub(crate) struct PrepareTypeHierarchyRequestHandler; impl RequestHandler for PrepareTypeHierarchyRequestHandler { - type RequestType = TypeHierarchyPrepare; + type RequestType = TypeHierarchyPrepareRequest; } impl BackgroundDocumentRequestHandler for PrepareTypeHierarchyRequestHandler { diff --git a/crates/ty_server/src/server/api/requests/references.rs b/crates/ty_server/src/server/api/requests/references.rs index c8d0ae5ae16a6..b1ef191687525 100644 --- a/crates/ty_server/src/server/api/requests/references.rs +++ b/crates/ty_server/src/server/api/requests/references.rs @@ -1,7 +1,7 @@ use std::borrow::Cow; -use lsp_types::request::References; -use lsp_types::{Location, ReferenceParams, Url}; +use lsp_types::ReferencesRequest; +use lsp_types::{Location, ReferenceParams, Uri as Url}; use ty_ide::find_references; use ty_project::ProjectDatabase; @@ -15,12 +15,12 @@ use crate::session::client::Client; pub(crate) struct ReferencesRequestHandler; impl RequestHandler for ReferencesRequestHandler { - type RequestType = References; + type RequestType = ReferencesRequest; } impl BackgroundDocumentRequestHandler for ReferencesRequestHandler { fn document_url(params: &ReferenceParams) -> Cow<'_, Url> { - Cow::Borrowed(¶ms.text_document_position.text_document.uri) + Cow::Borrowed(¶ms.text_document_position_params.text_document.uri) } fn run_with_snapshot( @@ -40,7 +40,7 @@ impl BackgroundDocumentRequestHandler for ReferencesRequestHandler { return Ok(None); }; - let Some(offset) = params.text_document_position.position.to_text_size( + let Some(offset) = params.text_document_position_params.position.to_text_size( db, file, snapshot.url(), diff --git a/crates/ty_server/src/server/api/requests/rename.rs b/crates/ty_server/src/server/api/requests/rename.rs index 71fd3b70c3f4b..ff75d5b5e5671 100644 --- a/crates/ty_server/src/server/api/requests/rename.rs +++ b/crates/ty_server/src/server/api/requests/rename.rs @@ -1,8 +1,8 @@ use std::borrow::Cow; use std::collections::HashMap; -use lsp_types::request::Rename; -use lsp_types::{RenameParams, TextEdit, Url, WorkspaceEdit}; +use lsp_types::RenameRequest; +use lsp_types::{RenameParams, TextEdit, Uri as Url, WorkspaceEdit}; use ty_ide::rename; use ty_project::ProjectDatabase; @@ -16,12 +16,12 @@ use crate::session::client::Client; pub(crate) struct RenameRequestHandler; impl RequestHandler for RenameRequestHandler { - type RequestType = Rename; + type RequestType = RenameRequest; } impl BackgroundDocumentRequestHandler for RenameRequestHandler { fn document_url(params: &RenameParams) -> Cow<'_, Url> { - Cow::Borrowed(¶ms.text_document_position.text_document.uri) + Cow::Borrowed(¶ms.text_document_position_params.text_document.uri) } fn run_with_snapshot( @@ -41,7 +41,7 @@ impl BackgroundDocumentRequestHandler for RenameRequestHandler { return Ok(None); }; - let Some(offset) = params.text_document_position.position.to_text_size( + let Some(offset) = params.text_document_position_params.position.to_text_size( db, file, snapshot.url(), diff --git a/crates/ty_server/src/server/api/requests/selection_range.rs b/crates/ty_server/src/server/api/requests/selection_range.rs index 5a8227fdc75bd..f3a1eb75bcb24 100644 --- a/crates/ty_server/src/server/api/requests/selection_range.rs +++ b/crates/ty_server/src/server/api/requests/selection_range.rs @@ -1,7 +1,8 @@ use std::borrow::Cow; -use lsp_types::request::SelectionRangeRequest; -use lsp_types::{SelectionRange as LspSelectionRange, SelectionRangeParams, Url}; +use lsp_types::{ + SelectionRange as LspSelectionRange, SelectionRangeParams, SelectionRangeRequest, Uri as Url, +}; use ty_ide::selection_range; use ty_project::ProjectDatabase; diff --git a/crates/ty_server/src/server/api/requests/semantic_tokens.rs b/crates/ty_server/src/server/api/requests/semantic_tokens.rs index 7673b9bbb4430..2927f5fed12c4 100644 --- a/crates/ty_server/src/server/api/requests/semantic_tokens.rs +++ b/crates/ty_server/src/server/api/requests/semantic_tokens.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use lsp_types::{SemanticTokens, SemanticTokensParams, SemanticTokensResult, Url}; +use lsp_types::{SemanticTokens, SemanticTokensParams, Uri}; use ruff_db::source::source_text; use ty_project::ProjectDatabase; @@ -15,11 +15,11 @@ use crate::session::client::Client; pub(crate) struct SemanticTokensRequestHandler; impl RequestHandler for SemanticTokensRequestHandler { - type RequestType = lsp_types::request::SemanticTokensFullRequest; + type RequestType = lsp_types::SemanticTokensRequest; } impl BackgroundDocumentRequestHandler for SemanticTokensRequestHandler { - fn document_url(params: &SemanticTokensParams) -> Cow<'_, Url> { + fn document_url(params: &SemanticTokensParams) -> Cow<'_, Uri> { Cow::Borrowed(¶ms.text_document.uri) } @@ -28,7 +28,7 @@ impl BackgroundDocumentRequestHandler for SemanticTokensRequestHandler { snapshot: &DocumentSnapshot, _client: &Client, _params: SemanticTokensParams, - ) -> crate::server::Result> { + ) -> crate::server::Result> { if snapshot .workspace_settings() .is_language_services_disabled() @@ -65,10 +65,10 @@ impl BackgroundDocumentRequestHandler for SemanticTokensRequestHandler { .supports_multiline_semantic_tokens(), ); - Ok(Some(SemanticTokensResult::Tokens(SemanticTokens { + Ok(Some(SemanticTokens { result_id: None, data: lsp_tokens, - }))) + })) } } diff --git a/crates/ty_server/src/server/api/requests/semantic_tokens_range.rs b/crates/ty_server/src/server/api/requests/semantic_tokens_range.rs index 3b945d13d0fa0..494ace957ff3c 100644 --- a/crates/ty_server/src/server/api/requests/semantic_tokens_range.rs +++ b/crates/ty_server/src/server/api/requests/semantic_tokens_range.rs @@ -1,6 +1,6 @@ use std::borrow::Cow; -use lsp_types::{SemanticTokens, SemanticTokensRangeParams, SemanticTokensRangeResult, Url}; +use lsp_types::{SemanticTokens, SemanticTokensRangeParams, Uri as Url}; use ty_project::ProjectDatabase; use crate::document::RangeExt; @@ -14,7 +14,7 @@ use crate::session::client::Client; pub(crate) struct SemanticTokensRangeRequestHandler; impl RequestHandler for SemanticTokensRangeRequestHandler { - type RequestType = lsp_types::request::SemanticTokensRangeRequest; + type RequestType = lsp_types::SemanticTokensRangeRequest; } impl BackgroundDocumentRequestHandler for SemanticTokensRangeRequestHandler { @@ -27,7 +27,7 @@ impl BackgroundDocumentRequestHandler for SemanticTokensRangeRequestHandler { snapshot: &DocumentSnapshot, _client: &Client, params: SemanticTokensRangeParams, - ) -> crate::server::Result> { + ) -> crate::server::Result> { if snapshot .workspace_settings() .is_language_services_disabled() @@ -58,10 +58,10 @@ impl BackgroundDocumentRequestHandler for SemanticTokensRangeRequestHandler { .supports_multiline_semantic_tokens(), ); - Ok(Some(SemanticTokensRangeResult::Tokens(SemanticTokens { + Ok(Some(SemanticTokens { result_id: None, data: lsp_tokens, - }))) + })) } } diff --git a/crates/ty_server/src/server/api/requests/shutdown.rs b/crates/ty_server/src/server/api/requests/shutdown.rs index 77c9e78f9821b..95addad3a11b6 100644 --- a/crates/ty_server/src/server/api/requests/shutdown.rs +++ b/crates/ty_server/src/server/api/requests/shutdown.rs @@ -2,13 +2,13 @@ use crate::Session; use crate::server::api::traits::{RequestHandler, SyncRequestHandler}; use crate::session::client::Client; -use lsp_types::{WorkspaceDiagnosticReport, WorkspaceDiagnosticReportResult}; +use lsp_types::WorkspaceDiagnosticReport; use salsa::Database; pub(crate) struct ShutdownHandler; impl RequestHandler for ShutdownHandler { - type RequestType = lsp_types::request::Shutdown; + type RequestType = lsp_types::ShutdownRequest; } impl SyncRequestHandler for ShutdownHandler { @@ -21,9 +21,7 @@ impl SyncRequestHandler for ShutdownHandler { { client.respond( &suspended_workspace_request.id, - Ok(WorkspaceDiagnosticReportResult::Report( - WorkspaceDiagnosticReport::default(), - )), + Ok(WorkspaceDiagnosticReport::default()), ); } diff --git a/crates/ty_server/src/server/api/requests/signature_help.rs b/crates/ty_server/src/server/api/requests/signature_help.rs index 7d02f878f2336..7f12591046fe3 100644 --- a/crates/ty_server/src/server/api/requests/signature_help.rs +++ b/crates/ty_server/src/server/api/requests/signature_help.rs @@ -6,10 +6,10 @@ use crate::server::api::traits::{ }; use crate::session::DocumentSnapshot; use crate::session::client::Client; -use lsp_types::request::SignatureHelpRequest; +use lsp_types::{ActiveParameter, SignatureHelpRequest}; use lsp_types::{ - Documentation, ParameterInformation, ParameterLabel, SignatureHelp, SignatureHelpParams, - SignatureInformation, Url, + Documentation, ParameterInformation, ParameterInformationLabel, SignatureHelp, + SignatureHelpParams, SignatureInformation, Uri as Url, }; use ty_ide::signature_help; use ty_project::ProjectDatabase; @@ -63,7 +63,8 @@ impl BackgroundDocumentRequestHandler for SignatureHelpRequestHandler { .active_signature .and_then(|s| signature_help_info.signatures.get(s)) .and_then(|sig| sig.active_parameter) - .and_then(|p| u32::try_from(p).ok()); + .and_then(|p| u32::try_from(p).ok()) + .map(ActiveParameter::Int); // Convert from IDE types to LSP types let signatures = signature_help_info @@ -102,12 +103,12 @@ impl BackgroundDocumentRequestHandler for SignatureHelpRequestHandler { let start_u32 = u32::try_from(start_char_offset).unwrap_or(u32::MAX); let end_u32 = u32::try_from(end_char_offset).unwrap_or(u32::MAX); - ParameterLabel::LabelOffsets([start_u32, end_u32]) + ParameterInformationLabel::Tuple((start_u32, end_u32)) } else { - ParameterLabel::Simple(param.label) + ParameterInformationLabel::String(param.label) } } else { - ParameterLabel::Simple(param.label) + ParameterInformationLabel::String(param.label) }; ParameterInformation { @@ -119,7 +120,9 @@ impl BackgroundDocumentRequestHandler for SignatureHelpRequestHandler { let active_parameter = if resolved_capabilities.supports_signature_active_parameter() { - sig.active_parameter.and_then(|p| u32::try_from(p).ok()) + sig.active_parameter + .and_then(|p| u32::try_from(p).ok()) + .map(ActiveParameter::Int) } else { None }; diff --git a/crates/ty_server/src/server/api/requests/type_hierarchy_subtypes.rs b/crates/ty_server/src/server/api/requests/type_hierarchy_subtypes.rs index 9411a0350bcc9..6c1accf899ffa 100644 --- a/crates/ty_server/src/server/api/requests/type_hierarchy_subtypes.rs +++ b/crates/ty_server/src/server/api/requests/type_hierarchy_subtypes.rs @@ -1,4 +1,4 @@ -use lsp_types::request::TypeHierarchySubtypes; +use lsp_types::TypeHierarchySubtypesRequest; use lsp_types::{TypeHierarchyItem, TypeHierarchySubtypesParams}; use crate::server::api::traits::{ @@ -16,7 +16,7 @@ use crate::session::client::Client; pub(crate) struct TypeHierarchySubtypesRequestHandler; impl RequestHandler for TypeHierarchySubtypesRequestHandler { - type RequestType = TypeHierarchySubtypes; + type RequestType = TypeHierarchySubtypesRequest; } impl BackgroundRequestHandler for TypeHierarchySubtypesRequestHandler { diff --git a/crates/ty_server/src/server/api/requests/type_hierarchy_supertypes.rs b/crates/ty_server/src/server/api/requests/type_hierarchy_supertypes.rs index 663a3649172ec..5a15bb791f2da 100644 --- a/crates/ty_server/src/server/api/requests/type_hierarchy_supertypes.rs +++ b/crates/ty_server/src/server/api/requests/type_hierarchy_supertypes.rs @@ -1,4 +1,4 @@ -use lsp_types::request::TypeHierarchySupertypes; +use lsp_types::TypeHierarchySupertypesRequest; use lsp_types::{TypeHierarchyItem, TypeHierarchySupertypesParams}; use crate::server::api::traits::{ @@ -16,7 +16,7 @@ use crate::session::client::Client; pub(crate) struct TypeHierarchySupertypesRequestHandler; impl RequestHandler for TypeHierarchySupertypesRequestHandler { - type RequestType = TypeHierarchySupertypes; + type RequestType = TypeHierarchySupertypesRequest; } impl BackgroundRequestHandler for TypeHierarchySupertypesRequestHandler { diff --git a/crates/ty_server/src/server/api/requests/workspace_diagnostic.rs b/crates/ty_server/src/server/api/requests/workspace_diagnostic.rs index 9941aa90bbdf3..6aaec640185ed 100644 --- a/crates/ty_server/src/server/api/requests/workspace_diagnostic.rs +++ b/crates/ty_server/src/server/api/requests/workspace_diagnostic.rs @@ -3,13 +3,13 @@ use std::sync::Mutex; use std::time::{Duration, Instant}; use lsp_server::RequestId; -use lsp_types::request::WorkspaceDiagnosticRequest; +use lsp_types::WorkspaceDiagnosticRequest; use lsp_types::{ - FullDocumentDiagnosticReport, PreviousResultId, ProgressToken, - UnchangedDocumentDiagnosticReport, Url, WorkspaceDiagnosticParams, WorkspaceDiagnosticReport, - WorkspaceDiagnosticReportPartialResult, WorkspaceDiagnosticReportResult, + FullDocumentDiagnosticReport, PreviousResultId, ProgressNotification, ProgressParams, + ProgressToken, UnchangedDocumentDiagnosticReport, Uri as Url, WorkspaceDiagnosticParams, + WorkspaceDiagnosticReport, WorkspaceDiagnosticReportPartialResult, WorkspaceDocumentDiagnosticReport, WorkspaceFullDocumentDiagnosticReport, - WorkspaceUnchangedDocumentDiagnosticReport, notification::Notification, + WorkspaceUnchangedDocumentDiagnosticReport, }; use ruff_db::diagnostic::Diagnostic; use ruff_db::files::File; @@ -110,12 +110,10 @@ impl BackgroundRequestHandler for WorkspaceDiagnosticRequestHandler { snapshot: &SessionSnapshot, client: &Client, params: WorkspaceDiagnosticParams, - ) -> Result { + ) -> Result { if !snapshot.global_settings().diagnostic_mode().is_workspace() { tracing::debug!("Workspace diagnostics is disabled; returning empty report"); - return Ok(WorkspaceDiagnosticReportResult::Report( - WorkspaceDiagnosticReport { items: vec![] }, - )); + return Ok(WorkspaceDiagnosticReport { items: vec![] }); } let writer = ResponseWriter::new( @@ -161,11 +159,15 @@ impl BackgroundRequestHandler for WorkspaceDiagnosticRequestHandler { // case we shouldn't do any long polling because some diagnostics changed). // * If this is a full report, then check if all items are unchanged (or empty), the same as for // the non-streaming case. - if let Ok(WorkspaceDiagnosticReportResult::Report(full)) = &result { - let all_unchanged = full - .items - .iter() - .all(|item| matches!(item, WorkspaceDocumentDiagnosticReport::Unchanged(_))); + if let Ok(WorkspaceDiagnosticReport { items }) = &result { + let all_unchanged = items.iter().all(|item| { + matches!( + item, + WorkspaceDocumentDiagnosticReport::WorkspaceUnchangedDocumentDiagnosticReport( + _ + ) + ) + }); if all_unchanged { tracing::debug!( @@ -224,7 +226,7 @@ impl<'a> WorkspaceDiagnosticsProgressReporter<'a> { } } - fn into_final_report(self) -> WorkspaceDiagnosticReportResult { + fn into_final_report(self) -> WorkspaceDiagnosticReport { let state = self.state.into_inner().unwrap(); state.response.into_final_report() } @@ -394,7 +396,7 @@ impl<'a> ResponseWriter<'a> { let version = self .index .document_handle(&url) - .map(|doc| i64::from(doc.version())) + .map(|doc| doc.version()) .ok(); let result_id = Diagnostics::result_id_from_hash(diagnostics, unnecessary_hints); @@ -403,7 +405,7 @@ impl<'a> ResponseWriter<'a> { let report = match result_id { Some(new_id) if Some(&new_id) == previous_result_id.as_ref() => { - WorkspaceDocumentDiagnosticReport::Unchanged( + WorkspaceDocumentDiagnosticReport::WorkspaceUnchangedDocumentDiagnosticReport( WorkspaceUnchangedDocumentDiagnosticReport { uri: url, version, @@ -436,14 +438,16 @@ impl<'a> ResponseWriter<'a> { unnecessary_hints, )); - WorkspaceDocumentDiagnosticReport::Full(WorkspaceFullDocumentDiagnosticReport { - uri: url, - version, - full_document_diagnostic_report: FullDocumentDiagnosticReport { - result_id: new_id, - items: lsp_diagnostics, + WorkspaceDocumentDiagnosticReport::WorkspaceFullDocumentDiagnosticReport( + WorkspaceFullDocumentDiagnosticReport { + uri: url, + version, + full_document_diagnostic_report: FullDocumentDiagnosticReport { + result_id: new_id, + items: lsp_diagnostics, + }, }, - }) + ) } }; @@ -475,7 +479,7 @@ impl<'a> ResponseWriter<'a> { /// /// The result can be a partial or full report depending on whether the server's streaming /// diagnostics and if it already sent some diagnostics. - fn into_final_report(mut self) -> WorkspaceDiagnosticReportResult { + fn into_final_report(mut self) -> WorkspaceDiagnosticReport { let mut items = Vec::new(); // Handle files that had diagnostics in previous request but no longer have any @@ -486,30 +490,31 @@ impl<'a> ResponseWriter<'a> { .index .document(&key) .ok() - .map(|doc| i64::from(doc.version())); + .map(crate::session::index::Document::version); let new_result_id = Diagnostics::result_id_from_hash(&[], &[]); let report = match new_result_id { Some(new_id) if new_id == previous_result_id => { - WorkspaceDocumentDiagnosticReport::Unchanged( - WorkspaceUnchangedDocumentDiagnosticReport { - uri: previous_url, - version, - unchanged_document_diagnostic_report: - UnchangedDocumentDiagnosticReport { result_id: new_id }, + WorkspaceUnchangedDocumentDiagnosticReport { + uri: previous_url, + version, + unchanged_document_diagnostic_report: UnchangedDocumentDiagnosticReport { + result_id: new_id, }, - ) + } + .into() } new_id => { - WorkspaceDocumentDiagnosticReport::Full(WorkspaceFullDocumentDiagnosticReport { + WorkspaceFullDocumentDiagnosticReport { uri: previous_url, version, full_document_diagnostic_report: FullDocumentDiagnosticReport { result_id: new_id, items: vec![], // No diagnostics }, - }) + } + .into() } }; @@ -519,15 +524,13 @@ impl<'a> ResponseWriter<'a> { match &mut self.mode { ReportingMode::Streaming(streaming) => { items.extend( - std::mem::take(&mut streaming.changed) - .into_iter() - .map(WorkspaceDocumentDiagnosticReport::Full), - ); - items.extend( - std::mem::take(&mut streaming.unchanged) - .into_iter() - .map(WorkspaceDocumentDiagnosticReport::Unchanged), + std::mem::take(&mut streaming.changed).into_iter().map( + WorkspaceDocumentDiagnosticReport::WorkspaceFullDocumentDiagnosticReport, + ), ); + items.extend(std::mem::take(&mut streaming.unchanged).into_iter().map( + WorkspaceDocumentDiagnosticReport::WorkspaceUnchangedDocumentDiagnosticReport, + )); } ReportingMode::Bulk(all) => { all.extend(items); @@ -554,12 +557,15 @@ impl ReportingMode { fn create_result( &mut self, items: Vec, - ) -> WorkspaceDiagnosticReportResult { + ) -> WorkspaceDiagnosticReport { match self { - ReportingMode::Streaming(streaming) => streaming.create_result(items), - ReportingMode::Bulk(..) => { - WorkspaceDiagnosticReportResult::Report(WorkspaceDiagnosticReport { items }) - } + ReportingMode::Streaming(streaming) => match streaming.create_result(items) { + WorkspaceReportResult::Report(report) => report, + WorkspaceReportResult::PartialReport(WorkspaceDiagnosticReportPartialResult { + items, + }) => WorkspaceDiagnosticReport { items }, + }, + ReportingMode::Bulk(..) => WorkspaceDiagnosticReport { items }, } } } @@ -583,13 +589,22 @@ struct Streaming { unchanged: Vec, } +#[derive(Deserialize, Clone, Debug, PartialEq, Eq, Serialize)] +#[serde(untagged)] +enum WorkspaceReportResult { + Report(WorkspaceDiagnosticReport), + PartialReport(WorkspaceDiagnosticReportPartialResult), +} + impl Streaming { fn write_report(&mut self, report: WorkspaceDocumentDiagnosticReport) { match report { - WorkspaceDocumentDiagnosticReport::Full(full) => { + WorkspaceDocumentDiagnosticReport::WorkspaceFullDocumentDiagnosticReport(full) => { self.changed.push(full); } - WorkspaceDocumentDiagnosticReport::Unchanged(unchanged) => { + WorkspaceDocumentDiagnosticReport::WorkspaceUnchangedDocumentDiagnosticReport( + unchanged, + ) => { self.unchanged.push(unchanged); } } @@ -613,14 +628,14 @@ impl Streaming { let items = self .changed .drain(..) - .map(WorkspaceDocumentDiagnosticReport::Full) + .map(WorkspaceDocumentDiagnosticReport::WorkspaceFullDocumentDiagnosticReport) .collect(); let report = self.create_result(items); self.client - .send_notification::(PartialWorkspaceProgressParams { + .send_notification::(ProgressParams { token: self.token.clone(), - value: report, + value: serde_json::to_value(report).expect("Report should be serializable"), }); self.last_flush = Instant::now(); } @@ -628,33 +643,15 @@ impl Streaming { fn create_result( &mut self, items: Vec, - ) -> WorkspaceDiagnosticReportResult { + ) -> WorkspaceReportResult { // As per the LSP spec: // > partial result: The first literal send need to be a WorkspaceDiagnosticReport followed // > by `n` WorkspaceDiagnosticReportPartialResult literals defined as follows: if self.first { self.first = false; - WorkspaceDiagnosticReportResult::Report(WorkspaceDiagnosticReport { items }) + WorkspaceReportResult::Report(WorkspaceDiagnosticReport { items }) } else { - WorkspaceDiagnosticReportResult::Partial(WorkspaceDiagnosticReportPartialResult { - items, - }) + WorkspaceReportResult::PartialReport(WorkspaceDiagnosticReportPartialResult { items }) } } } - -/// The `$/progress` notification for partial workspace diagnostics. -/// -/// This type is missing in `lsp_types`. That's why we define it here. -pub struct PartialWorkspaceProgress; - -impl Notification for PartialWorkspaceProgress { - type Params = PartialWorkspaceProgressParams; - const METHOD: &'static str = "$/progress"; -} - -#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] -pub struct PartialWorkspaceProgressParams { - pub token: ProgressToken, - pub value: WorkspaceDiagnosticReportResult, -} diff --git a/crates/ty_server/src/server/api/requests/workspace_symbols.rs b/crates/ty_server/src/server/api/requests/workspace_symbols.rs index 252857e7e445c..0bbb04cbe91dd 100644 --- a/crates/ty_server/src/server/api/requests/workspace_symbols.rs +++ b/crates/ty_server/src/server/api/requests/workspace_symbols.rs @@ -1,4 +1,4 @@ -use lsp_types::request::WorkspaceSymbolRequest; +use lsp_types::WorkspaceSymbolRequest; use lsp_types::{WorkspaceSymbolParams, WorkspaceSymbolResponse}; use ty_ide::{WorkspaceSymbolInfo, workspace_symbols}; @@ -58,7 +58,7 @@ impl BackgroundRequestHandler for WorkspaceSymbolRequestHandler { if all_symbols.is_empty() { Ok(None) } else { - Ok(Some(WorkspaceSymbolResponse::Flat(all_symbols))) + Ok(Some(all_symbols.into())) } } } diff --git a/crates/ty_server/src/server/api/symbols.rs b/crates/ty_server/src/server/api/symbols.rs index 78563400eae1f..b2cc45592a248 100644 --- a/crates/ty_server/src/server/api/symbols.rs +++ b/crates/ty_server/src/server/api/symbols.rs @@ -1,7 +1,7 @@ //! Utility functions common to language server request handlers //! that return symbol information. -use lsp_types::{SymbolInformation, SymbolKind}; +use lsp_types::{BaseSymbolInformation, SymbolInformation, SymbolKind}; use ty_ide::SymbolInfo; use crate::Db; @@ -10,18 +10,18 @@ use crate::document::{PositionEncoding, ToRangeExt}; /// Convert `ty_ide` `SymbolKind` to LSP `SymbolKind` pub(crate) fn convert_symbol_kind(kind: ty_ide::SymbolKind) -> SymbolKind { match kind { - ty_ide::SymbolKind::Module => SymbolKind::MODULE, - ty_ide::SymbolKind::Class => SymbolKind::CLASS, - ty_ide::SymbolKind::Method => SymbolKind::METHOD, - ty_ide::SymbolKind::Function => SymbolKind::FUNCTION, - ty_ide::SymbolKind::Variable => SymbolKind::VARIABLE, - ty_ide::SymbolKind::Constant => SymbolKind::CONSTANT, - ty_ide::SymbolKind::Property => SymbolKind::PROPERTY, - ty_ide::SymbolKind::Field => SymbolKind::FIELD, - ty_ide::SymbolKind::Constructor => SymbolKind::CONSTRUCTOR, - ty_ide::SymbolKind::Parameter => SymbolKind::VARIABLE, - ty_ide::SymbolKind::TypeParameter => SymbolKind::TYPE_PARAMETER, - ty_ide::SymbolKind::Import => SymbolKind::MODULE, + ty_ide::SymbolKind::Module => SymbolKind::Module, + ty_ide::SymbolKind::Class => SymbolKind::Class, + ty_ide::SymbolKind::Method => SymbolKind::Method, + ty_ide::SymbolKind::Function => SymbolKind::Function, + ty_ide::SymbolKind::Variable => SymbolKind::Variable, + ty_ide::SymbolKind::Constant => SymbolKind::Constant, + ty_ide::SymbolKind::Property => SymbolKind::Property, + ty_ide::SymbolKind::Field => SymbolKind::Field, + ty_ide::SymbolKind::Constructor => SymbolKind::Constructor, + ty_ide::SymbolKind::Parameter => SymbolKind::Variable, + ty_ide::SymbolKind::TypeParameter => SymbolKind::TypeParameter, + ty_ide::SymbolKind::Import => SymbolKind::Module, } } @@ -41,12 +41,14 @@ pub(crate) fn convert_to_lsp_symbol_information( .to_lsp_range(db, file, encoding)? .to_location()?; Some(SymbolInformation { - name: symbol.name.into_owned(), - kind: symbol_kind, - tags: None, + base_symbol_information: BaseSymbolInformation { + name: symbol.name.into_owned(), + kind: symbol_kind, + tags: None, + container_name: None, + }, #[allow(deprecated)] deprecated: None, location, - container_name: None, }) } diff --git a/crates/ty_server/src/server/api/traits.rs b/crates/ty_server/src/server/api/traits.rs index 59d3289e4b4a1..7f5bdbc1877b1 100644 --- a/crates/ty_server/src/server/api/traits.rs +++ b/crates/ty_server/src/server/api/traits.rs @@ -38,15 +38,13 @@ use crate::session::{DocumentSnapshot, Session, SessionSnapshot}; use lsp_server::RequestId; use std::borrow::Cow; -use lsp_types::Url; -use lsp_types::notification::Notification; -use lsp_types::request::Request; +use lsp_types::{LspNotificationMethod, LspRequestMethod, Notification, Request, Uri as Url}; use ty_project::ProjectDatabase; /// A supertrait for any server request handler. pub(super) trait RequestHandler { type RequestType: Request; - const METHOD: &'static str = <::RequestType>::METHOD; + const METHOD: LspRequestMethod = <::RequestType>::METHOD; } /// A request handler that needs mutable access to the session. @@ -169,7 +167,7 @@ pub(super) trait BackgroundRequestHandler: RetriableRequestHandler { /// A supertrait for any server notification handler. pub(super) trait NotificationHandler { type NotificationType: Notification; - const METHOD: &'static str = <::NotificationType>::METHOD; + const METHOD: LspNotificationMethod = <::NotificationType>::METHOD; } /// A notification handler that needs mutable access to the session. diff --git a/crates/ty_server/src/server/api/type_hierarchy.rs b/crates/ty_server/src/server/api/type_hierarchy.rs index 982eecba887b8..724155877408f 100644 --- a/crates/ty_server/src/server/api/type_hierarchy.rs +++ b/crates/ty_server/src/server/api/type_hierarchy.rs @@ -92,7 +92,7 @@ pub(crate) fn convert_to_lsp_item( Some(TypeHierarchyItem { name: item.name.into(), - kind: SymbolKind::CLASS, + kind: SymbolKind::Class, tags: None, detail: item.detail, uri, diff --git a/crates/ty_server/src/server/lazy_work_done_progress.rs b/crates/ty_server/src/server/lazy_work_done_progress.rs index 567ef6cb4af44..87d0c19d2e408 100644 --- a/crates/ty_server/src/server/lazy_work_done_progress.rs +++ b/crates/ty_server/src/server/lazy_work_done_progress.rs @@ -1,9 +1,8 @@ use crate::capabilities::ResolvedClientCapabilities; use crate::session::client::Client; -use lsp_types::request::WorkDoneProgressCreate; use lsp_types::{ - ProgressParams, ProgressParamsValue, ProgressToken, WorkDoneProgress, WorkDoneProgressBegin, - WorkDoneProgressCreateParams, WorkDoneProgressEnd, WorkDoneProgressReport, + ProgressParams, ProgressToken, WorkDoneProgressBegin, WorkDoneProgressCreateParams, + WorkDoneProgressCreateRequest, WorkDoneProgressEnd, WorkDoneProgressReport, }; use std::fmt::Display; use std::sync::Arc; @@ -83,7 +82,7 @@ impl LazyWorkDoneProgress { let work_done = work_done.clone(); let title = title.to_string(); - client.send_deferred_request::( + client.send_deferred_request::( WorkDoneProgressCreateParams { token: token.clone(), }, @@ -106,14 +105,15 @@ impl LazyWorkDoneProgress { } fn send_begin(client: &Client, token: ProgressToken, title: String) { - client.send_notification::(ProgressParams { + client.send_notification::(ProgressParams { token, - value: ProgressParamsValue::WorkDone(WorkDoneProgress::Begin(WorkDoneProgressBegin { + value: serde_json::to_value(WorkDoneProgressBegin { title, cancellable: Some(false), message: None, percentage: Some(0), - })), + }) + .expect("Failed to serialize work done progress begin"), }); } @@ -125,15 +125,14 @@ impl LazyWorkDoneProgress { self.inner .client - .send_notification::(ProgressParams { + .send_notification::(ProgressParams { token: token.clone(), - value: ProgressParamsValue::WorkDone(WorkDoneProgress::Report( - WorkDoneProgressReport { - cancellable: Some(false), - message: Some(message.to_string()), - percentage, - }, - )), + value: serde_json::to_value(WorkDoneProgressReport { + cancellable: Some(false), + message: Some(message.to_string()), + percentage, + }) + .expect("Failed to serialize work done progress report"), }); } } @@ -157,11 +156,12 @@ impl Drop for Inner { .and_then(|mut message| message.take()); self.client - .send_notification::(ProgressParams { + .send_notification::(ProgressParams { token: token.clone(), - value: ProgressParamsValue::WorkDone(WorkDoneProgress::End(WorkDoneProgressEnd { + value: serde_json::to_value(WorkDoneProgressEnd { message: finish_message, - })), + }) + .expect("Failed to serialize work done progress end"), }); } } diff --git a/crates/ty_server/src/server/main_loop.rs b/crates/ty_server/src/server/main_loop.rs index d69ec66292ef4..cd40afd73d740 100644 --- a/crates/ty_server/src/server/main_loop.rs +++ b/crates/ty_server/src/server/main_loop.rs @@ -5,8 +5,8 @@ use crate::session::{ClientOptions, SuspendedWorkspaceDiagnosticRequest}; use anyhow::anyhow; use crossbeam::select; use lsp_server::Message; -use lsp_types::Url; -use lsp_types::notification::Notification; +use lsp_types::Notification; +use lsp_types::Uri as Url; pub(crate) type ConnectionSender = crossbeam::channel::Sender; pub(crate) type MainLoopSender = crossbeam::channel::Sender; @@ -63,7 +63,7 @@ impl Server { api::request(req) } Message::Notification(notification) => { - if notification.method == lsp_types::notification::Exit::METHOD { + if notification.method == lsp_types::ExitNotification::METHOD.as_str() { if !self.session.is_shutdown_requested() { return Err(anyhow!( "Received exit notification before a shutdown request" diff --git a/crates/ty_server/src/session.rs b/crates/ty_server/src/session.rs index b34db878d6a8d..5a91d7bf44f32 100644 --- a/crates/ty_server/src/session.rs +++ b/crates/ty_server/src/session.rs @@ -7,15 +7,15 @@ use std::sync::Arc; use anyhow::{Context, anyhow}; use lsp_server::{Message, RequestId}; -use lsp_types::notification::{DidChangeWatchedFiles, Exit, Notification}; -use lsp_types::request::{ - DocumentDiagnosticRequest, RegisterCapability, Request, Shutdown, UnregisterCapability, - WorkspaceDiagnosticRequest, -}; use lsp_types::{ - ClientInfo, DiagnosticRegistrationOptions, DiagnosticServerCapabilities, + ClientInfo, DiagnosticProvider, DiagnosticRegistrationOptions, DidChangeWatchedFilesRegistrationOptions, FileSystemWatcher, Registration, RegistrationParams, - TextDocumentContentChangeEvent, Unregistration, UnregistrationParams, Url, + TextDocumentContentChangeEvent, Unregistration, UnregistrationParams, Uri as Url, +}; +use lsp_types::{DidChangeWatchedFilesNotification, ExitNotification, Notification}; +use lsp_types::{ + DocumentDiagnosticRequest, RegistrationRequest, Request, ShutdownRequest, + UnregistrationRequest, WorkspaceDiagnosticRequest, }; use ruff_db::Db; use ruff_db::files::{File, system_path_to_file}; @@ -265,7 +265,7 @@ impl Session { } else { match &message { Message::Request(request) => { - if request.method == Shutdown::METHOD { + if request.method == ShutdownRequest::METHOD.as_str() { return Some(message); } tracing::debug!( @@ -278,7 +278,7 @@ impl Session { return Some(message); } Message::Notification(notification) => { - if notification.method == Exit::METHOD { + if notification.method == ExitNotification::METHOD.as_str() { return Some(message); } tracing::debug!( @@ -739,7 +739,7 @@ impl Session { .collect(); tracing::debug!("Requesting workspace configuration for workspaces"); - client.send_request::( + client.send_request::( self, lsp_types::ConfigurationParams { items }, move |client, result: Vec| { @@ -871,7 +871,7 @@ impl Session { if self.global_settings().diagnostic_mode().is_off() { return; } - client.send_notification::( + client.send_notification::( lsp_types::PublishDiagnosticsParams { uri: uri.clone(), diagnostics: vec![], @@ -912,7 +912,7 @@ impl Session { { if self .registrations - .contains(DocumentDiagnosticRequest::METHOD) + .contains(DocumentDiagnosticRequest::METHOD.as_str()) { unregistrations.push(Unregistration { id: DIAGNOSTIC_REGISTRATION_ID.into(), @@ -937,7 +937,7 @@ impl Session { method: DocumentDiagnosticRequest::METHOD.into(), register_options: Some( serde_json::to_value( - DiagnosticServerCapabilities::RegistrationOptions( + DiagnosticProvider::DiagnosticRegistrationOptions( DiagnosticRegistrationOptions { diagnostic_options: server_diagnostic_options( diagnostic_mode.is_workspace(), @@ -954,15 +954,18 @@ impl Session { } if let Some(register_options) = self.file_watcher_registration_options() { - if self.registrations.contains(DidChangeWatchedFiles::METHOD) { + if self + .registrations + .contains(DidChangeWatchedFilesNotification::METHOD.as_str()) + { unregistrations.push(Unregistration { id: FILE_WATCHER_REGISTRATION_ID.into(), - method: DidChangeWatchedFiles::METHOD.into(), + method: DidChangeWatchedFilesNotification::METHOD.into(), }); } registrations.push(Registration { id: FILE_WATCHER_REGISTRATION_ID.into(), - method: DidChangeWatchedFiles::METHOD.into(), + method: DidChangeWatchedFilesNotification::METHOD.into(), register_options: Some(serde_json::to_value(register_options).unwrap()), }); } @@ -982,7 +985,7 @@ impl Session { self.registrations.insert(registration.method.clone()); } - client.send_request::( + client.send_request::( self, RegistrationParams { registrations }, |_: &Client, ()| { @@ -1010,7 +1013,7 @@ impl Session { } } - client.send_request::( + client.send_request::( self, UnregistrationParams { unregisterations: unregistrations, @@ -1031,21 +1034,26 @@ impl Session { ) -> Option { fn make_watcher(glob: &str) -> FileSystemWatcher { FileSystemWatcher { - glob_pattern: lsp_types::GlobPattern::String(glob.into()), - kind: Some(lsp_types::WatchKind::all()), + glob_pattern: lsp_types::GlobPattern::Pattern(glob.into()), + kind: None, } } fn make_relative_watcher(relative_to: &SystemPath, glob: &str) -> FileSystemWatcher { let base_uri = Url::from_file_path(relative_to.as_std_path()) .expect("system path must be a valid URI"); - let glob_pattern = lsp_types::GlobPattern::Relative(lsp_types::RelativePattern { - base_uri: lsp_types::OneOf::Right(base_uri), - pattern: glob.to_string(), - }); + let glob_pattern = + lsp_types::GlobPattern::RelativePattern(lsp_types::RelativePattern { + base_uri: base_uri.into(), + pattern: glob.to_string(), + }); FileSystemWatcher { glob_pattern, - kind: Some(lsp_types::WatchKind::all()), + kind: Some( + lsp_types::WatchKind::Change + | lsp_types::WatchKind::Delete + | lsp_types::WatchKind::Create, + ), } } @@ -1162,7 +1170,7 @@ impl Session { /// If the document is not found. pub(crate) fn document_handle( &self, - url: &lsp_types::Url, + url: &lsp_types::Uri, ) -> Result { self.index().document_handle(url) } @@ -1380,7 +1388,7 @@ impl DocumentSnapshot { &self.document } - pub(crate) fn url(&self) -> &lsp_types::Url { + pub(crate) fn url(&self) -> &lsp_types::Uri { self.document.url() } @@ -1669,17 +1677,17 @@ impl SuspendedWorkspaceDiagnosticRequest { #[derive(Clone, Debug)] pub(crate) enum DocumentHandle { Text { - url: lsp_types::Url, + url: lsp_types::Uri, path: AnySystemPath, version: DocumentVersion, }, Notebook { - url: lsp_types::Url, + url: lsp_types::Uri, path: AnySystemPath, version: DocumentVersion, }, Cell { - url: lsp_types::Url, + url: lsp_types::Uri, version: DocumentVersion, notebook_path: AnySystemPath, }, @@ -1729,7 +1737,7 @@ impl DocumentHandle { } /// The URL as used by the client to reference this document. - pub(crate) fn url(&self) -> &lsp_types::Url { + pub(crate) fn url(&self) -> &lsp_types::Uri { match self { Self::Text { url, .. } | Self::Notebook { url, .. } | Self::Cell { url, .. } => url, } @@ -1819,8 +1827,8 @@ impl DocumentHandle { pub(crate) fn update_notebook_document( &mut self, session: &mut Session, - cells: Option, - metadata: Option, + cells: Option, + metadata: Option, new_version: DocumentVersion, ) -> crate::Result<()> { let position_encoding = session.position_encoding(); diff --git a/crates/ty_server/src/session/client.rs b/crates/ty_server/src/session/client.rs index 5ab82c7b211fd..531a1cd0a5231 100644 --- a/crates/ty_server/src/session/client.rs +++ b/crates/ty_server/src/session/client.rs @@ -40,7 +40,7 @@ impl Client { params: R::Params, response_handler: impl FnOnce(&Client, R::Result) + Send + 'static, ) where - R: lsp_types::request::Request, + R: lsp_types::Request, { self.send_request_raw( session, @@ -64,7 +64,7 @@ impl Client { params: R::Params, response_handler: impl FnOnce(&Client, R::Result) + Send + 'static, ) where - R: lsp_types::request::Request, + R: lsp_types::Request, { self.main_loop_sender .send(Event::Action(Action::SendRequest(SendRequest { @@ -99,7 +99,7 @@ impl Client { /// Sends a notification to the client. pub(crate) fn send_notification(&self, params: N::Params) where - N: lsp_types::notification::Notification, + N: lsp_types::Notification, { if let Err(err) = self.client_sender @@ -172,9 +172,9 @@ impl Client { /// /// This opens a pop up in VS Code showing `message`. pub(crate) fn show_message(&self, message: impl Display, message_type: lsp_types::MessageType) { - self.send_notification::( + self.send_notification::( lsp_types::ShowMessageParams { - typ: message_type, + kind: message_type, message: message.to_string(), }, ); @@ -185,7 +185,7 @@ impl Client { /// /// Logs an error if the message could not be sent. pub(crate) fn show_warning_message(&self, message: impl Display) { - self.show_message(message, lsp_types::MessageType::WARNING); + self.show_message(message, lsp_types::MessageType::Warning); } /// Sends a request to display an error to the client with a formatted message. The error is @@ -193,7 +193,7 @@ impl Client { /// /// Logs an error if the message could not be sent. pub(crate) fn show_error_message(&self, message: impl Display) { - self.show_message(message, lsp_types::MessageType::ERROR); + self.show_message(message, lsp_types::MessageType::Error); } /// Re-queues this request after a salsa cancellation for a retry. @@ -245,12 +245,12 @@ pub(crate) struct ClientResponseHandler(Box(response_handler: impl FnOnce(&Client, R::Result) + Send + 'static) -> Self where - R: lsp_types::request::Request, + R: lsp_types::Request, { Self(Box::new( move |client: &Client, response: lsp_server::Response| { let _span = - tracing::debug_span!("client_response", id=%response.id, method = R::METHOD) + tracing::debug_span!("client_response", id=%response.id, method = R::METHOD.as_str()) .entered(); match (response.error, response.result) { diff --git a/crates/ty_server/src/session/index.rs b/crates/ty_server/src/session/index.rs index 10fc6ddfacc5e..b8f1b3cb8a3eb 100644 --- a/crates/ty_server/src/session/index.rs +++ b/crates/ty_server/src/session/index.rs @@ -1,4 +1,5 @@ use rustc_hash::FxHashMap; +use std::collections::HashMap; use std::sync::Arc; use crate::document::{DocumentKey, LanguageId}; @@ -33,7 +34,7 @@ impl Index { pub(crate) fn document_handle( &self, - url: &lsp_types::Url, + url: &lsp_types::Uri, ) -> Result { let key = DocumentKey::from_url(url); let Some(document) = self.documents.get(&key) else { @@ -54,8 +55,8 @@ impl Index { pub(super) fn update_notebook_document( &mut self, notebook_key: &DocumentKey, - cells: Option, - metadata: Option>, + cells: Option, + metadata: Option>, new_version: DocumentVersion, encoding: PositionEncoding, ) -> crate::Result<()> { @@ -66,7 +67,7 @@ impl Index { let (structure, data, text_content) = cells .map(|cells| { - let lsp_types::NotebookDocumentCellChange { + let lsp_types::NotebookDocumentCellChanges { structure, data, text_content, @@ -114,7 +115,7 @@ impl Index { opened_cell.uri, opened_cell.text, opened_cell.version, - &opened_cell.language_id, + opened_cell.language_id, ) .with_notebook(notebook_path.clone()) .into(), @@ -123,12 +124,12 @@ impl Index { } for updated_cell in text_content.into_iter().flatten() { - let Ok(document_mut) = - self.document_mut(&DocumentKey::from_url(&updated_cell.document.uri)) - else { + let Ok(document_mut) = self.document_mut(&DocumentKey::from_url( + &updated_cell.document.text_document_identifier.uri, + )) else { tracing::warn!( "Could not find document for cell {}", - updated_cell.document.uri + updated_cell.document.text_document_identifier.uri ); continue; }; diff --git a/crates/ty_server/src/session/options.rs b/crates/ty_server/src/session/options.rs index 3ad1780cf8529..0df6f96d02170 100644 --- a/crates/ty_server/src/session/options.rs +++ b/crates/ty_server/src/session/options.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use lsp_types::Url; +use lsp_types::Uri as Url; use ruff_db::system::{System, SystemPath, SystemPathBuf}; use ruff_macros::Combine; use ruff_python_ast::PythonVersion; diff --git a/crates/ty_server/src/system.rs b/crates/ty_server/src/system.rs index 0c157ddf2c932..e0c6568e8879d 100644 --- a/crates/ty_server/src/system.rs +++ b/crates/ty_server/src/system.rs @@ -8,7 +8,7 @@ use std::sync::Arc; use crate::Db; use crate::document::{DocumentKey, LanguageId}; use crate::session::index::{Document, Index}; -use lsp_types::Url; +use lsp_types::Uri as Url; use ruff_db::file_revision::FileRevision; use ruff_db::files::{File, FilePath}; use ruff_db::system::walk_directory::WalkDirectoryBuilder; diff --git a/crates/ty_server/tests/e2e/code_actions.rs b/crates/ty_server/tests/e2e/code_actions.rs index 6914fe4c3c3c3..c3e8910e02333 100644 --- a/crates/ty_server/tests/e2e/code_actions.rs +++ b/crates/ty_server/tests/e2e/code_actions.rs @@ -1,11 +1,11 @@ use crate::{TestServer, TestServerBuilder}; use anyhow::Result; -use lsp_types::{DocumentDiagnosticReportResult, Position, Range, request::CodeActionRequest}; +use lsp_types::{CodeActionRequest, DocumentDiagnosticReport, Position, Range}; use ruff_db::system::SystemPath; fn code_actions_at( server: &TestServer, - diagnostics: DocumentDiagnosticReportResult, + diagnostics: DocumentDiagnosticReport, file: &SystemPath, range: Range, ) -> lsp_types::CodeActionParams { @@ -16,8 +16,8 @@ fn code_actions_at( range, context: lsp_types::CodeActionContext { diagnostics: match diagnostics { - lsp_types::DocumentDiagnosticReportResult::Report( - lsp_types::DocumentDiagnosticReport::Full(report), + lsp_types::DocumentDiagnosticReport::RelatedFullDocumentDiagnosticReport( + report, ) => report.full_document_diagnostic_report.items, _ => panic!("Expected full diagnostic report"), }, diff --git a/crates/ty_server/tests/e2e/commands.rs b/crates/ty_server/tests/e2e/commands.rs index 4f7f4e67afe2d..b6720e3b61435 100644 --- a/crates/ty_server/tests/e2e/commands.rs +++ b/crates/ty_server/tests/e2e/commands.rs @@ -1,5 +1,5 @@ use anyhow::Result; -use lsp_types::{ExecuteCommandParams, WorkDoneProgressParams, request::ExecuteCommand}; +use lsp_types::{ExecuteCommandParams, ExecuteCommandRequest, WorkDoneProgressParams}; use ruff_db::system::SystemPath; use crate::{TestServer, TestServerBuilder}; @@ -12,11 +12,11 @@ fn execute_command( ) -> Option { let params = ExecuteCommandParams { command, - arguments, + arguments: Some(arguments), work_done_progress_params: WorkDoneProgressParams::default(), }; - let id = server.send_request::(params); - server.await_response::(&id) + let id = server.send_request::(params); + server.await_response::(&id) } #[test] diff --git a/crates/ty_server/tests/e2e/configuration.rs b/crates/ty_server/tests/e2e/configuration.rs index 57af9989e648f..c805b4d226791 100644 --- a/crates/ty_server/tests/e2e/configuration.rs +++ b/crates/ty_server/tests/e2e/configuration.rs @@ -90,7 +90,7 @@ unresolved-reference="warn" .wait_until_workspaces_are_initialized(); server.open_text_document(foo, foo_content, 1); - let show_message = server.await_notification::(); + let show_message = server.await_notification::(); let diagnostics = server.document_diagnostic_request(foo, None); assert_json_snapshot!(show_message, @r#" @@ -216,7 +216,6 @@ reveal_type(sys.version_info[:2]) assert_json_snapshot!(diagnostics, @r#" { - "kind": "full", "resultId": "[RESULT_ID]", "items": [ { @@ -235,7 +234,8 @@ reveal_type(sys.version_info[:2]) "source": "ty", "message": "Revealed type: `tuple[Literal[3], Literal[14]]`" } - ] + ], + "kind": "full" } "#); diff --git a/crates/ty_server/tests/e2e/initialize.rs b/crates/ty_server/tests/e2e/initialize.rs index ad95911ce3d1d..8e5600e608f09 100644 --- a/crates/ty_server/tests/e2e/initialize.rs +++ b/crates/ty_server/tests/e2e/initialize.rs @@ -1,6 +1,6 @@ use anyhow::Result; -use lsp_types::notification::ShowMessage; -use lsp_types::{Position, request::RegisterCapability}; +use lsp_types::ShowMessageNotification; +use lsp_types::{Position, RegistrationRequest}; use ruff_db::system::SystemPath; use serde_json::Value; use ty_server::{ClientOptions, DiagnosticMode}; @@ -53,7 +53,7 @@ fn workspace_diagnostic_registration_without_configuration() -> Result<()> { // No need to wait for workspaces to initialize as the client does not support workspace // configuration. - let (_, params) = server.await_request::(); + let (_, params) = server.await_request::(); let [registration] = params.registrations.as_slice() else { panic!( "Expected a single registration, got: {:#?}", @@ -96,7 +96,7 @@ fn open_files_diagnostic_registration_without_configuration() -> Result<()> { // No need to wait for workspaces to initialize as the client does not support workspace // configuration. - let (_, params) = server.await_request::(); + let (_, params) = server.await_request::(); let [registration] = params.registrations.as_slice() else { panic!( "Expected a single registration, got: {:#?}", @@ -135,7 +135,7 @@ fn workspace_diagnostic_registration_via_initialization() -> Result<()> { .build() .wait_until_workspaces_are_initialized(); - let (_, params) = server.await_request::(); + let (_, params) = server.await_request::(); let [registration] = params.registrations.as_slice() else { panic!( "Expected a single registration, got: {:#?}", @@ -174,7 +174,7 @@ fn open_files_diagnostic_registration_via_initialization() -> Result<()> { .build() .wait_until_workspaces_are_initialized(); - let (_, params) = server.await_request::(); + let (_, params) = server.await_request::(); let [registration] = params.registrations.as_slice() else { panic!( "Expected a single registration, got: {:#?}", @@ -213,7 +213,7 @@ fn workspace_diagnostic_registration() -> Result<()> { .build() .wait_until_workspaces_are_initialized(); - let (_, params) = server.await_request::(); + let (_, params) = server.await_request::(); let [registration] = params.registrations.as_slice() else { panic!( "Expected a single registration, got: {:#?}", @@ -252,7 +252,7 @@ fn open_files_diagnostic_registration() -> Result<()> { .build() .wait_until_workspaces_are_initialized(); - let (_, params) = server.await_request::(); + let (_, params) = server.await_request::(); let [registration] = params.registrations.as_slice() else { panic!( "Expected a single registration, got: {:#?}", @@ -395,7 +395,7 @@ fn unknown_initialization_options() -> Result<()> { .build() .wait_until_workspaces_are_initialized(); - let show_message_params = server.await_notification::(); + let show_message_params = server.await_notification::(); insta::assert_json_snapshot!(show_message_params, @r#" { @@ -420,7 +420,7 @@ fn unknown_options_in_workspace_configuration() -> Result<()> { .build() .wait_until_workspaces_are_initialized(); - let show_message_params = server.await_notification::(); + let show_message_params = server.await_notification::(); insta::assert_json_snapshot!(show_message_params, @r#" { @@ -451,7 +451,7 @@ fn register_multiple_capabilities() -> Result<()> { .build() .wait_until_workspaces_are_initialized(); - let (_, params) = server.await_request::(); + let (_, params) = server.await_request::(); let registrations = params.registrations; insta::assert_json_snapshot!(registrations, @r#" @@ -487,7 +487,7 @@ fn missing_virtual_env_does_not_panic() -> Result<()> { .build() .wait_until_workspaces_are_initialized(); - let show_message_params = server.await_notification::(); + let show_message_params = server.await_notification::(); insta::assert_snapshot!(show_message_params.message, @"Failed to load project for workspace file:///project. Please refer to the logs for more details."); diff --git a/crates/ty_server/tests/e2e/inlay_hints.rs b/crates/ty_server/tests/e2e/inlay_hints.rs index ec1af0d3d8044..5daf077fc7390 100644 --- a/crates/ty_server/tests/e2e/inlay_hints.rs +++ b/crates/ty_server/tests/e2e/inlay_hints.rs @@ -1,9 +1,10 @@ use anyhow::Result; -use lsp_types::notification::DidOpenTextDocument; -use lsp_types::request::InlayHintRequest; +use lsp_types::DidOpenTextDocumentNotification; +use lsp_types::InlayHintRequest; +use lsp_types::LanguageKind; use lsp_types::{ DidOpenTextDocumentParams, InlayHintParams, Position, Range, TextDocumentIdentifier, - TextDocumentItem, Url, WorkDoneProgressParams, + TextDocumentItem, Uri as Url, WorkDoneProgressParams, }; use ruff_db::system::SystemPath; use ty_server::ClientOptions; @@ -183,10 +184,10 @@ fn variable_inlay_hints_disabled_for_virtual_file() -> Result<()> { let file_uri = server.file_uri(file); let virtual_uri = Url::parse(&format!("untitled://{}", file_uri.path())).unwrap(); - server.send_notification::(DidOpenTextDocumentParams { + server.send_notification::(DidOpenTextDocumentParams { text_document: TextDocumentItem { uri: virtual_uri.clone(), - language_id: "python".to_string(), + language_id: LanguageKind::Python, version: 1, text: content.to_string(), }, diff --git a/crates/ty_server/tests/e2e/main.rs b/crates/ty_server/tests/e2e/main.rs index b43d9cd809cff..c98fa68208a88 100644 --- a/crates/ty_server/tests/e2e/main.rs +++ b/crates/ty_server/tests/e2e/main.rs @@ -54,29 +54,26 @@ use anyhow::{Context, Result, anyhow}; use crossbeam::channel::RecvTimeoutError; use insta::internals::SettingsBindDropGuard; use lsp_server::{Connection, Message, RequestId, Response, ResponseError}; -use lsp_types::notification::{ - DidChangeTextDocument, DidChangeWatchedFiles, DidChangeWorkspaceFolders, DidCloseTextDocument, - DidOpenTextDocument, Exit, Initialized, Notification, -}; -use lsp_types::request::{ - Completion, DocumentDiagnosticRequest, HoverRequest, Initialize, InlayHintRequest, - PrepareRenameRequest, Request, Shutdown, SignatureHelpRequest, WorkspaceConfiguration, - WorkspaceDiagnosticRequest, -}; use lsp_types::{ - ClientCapabilities, CompletionItem, CompletionParams, CompletionResponse, - CompletionTriggerKind, ConfigurationParams, DiagnosticClientCapabilities, - DidChangeTextDocumentParams, DidChangeWatchedFilesClientCapabilities, - DidChangeWatchedFilesParams, DidChangeWorkspaceFoldersParams, DidCloseTextDocumentParams, - DidOpenTextDocumentParams, DocumentDiagnosticParams, DocumentDiagnosticReportResult, FileEvent, - FoldingRange, FoldingRangeParams, Hover, HoverParams, InitializeParams, InitializeResult, - InitializedParams, InlayHint, InlayHintClientCapabilities, InlayHintParams, NumberOrString, - PartialResultParams, Position, PreviousResultId, PublishDiagnosticsClientCapabilities, Range, - SemanticTokensResult, SignatureHelp, SignatureHelpParams, SignatureHelpTriggerKind, + ClientCapabilities, CompletionItem, CompletionParams, CompletionRequest, CompletionResponse, + CompletionTriggerKind, ConfigurationParams, ConfigurationRequest, DiagnosticClientCapabilities, + DidChangeTextDocumentNotification, DidChangeTextDocumentParams, + DidChangeWatchedFilesClientCapabilities, DidChangeWatchedFilesNotification, + DidChangeWatchedFilesParams, DidChangeWorkspaceFoldersNotification, + DidChangeWorkspaceFoldersParams, DidCloseTextDocumentNotification, DidCloseTextDocumentParams, + DidOpenTextDocumentNotification, DidOpenTextDocumentParams, DocumentDiagnosticParams, + DocumentDiagnosticReport, DocumentDiagnosticRequest, ExitNotification, FileEvent, FoldingRange, + FoldingRangeParams, Hover, HoverParams, HoverRequest, InitializeParams, InitializeRequest, + InitializeResult, InitializedNotification, InitializedParams, InlayHint, + InlayHintClientCapabilities, InlayHintParams, InlayHintRequest, LanguageKind, Notification, + PartialResultParams, Position, PrepareRenameRequest, PreviousResultId, + PublishDiagnosticsClientCapabilities, Range, Request, SemanticTokens, ShutdownRequest, + SignatureHelp, SignatureHelpParams, SignatureHelpRequest, SignatureHelpTriggerKind, TextDocumentClientCapabilities, TextDocumentContentChangeEvent, TextDocumentIdentifier, - TextDocumentItem, TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, + TextDocumentItem, TextDocumentPositionParams, Uri as Url, VersionedTextDocumentIdentifier, WorkDoneProgressParams, WorkspaceClientCapabilities, WorkspaceDiagnosticParams, - WorkspaceDiagnosticReportResult, WorkspaceEdit, WorkspaceFolder, WorkspaceFoldersChangeEvent, + WorkspaceDiagnosticReport, WorkspaceDiagnosticRequest, WorkspaceEdit, WorkspaceFolder, + WorkspaceFoldersChangeEvent, WorkspaceFoldersInitializeParams, }; use ruff_db::system::{OsSystem, SystemPath, SystemPathBuf, TestSystem}; use rustc_hash::FxHashMap; @@ -292,7 +289,9 @@ impl TestServer { ) -> Self { let init_params = InitializeParams { capabilities, - workspace_folders: Some(workspace_folders), + workspace_folders_initialize_params: WorkspaceFoldersInitializeParams { + workspace_folders: Some(workspace_folders.into()), + }, initialization_options: initialization_options.map(|options| { serde_json::to_value(options) .context("Failed to serialize initialization options to `ClientOptions`") @@ -301,9 +300,9 @@ impl TestServer { ..Default::default() }; - let init_request_id = self.send_request::(init_params); - self.initialize_response = Some(self.await_response::(&init_request_id)); - self.send_notification::(InitializedParams {}); + let init_request_id = self.send_request::(init_params); + self.initialize_response = Some(self.await_response::(&init_request_id)); + self.send_notification::(InitializedParams {}); self } @@ -316,7 +315,7 @@ impl TestServer { /// This should only be called if the server is expected to send this request. #[track_caller] pub(crate) fn wait_until_workspaces_are_initialized(mut self) -> Self { - let (request_id, params) = self.await_request::(); + let (request_id, params) = self.await_request::(); self.handle_workspace_configuration_request(request_id, ¶ms); self } @@ -395,7 +394,7 @@ impl TestServer { R: Request, { // Track if an Exit notification is being sent - if R::METHOD == lsp_types::request::Shutdown::METHOD { + if R::METHOD == lsp_types::ShutdownRequest::METHOD { self.shutdown_requested = true; } @@ -546,7 +545,7 @@ impl TestServer { let notification = self .notifications .iter() - .position(|notification| N::METHOD == notification.method) + .position(|notification| N::METHOD.as_str() == notification.method) .and_then(|index| self.notifications.remove(index)); if let Some(notification) = notification { let params = serde_json::from_value(notification.params)?; @@ -567,12 +566,12 @@ impl TestServer { pub(crate) fn collect_publish_diagnostic_notifications( &mut self, count: usize, - ) -> BTreeMap> { + ) -> BTreeMap> { let mut results = BTreeMap::default(); for _ in 0..count { let notification = - self.await_notification::(); + self.await_notification::(); if let Some(existing) = results.insert(notification.uri.clone(), notification.diagnostics) @@ -633,7 +632,7 @@ impl TestServer { let request = self .requests .iter() - .position(|request| R::METHOD == request.method) + .position(|request| R::METHOD.as_str() == request.method) .and_then(|index| self.requests.remove(index)); if let Some(request) = request { let params = serde_json::from_value(request.params)?; @@ -714,10 +713,10 @@ impl TestServer { pub(crate) fn cancel(&mut self, request_id: &RequestId) { let id_string = request_id.to_string(); - self.send_notification::(lsp_types::CancelParams { + self.send_notification::(lsp_types::CancelParams { id: match id_string.parse() { - Ok(id) => NumberOrString::Number(id), - Err(_) => NumberOrString::String(id_string), + Ok(id) => lsp_types::Id::Int(id), + Err(_) => lsp_types::Id::String(id_string), }, }); } @@ -813,12 +812,12 @@ impl TestServer { let params = DidOpenTextDocumentParams { text_document: TextDocumentItem { uri: self.file_uri(path), - language_id: "python".to_string(), + language_id: LanguageKind::Python, version, text: content.as_ref().to_string(), }, }; - self.send_notification::(params); + self.send_notification::(params); } /// Send a `textDocument/didChange` notification with the given content changes @@ -830,12 +829,14 @@ impl TestServer { ) { let params = DidChangeTextDocumentParams { text_document: VersionedTextDocumentIdentifier { - uri: self.file_uri(path), + text_document_identifier: TextDocumentIdentifier { + uri: self.file_uri(path), + }, version, }, content_changes: changes, }; - self.send_notification::(params); + self.send_notification::(params); } /// Send a `textDocument/didClose` notification @@ -845,13 +846,13 @@ impl TestServer { uri: self.file_uri(path), }, }; - self.send_notification::(params); + self.send_notification::(params); } /// Send a `workspace/didChangeWatchedFiles` notification with the given file events pub(crate) fn did_change_watched_files(&mut self, events: Vec) { let params = DidChangeWatchedFilesParams { changes: events }; - self.send_notification::(params); + self.send_notification::(params); } /// Send a `workspace/didChangeWorkspaceFolders` notification with the given added/removed @@ -880,7 +881,7 @@ impl TestServer { .collect(), }, }; - self.send_notification::(params); + self.send_notification::(params); } pub(crate) fn rename( @@ -890,11 +891,14 @@ impl TestServer { new_name: &str, ) -> Result, ()> { if self - .send_request_await::(lsp_types::TextDocumentPositionParams { - text_document: TextDocumentIdentifier { - uri: document.clone(), + .send_request_await::(lsp_types::PrepareRenameParams { + text_document_position_params: TextDocumentPositionParams { + text_document: TextDocumentIdentifier { + uri: document.clone(), + }, + position, }, - position, + work_done_progress_params: WorkDoneProgressParams::default(), }) .is_none() { @@ -902,8 +906,8 @@ impl TestServer { } Ok( - self.send_request_await::(lsp_types::RenameParams { - text_document_position: TextDocumentPositionParams { + self.send_request_await::(lsp_types::RenameParams { + text_document_position_params: TextDocumentPositionParams { text_document: TextDocumentIdentifier { uri: document.clone(), }, @@ -920,7 +924,7 @@ impl TestServer { &mut self, path: impl AsRef, previous_result_id: Option, - ) -> DocumentDiagnosticReportResult { + ) -> DocumentDiagnosticReport { let params = DocumentDiagnosticParams { text_document: TextDocumentIdentifier { uri: self.file_uri(path), @@ -937,9 +941,9 @@ impl TestServer { /// Send a `workspace/diagnostic` request with optional previous result IDs. pub(crate) fn workspace_diagnostic_request( &mut self, - work_done_token: Option, + work_done_token: Option, previous_result_ids: Option>, - ) -> WorkspaceDiagnosticReportResult { + ) -> WorkspaceDiagnosticReport { let params = WorkspaceDiagnosticParams { identifier: Some("ty".to_string()), previous_result_ids: previous_result_ids.unwrap_or_default(), @@ -993,21 +997,23 @@ impl TestServer { uri: &Url, position: Position, ) -> Vec { - let completions_id = self.send_request::(CompletionParams { - text_document_position: TextDocumentPositionParams { + let completions_id = self.send_request::(CompletionParams { + text_document_position_params: TextDocumentPositionParams { text_document: TextDocumentIdentifier { uri: uri.clone() }, position, }, work_done_progress_params: lsp_types::WorkDoneProgressParams::default(), partial_result_params: lsp_types::PartialResultParams::default(), context: Some(lsp_types::CompletionContext { - trigger_kind: CompletionTriggerKind::TRIGGER_FOR_INCOMPLETE_COMPLETIONS, + trigger_kind: CompletionTriggerKind::TriggerForIncompleteCompletions, trigger_character: None, }), }); - match self.await_response::(&completions_id) { - Some(CompletionResponse::Array(array)) => array, - Some(CompletionResponse::List(lsp_types::CompletionList { items, .. })) => items, + match self.await_response::(&completions_id) { + Some(CompletionResponse::CompletionItemList(array)) => array, + Some(CompletionResponse::CompletionList(lsp_types::CompletionList { + items, .. + })) => items, None => vec![], } } @@ -1025,7 +1031,7 @@ impl TestServer { }, work_done_progress_params: lsp_types::WorkDoneProgressParams::default(), context: Some(lsp_types::SignatureHelpContext { - trigger_kind: SignatureHelpTriggerKind::INVOKED, + trigger_kind: SignatureHelpTriggerKind::Invoked, trigger_character: None, is_retrigger: false, active_signature_help: None, @@ -1034,11 +1040,8 @@ impl TestServer { self.await_response::(&signature_help_id) } - pub(crate) fn semantic_tokens_full_request( - &mut self, - uri: &Url, - ) -> Option { - self.send_request_await::( + pub(crate) fn semantic_tokens_full_request(&mut self, uri: &Url) -> Option { + self.send_request_await::( lsp_types::SemanticTokensParams { text_document: TextDocumentIdentifier { uri: uri.clone() }, work_done_progress_params: lsp_types::WorkDoneProgressParams::default(), @@ -1048,7 +1051,7 @@ impl TestServer { } pub(crate) fn folding_range_request(&mut self, uri: &Url) -> Option> { - self.send_request_await::(FoldingRangeParams { + self.send_request_await::(FoldingRangeParams { text_document: TextDocumentIdentifier { uri: uri.clone() }, work_done_progress_params: WorkDoneProgressParams::default(), partial_result_params: PartialResultParams::default(), @@ -1104,10 +1107,10 @@ impl Drop for TestServer { // The `server_thread` could be `None` if the server exited unexpectedly or panicked or if // it dropped the client connection. let shutdown_error = if self.server_thread.is_some() && !self.shutdown_requested { - let shutdown_id = self.send_request::(()); - match self.try_await_response::(&shutdown_id, None) { + let shutdown_id = self.send_request::(()); + match self.try_await_response::(&shutdown_id, None) { Ok(()) => { - self.send_notification::(()); + self.send_notification::(()); None } @@ -1318,6 +1321,7 @@ impl TestServerBuilder { .get_or_insert_default() .publish_diagnostics .get_or_insert_default() + .diagnostics_capabilities .related_information = Some(enabled); self } diff --git a/crates/ty_server/tests/e2e/notebook.rs b/crates/ty_server/tests/e2e/notebook.rs index b8899facee72d..03a472c7d76c3 100644 --- a/crates/ty_server/tests/e2e/notebook.rs +++ b/crates/ty_server/tests/e2e/notebook.rs @@ -1,5 +1,7 @@ use insta::assert_json_snapshot; -use lsp_types::{NotebookCellKind, Position, Range}; +use lsp_types::{ + NotebookCellKind, Position, Range, TextDocumentContentChangePartial, TextDocumentIdentifier, +}; use ruff_db::system::SystemPath; use ty_server::ClientOptions; @@ -45,11 +47,11 @@ type Style = Literal["italic", "bold", "underline"]"#, builder.open(&mut server); let cell1_diagnostics = - server.await_notification::(); + server.await_notification::(); let cell2_diagnostics = - server.await_notification::(); + server.await_notification::(); let cell3_diagnostics = - server.await_notification::(); + server.await_notification::(); assert_json_snapshot!([cell1_diagnostics, cell2_diagnostics, cell3_diagnostics]); @@ -144,7 +146,7 @@ IOError"#, server.collect_publish_diagnostic_notifications(3); - server.send_notification::( + server.send_notification::( lsp_types::DidChangeNotebookDocumentParams { notebook_document: lsp_types::VersionedNotebookDocumentIdentifier { version: 0, @@ -152,21 +154,21 @@ IOError"#, }, change: lsp_types::NotebookDocumentChangeEvent { metadata: None, - cells: Some(lsp_types::NotebookDocumentCellChange { + cells: Some(lsp_types::NotebookDocumentCellChanges { structure: None, data: None, - text_content: Some(vec![lsp_types::NotebookDocumentChangeTextContent { + text_content: Some(vec![lsp_types::NotebookDocumentCellContentChanges { document: lsp_types::VersionedTextDocumentIdentifier { - uri: cell_3, + text_document_identifier: TextDocumentIdentifier { uri: cell_3 }, version: 0, }, changes: { - vec![lsp_types::TextDocumentContentChangeEvent { - range: Some(Range::new(Position::new(0, 16), Position::new(0, 17))), - range_length: Some(1), + vec![lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangePartial (TextDocumentContentChangePartial{ + range: Range::new(Position::new(0, 16), Position::new(0, 17)), text: String::new(), - }] + ..Default::default() + })] }, }]), }), @@ -278,7 +280,7 @@ fn swap_cells() -> anyhow::Result<()> { "#); // Re-order the cells from `b`, `a`, `c` to `a`, `b`, `c` (swapping cell 1 and 2) - server.send_notification::( + server.send_notification::( lsp_types::DidChangeNotebookDocumentParams { notebook_document: lsp_types::VersionedNotebookDocumentIdentifier { version: 1, @@ -286,7 +288,7 @@ fn swap_cells() -> anyhow::Result<()> { }, change: lsp_types::NotebookDocumentChangeEvent { metadata: None, - cells: Some(lsp_types::NotebookDocumentCellChange { + cells: Some(lsp_types::NotebookDocumentCellChanges { structure: Some(lsp_types::NotebookDocumentCellChangeStructure { array: lsp_types::NotebookCellArrayChange { start: 0, @@ -523,38 +525,37 @@ fn invalid_syntax_with_syntax_errors_disabled() -> anyhow::Result<()> { fn semantic_tokens_full_for_cell( server: &mut TestServer, - cell_uri: &lsp_types::Url, -) -> Option { - let cell1_tokens_req_id = server.send_request::( - lsp_types::SemanticTokensParams { + cell_uri: &lsp_types::Uri, +) -> Option { + let cell1_tokens_req_id = + server.send_request::(lsp_types::SemanticTokensParams { work_done_progress_params: lsp_types::WorkDoneProgressParams::default(), partial_result_params: lsp_types::PartialResultParams::default(), text_document: lsp_types::TextDocumentIdentifier { uri: cell_uri.clone(), }, - }, - ); + }); - server.await_response::(&cell1_tokens_req_id) + server.await_response::(&cell1_tokens_req_id) } #[derive(Debug)] pub(crate) struct NotebookBuilder { - notebook_url: lsp_types::Url, + notebook_url: lsp_types::Uri, // The cells: (cell_metadata, content, language_id) cells: Vec<(lsp_types::NotebookCell, String, String)>, } impl NotebookBuilder { pub(crate) fn virtual_file(name: &str) -> Self { - let url: lsp_types::Url = format!("vs-code:/{name}").parse().unwrap(); + let url: lsp_types::Uri = format!("vs-code:/{name}").parse().unwrap(); Self { notebook_url: url, cells: Vec::new(), } } - pub(crate) fn add_python_cell(&mut self, content: &str) -> lsp_types::Url { + pub(crate) fn add_python_cell(&mut self, content: &str) -> lsp_types::Uri { let index = self.cells.len(); let id = format!( "vscode-notebook-cell:/{}#{}", @@ -562,7 +563,7 @@ impl NotebookBuilder { index ); - let url: lsp_types::Url = id.parse().unwrap(); + let url: lsp_types::Uri = id.parse().unwrap(); self.cells.push(( lsp_types::NotebookCell { @@ -578,8 +579,8 @@ impl NotebookBuilder { url } - pub(crate) fn open(self, server: &mut TestServer) -> lsp_types::Url { - server.send_notification::( + pub(crate) fn open(self, server: &mut TestServer) -> lsp_types::Uri { + server.send_notification::( lsp_types::DidOpenNotebookDocumentParams { notebook_document: lsp_types::NotebookDocument { uri: self.notebook_url.clone(), @@ -593,7 +594,7 @@ impl NotebookBuilder { .iter() .map(|(cell, content, language_id)| lsp_types::TextDocumentItem { uri: cell.document.clone(), - language_id: language_id.clone(), + language_id: language_id.clone().into(), version: 0, text: content.clone(), }) @@ -607,7 +608,7 @@ impl NotebookBuilder { fn literal_completions( server: &mut TestServer, - cell: &lsp_types::Url, + cell: &lsp_types::Uri, position: Position, ) -> Vec { let mut items = server.completion_request(cell, position); diff --git a/crates/ty_server/tests/e2e/publish_diagnostics.rs b/crates/ty_server/tests/e2e/publish_diagnostics.rs index 8801195c274f6..0bd4245263949 100644 --- a/crates/ty_server/tests/e2e/publish_diagnostics.rs +++ b/crates/ty_server/tests/e2e/publish_diagnostics.rs @@ -2,8 +2,9 @@ use std::time::Duration; use anyhow::Result; use lsp_types::{ - DidOpenTextDocumentParams, FileChangeType, FileEvent, TextDocumentItem, Url, - notification::{DidOpenTextDocument, PublishDiagnostics}, + DidOpenTextDocumentNotification, DidOpenTextDocumentParams, FileChangeType, FileEvent, + LanguageKind, PublishDiagnosticsNotification, TextDocumentContentChangeWholeDocument, + TextDocumentItem, Uri as Url, }; use ruff_db::system::SystemPath; use ty_server::ClientOptions; @@ -27,7 +28,7 @@ def foo() -> str: .wait_until_workspaces_are_initialized(); server.open_text_document(foo, foo_content, 1); - let diagnostics = server.await_notification::(); + let diagnostics = server.await_notification::(); insta::assert_debug_snapshot!(diagnostics); @@ -58,7 +59,7 @@ def foo() -> str: .wait_until_workspaces_are_initialized(); server.open_text_document(foo, foo_content, 1); - let diagnostics = server.await_notification::(); + let diagnostics = server.await_notification::(); insta::assert_debug_snapshot!(diagnostics); Ok(()) @@ -91,7 +92,7 @@ def foo() -> str: .wait_until_workspaces_are_initialized(); server.open_text_document(foo, foo_content, 1); - let diagnostics = server.await_notification::(); + let diagnostics = server.await_notification::(); insta::assert_debug_snapshot!(diagnostics); Ok(()) @@ -130,18 +131,18 @@ def foo() -> str: .build() .wait_until_workspaces_are_initialized(); - server.send_notification::(DidOpenTextDocumentParams { + server.send_notification::(DidOpenTextDocumentParams { text_document: TextDocumentItem { uri: { let uri = server.file_uri(foo); Url::parse(&format!("untitled://{}", uri.path())).unwrap() }, - language_id: "python".to_string(), + language_id: LanguageKind::Python, version: 1, text: foo_content.to_string(), }, }); - let diagnostics = server.await_notification::(); + let diagnostics = server.await_notification::(); insta::assert_debug_snapshot!(diagnostics); Ok(()) @@ -167,8 +168,8 @@ def foo() -> str: .wait_until_workspaces_are_initialized(); server.open_text_document(foo, foo_content, 1); - let diagnostics = - server.try_await_notification::(Some(Duration::from_millis(100))); + let diagnostics = server + .try_await_notification::(Some(Duration::from_millis(100))); assert!( diagnostics.is_err(), @@ -195,17 +196,19 @@ def foo() -> str: .wait_until_workspaces_are_initialized(); server.open_text_document(foo, foo_content, 1); - let _ = server.await_notification::(); + let _ = server.await_notification::(); - let changes = vec![lsp_types::TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: "def foo() -> int: return 42".to_string(), - }]; + let changes = vec![ + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { + text: "def foo() -> int: return 42".to_string(), + }, + ), + ]; server.change_text_document(foo, changes, 2); - let diagnostics = server.await_notification::(); + let diagnostics = server.await_notification::(); assert_eq!(diagnostics.version, Some(2)); @@ -235,16 +238,18 @@ def foo() -> str: server.open_text_document(foo, foo_content, 1); - let changes = vec![lsp_types::TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: "def foo() -> int: return 42".to_string(), - }]; + let changes = vec![ + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { + text: "def foo() -> int: return 42".to_string(), + }, + ), + ]; server.change_text_document(foo, changes, 2); - let diagnostics = - server.try_await_notification::(Some(Duration::from_millis(100))); + let diagnostics = server + .try_await_notification::(Some(Duration::from_millis(100))); assert!( diagnostics.is_err(), @@ -272,7 +277,7 @@ assert_type("test", list[str]) .wait_until_workspaces_are_initialized(); server.open_text_document(foo, foo_content, 1); - let diagnostics = server.await_notification::(); + let diagnostics = server.await_notification::(); insta::assert_debug_snapshot!(diagnostics); @@ -298,7 +303,7 @@ assert_type("test", list[str]) .wait_until_workspaces_are_initialized(); server.open_text_document(foo, foo_content, 1); - let diagnostics = server.await_notification::(); + let diagnostics = server.await_notification::(); insta::assert_debug_snapshot!(diagnostics); @@ -325,16 +330,16 @@ def foo() -> str: server.open_text_document(&foo, "", 1); - let _open_diagnostics = server.await_notification::(); + let _open_diagnostics = server.await_notification::(); std::fs::write(&foo, foo_content)?; server.did_change_watched_files(vec![FileEvent { uri: server.file_uri(foo), - typ: FileChangeType::CHANGED, + kind: FileChangeType::Changed, }]); - let diagnostics = server.await_notification::(); + let diagnostics = server.await_notification::(); // Note how ty reports no diagnostics here. This is because // the contents received by didOpen/didChange take precedence over the file @@ -371,11 +376,11 @@ def foo() -> str: server.did_change_watched_files(vec![FileEvent { uri: server.file_uri(foo), - typ: FileChangeType::CHANGED, + kind: FileChangeType::Changed, }]); - let diagnostics = - server.try_await_notification::(Some(Duration::from_millis(100))); + let diagnostics = server + .try_await_notification::(Some(Duration::from_millis(100))); assert!( diagnostics.is_err(), @@ -401,7 +406,7 @@ def foo() -> str: .wait_until_workspaces_are_initialized(); server.open_text_document(foo, foo_content, 1); - let diagnostics = server.await_notification::(); + let diagnostics = server.await_notification::(); insta::assert_debug_snapshot!(diagnostics); @@ -424,24 +429,24 @@ def foo() -> str: .wait_until_workspaces_are_initialized(); server.open_text_document(foo, foo_content, 1); - let diagnostics = server.await_notification::(); + let diagnostics = server.await_notification::(); insta::assert_debug_snapshot!(diagnostics); server.close_text_document(foo); - let diagnostics = server.await_notification::(); + let diagnostics = server.await_notification::(); insta::assert_debug_snapshot!(diagnostics); let params = DidOpenTextDocumentParams { text_document: TextDocumentItem { uri: server.file_uri(foo), - language_id: "text".to_string(), + language_id: LanguageKind::new("text"), version: 1, text: foo_content.to_string(), }, }; - server.send_notification::(params); - let diagnostics = server.await_notification::(); + server.send_notification::(params); + let diagnostics = server.await_notification::(); insta::assert_debug_snapshot!(diagnostics); @@ -468,7 +473,7 @@ def foo( server.open_text_document(foo, foo_content, 1); - let diagnostics = server.await_notification::(); + let diagnostics = server.await_notification::(); insta::assert_debug_snapshot!(diagnostics); diff --git a/crates/ty_server/tests/e2e/pull_diagnostics.rs b/crates/ty_server/tests/e2e/pull_diagnostics.rs index d7bbf5b058b03..1f4f0c302f0bf 100644 --- a/crates/ty_server/tests/e2e/pull_diagnostics.rs +++ b/crates/ty_server/tests/e2e/pull_diagnostics.rs @@ -3,13 +3,14 @@ use std::time::Duration; use anyhow::Result; use insta::{assert_compact_json_snapshot, assert_debug_snapshot}; use lsp_server::RequestId; -use lsp_types::request::WorkspaceDiagnosticRequest; use lsp_types::{ - NumberOrString, PartialResultParams, PreviousResultId, Url, WorkDoneProgressParams, - WorkspaceDiagnosticParams, WorkspaceDiagnosticReportResult, WorkspaceDocumentDiagnosticReport, + PartialResultParams, PreviousResultId, ProgressNotification, Uri as Url, WorkDoneProgressBegin, + WorkDoneProgressEnd, WorkDoneProgressParams, WorkspaceDiagnosticParams, + WorkspaceDiagnosticReport, WorkspaceDocumentDiagnosticReport, }; +use lsp_types::{TextDocumentContentChangeWholeDocument, WorkspaceDiagnosticRequest}; use ruff_db::system::SystemPath; -use ty_server::{ClientOptions, DiagnosticMode, PartialWorkspaceProgress}; +use ty_server::{ClientOptions, DiagnosticMode}; use crate::workspace_folders::condensed_document_diagnostic_snapshot; use crate::{AwaitResponseError, TestServer, TestServerBuilder}; @@ -273,7 +274,7 @@ def buy_sell_once(prices: list[float]) -> float: server.open_text_document(foo, foo_content, 1); let diagnostics = server.document_diagnostic_request(foo, None); - assert_compact_json_snapshot!(diagnostics, @r#"{"kind": "full", "items": []}"#); + assert_compact_json_snapshot!(diagnostics, @r#"{"items": [], "kind": "full"}"#); Ok(()) } @@ -301,7 +302,7 @@ def foo() -> str: server.open_text_document(foo, foo_content, 1); let diagnostics = server.document_diagnostic_request(foo, None); - assert_compact_json_snapshot!(diagnostics, @r#"{"kind": "full", "items": []}"#); + assert_compact_json_snapshot!(diagnostics, @r#"{"items": [], "kind": "full"}"#); Ok(()) } @@ -335,11 +336,11 @@ def foo( { "items": [ { - "kind": "full", "uri": "file:///src/foo.py", "version": null, "resultId": "[RESULT_ID]", - "items": [] + "items": [], + "kind": "full" } ] } @@ -348,7 +349,7 @@ def foo( server.open_text_document(foo, foo_content, 1); let diagnostics = server.document_diagnostic_request(foo, None); - assert_compact_json_snapshot!(diagnostics, @r#"{"kind": "full", "resultId": "[RESULT_ID]", "items": []}"#); + assert_compact_json_snapshot!(diagnostics, @r#"{"resultId": "[RESULT_ID]", "items": [], "kind": "full"}"#); Ok(()) } @@ -445,9 +446,7 @@ def foo() -> str: // Extract result ID from first response let result_id = match &first_response { - lsp_types::DocumentDiagnosticReportResult::Report( - lsp_types::DocumentDiagnosticReport::Full(report), - ) => report + lsp_types::DocumentDiagnosticReport::RelatedFullDocumentDiagnosticReport(report) => report .full_document_diagnostic_report .result_id .as_ref() @@ -461,9 +460,7 @@ def foo() -> str: // Verify it's an unchanged report match second_response { - lsp_types::DocumentDiagnosticReportResult::Report( - lsp_types::DocumentDiagnosticReport::Unchanged(_), - ) => { + lsp_types::DocumentDiagnosticReport::RelatedUnchangedDocumentDiagnosticReport(_) => { // Success - got unchanged report as expected } _ => panic!("Expected an unchanged report when diagnostics haven't changed"), @@ -500,9 +497,7 @@ def foo() -> str: // Extract result ID from first response let result_id = match &first_response { - lsp_types::DocumentDiagnosticReportResult::Report( - lsp_types::DocumentDiagnosticReport::Full(report), - ) => report + lsp_types::DocumentDiagnosticReport::RelatedFullDocumentDiagnosticReport(report) => report .full_document_diagnostic_report .result_id .as_ref() @@ -514,11 +509,13 @@ def foo() -> str: // Change the document to fix the error server.change_text_document( foo, - vec![lsp_types::TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: foo_content_v2.to_string(), - }], + vec![ + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { + text: foo_content_v2.to_string(), + }, + ), + ], 2, ); @@ -527,9 +524,7 @@ def foo() -> str: // Verify it's a full report (not unchanged) match second_response { - lsp_types::DocumentDiagnosticReportResult::Report( - lsp_types::DocumentDiagnosticReport::Full(report), - ) => { + lsp_types::DocumentDiagnosticReport::RelatedFullDocumentDiagnosticReport(report) => { // Should have no diagnostics now assert_eq!(report.full_document_diagnostic_report.items.len(), 0); } @@ -615,8 +610,10 @@ def foo() -> str: server.open_text_document(file_a, file_a_content, 1); // First request with no previous result IDs - let mut first_response = server - .workspace_diagnostic_request(Some(NumberOrString::String("progress-1".to_string())), None); + let mut first_response = server.workspace_diagnostic_request( + Some(lsp_types::ProgressToken::String("progress-1".to_string())), + None, + ); sort_workspace_diagnostic_response(&mut first_response); assert_debug_snapshot!("workspace_diagnostic_initial_state", first_response); @@ -637,44 +634,52 @@ def foo() -> str: // File B: Add a new error server.change_text_document( file_b, - vec![lsp_types::TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: file_b_content_v2.to_string(), - }], + vec![ + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { + text: file_b_content_v2.to_string(), + }, + ), + ], 2, ); // File C: Fix the error server.change_text_document( file_c, - vec![lsp_types::TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: file_c_content_v2.to_string(), - }], + vec![ + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { + text: file_c_content_v2.to_string(), + }, + ), + ], 2, ); // File D: Change the error server.change_text_document( file_d, - vec![lsp_types::TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: file_d_content_v2.to_string(), - }], + vec![ + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { + text: file_d_content_v2.to_string(), + }, + ), + ], 2, ); // File E: Modify the file but keep the same diagnostic server.change_text_document( file_e, - vec![lsp_types::TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: file_e_content_v2.to_string(), - }], + vec![ + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { + text: file_e_content_v2.to_string(), + }, + ), + ], 2, ); @@ -686,7 +691,7 @@ def foo() -> str: // - File D: Full report (diagnostic content changed) // - File E: Full report (the range changes) let mut second_response = server.workspace_diagnostic_request( - Some(NumberOrString::String("progress-2".to_string())), + Some(lsp_types::ProgressToken::String("progress-2".to_string())), Some(previous_result_ids), ); sort_workspace_diagnostic_response(&mut second_response); @@ -746,7 +751,7 @@ def foo() -> str: let second_response = shutdown_and_await_workspace_diagnostic(server, &workspace_request_id); - insta::assert_compact_debug_snapshot!(second_response, @"Report(WorkspaceDiagnosticReport { items: [] })"); + insta::assert_compact_debug_snapshot!(second_response, @"WorkspaceDiagnosticReport { items: [] }"); Ok(()) } @@ -760,23 +765,19 @@ pub(crate) fn filter_result_id() -> insta::internals::SettingsBindDropGuard { fn consume_all_progress_notifications(server: &mut TestServer) -> Result<()> { // Always consume Begin - let begin_params = server.await_notification::(); + let begin_params = server.await_notification::(); // The params are already the ProgressParams type - let lsp_types::ProgressParamsValue::WorkDone(lsp_types::WorkDoneProgress::Begin(_)) = - begin_params.value - else { + let Ok(_) = serde_json::from_value::(begin_params.value) else { return Err(anyhow::anyhow!("Expected Begin progress notification")); }; // Consume Report notifications - there may be multiple based on number of files // Keep consuming until we hit the End notification loop { - let params = server.await_notification::(); + let params = server.await_notification::(); - if let lsp_types::ProgressParamsValue::WorkDone(lsp_types::WorkDoneProgress::End(_)) = - params.value - { + if let Ok(_) = serde_json::from_value::(params.value) { // Found the End notification, we're done break; } @@ -842,10 +843,7 @@ def foo() -> str: // This should always be a partial report. However, the type definition in the LSP specification // is broken in the sense that both `Report` and `Partial` have the exact same shape // and deserializing a previously serialized `Partial` result will yield a `Report` type. - let response_items = match final_response { - WorkspaceDiagnosticReportResult::Report(report) => report.items, - WorkspaceDiagnosticReportResult::Partial(partial) => partial.items, - }; + let response_items = final_response.items; // The last batch should contain 1 item because the server sends a partial result with // 2 items each. @@ -854,18 +852,16 @@ def foo() -> str: // Collect any partial results sent via progress notifications while let Ok(params) = - server.try_await_notification::(Some(Duration::from_secs(1))) + server.try_await_notification::(Some(Duration::from_secs(1))) { if params.token == partial_token { - let streamed_items = match params.value { - // Ideally we'd assert that only the first response is a full report - // However, the type definition in the LSP specification is broken - // in the sense that both `Report` and `Partial` have the exact same structure - // but it also doesn't use a tag to tell them apart... - // That means, a client can never tell if it's a full report or a partial report - WorkspaceDiagnosticReportResult::Report(report) => report.items, - WorkspaceDiagnosticReportResult::Partial(partial) => partial.items, - }; + // Ideally we'd assert that only the first response is a full report + // However, the type definition in the LSP specification is broken + // in the sense that both `Report` and `Partial` have the exact same structure + // but it also doesn't use a tag to tell them apart... + // That means, a client can never tell if it's a full report or a partial report + let report = serde_json::from_value::(params.value).unwrap(); + let streamed_items = report.items; // All streamed batches should contain 2 items (test behavior). assert_eq!(streamed_items.len(), 2); @@ -922,31 +918,37 @@ fn workspace_diagnostic_streaming_with_caching() -> Result<()> { // Fix three errors server.change_text_document( SystemPath::new("src/error_0.py"), - vec![lsp_types::TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: changed_content.to_string(), - }], + vec![ + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { + text: changed_content.to_string(), + }, + ), + ], 2, ); server.change_text_document( SystemPath::new("src/error_1.py"), - vec![lsp_types::TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: changed_content.to_string(), - }], + vec![ + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { + text: changed_content.to_string(), + }, + ), + ], 2, ); server.change_text_document( SystemPath::new("src/error_2.py"), - vec![lsp_types::TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: changed_content.to_string(), - }], + vec![ + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { + text: changed_content.to_string(), + }, + ), + ], 2, ); @@ -969,10 +971,7 @@ fn workspace_diagnostic_streaming_with_caching() -> Result<()> { let mut all_items = Vec::new(); // The final response should contain one fixed file and all unchanged files - let items = match final_response2 { - WorkspaceDiagnosticReportResult::Report(report) => report.items, - WorkspaceDiagnosticReportResult::Partial(partial) => partial.items, - }; + let items = final_response2.items; assert_eq!(items.len(), NUM_FILES - 3 + 1); // 3 fixed, 4 unchanged, 1 full report for fixed file @@ -980,18 +979,16 @@ fn workspace_diagnostic_streaming_with_caching() -> Result<()> { // Collect any partial results sent via progress notifications while let Ok(params) = - server.try_await_notification::(Some(Duration::from_secs(1))) + server.try_await_notification::(Some(Duration::from_secs(1))) { if params.token == partial_token { - let streamed_items = match params.value { - // Ideally we'd assert that only the first response is a full report - // However, the type definition in the LSP specification is broken - // in the sense that both `Report` and `Partial` have the exact same structure - // but it also doesn't use a tag to tell them apart... - // That means, a client can never tell if it's a full report or a partial report - WorkspaceDiagnosticReportResult::Report(report) => report.items, - WorkspaceDiagnosticReportResult::Partial(partial) => partial.items, - }; + // Ideally we'd assert that only the first response is a full report + // However, the type definition in the LSP specification is broken + // in the sense that both `Report` and `Partial` have the exact same structure + // but it also doesn't use a tag to tell them apart... + // That means, a client can never tell if it's a full report or a partial report + let report = serde_json::from_value::(params.value).unwrap(); + let streamed_items = report.items; // All streamed batches should contain 2 items. assert_eq!(streamed_items.len(), 2); @@ -1010,20 +1007,19 @@ fn workspace_diagnostic_streaming_with_caching() -> Result<()> { Ok(()) } -fn sort_workspace_diagnostic_response(response: &mut WorkspaceDiagnosticReportResult) { - let items = match response { - WorkspaceDiagnosticReportResult::Report(report) => &mut report.items, - WorkspaceDiagnosticReportResult::Partial(partial) => &mut partial.items, - }; - - sort_workspace_report_items(items); +fn sort_workspace_diagnostic_response(response: &mut WorkspaceDiagnosticReport) { + sort_workspace_report_items(&mut response.items); } fn sort_workspace_report_items(items: &mut [WorkspaceDocumentDiagnosticReport]) { fn item_uri(item: &WorkspaceDocumentDiagnosticReport) -> &Url { match item { - WorkspaceDocumentDiagnosticReport::Full(full_report) => &full_report.uri, - WorkspaceDocumentDiagnosticReport::Unchanged(unchanged_report) => &unchanged_report.uri, + WorkspaceDocumentDiagnosticReport::WorkspaceFullDocumentDiagnosticReport( + full_report, + ) => &full_report.uri, + WorkspaceDocumentDiagnosticReport::WorkspaceUnchangedDocumentDiagnosticReport( + unchanged_report, + ) => &unchanged_report.uri, } } @@ -1100,11 +1096,13 @@ def hello() -> str: // Now introduce an error to the file - this should trigger the long-polling request to complete server.change_text_document( file_path, - vec![lsp_types::TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: file_content_with_error.to_string(), - }], + vec![ + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { + text: file_content_with_error.to_string(), + }, + ), + ], 2, ); @@ -1200,11 +1198,13 @@ def hello() -> str: // PHASE 2: Introduce error to trigger response server.change_text_document( file_path, - vec![lsp_types::TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: file_content_with_error.to_string(), - }], + vec![ + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { + text: file_content_with_error.to_string(), + }, + ), + ], 2, ); @@ -1233,11 +1233,13 @@ def hello() -> str: // PHASE 4: Fix the error to trigger the second response server.change_text_document( file_path, - vec![lsp_types::TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: file_content_fixed.to_string(), - }], + vec![ + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { + text: file_content_fixed.to_string(), + }, + ), + ], 3, ); @@ -1353,16 +1355,16 @@ pub(crate) fn send_workspace_diagnostic_request(server: &mut TestServer) -> lsp_ pub(crate) fn shutdown_and_await_workspace_diagnostic( mut server: TestServer, request_id: &RequestId, -) -> WorkspaceDiagnosticReportResult { +) -> WorkspaceDiagnosticReport { // Send shutdown request - this should cause the suspended workspace diagnostic request to respond - let shutdown_id = server.send_request::(()); + let shutdown_id = server.send_request::(()); // The workspace diagnostic request should now respond with an empty report let workspace_response = server.await_response::(request_id); // Complete shutdown sequence - server.await_response::(&shutdown_id); - server.send_notification::(()); + server.await_response::(&shutdown_id); + server.send_notification::(()); workspace_response } @@ -1389,21 +1391,15 @@ pub(crate) fn assert_workspace_diagnostics_suspends_for_long_polling( } } -fn extract_result_ids_from_response( - response: &WorkspaceDiagnosticReportResult, -) -> Vec { - let items = match response { - WorkspaceDiagnosticReportResult::Report(report) => &report.items, - WorkspaceDiagnosticReportResult::Partial(partial) => { - // For partial results, extract from items the same way - &partial.items - } - }; +fn extract_result_ids_from_response(response: &WorkspaceDiagnosticReport) -> Vec { + let items = &response.items; items .iter() .filter_map(|item| match item { - WorkspaceDocumentDiagnosticReport::Full(full_report) => { + WorkspaceDocumentDiagnosticReport::WorkspaceFullDocumentDiagnosticReport( + full_report, + ) => { let result_id = full_report .full_document_diagnostic_report .result_id @@ -1414,7 +1410,7 @@ fn extract_result_ids_from_response( value: result_id.clone(), }) } - WorkspaceDocumentDiagnosticReport::Unchanged(_) => { + WorkspaceDocumentDiagnosticReport::WorkspaceUnchangedDocumentDiagnosticReport(_) => { // Unchanged reports don't provide new result IDs None } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action.snap b/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action.snap index a7aa74dfbfd0f..282da9eed1816 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action.snap @@ -30,6 +30,7 @@ expression: code_actions ] } ], + "isPreferred": true, "edit": { "changes": { "file:///src/foo.py": [ @@ -48,8 +49,7 @@ expression: code_actions } ] } - }, - "isPreferred": true + } }, { "title": "Ignore 'unused-ignore-comment' for this line", @@ -78,6 +78,7 @@ expression: code_actions ] } ], + "isPreferred": false, "edit": { "changes": { "file:///src/foo.py": [ @@ -96,7 +97,6 @@ expression: code_actions } ] } - }, - "isPreferred": false + } } ] diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_attribute_access_on_unimported.snap b/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_attribute_access_on_unimported.snap index 78da8d45f782c..8baf89d666ae5 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_attribute_access_on_unimported.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_attribute_access_on_unimported.snap @@ -27,6 +27,7 @@ expression: code_actions "message": "Name `typing` used when not defined" } ], + "isPreferred": true, "edit": { "changes": { "file:///src/foo.py": [ @@ -45,8 +46,7 @@ expression: code_actions } ] } - }, - "isPreferred": true + } }, { "title": "Ignore 'unresolved-reference' for this line", @@ -72,6 +72,7 @@ expression: code_actions "message": "Name `typing` used when not defined" } ], + "isPreferred": false, "edit": { "changes": { "file:///src/foo.py": [ @@ -90,7 +91,6 @@ expression: code_actions } ] } - }, - "isPreferred": false + } } ] diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_existing_import_undefined_decorator.snap b/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_existing_import_undefined_decorator.snap index ceaf6ad94ab11..7c41413d40e22 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_existing_import_undefined_decorator.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_existing_import_undefined_decorator.snap @@ -27,6 +27,7 @@ expression: code_actions "message": "Name `deprecated` used when not defined" } ], + "isPreferred": true, "edit": { "changes": { "file:///src/foo.py": [ @@ -45,8 +46,7 @@ expression: code_actions } ] } - }, - "isPreferred": true + } }, { "title": "qualify warnings.deprecated", @@ -72,6 +72,7 @@ expression: code_actions "message": "Name `deprecated` used when not defined" } ], + "isPreferred": true, "edit": { "changes": { "file:///src/foo.py": [ @@ -90,8 +91,7 @@ expression: code_actions } ] } - }, - "isPreferred": true + } }, { "title": "Ignore 'unresolved-reference' for this line", @@ -117,6 +117,7 @@ expression: code_actions "message": "Name `deprecated` used when not defined" } ], + "isPreferred": false, "edit": { "changes": { "file:///src/foo.py": [ @@ -135,7 +136,6 @@ expression: code_actions } ] } - }, - "isPreferred": false + } } ] diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_invalid_string_annotations.snap b/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_invalid_string_annotations.snap index 6e5e2f3edc1e0..3f6b711aad894 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_invalid_string_annotations.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_invalid_string_annotations.snap @@ -27,6 +27,7 @@ expression: code_actions "message": "Name `foobar` used when not defined" } ], + "isPreferred": false, "edit": { "changes": { "file:///src/foo.py": [ @@ -45,7 +46,6 @@ expression: code_actions } ] } - }, - "isPreferred": false + } } ] diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_possible_missing_submodule_attribute.snap b/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_possible_missing_submodule_attribute.snap index 2b77f284d5b64..709c85ce8751d 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_possible_missing_submodule_attribute.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_possible_missing_submodule_attribute.snap @@ -27,6 +27,7 @@ expression: code_actions "message": "Submodule `parser` might not have been imported\n\nhelp: Consider explicitly importing `html.parser`" } ], + "isPreferred": false, "edit": { "changes": { "file:///src/foo.py": [ @@ -45,7 +46,6 @@ expression: code_actions } ] } - }, - "isPreferred": false + } } ] diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_undefined_decorator.snap b/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_undefined_decorator.snap index 6c42ea73da40e..a3fac399ac4b3 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_undefined_decorator.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_undefined_decorator.snap @@ -27,6 +27,7 @@ expression: code_actions "message": "Name `deprecated` used when not defined" } ], + "isPreferred": true, "edit": { "changes": { "file:///src/foo.py": [ @@ -45,8 +46,7 @@ expression: code_actions } ] } - }, - "isPreferred": true + } }, { "title": "Ignore 'unresolved-reference' for this line", @@ -72,6 +72,7 @@ expression: code_actions "message": "Name `deprecated` used when not defined" } ], + "isPreferred": false, "edit": { "changes": { "file:///src/foo.py": [ @@ -90,7 +91,6 @@ expression: code_actions } ] } - }, - "isPreferred": false + } } ] diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_undefined_reference_multi.snap b/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_undefined_reference_multi.snap index c1ed495ca8680..58d613c0dc988 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_undefined_reference_multi.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__code_actions__code_action_undefined_reference_multi.snap @@ -27,6 +27,7 @@ expression: code_actions "message": "Name `Literal` used when not defined" } ], + "isPreferred": true, "edit": { "changes": { "file:///src/foo.py": [ @@ -45,8 +46,7 @@ expression: code_actions } ] } - }, - "isPreferred": true + } }, { "title": "Ignore 'unresolved-reference' for this line", @@ -72,6 +72,7 @@ expression: code_actions "message": "Name `Literal` used when not defined" } ], + "isPreferred": false, "edit": { "changes": { "file:///src/foo.py": [ @@ -90,7 +91,6 @@ expression: code_actions } ] } - }, - "isPreferred": false + } } ] diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__configuration__configuration_file.snap b/crates/ty_server/tests/e2e/snapshots/e2e__configuration__configuration_file.snap index b8be0bab25c5a..524d347c014e8 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__configuration__configuration_file.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__configuration__configuration_file.snap @@ -3,7 +3,6 @@ source: crates/ty_server/tests/e2e/configuration.rs expression: diagnostics --- { - "kind": "full", "resultId": "[RESULT_ID]", "items": [ { @@ -25,5 +24,6 @@ expression: diagnostics "source": "ty", "message": "Name `a` used when not defined" } - ] + ], + "kind": "full" } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__configuration__configuration_file_and_overrides.snap b/crates/ty_server/tests/e2e/snapshots/e2e__configuration__configuration_file_and_overrides.snap index c01f9192b8b61..a5dd978805429 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__configuration__configuration_file_and_overrides.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__configuration__configuration_file_and_overrides.snap @@ -3,6 +3,6 @@ source: crates/ty_server/tests/e2e/configuration.rs expression: diagnostics --- { - "kind": "full", - "items": [] + "items": [], + "kind": "full" } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__configuration__configuration_overrides.snap b/crates/ty_server/tests/e2e/snapshots/e2e__configuration__configuration_overrides.snap index b8be0bab25c5a..524d347c014e8 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__configuration__configuration_overrides.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__configuration__configuration_overrides.snap @@ -3,7 +3,6 @@ source: crates/ty_server/tests/e2e/configuration.rs expression: diagnostics --- { - "kind": "full", "resultId": "[RESULT_ID]", "items": [ { @@ -25,5 +24,6 @@ expression: diagnostics "source": "ty", "message": "Name `a` used when not defined" } - ] + ], + "kind": "full" } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__configuration__invalid_configuration_file-2.snap b/crates/ty_server/tests/e2e/snapshots/e2e__configuration__invalid_configuration_file-2.snap index 77d404ec7983c..99cdf274f9f23 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__configuration__invalid_configuration_file-2.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__configuration__invalid_configuration_file-2.snap @@ -3,7 +3,6 @@ source: crates/ty_server/tests/e2e/configuration.rs expression: diagnostics --- { - "kind": "full", "resultId": "[RESULT_ID]", "items": [ { @@ -25,5 +24,6 @@ expression: diagnostics "source": "ty", "message": "Name `a` used when not defined" } - ] + ], + "kind": "full" } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__initialize__initialization.snap b/crates/ty_server/tests/e2e/snapshots/e2e__initialize__initialization.snap index 70da6fccdfb27..fb728b5b94068 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__initialize__initialization.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__initialize__initialization.snap @@ -21,13 +21,12 @@ expression: initialization_result ], "save": false }, - "selectionRangeProvider": true, - "hoverProvider": true, "completionProvider": { "triggerCharacters": [ "." ] }, + "hoverProvider": true, "signatureHelpProvider": { "triggerCharacters": [ "(", @@ -37,34 +36,29 @@ expression: initialization_result ")" ] }, + "declarationProvider": true, "definitionProvider": true, "typeDefinitionProvider": true, "referencesProvider": true, "documentHighlightProvider": true, "documentSymbolProvider": true, - "workspaceSymbolProvider": true, "codeActionProvider": { "codeActionKinds": [ "quickfix" ] }, + "workspaceSymbolProvider": true, "renameProvider": { "prepareProvider": true }, "foldingRangeProvider": true, - "declarationProvider": true, + "selectionRangeProvider": true, "executeCommandProvider": { "commands": [ "ty.printDebugInformation" ], "workDoneProgress": false }, - "workspace": { - "workspaceFolders": { - "supported": true, - "changeNotifications": true - } - }, "semanticTokensProvider": { "legend": { "tokenTypes": [ @@ -101,6 +95,12 @@ expression: initialization_result "interFileDependencies": true, "workspaceDiagnostics": true, "workDoneProgress": true + }, + "workspace": { + "workspaceFolders": { + "supported": true, + "changeNotifications": true + } } }, "serverInfo": { diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__initialize__initialization_with_workspace.snap b/crates/ty_server/tests/e2e/snapshots/e2e__initialize__initialization_with_workspace.snap index 70da6fccdfb27..fb728b5b94068 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__initialize__initialization_with_workspace.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__initialize__initialization_with_workspace.snap @@ -21,13 +21,12 @@ expression: initialization_result ], "save": false }, - "selectionRangeProvider": true, - "hoverProvider": true, "completionProvider": { "triggerCharacters": [ "." ] }, + "hoverProvider": true, "signatureHelpProvider": { "triggerCharacters": [ "(", @@ -37,34 +36,29 @@ expression: initialization_result ")" ] }, + "declarationProvider": true, "definitionProvider": true, "typeDefinitionProvider": true, "referencesProvider": true, "documentHighlightProvider": true, "documentSymbolProvider": true, - "workspaceSymbolProvider": true, "codeActionProvider": { "codeActionKinds": [ "quickfix" ] }, + "workspaceSymbolProvider": true, "renameProvider": { "prepareProvider": true }, "foldingRangeProvider": true, - "declarationProvider": true, + "selectionRangeProvider": true, "executeCommandProvider": { "commands": [ "ty.printDebugInformation" ], "workDoneProgress": false }, - "workspace": { - "workspaceFolders": { - "supported": true, - "changeNotifications": true - } - }, "semanticTokensProvider": { "legend": { "tokenTypes": [ @@ -101,6 +95,12 @@ expression: initialization_result "interFileDependencies": true, "workspaceDiagnostics": true, "workDoneProgress": true + }, + "workspace": { + "workspaceFolders": { + "supported": true, + "changeNotifications": true + } } }, "serverInfo": { diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__notebook__publish_diagnostics_open.snap b/crates/ty_server/tests/e2e/snapshots/e2e__notebook__publish_diagnostics_open.snap index cd6dd34c08c71..2da1ebedc6e3d 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__notebook__publish_diagnostics_open.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__notebook__publish_diagnostics_open.snap @@ -5,6 +5,7 @@ expression: "[cell1_diagnostics, cell2_diagnostics, cell3_diagnostics]" [ { "uri": "vscode-notebook-cell://test.ipynb#1", + "version": 0, "diagnostics": [ { "range": { @@ -26,11 +27,11 @@ expression: "[cell1_diagnostics, cell2_diagnostics, cell3_diagnostics]" "message": "Function can implicitly return `None`, which is not assignable to return type `str`", "relatedInformation": [] } - ], - "version": 0 + ] }, { "uri": "vscode-notebook-cell://test.ipynb#2", + "version": 0, "diagnostics": [ { "range": { @@ -85,12 +86,11 @@ expression: "[cell1_diagnostics, cell2_diagnostics, cell3_diagnostics]" } ] } - ], - "version": 0 + ] }, { "uri": "vscode-notebook-cell://test.ipynb#0", - "diagnostics": [], - "version": 0 + "version": 0, + "diagnostics": [] } ] diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__changing_language_of_file_without_extension-2.snap b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__changing_language_of_file_without_extension-2.snap index f29237130921a..c4ccb9920d60f 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__changing_language_of_file_without_extension-2.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__changing_language_of_file_without_extension-2.snap @@ -14,6 +14,6 @@ PublishDiagnosticsParams { query: None, fragment: None, }, - diagnostics: [], version: None, + diagnostics: [], } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__changing_language_of_file_without_extension-3.snap b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__changing_language_of_file_without_extension-3.snap index 91a4a10b81dc0..152096681ccf9 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__changing_language_of_file_without_extension-3.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__changing_language_of_file_without_extension-3.snap @@ -14,8 +14,8 @@ PublishDiagnosticsParams { query: None, fragment: None, }, - diagnostics: [], version: Some( 1, ), + diagnostics: [], } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__changing_language_of_file_without_extension.snap b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__changing_language_of_file_without_extension.snap index d6a9af02de7ad..2cc85dc7bb5f4 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__changing_language_of_file_without_extension.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__changing_language_of_file_without_extension.snap @@ -14,6 +14,9 @@ PublishDiagnosticsParams { query: None, fragment: None, }, + version: Some( + 1, + ), diagnostics: [ Diagnostic { range: Range { @@ -59,12 +62,9 @@ PublishDiagnosticsParams { "ty", ), message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, tags: None, + related_information: None, data: None, }, ], - version: Some( - 1, - ), } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__invalid_syntax_with_syntax_errors_disabled.snap b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__invalid_syntax_with_syntax_errors_disabled.snap index 1bea2c0877a9d..bcbb04e92b2dc 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__invalid_syntax_with_syntax_errors_disabled.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__invalid_syntax_with_syntax_errors_disabled.snap @@ -14,8 +14,8 @@ PublishDiagnosticsParams { query: None, fragment: None, }, - diagnostics: [], version: Some( 1, ), + diagnostics: [], } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__message_with_related_information_support.snap b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__message_with_related_information_support.snap index d5cc99a6dcab3..9a9663ece9d6e 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__message_with_related_information_support.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__message_with_related_information_support.snap @@ -14,6 +14,9 @@ PublishDiagnosticsParams { query: None, fragment: None, }, + version: Some( + 1, + ), diagnostics: [ Diagnostic { range: Range { @@ -59,6 +62,7 @@ PublishDiagnosticsParams { "ty", ), message: "Argument does not have asserted type `list[str]`\n\ninfo: `list[str]` and `Literal[\"test\"]` are not equivalent types", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -89,11 +93,7 @@ PublishDiagnosticsParams { }, ], ), - tags: None, data: None, }, ], - version: Some( - 1, - ), } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__message_without_related_information_support.snap b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__message_without_related_information_support.snap index 8fbf3baa8126a..e42510019fd59 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__message_without_related_information_support.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__message_without_related_information_support.snap @@ -14,6 +14,9 @@ PublishDiagnosticsParams { query: None, fragment: None, }, + version: Some( + 1, + ), diagnostics: [ Diagnostic { range: Range { @@ -59,12 +62,9 @@ PublishDiagnosticsParams { "ty", ), message: "Type `Literal[\"test\"]` does not match asserted type `list[str]`\n\ninfo: `list[str]` and `Literal[\"test\"]` are not equivalent types", - related_information: None, tags: None, + related_information: None, data: None, }, ], - version: Some( - 1, - ), } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_change.snap b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_change.snap index 02ea49ca9207a..300437ef140b2 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_change.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_change.snap @@ -14,8 +14,8 @@ PublishDiagnosticsParams { query: None, fragment: None, }, - diagnostics: [], version: Some( 2, ), + diagnostics: [], } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_change_watched_files.snap b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_change_watched_files.snap index 52ce909cad417..748f9d8b1f6c2 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_change_watched_files.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_change_watched_files.snap @@ -4,6 +4,6 @@ expression: diagnostics --- { "uri": "file:///src/foo.py", - "diagnostics": [], - "version": 1 + "version": 1, + "diagnostics": [] } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open.snap b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open.snap index 63f94e2ae7f7a..f76fa784f8e4a 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open.snap @@ -14,6 +14,9 @@ PublishDiagnosticsParams { query: None, fragment: None, }, + version: Some( + 1, + ), diagnostics: [ Diagnostic { range: Range { @@ -59,12 +62,9 @@ PublishDiagnosticsParams { "ty", ), message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, tags: None, + related_information: None, data: None, }, ], - version: Some( - 1, - ), } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_file_without_extension_but_python_language.snap b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_file_without_extension_but_python_language.snap index d6a9af02de7ad..2cc85dc7bb5f4 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_file_without_extension_but_python_language.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_file_without_extension_but_python_language.snap @@ -14,6 +14,9 @@ PublishDiagnosticsParams { query: None, fragment: None, }, + version: Some( + 1, + ), diagnostics: [ Diagnostic { range: Range { @@ -59,12 +62,9 @@ PublishDiagnosticsParams { "ty", ), message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, tags: None, + related_information: None, data: None, }, ], - version: Some( - 1, - ), } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_non_existing_file_open_files_only.snap b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_non_existing_file_open_files_only.snap index 63f94e2ae7f7a..f76fa784f8e4a 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_non_existing_file_open_files_only.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_non_existing_file_open_files_only.snap @@ -14,6 +14,9 @@ PublishDiagnosticsParams { query: None, fragment: None, }, + version: Some( + 1, + ), diagnostics: [ Diagnostic { range: Range { @@ -59,12 +62,9 @@ PublishDiagnosticsParams { "ty", ), message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, tags: None, + related_information: None, data: None, }, ], - version: Some( - 1, - ), } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_non_existing_file_workspace_with_file_uri.snap b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_non_existing_file_workspace_with_file_uri.snap index 63f94e2ae7f7a..f76fa784f8e4a 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_non_existing_file_workspace_with_file_uri.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_non_existing_file_workspace_with_file_uri.snap @@ -14,6 +14,9 @@ PublishDiagnosticsParams { query: None, fragment: None, }, + version: Some( + 1, + ), diagnostics: [ Diagnostic { range: Range { @@ -59,12 +62,9 @@ PublishDiagnosticsParams { "ty", ), message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, tags: None, + related_information: None, data: None, }, ], - version: Some( - 1, - ), } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_non_existing_file_workspace_with_untitled_uri.snap b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_non_existing_file_workspace_with_untitled_uri.snap index 6c43437338557..a6f7a90193c6b 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_non_existing_file_workspace_with_untitled_uri.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__publish_diagnostics__on_did_open_non_existing_file_workspace_with_untitled_uri.snap @@ -14,6 +14,9 @@ PublishDiagnosticsParams { query: None, fragment: None, }, + version: Some( + 1, + ), diagnostics: [ Diagnostic { range: Range { @@ -59,12 +62,9 @@ PublishDiagnosticsParams { "ty", ), message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, tags: None, + related_information: None, data: None, }, ], - version: Some( - 1, - ), } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__current_analysis_unreachable_code_has_unnecessary_hint_tag.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__current_analysis_unreachable_code_has_unnecessary_hint_tag.snap index d969cdb8a141a..67e0df13ebd3d 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__current_analysis_unreachable_code_has_unnecessary_hint_tag.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__current_analysis_unreachable_code_has_unnecessary_hint_tag.snap @@ -3,7 +3,6 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: diagnostics --- { - "kind": "full", "resultId": "[RESULT_ID]", "items": [ { @@ -24,5 +23,6 @@ expression: diagnostics 1 ] } - ] + ], + "kind": "full" } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__excluded.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__excluded.snap index d8deb392762a9..358632d800bc8 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__excluded.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__excluded.snap @@ -2,4 +2,4 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: excluded_diagnostics --- -{"kind": "full", "items": []} +{"items": [], "kind": "full"} diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__main.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__main.snap index c33ad3446602f..7f898a403d9da 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__main.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__main.snap @@ -3,7 +3,6 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: main_diagnostics --- { - "kind": "full", "resultId": "[RESULT_ID]", "items": [ { @@ -41,5 +40,6 @@ expression: main_diagnostics "source": "ty", "message": "Revealed type: `Literal[\"included\"]`" } - ] + ], + "kind": "full" } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__on_did_open.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__on_did_open.snap index 86cf96fef5bd2..d06686090ac25 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__on_did_open.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__on_did_open.snap @@ -2,65 +2,63 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: diagnostics --- -Report( - Full( - RelatedFullDocumentDiagnosticReport { - related_documents: None, - full_document_diagnostic_report: FullDocumentDiagnosticReport { - result_id: Some( - "[RESULT_ID]", - ), - items: [ - Diagnostic { - range: Range { - start: Position { - line: 1, - character: 11, - }, - end: Position { - line: 1, - character: 13, - }, +RelatedFullDocumentDiagnosticReport( + RelatedFullDocumentDiagnosticReport { + related_documents: None, + full_document_diagnostic_report: FullDocumentDiagnosticReport { + result_id: Some( + "[RESULT_ID]", + ), + items: [ + Diagnostic { + range: Range { + start: Position { + line: 1, + character: 11, }, - severity: Some( - Error, - ), - code: Some( - String( - "invalid-return-type", - ), + end: Position { + line: 1, + character: 13, + }, + }, + severity: Some( + Error, + ), + code: Some( + String( + "invalid-return-type", ), - code_description: Some( - CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "ty.dev", - ), + ), + code_description: Some( + CodeDescription { + href: Url { + scheme: "https", + cannot_be_a_base: false, + username: "", + password: None, + host: Some( + Domain( + "ty.dev", ), - port: None, - path: "/rules", - query: None, - fragment: Some( - "invalid-return-type", - ), - }, + ), + port: None, + path: "/rules", + query: None, + fragment: Some( + "invalid-return-type", + ), }, - ), - source: Some( - "ty", - ), - message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, - tags: None, - data: None, - }, - ], - }, + }, + ), + source: Some( + "ty", + ), + message: "Return type does not match returned value: expected `str`, found `Literal[42]`", + tags: None, + related_information: None, + data: None, + }, + ], }, - ), + }, ) diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__stack_size.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__stack_size.snap index a1f90df2b2a89..9f64962a563ed 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__stack_size.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__stack_size.snap @@ -3,7 +3,6 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: diagnostics --- { - "kind": "full", "resultId": "[RESULT_ID]", "items": [ { @@ -22,5 +21,6 @@ expression: diagnostics "source": "ty", "message": "Revealed type: `Literal[2000]`" } - ] + ], + "kind": "full" } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__unreachable_code_has_unnecessary_hint_tag.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__unreachable_code_has_unnecessary_hint_tag.snap index f91ac1921afb2..0c09a137e46fe 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__unreachable_code_has_unnecessary_hint_tag.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__unreachable_code_has_unnecessary_hint_tag.snap @@ -3,7 +3,6 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: diagnostics --- { - "kind": "full", "resultId": "[RESULT_ID]", "items": [ { @@ -24,5 +23,6 @@ expression: diagnostics 1 ] } - ] + ], + "kind": "full" } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__unreachable_code_suppresses_unused_binding_hint.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__unreachable_code_suppresses_unused_binding_hint.snap index 9fa46652a9fbf..aaf28bb322dc8 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__unreachable_code_suppresses_unused_binding_hint.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__unreachable_code_suppresses_unused_binding_hint.snap @@ -3,7 +3,6 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: diagnostics --- { - "kind": "full", "resultId": "[RESULT_ID]", "items": [ { @@ -24,5 +23,6 @@ expression: diagnostics 1 ] } - ] + ], + "kind": "full" } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__unused_binding_has_unnecessary_hint_tag.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__unused_binding_has_unnecessary_hint_tag.snap index 33e093b0a6a8b..75c3c308fa583 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__unused_binding_has_unnecessary_hint_tag.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__unused_binding_has_unnecessary_hint_tag.snap @@ -3,7 +3,6 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: diagnostics --- { - "kind": "full", "resultId": "[RESULT_ID]", "items": [ { @@ -24,5 +23,6 @@ expression: diagnostics 1 ] } - ] + ], + "kind": "full" } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_after_changes.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_after_changes.snap index 66336f330855b..9d2166f0b446f 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_after_changes.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_after_changes.snap @@ -2,271 +2,269 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: second_response --- -Report( - WorkspaceDiagnosticReport { - items: [ - Full( - WorkspaceFullDocumentDiagnosticReport { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/src/changed_error.py", - query: None, - fragment: None, - }, - version: Some( - 2, +WorkspaceDiagnosticReport { + items: [ + WorkspaceFullDocumentDiagnosticReport( + WorkspaceFullDocumentDiagnosticReport { + uri: Url { + scheme: "file", + cannot_be_a_base: false, + username: "", + password: None, + host: None, + port: None, + path: "/src/changed_error.py", + query: None, + fragment: None, + }, + version: Some( + 2, + ), + full_document_diagnostic_report: FullDocumentDiagnosticReport { + result_id: Some( + "[RESULT_ID]", ), - full_document_diagnostic_report: FullDocumentDiagnosticReport { - result_id: Some( - "[RESULT_ID]", - ), - items: [ - Diagnostic { - range: Range { - start: Position { - line: 1, - character: 11, - }, - end: Position { - line: 1, - character: 18, - }, + items: [ + Diagnostic { + range: Range { + start: Position { + line: 1, + character: 11, }, - severity: Some( - Error, - ), - code: Some( - String( - "invalid-return-type", - ), + end: Position { + line: 1, + character: 18, + }, + }, + severity: Some( + Error, + ), + code: Some( + String( + "invalid-return-type", ), - code_description: Some( - CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "ty.dev", - ), - ), - port: None, - path: "/rules", - query: None, - fragment: Some( - "invalid-return-type", + ), + code_description: Some( + CodeDescription { + href: Url { + scheme: "https", + cannot_be_a_base: false, + username: "", + password: None, + host: Some( + Domain( + "ty.dev", ), - }, + ), + port: None, + path: "/rules", + query: None, + fragment: Some( + "invalid-return-type", + ), }, - ), - source: Some( - "ty", - ), - message: "Return type does not match returned value: expected `int`, found `Literal[\"hello\"]`", - related_information: None, - tags: None, - data: None, - }, - ], - }, + }, + ), + source: Some( + "ty", + ), + message: "Return type does not match returned value: expected `int`, found `Literal[\"hello\"]`", + tags: None, + related_information: None, + data: None, + }, + ], }, - ), - Full( - WorkspaceFullDocumentDiagnosticReport { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/src/fixed_error.py", - query: None, - fragment: None, - }, - version: Some( - 2, - ), - full_document_diagnostic_report: FullDocumentDiagnosticReport { - result_id: None, - items: [], - }, + }, + ), + WorkspaceFullDocumentDiagnosticReport( + WorkspaceFullDocumentDiagnosticReport { + uri: Url { + scheme: "file", + cannot_be_a_base: false, + username: "", + password: None, + host: None, + port: None, + path: "/src/fixed_error.py", + query: None, + fragment: None, + }, + version: Some( + 2, + ), + full_document_diagnostic_report: FullDocumentDiagnosticReport { + result_id: None, + items: [], }, - ), - Full( - WorkspaceFullDocumentDiagnosticReport { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/src/modified_same_error.py", - query: None, - fragment: None, - }, - version: Some( - 2, + }, + ), + WorkspaceFullDocumentDiagnosticReport( + WorkspaceFullDocumentDiagnosticReport { + uri: Url { + scheme: "file", + cannot_be_a_base: false, + username: "", + password: None, + host: None, + port: None, + path: "/src/modified_same_error.py", + query: None, + fragment: None, + }, + version: Some( + 2, + ), + full_document_diagnostic_report: FullDocumentDiagnosticReport { + result_id: Some( + "[RESULT_ID]", ), - full_document_diagnostic_report: FullDocumentDiagnosticReport { - result_id: Some( - "[RESULT_ID]", - ), - items: [ - Diagnostic { - range: Range { - start: Position { - line: 4, - character: 11, - }, - end: Position { - line: 4, - character: 13, - }, + items: [ + Diagnostic { + range: Range { + start: Position { + line: 4, + character: 11, }, - severity: Some( - Error, - ), - code: Some( - String( - "invalid-return-type", - ), + end: Position { + line: 4, + character: 13, + }, + }, + severity: Some( + Error, + ), + code: Some( + String( + "invalid-return-type", ), - code_description: Some( - CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "ty.dev", - ), + ), + code_description: Some( + CodeDescription { + href: Url { + scheme: "https", + cannot_be_a_base: false, + username: "", + password: None, + host: Some( + Domain( + "ty.dev", ), - port: None, - path: "/rules", - query: None, - fragment: Some( - "invalid-return-type", - ), - }, + ), + port: None, + path: "/rules", + query: None, + fragment: Some( + "invalid-return-type", + ), }, - ), - source: Some( - "ty", - ), - message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, - tags: None, - data: None, - }, - ], - }, + }, + ), + source: Some( + "ty", + ), + message: "Return type does not match returned value: expected `str`, found `Literal[42]`", + tags: None, + related_information: None, + data: None, + }, + ], }, - ), - Full( - WorkspaceFullDocumentDiagnosticReport { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/src/new_error.py", - query: None, - fragment: None, - }, - version: Some( - 2, + }, + ), + WorkspaceFullDocumentDiagnosticReport( + WorkspaceFullDocumentDiagnosticReport { + uri: Url { + scheme: "file", + cannot_be_a_base: false, + username: "", + password: None, + host: None, + port: None, + path: "/src/new_error.py", + query: None, + fragment: None, + }, + version: Some( + 2, + ), + full_document_diagnostic_report: FullDocumentDiagnosticReport { + result_id: Some( + "[RESULT_ID]", ), - full_document_diagnostic_report: FullDocumentDiagnosticReport { - result_id: Some( - "[RESULT_ID]", - ), - items: [ - Diagnostic { - range: Range { - start: Position { - line: 1, - character: 11, - }, - end: Position { - line: 1, - character: 13, - }, + items: [ + Diagnostic { + range: Range { + start: Position { + line: 1, + character: 11, }, - severity: Some( - Error, - ), - code: Some( - String( - "invalid-return-type", - ), + end: Position { + line: 1, + character: 13, + }, + }, + severity: Some( + Error, + ), + code: Some( + String( + "invalid-return-type", ), - code_description: Some( - CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "ty.dev", - ), - ), - port: None, - path: "/rules", - query: None, - fragment: Some( - "invalid-return-type", + ), + code_description: Some( + CodeDescription { + href: Url { + scheme: "https", + cannot_be_a_base: false, + username: "", + password: None, + host: Some( + Domain( + "ty.dev", ), - }, + ), + port: None, + path: "/rules", + query: None, + fragment: Some( + "invalid-return-type", + ), }, - ), - source: Some( - "ty", - ), - message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, - tags: None, - data: None, - }, - ], - }, + }, + ), + source: Some( + "ty", + ), + message: "Return type does not match returned value: expected `str`, found `Literal[42]`", + tags: None, + related_information: None, + data: None, + }, + ], }, - ), - Unchanged( - WorkspaceUnchangedDocumentDiagnosticReport { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/src/unchanged.py", - query: None, - fragment: None, - }, - version: Some( - 1, - ), - unchanged_document_diagnostic_report: UnchangedDocumentDiagnosticReport { - result_id: "[RESULT_ID]", - }, + }, + ), + WorkspaceUnchangedDocumentDiagnosticReport( + WorkspaceUnchangedDocumentDiagnosticReport { + uri: Url { + scheme: "file", + cannot_be_a_base: false, + username: "", + password: None, + host: None, + port: None, + path: "/src/unchanged.py", + query: None, + fragment: None, + }, + version: Some( + 1, + ), + unchanged_document_diagnostic_report: UnchangedDocumentDiagnosticReport { + result_id: "[RESULT_ID]", }, - ), - ], - }, -) + }, + ), + ], +} diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_initial_state.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_initial_state.snap index ddd394492839c..23002c5279ebe 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_initial_state.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_initial_state.snap @@ -2,295 +2,293 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: first_response --- -Report( - WorkspaceDiagnosticReport { - items: [ - Full( - WorkspaceFullDocumentDiagnosticReport { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/src/changed_error.py", - query: None, - fragment: None, - }, - version: None, - full_document_diagnostic_report: FullDocumentDiagnosticReport { - result_id: Some( - "[RESULT_ID]", - ), - items: [ - Diagnostic { - range: Range { - start: Position { - line: 1, - character: 11, - }, - end: Position { - line: 1, - character: 13, - }, +WorkspaceDiagnosticReport { + items: [ + WorkspaceFullDocumentDiagnosticReport( + WorkspaceFullDocumentDiagnosticReport { + uri: Url { + scheme: "file", + cannot_be_a_base: false, + username: "", + password: None, + host: None, + port: None, + path: "/src/changed_error.py", + query: None, + fragment: None, + }, + version: None, + full_document_diagnostic_report: FullDocumentDiagnosticReport { + result_id: Some( + "[RESULT_ID]", + ), + items: [ + Diagnostic { + range: Range { + start: Position { + line: 1, + character: 11, }, - severity: Some( - Error, - ), - code: Some( - String( - "invalid-return-type", - ), + end: Position { + line: 1, + character: 13, + }, + }, + severity: Some( + Error, + ), + code: Some( + String( + "invalid-return-type", ), - code_description: Some( - CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "ty.dev", - ), - ), - port: None, - path: "/rules", - query: None, - fragment: Some( - "invalid-return-type", + ), + code_description: Some( + CodeDescription { + href: Url { + scheme: "https", + cannot_be_a_base: false, + username: "", + password: None, + host: Some( + Domain( + "ty.dev", ), - }, + ), + port: None, + path: "/rules", + query: None, + fragment: Some( + "invalid-return-type", + ), }, - ), - source: Some( - "ty", - ), - message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, - tags: None, - data: None, - }, - ], - }, + }, + ), + source: Some( + "ty", + ), + message: "Return type does not match returned value: expected `str`, found `Literal[42]`", + tags: None, + related_information: None, + data: None, + }, + ], }, - ), - Full( - WorkspaceFullDocumentDiagnosticReport { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/src/fixed_error.py", - query: None, - fragment: None, - }, - version: None, - full_document_diagnostic_report: FullDocumentDiagnosticReport { - result_id: Some( - "[RESULT_ID]", - ), - items: [ - Diagnostic { - range: Range { - start: Position { - line: 1, - character: 11, - }, - end: Position { - line: 1, - character: 13, - }, + }, + ), + WorkspaceFullDocumentDiagnosticReport( + WorkspaceFullDocumentDiagnosticReport { + uri: Url { + scheme: "file", + cannot_be_a_base: false, + username: "", + password: None, + host: None, + port: None, + path: "/src/fixed_error.py", + query: None, + fragment: None, + }, + version: None, + full_document_diagnostic_report: FullDocumentDiagnosticReport { + result_id: Some( + "[RESULT_ID]", + ), + items: [ + Diagnostic { + range: Range { + start: Position { + line: 1, + character: 11, }, - severity: Some( - Error, - ), - code: Some( - String( - "invalid-return-type", - ), + end: Position { + line: 1, + character: 13, + }, + }, + severity: Some( + Error, + ), + code: Some( + String( + "invalid-return-type", ), - code_description: Some( - CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "ty.dev", - ), - ), - port: None, - path: "/rules", - query: None, - fragment: Some( - "invalid-return-type", + ), + code_description: Some( + CodeDescription { + href: Url { + scheme: "https", + cannot_be_a_base: false, + username: "", + password: None, + host: Some( + Domain( + "ty.dev", ), - }, + ), + port: None, + path: "/rules", + query: None, + fragment: Some( + "invalid-return-type", + ), }, - ), - source: Some( - "ty", - ), - message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, - tags: None, - data: None, - }, - ], - }, + }, + ), + source: Some( + "ty", + ), + message: "Return type does not match returned value: expected `str`, found `Literal[42]`", + tags: None, + related_information: None, + data: None, + }, + ], }, - ), - Full( - WorkspaceFullDocumentDiagnosticReport { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/src/modified_same_error.py", - query: None, - fragment: None, - }, - version: None, - full_document_diagnostic_report: FullDocumentDiagnosticReport { - result_id: Some( - "[RESULT_ID]", - ), - items: [ - Diagnostic { - range: Range { - start: Position { - line: 1, - character: 11, - }, - end: Position { - line: 1, - character: 13, - }, + }, + ), + WorkspaceFullDocumentDiagnosticReport( + WorkspaceFullDocumentDiagnosticReport { + uri: Url { + scheme: "file", + cannot_be_a_base: false, + username: "", + password: None, + host: None, + port: None, + path: "/src/modified_same_error.py", + query: None, + fragment: None, + }, + version: None, + full_document_diagnostic_report: FullDocumentDiagnosticReport { + result_id: Some( + "[RESULT_ID]", + ), + items: [ + Diagnostic { + range: Range { + start: Position { + line: 1, + character: 11, }, - severity: Some( - Error, - ), - code: Some( - String( - "invalid-return-type", - ), + end: Position { + line: 1, + character: 13, + }, + }, + severity: Some( + Error, + ), + code: Some( + String( + "invalid-return-type", ), - code_description: Some( - CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "ty.dev", - ), - ), - port: None, - path: "/rules", - query: None, - fragment: Some( - "invalid-return-type", + ), + code_description: Some( + CodeDescription { + href: Url { + scheme: "https", + cannot_be_a_base: false, + username: "", + password: None, + host: Some( + Domain( + "ty.dev", ), - }, + ), + port: None, + path: "/rules", + query: None, + fragment: Some( + "invalid-return-type", + ), }, - ), - source: Some( - "ty", - ), - message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, - tags: None, - data: None, - }, - ], - }, + }, + ), + source: Some( + "ty", + ), + message: "Return type does not match returned value: expected `str`, found `Literal[42]`", + tags: None, + related_information: None, + data: None, + }, + ], }, - ), - Full( - WorkspaceFullDocumentDiagnosticReport { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/src/unchanged.py", - query: None, - fragment: None, - }, - version: Some( - 1, + }, + ), + WorkspaceFullDocumentDiagnosticReport( + WorkspaceFullDocumentDiagnosticReport { + uri: Url { + scheme: "file", + cannot_be_a_base: false, + username: "", + password: None, + host: None, + port: None, + path: "/src/unchanged.py", + query: None, + fragment: None, + }, + version: Some( + 1, + ), + full_document_diagnostic_report: FullDocumentDiagnosticReport { + result_id: Some( + "[RESULT_ID]", ), - full_document_diagnostic_report: FullDocumentDiagnosticReport { - result_id: Some( - "[RESULT_ID]", - ), - items: [ - Diagnostic { - range: Range { - start: Position { - line: 1, - character: 11, - }, - end: Position { - line: 1, - character: 13, - }, + items: [ + Diagnostic { + range: Range { + start: Position { + line: 1, + character: 11, }, - severity: Some( - Error, - ), - code: Some( - String( - "invalid-return-type", - ), + end: Position { + line: 1, + character: 13, + }, + }, + severity: Some( + Error, + ), + code: Some( + String( + "invalid-return-type", ), - code_description: Some( - CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "ty.dev", - ), + ), + code_description: Some( + CodeDescription { + href: Url { + scheme: "https", + cannot_be_a_base: false, + username: "", + password: None, + host: Some( + Domain( + "ty.dev", ), - port: None, - path: "/rules", - query: None, - fragment: Some( - "invalid-return-type", - ), - }, + ), + port: None, + path: "/rules", + query: None, + fragment: Some( + "invalid-return-type", + ), }, - ), - source: Some( - "ty", - ), - message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, - tags: None, - data: None, - }, - ], - }, + }, + ), + source: Some( + "ty", + ), + message: "Return type does not match returned value: expected `str`, found `Literal[42]`", + tags: None, + related_information: None, + data: None, + }, + ], }, - ), - ], - }, -) + }, + ), + ], +} diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_long_polling_change_response.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_long_polling_change_response.snap index e1e5223e0dd20..5ce124d740fd4 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_long_polling_change_response.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_long_polling_change_response.snap @@ -2,82 +2,80 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: workspace_response --- -Report( - WorkspaceDiagnosticReport { - items: [ - Full( - WorkspaceFullDocumentDiagnosticReport { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/src/test.py", - query: None, - fragment: None, - }, - version: Some( - 2, +WorkspaceDiagnosticReport { + items: [ + WorkspaceFullDocumentDiagnosticReport( + WorkspaceFullDocumentDiagnosticReport { + uri: Url { + scheme: "file", + cannot_be_a_base: false, + username: "", + password: None, + host: None, + port: None, + path: "/src/test.py", + query: None, + fragment: None, + }, + version: Some( + 2, + ), + full_document_diagnostic_report: FullDocumentDiagnosticReport { + result_id: Some( + "[RESULT_ID]", ), - full_document_diagnostic_report: FullDocumentDiagnosticReport { - result_id: Some( - "[RESULT_ID]", - ), - items: [ - Diagnostic { - range: Range { - start: Position { - line: 1, - character: 11, - }, - end: Position { - line: 1, - character: 13, - }, + items: [ + Diagnostic { + range: Range { + start: Position { + line: 1, + character: 11, }, - severity: Some( - Error, - ), - code: Some( - String( - "invalid-return-type", - ), + end: Position { + line: 1, + character: 13, + }, + }, + severity: Some( + Error, + ), + code: Some( + String( + "invalid-return-type", ), - code_description: Some( - CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "ty.dev", - ), + ), + code_description: Some( + CodeDescription { + href: Url { + scheme: "https", + cannot_be_a_base: false, + username: "", + password: None, + host: Some( + Domain( + "ty.dev", ), - port: None, - path: "/rules", - query: None, - fragment: Some( - "invalid-return-type", - ), - }, + ), + port: None, + path: "/rules", + query: None, + fragment: Some( + "invalid-return-type", + ), }, - ), - source: Some( - "ty", - ), - message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, - tags: None, - data: None, - }, - ], - }, + }, + ), + source: Some( + "ty", + ), + message: "Return type does not match returned value: expected `str`, found `Literal[42]`", + tags: None, + related_information: None, + data: None, + }, + ], }, - ), - ], - }, -) + }, + ), + ], +} diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_long_polling_shutdown_response.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_long_polling_shutdown_response.snap index fb97ba434a6ae..1ce265b6ad616 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_long_polling_shutdown_response.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_long_polling_shutdown_response.snap @@ -2,8 +2,6 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: workspace_response --- -Report( - WorkspaceDiagnosticReport { - items: [], - }, -) +WorkspaceDiagnosticReport { + items: [], +} diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_streaming_with_caching.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_streaming_with_caching.snap index d6832c5425bb1..5503bef863c19 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_streaming_with_caching.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_streaming_with_caching.snap @@ -3,7 +3,7 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: all_items --- [ - Full( + WorkspaceFullDocumentDiagnosticReport( WorkspaceFullDocumentDiagnosticReport { uri: Url { scheme: "file", @@ -68,15 +68,15 @@ expression: all_items "ty", ), message: "Name `true` used when not defined", - related_information: None, tags: None, + related_information: None, data: None, }, ], }, }, ), - Full( + WorkspaceFullDocumentDiagnosticReport( WorkspaceFullDocumentDiagnosticReport { uri: Url { scheme: "file", @@ -141,15 +141,15 @@ expression: all_items "ty", ), message: "Name `true` used when not defined", - related_information: None, tags: None, + related_information: None, data: None, }, ], }, }, ), - Full( + WorkspaceFullDocumentDiagnosticReport( WorkspaceFullDocumentDiagnosticReport { uri: Url { scheme: "file", @@ -214,15 +214,15 @@ expression: all_items "ty", ), message: "Name `true` used when not defined", - related_information: None, tags: None, + related_information: None, data: None, }, ], }, }, ), - Unchanged( + WorkspaceUnchangedDocumentDiagnosticReport( WorkspaceUnchangedDocumentDiagnosticReport { uri: Url { scheme: "file", @@ -241,7 +241,7 @@ expression: all_items }, }, ), - Unchanged( + WorkspaceUnchangedDocumentDiagnosticReport( WorkspaceUnchangedDocumentDiagnosticReport { uri: Url { scheme: "file", @@ -260,7 +260,7 @@ expression: all_items }, }, ), - Unchanged( + WorkspaceUnchangedDocumentDiagnosticReport( WorkspaceUnchangedDocumentDiagnosticReport { uri: Url { scheme: "file", @@ -279,7 +279,7 @@ expression: all_items }, }, ), - Unchanged( + WorkspaceUnchangedDocumentDiagnosticReport( WorkspaceUnchangedDocumentDiagnosticReport { uri: Url { scheme: "file", diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_suspend_change_suspend_first_response.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_suspend_change_suspend_first_response.snap index 20524855606e0..be27fc05d3de0 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_suspend_change_suspend_first_response.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_suspend_change_suspend_first_response.snap @@ -2,82 +2,80 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: first_response --- -Report( - WorkspaceDiagnosticReport { - items: [ - Full( - WorkspaceFullDocumentDiagnosticReport { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/src/test.py", - query: None, - fragment: None, - }, - version: Some( - 2, +WorkspaceDiagnosticReport { + items: [ + WorkspaceFullDocumentDiagnosticReport( + WorkspaceFullDocumentDiagnosticReport { + uri: Url { + scheme: "file", + cannot_be_a_base: false, + username: "", + password: None, + host: None, + port: None, + path: "/src/test.py", + query: None, + fragment: None, + }, + version: Some( + 2, + ), + full_document_diagnostic_report: FullDocumentDiagnosticReport { + result_id: Some( + "[RESULT_ID]", ), - full_document_diagnostic_report: FullDocumentDiagnosticReport { - result_id: Some( - "[RESULT_ID]", - ), - items: [ - Diagnostic { - range: Range { - start: Position { - line: 1, - character: 11, - }, - end: Position { - line: 1, - character: 13, - }, + items: [ + Diagnostic { + range: Range { + start: Position { + line: 1, + character: 11, }, - severity: Some( - Error, - ), - code: Some( - String( - "invalid-return-type", - ), + end: Position { + line: 1, + character: 13, + }, + }, + severity: Some( + Error, + ), + code: Some( + String( + "invalid-return-type", ), - code_description: Some( - CodeDescription { - href: Url { - scheme: "https", - cannot_be_a_base: false, - username: "", - password: None, - host: Some( - Domain( - "ty.dev", - ), + ), + code_description: Some( + CodeDescription { + href: Url { + scheme: "https", + cannot_be_a_base: false, + username: "", + password: None, + host: Some( + Domain( + "ty.dev", ), - port: None, - path: "/rules", - query: None, - fragment: Some( - "invalid-return-type", - ), - }, + ), + port: None, + path: "/rules", + query: None, + fragment: Some( + "invalid-return-type", + ), }, - ), - source: Some( - "ty", - ), - message: "Return type does not match returned value: expected `str`, found `Literal[42]`", - related_information: None, - tags: None, - data: None, - }, - ], - }, + }, + ), + source: Some( + "ty", + ), + message: "Return type does not match returned value: expected `str`, found `Literal[42]`", + tags: None, + related_information: None, + data: None, + }, + ], }, - ), - ], - }, -) + }, + ), + ], +} diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_suspend_change_suspend_second_response.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_suspend_change_suspend_second_response.snap index 1276eabc94d89..68cbc4702277c 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_suspend_change_suspend_second_response.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_diagnostic_suspend_change_suspend_second_response.snap @@ -2,31 +2,29 @@ source: crates/ty_server/tests/e2e/pull_diagnostics.rs expression: second_response --- -Report( - WorkspaceDiagnosticReport { - items: [ - Full( - WorkspaceFullDocumentDiagnosticReport { - uri: Url { - scheme: "file", - cannot_be_a_base: false, - username: "", - password: None, - host: None, - port: None, - path: "/src/test.py", - query: None, - fragment: None, - }, - version: Some( - 3, - ), - full_document_diagnostic_report: FullDocumentDiagnosticReport { - result_id: None, - items: [], - }, +WorkspaceDiagnosticReport { + items: [ + WorkspaceFullDocumentDiagnosticReport( + WorkspaceFullDocumentDiagnosticReport { + uri: Url { + scheme: "file", + cannot_be_a_base: false, + username: "", + password: None, + host: None, + port: None, + path: "/src/test.py", + query: None, + fragment: None, }, - ), - ], - }, -) + version: Some( + 3, + ), + full_document_diagnostic_report: FullDocumentDiagnosticReport { + result_id: None, + items: [], + }, + }, + ), + ], +} diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_reports_current_analysis_unreachable_code_hint_tag.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_reports_current_analysis_unreachable_code_hint_tag.snap index 3bee0a1b0a214..c96fc6df1c4a5 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_reports_current_analysis_unreachable_code_hint_tag.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_reports_current_analysis_unreachable_code_hint_tag.snap @@ -5,7 +5,6 @@ expression: diagnostics { "items": [ { - "kind": "full", "uri": "file:///src/foo.py", "version": null, "resultId": "[RESULT_ID]", @@ -28,7 +27,8 @@ expression: diagnostics 1 ] } - ] + ], + "kind": "full" } ] } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_reports_unreachable_code_hint_tag.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_reports_unreachable_code_hint_tag.snap index 1d8149413f4cf..36e681d98946a 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_reports_unreachable_code_hint_tag.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_reports_unreachable_code_hint_tag.snap @@ -5,7 +5,6 @@ expression: diagnostics { "items": [ { - "kind": "full", "uri": "file:///src/foo.py", "version": null, "resultId": "[RESULT_ID]", @@ -28,7 +27,8 @@ expression: diagnostics 1 ] } - ] + ], + "kind": "full" } ] } diff --git a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_reports_unused_binding_hint_tag.snap b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_reports_unused_binding_hint_tag.snap index ab01655f55c8b..51fc400f62185 100644 --- a/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_reports_unused_binding_hint_tag.snap +++ b/crates/ty_server/tests/e2e/snapshots/e2e__pull_diagnostics__workspace_reports_unused_binding_hint_tag.snap @@ -5,7 +5,6 @@ expression: diagnostics { "items": [ { - "kind": "full", "uri": "file:///src/foo.py", "version": null, "resultId": "[RESULT_ID]", @@ -28,7 +27,8 @@ expression: diagnostics 1 ] } - ] + ], + "kind": "full" } ] } diff --git a/crates/ty_server/tests/e2e/type_hierarchy.rs b/crates/ty_server/tests/e2e/type_hierarchy.rs index ba28b1430325d..fe9c02e4f093a 100644 --- a/crates/ty_server/tests/e2e/type_hierarchy.rs +++ b/crates/ty_server/tests/e2e/type_hierarchy.rs @@ -1,9 +1,11 @@ -use lsp_types::request::{TypeHierarchyPrepare, TypeHierarchySubtypes, TypeHierarchySupertypes}; use lsp_types::{ PartialResultParams, Position, TextDocumentIdentifier, TextDocumentPositionParams, TypeHierarchyPrepareParams, TypeHierarchySubtypesParams, TypeHierarchySupertypesParams, WorkDoneProgressParams, }; +use lsp_types::{ + TypeHierarchyPrepareRequest, TypeHierarchySubtypesRequest, TypeHierarchySupertypesRequest, +}; use crate::TestServerBuilder; @@ -161,7 +163,7 @@ fn prepare( path: impl AsRef, position: Position, ) -> Option> { - server.send_request_await::(TypeHierarchyPrepareParams { + server.send_request_await::(TypeHierarchyPrepareParams { text_document_position_params: TextDocumentPositionParams { text_document: TextDocumentIdentifier { uri: server.file_uri(path), @@ -177,7 +179,7 @@ fn supertypes( server: &mut crate::TestServer, item: lsp_types::TypeHierarchyItem, ) -> Option> { - server.send_request_await::(TypeHierarchySupertypesParams { + server.send_request_await::(TypeHierarchySupertypesParams { item, work_done_progress_params: WorkDoneProgressParams::default(), partial_result_params: PartialResultParams::default(), @@ -189,7 +191,7 @@ fn subtypes( server: &mut crate::TestServer, item: lsp_types::TypeHierarchyItem, ) -> Option> { - server.send_request_await::(TypeHierarchySubtypesParams { + server.send_request_await::(TypeHierarchySubtypesParams { item, work_done_progress_params: WorkDoneProgressParams::default(), partial_result_params: PartialResultParams::default(), diff --git a/crates/ty_server/tests/e2e/workspace_folders.rs b/crates/ty_server/tests/e2e/workspace_folders.rs index cac232dc13600..75c99897f0372 100644 --- a/crates/ty_server/tests/e2e/workspace_folders.rs +++ b/crates/ty_server/tests/e2e/workspace_folders.rs @@ -1,10 +1,8 @@ use anyhow::Result; use insta::assert_snapshot; use lsp_types::{ - DiagnosticSeverity, DocumentDiagnosticReport, DocumentDiagnosticReportResult, - FullDocumentDiagnosticReport, Position, WorkspaceDiagnosticReport, - WorkspaceDiagnosticReportPartialResult, WorkspaceDiagnosticReportResult, - WorkspaceDocumentDiagnosticReport, + DiagnosticSeverity, DocumentDiagnosticReport, FullDocumentDiagnosticReport, Position, + WorkspaceDiagnosticReport, WorkspaceDocumentDiagnosticReport, }; use ruff_db::system::SystemPath; use ty_server::{ClientOptions, DiagnosticMode, GlobalOptions, WorkspaceOptions}; @@ -705,24 +703,23 @@ fn global_settings_change() -> Result<()> { /// LSP is correctly recognizing and reporting diagnostics for each /// workspace folder. This isn't really meant to test the diagnostics /// themselves, hence the condensed output. -fn condensed_workspace_diagnostic_snapshot(report: WorkspaceDiagnosticReportResult) -> String { - let items = match report { - WorkspaceDiagnosticReportResult::Report(WorkspaceDiagnosticReport { items }) => items, - WorkspaceDiagnosticReportResult::Partial(WorkspaceDiagnosticReportPartialResult { - items, - }) => items, - }; +fn condensed_workspace_diagnostic_snapshot(report: WorkspaceDiagnosticReport) -> String { + let items = report.items; items .into_iter() .map(|item| match item { - WorkspaceDocumentDiagnosticReport::Full(doc_report) => { + WorkspaceDocumentDiagnosticReport::WorkspaceFullDocumentDiagnosticReport( + doc_report, + ) => { let diagnostics = condensed_full_document_diagnostic_report( doc_report.full_document_diagnostic_report, ) .join("\n\t"); format!("{}\n\t{diagnostics}", doc_report.uri) } - WorkspaceDocumentDiagnosticReport::Unchanged(doc_report) => { + WorkspaceDocumentDiagnosticReport::WorkspaceUnchangedDocumentDiagnosticReport( + doc_report, + ) => { format!("{}\n\tUNCHANGED", doc_report.uri) } }) @@ -730,21 +727,18 @@ fn condensed_workspace_diagnostic_snapshot(report: WorkspaceDiagnosticReportResu .join("\n") } -pub(crate) fn condensed_document_diagnostic_snapshot( - report: DocumentDiagnosticReportResult, -) -> String { +pub(crate) fn condensed_document_diagnostic_snapshot(report: DocumentDiagnosticReport) -> String { match report { - DocumentDiagnosticReportResult::Report(DocumentDiagnosticReport::Full(full)) => { + DocumentDiagnosticReport::RelatedFullDocumentDiagnosticReport(full) => { condensed_full_document_diagnostic_report(full.full_document_diagnostic_report) .join("\n") } // NOTE: It might be worth providing more details for these // cases, but I don't think there's currently a use case for // it. - DocumentDiagnosticReportResult::Report(DocumentDiagnosticReport::Unchanged(_)) => { + DocumentDiagnosticReport::RelatedUnchangedDocumentDiagnosticReport(_) => { "UNCHANGED".to_string() } - DocumentDiagnosticReportResult::Partial(_) => "PARTIAL".to_string(), } } @@ -761,11 +755,11 @@ fn condensed_full_document_diagnostic_report(report: FullDocumentDiagnosticRepor end_char = d.range.end.character, ); let severity = match d.severity { - Some(DiagnosticSeverity::ERROR) => "ERROR", - Some(DiagnosticSeverity::WARNING) => "WARNING", - Some(DiagnosticSeverity::INFORMATION) => "INFORMATION", - Some(DiagnosticSeverity::HINT) => "HINT", - None | Some(_) => "unknown", + Some(DiagnosticSeverity::Error) => "ERROR", + Some(DiagnosticSeverity::Warning) => "WARNING", + Some(DiagnosticSeverity::Information) => "INFORMATION", + Some(DiagnosticSeverity::Hint) => "HINT", + None => "unknown", }; format!("{range}[{severity}]: {message}", message = d.message) }) @@ -787,7 +781,7 @@ fn condensed_full_document_diagnostic_report(report: FullDocumentDiagnosticRepor /// expect to never have a response for. fn get_expected_empty_workspace_diagnostics_and_shutdown( mut server: TestServer, -) -> WorkspaceDiagnosticReportResult { +) -> WorkspaceDiagnosticReport { let request_id = send_workspace_diagnostic_request(&mut server); assert_workspace_diagnostics_suspends_for_long_polling(&mut server, &request_id); shutdown_and_await_workspace_diagnostic(server, &request_id)