Unnamed repository; edit this file 'description' to name the repository.
Revert "Merge pull request #22115 from BenjaminBrienen/gen-lsp-types"
This reverts commit 3f41d0b249859a974ca165cc39184948f07b1d81, reversing
changes made to 53daf99e1f78bf9a775fcd6b9fbfdd81342b32eb.
39 files changed, 1370 insertions, 1973 deletions
diff --git a/Cargo.lock b/Cargo.lock index 67cfcbdcaa..aca2d553b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -136,6 +136,12 @@ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" [[package]] name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" version = "2.12.1" ||||||| parent of 527dfbec94 (hmmm2) version = "2.9.4" @@ -623,7 +629,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" <<<<<<< HEAD checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags", + "bitflags 2.12.1", "block2", "libc", "objc2", @@ -819,17 +825,6 @@ dependencies = [ ] [[package]] -name = "gen-lsp-types" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5b8ec601e62362b666a3def1fed667ee87b10a4507402618376d142a05373c6" -dependencies = [ - "serde", - "serde_json", - "url", -] - -[[package]] name = "getrandom" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1003,7 +998,7 @@ version = "0.0.0" dependencies = [ "arrayvec", "base-db", - "bitflags", + "bitflags 2.12.1", "cfg", "cov-mark", "drop_bomb", @@ -1068,7 +1063,7 @@ version = "0.0.0" dependencies = [ "arrayvec", "base-db", - "bitflags", + "bitflags 2.12.1", "cov-mark", "either", "ena", @@ -1361,7 +1356,7 @@ version = "0.0.0" dependencies = [ "arrayvec", "base-db", - "bitflags", + "bitflags 2.12.1", "cov-mark", "crossbeam-channel", "either", @@ -1483,7 +1478,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "533e68a5842e734946fe159fb03fc9bbbb254f590dd0d8ad321ae5ff7beca2c1" dependencies = [ - "bitflags", + "bitflags 2.12.1", "inotify-sys", "libc", ] @@ -1609,7 +1604,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" dependencies = [ - "bitflags", + "bitflags 2.12.1", "libc", ] @@ -1770,30 +1765,43 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lsp-server" version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d6ada348dbc2703cbe7637b2dda05cff84d3da2819c24abcb305dd613e0ba2e" dependencies = [ + "anyhow", "crossbeam-channel", + "ctrlc", "log", + "lsp-types", + "rustc-hash 2.1.2", "serde", "serde_derive", "serde_json", + "toolchain", ] [[package]] name = "lsp-server" -version = "0.8.0" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d6ada348dbc2703cbe7637b2dda05cff84d3da2819c24abcb305dd613e0ba2e" dependencies = [ - "anyhow", "crossbeam-channel", - "ctrlc", - "gen-lsp-types", "log", - "rustc-hash 2.1.2", "serde", "serde_derive", "serde_json", - "toolchain", +] + +[[package]] +name = "lsp-types" +version = "0.95.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "158c1911354ef73e8fe42da6b10c0484cb65c7f1007f28022e847706c1ab6984" +dependencies = [ + "bitflags 1.3.2", + "serde", + "serde_json", + "serde_repr", + "url", ] [[package]] @@ -1811,7 +1819,7 @@ name = "mbe" version = "0.0.0" dependencies = [ "arrayvec", - "bitflags", + "bitflags 2.12.1", "cov-mark", "expect-test", "intern", @@ -1914,7 +1922,7 @@ version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ - "bitflags", + "bitflags 2.12.1", "cfg-if", "cfg_aliases", "libc", @@ -1932,7 +1940,7 @@ version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags", + "bitflags 2.12.1", "fsevent-sys", "inotify", "kqueue", @@ -1950,7 +1958,7 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" dependencies = [ - "bitflags", + "bitflags 2.12.1", ] [[package]] @@ -2369,7 +2377,7 @@ checksum = "37566cb3fdacef14c0737f9546df7cfeadbfbc9fef10991038bf5015d0c80532" dependencies = [ "bit-set", "bit-vec", - "bitflags", + "bitflags 2.12.1", "num-traits", "rand", "rand_chacha", @@ -2406,7 +2414,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags", + "bitflags 2.12.1", "memchr", "unicase", ] @@ -2477,7 +2485,7 @@ version = "0.165.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f25a779e21ca3bba6795193b16508c8ab159f96ee4b07349893fd272065b525" dependencies = [ - "bitflags", + "bitflags 2.12.1", "ra-ap-rustc_hashes", "ra-ap-rustc_index", "tracing", @@ -2572,7 +2580,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c5d9a4d3e7bee7313599bc6d794037247ac0165f03857379cf4fc3097199e05" dependencies = [ "arrayvec", - "bitflags", + "bitflags 2.12.1", "derive-where", "ena", "indexmap", @@ -2662,7 +2670,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags", + "bitflags 2.12.1", ] [[package]] @@ -2743,7 +2751,6 @@ dependencies = [ "dirs", "dissimilar", "expect-test", - "gen-lsp-types", "hir", "hir-def", "hir-ty", @@ -2755,7 +2762,8 @@ dependencies = [ "intern", "itertools 0.15.0", "load-cargo", - "lsp-server 0.7.9", + "lsp-server 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lsp-types", "memchr", "mimalloc", "num_cpus", @@ -2833,7 +2841,7 @@ version = "0.2.3+llvm-462a31f5a5ab" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "486c2179b4796f65bfe2ee33679acf0927ac83ecf583ad6c91c3b4570911b9ad" dependencies = [ - "bitflags", + "bitflags 2.12.1", "smallvec", ] @@ -2855,7 +2863,7 @@ checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" >>>>>>> 527dfbec94 (hmmm2) dependencies = [ - "bitflags", + "bitflags 2.12.1", "errno", "libc", "linux-raw-sys", @@ -2990,9 +2998,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "indexmap", "itoa", @@ -3004,6 +3012,17 @@ dependencies = [ ] [[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" <<<<<<< HEAD version = "1.1.1" @@ -3961,7 +3980,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags", + "bitflags 2.12.1", "hashbrown 0.15.5", "indexmap", "semver", @@ -4336,7 +4355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags", + "bitflags 2.12.1", "indexmap", "log", "serde", diff --git a/crates/rust-analyzer/src/bin/mod.rs b/crates/rust-analyzer/src/bin/mod.rs index e4e8f9daf3..552e3f57b9 100644 --- a/crates/rust-analyzer/src/bin/mod.rs +++ b/crates/rust-analyzer/src/bin/mod.rs @@ -233,15 +233,25 @@ pub fn run_server(connection: Connection) -> anyhow::Result<()> { tracing::info!("InitializeParams: {}", initialize_params); let lsp_types::InitializeParams { - #[expect(deprecated, reason = "compatibility with old clients")] root_uri, - capabilities, - workspace_folders_initialize_params, + mut capabilities, + workspace_folders, initialization_options, client_info, .. } = from_json::<lsp_types::InitializeParams>("InitializeParams", &initialize_params)?; + // lsp-types has a typo in the `/capabilities/workspace/diagnostics` field, its typoed as `diagnostic` + if let Some(val) = initialize_params.pointer("/capabilities/workspace/diagnostics") + && let Ok(diag_caps) = from_json::<lsp_types::DiagnosticWorkspaceClientCapabilities>( + "DiagnosticWorkspaceClientCapabilities", + val, + ) + { + tracing::info!("Patching lsp-types workspace diagnostics capabilities: {diag_caps:#?}"); + capabilities.workspace.get_or_insert_default().diagnostic.get_or_insert(diag_caps); + } + let root_path = match root_uri .and_then(|it| it.to_file_path().ok()) .map(patch_path_prefix) @@ -263,14 +273,7 @@ pub fn run_server(connection: Connection) -> anyhow::Result<()> { ); } - let workspace_roots = workspace_folders_initialize_params - .workspace_folders - .and_then(|workspaces| match workspaces { - lsp_types::WorkspaceFolders::WorkspaceFolderList(workspace_folders) => { - Some(workspace_folders) - } - lsp_types::WorkspaceFolders::Null => None, - }) + let workspace_roots = workspace_folders .map(|workspaces| { workspaces .into_iter() @@ -292,11 +295,12 @@ pub fn run_server(connection: Connection) -> anyhow::Result<()> { if !error_sink.is_empty() { use lsp_types::{ - MessageType, Notification as _, ShowMessageNotification, ShowMessageParams, + MessageType, ShowMessageParams, + notification::{Notification, ShowMessage}, }; let not = lsp_server::Notification::new( - ShowMessageNotification::METHOD.into(), - ShowMessageParams { kind: MessageType::Warning, message: error_sink.to_string() }, + ShowMessage::METHOD.to_owned(), + ShowMessageParams { typ: MessageType::WARNING, message: error_sink.to_string() }, ); connection.sender.send(lsp_server::Message::Notification(not)).unwrap(); } @@ -310,6 +314,7 @@ pub fn run_server(connection: Connection) -> anyhow::Result<()> { name: String::from("rust-analyzer"), version: Some(crate::version().to_string()), }), + offset_encoding: None, }; let initialize_result = serde_json::to_value(initialize_result).unwrap(); diff --git a/crates/rust-analyzer/src/cli/lsif.rs b/crates/rust-analyzer/src/cli/lsif.rs index 8a1d5f336d..4f6de6850a 100644 --- a/crates/rust-analyzer/src/cli/lsif.rs +++ b/crates/rust-analyzer/src/cli/lsif.rs @@ -1,4 +1,5 @@ //! LSIF (language server index format) generator + use std::env; use std::time::Instant; @@ -9,14 +10,12 @@ use ide::{ }; use ide_db::{line_index, line_index::WideEncoding}; use load_cargo::{LoadCargoConfig, ProcMacroServerChoice, load_workspace}; +use lsp_types::lsif; use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace, RustLibSource}; use rustc_hash::FxHashMap; use stdx::format_to; -use vendored as lsif; use vfs::{AbsPathBuf, Vfs}; -mod vendored; - use crate::{ cli::flags, line_index::{LineEndings, LineIndex, PositionEncoding}, @@ -39,9 +38,9 @@ struct LsifManager<'a, 'w> { #[derive(Clone, Copy)] struct Id(i32); -impl From<Id> for lsp_types::Code { +impl From<Id> for lsp_types::NumberOrString { fn from(Id(it): Id) -> Self { - lsp_types::Code::Int(it) + lsp_types::NumberOrString::Number(it) } } @@ -146,7 +145,7 @@ impl LsifManager<'_, '_> { let path = path.as_path().unwrap(); let doc_id = self.add_vertex(lsif::Vertex::Document(lsif::Document { language_id: "rust".to_owned(), - uri: lsp_types::Uri::from_file_path(path).unwrap(), + uri: lsp_types::Url::from_file_path(path).unwrap(), })); self.file_map.insert(id, doc_id); doc_id @@ -157,7 +156,7 @@ impl LsifManager<'_, '_> { if let Some(hover) = token.hover { let hover_id = self.add_vertex(lsif::Vertex::HoverResult { result: lsp_types::Hover { - contents: lsp_types::Contents::MarkupContent(to_proto::markup_content( + contents: lsp_types::HoverContents::Markup(to_proto::markup_content( hover.markup, ide::HoverDocFormat::Markdown, )), @@ -212,7 +211,7 @@ impl LsifManager<'_, '_> { out_v: result_set_id.into(), })); let mut edges = token.references.iter().fold( - FxHashMap::<_, Vec<lsp_types::Code>>::default(), + FxHashMap::<_, Vec<lsp_types::NumberOrString>>::default(), |mut edges, it| { let entry = edges.entry((it.range.file_id, it.is_definition)).or_default(); entry.push((*self.range_map.get(&it.range).unwrap()).into()); @@ -322,9 +321,9 @@ impl flags::Lsif { let mut lsif = LsifManager::new(&analysis, db, &vfs, out); lsif.add_vertex(lsif::Vertex::MetaData(lsif::MetaData { version: String::from("0.5.0"), - project_root: lsp_types::Uri::from_file_path(path).unwrap(), + project_root: lsp_types::Url::from_file_path(path).unwrap(), position_encoding: lsif::Encoding::Utf16, - tool_info: Some(lsif::ToolInfo { + tool_info: Some(lsp_types::lsif::ToolInfo { name: "rust-analyzer".to_owned(), args: vec![], version: Some(version().to_string()), diff --git a/crates/rust-analyzer/src/cli/lsif/vendored.rs b/crates/rust-analyzer/src/cli/lsif/vendored.rs deleted file mode 100644 index cad2514bec..0000000000 --- a/crates/rust-analyzer/src/cli/lsif/vendored.rs +++ /dev/null @@ -1,338 +0,0 @@ -//! Types of Language Server Index Format (LSIF). LSIF is a standard format -//! for language servers or other programming tools to dump their knowledge -//! about a workspace. -//! -//! Based on <https://microsoft.github.io/language-server-protocol/specifications/lsif/0.6.0/specification/> - -#![allow(unused, unreachable_pub, reason = "implementing the full spec is fine")] - -use lsp_types::{Range, Uri}; -use serde::{Deserialize, Serialize}; - -pub type Id = lsp_types::Code; - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(untagged)] -pub enum LocationOrRangeId { - Location(lsp_types::Location), - RangeId(Id), -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Entry { - pub id: Id, - #[serde(flatten)] - pub data: Element, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -#[serde(tag = "type")] -pub enum Element { - Vertex(Vertex), - Edge(Edge), -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -pub struct ToolInfo { - pub name: String, - #[serde(default = "Default::default")] - #[serde(skip_serializing_if = "Vec::is_empty")] - pub args: Vec<String>, - #[serde(skip_serializing_if = "Option::is_none")] - pub version: Option<String>, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, Copy)] -pub enum Encoding { - /// Currently only 'utf-16' is supported due to the limitations in LSP. - #[serde(rename = "utf-16")] - Utf16, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -pub struct RangeBasedDocumentSymbol { - pub id: Id, - #[serde(default = "Default::default")] - #[serde(skip_serializing_if = "Vec::is_empty")] - pub children: Vec<RangeBasedDocumentSymbol>, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -#[serde(untagged)] -pub enum DocumentSymbolOrRangeBasedVec { - DocumentSymbol(Vec<lsp_types::DocumentSymbol>), - RangeBased(Vec<RangeBasedDocumentSymbol>), -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct DefinitionTag { - /// The text covered by the range - text: String, - /// The symbol kind. - kind: lsp_types::SymbolKind, - /// Indicates if this symbol is deprecated. - #[serde(default)] - #[serde(skip_serializing_if = "std::ops::Not::not")] - deprecated: bool, - /// The full range of the definition not including leading/trailing whitespace but everything else, e.g comments and code. - /// The range must be included in fullRange. - full_range: Range, - /// Optional detail information for the definition. - #[serde(skip_serializing_if = "Option::is_none")] - detail: Option<String>, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct DeclarationTag { - /// The text covered by the range - text: String, - /// The symbol kind. - kind: lsp_types::SymbolKind, - /// Indicates if this symbol is deprecated. - #[serde(default)] - deprecated: bool, - /// The full range of the definition not including leading/trailing whitespace but everything else, e.g comments and code. - /// The range must be included in fullRange. - full_range: Range, - /// Optional detail information for the definition. - #[serde(skip_serializing_if = "Option::is_none")] - detail: Option<String>, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ReferenceTag { - text: String, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct UnknownTag { - text: String, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -#[serde(tag = "type")] -pub enum RangeTag { - Definition(DefinitionTag), - Declaration(DeclarationTag), - Reference(ReferenceTag), - Unknown(UnknownTag), -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -#[serde(tag = "label")] -pub enum Vertex { - MetaData(MetaData), - /// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#the-project-vertex> - Project(Project), - Document(Document), - /// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#ranges> - Range { - #[serde(flatten)] - range: Range, - #[serde(skip_serializing_if = "Option::is_none")] - tag: Option<RangeTag>, - }, - /// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#result-set> - ResultSet(ResultSet), - Moniker(lsp_types::Moniker), - PackageInformation(PackageInformation), - - #[serde(rename = "$event")] - Event(Event), - - DefinitionResult, - DeclarationResult, - TypeDefinitionResult, - ReferenceResult, - ImplementationResult, - FoldingRangeResult { - result: Vec<lsp_types::FoldingRange>, - }, - HoverResult { - result: lsp_types::Hover, - }, - DocumentSymbolResult { - result: DocumentSymbolOrRangeBasedVec, - }, - DocumentLinkResult { - result: Vec<lsp_types::DocumentLink>, - }, - DiagnosticResult { - result: Vec<lsp_types::Diagnostic>, - }, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub enum EventKind { - Begin, - End, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub enum EventScope { - Document, - Project, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -pub struct Event { - pub kind: EventKind, - pub scope: EventScope, - pub data: Id, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -#[serde(tag = "label")] -pub enum Edge { - Contains(EdgeDataMultiIn), - Moniker(EdgeData), - NextMoniker(EdgeData), - Next(EdgeData), - PackageInformation(EdgeData), - Item(Item), - - // Methods - #[serde(rename = "textDocument/definition")] - Definition(EdgeData), - #[serde(rename = "textDocument/declaration")] - Declaration(EdgeData), - #[serde(rename = "textDocument/hover")] - Hover(EdgeData), - #[serde(rename = "textDocument/references")] - References(EdgeData), - #[serde(rename = "textDocument/implementation")] - Implementation(EdgeData), - #[serde(rename = "textDocument/typeDefinition")] - TypeDefinition(EdgeData), - #[serde(rename = "textDocument/foldingRange")] - FoldingRange(EdgeData), - #[serde(rename = "textDocument/documentLink")] - DocumentLink(EdgeData), - #[serde(rename = "textDocument/documentSymbol")] - DocumentSymbol(EdgeData), - #[serde(rename = "textDocument/diagnostic")] - Diagnostic(EdgeData), -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct EdgeData { - pub in_v: Id, - pub out_v: Id, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct EdgeDataMultiIn { - pub in_vs: Vec<Id>, - pub out_v: Id, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(untagged)] -pub enum DefinitionResultType { - Scalar(LocationOrRangeId), - Array(LocationOrRangeId), -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub enum ItemKind { - Declarations, - Definitions, - References, - ReferenceResults, - ImplementationResults, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Item { - pub document: Id, - #[serde(skip_serializing_if = "Option::is_none")] - pub property: Option<ItemKind>, - #[serde(flatten)] - pub edge_data: EdgeDataMultiIn, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Document { - pub uri: Uri, - pub language_id: String, -} - -/// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#result-set> -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct ResultSet { - #[serde(skip_serializing_if = "Option::is_none")] - pub key: Option<String>, -} - -/// <https://github.com/Microsoft/language-server-protocol/blob/master/indexFormat/specification.md#the-project-vertex> -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Project { - #[serde(skip_serializing_if = "Option::is_none")] - pub resource: Option<Uri>, - #[serde(skip_serializing_if = "Option::is_none")] - pub content: Option<String>, - pub kind: String, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct MetaData { - /// The version of the LSIF format using semver notation. See <https://semver.org/>. Please note - /// the version numbers starting with 0 don't adhere to semver and adopters have to assume - /// that each new version is breaking. - pub version: String, - - /// The project root (in form of an URI) used to compute this dump. - pub project_root: Uri, - - /// The string encoding used to compute line and character values in - /// positions and ranges. - pub position_encoding: Encoding, - - /// Information about the tool that created the dump - #[serde(skip_serializing_if = "Option::is_none")] - pub tool_info: Option<ToolInfo>, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct Repository { - pub r#type: String, - pub url: String, - #[serde(skip_serializing_if = "Option::is_none")] - pub commit_id: Option<String>, -} - -#[derive(Debug, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct PackageInformation { - pub name: String, - pub manager: String, - #[serde(skip_serializing_if = "Option::is_none")] - pub uri: Option<Uri>, - #[serde(skip_serializing_if = "Option::is_none")] - pub content: Option<String>, - #[serde(skip_serializing_if = "Option::is_none")] - pub repository: Option<Repository>, - #[serde(skip_serializing_if = "Option::is_none")] - pub version: Option<String>, -} diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 552fb079c2..1b124ddfd6 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs @@ -1131,7 +1131,7 @@ pub struct Config { default_config: &'static DefaultConfigData, /// Config node that obtains its initial value during the server initialization and - /// by receiving a [`lsp_types::DidChangeConfigurationNotification`]. + /// by receiving a `lsp_types::notification::DidChangeConfiguration`. client_config: (FullConfigInput, ConfigErrors), /// Config node whose values apply to **every** Rust project. diff --git a/crates/rust-analyzer/src/diagnostics.rs b/crates/rust-analyzer/src/diagnostics.rs index f690e38585..8bc4a2c4e9 100644 --- a/crates/rust-analyzer/src/diagnostics.rs +++ b/crates/rust-analyzer/src/diagnostics.rs @@ -358,14 +358,14 @@ pub(crate) fn convert_diagnostic( lsp_types::Diagnostic { range: lsp::to_proto::range(line_index, d.range.range), severity: Some(lsp::to_proto::diagnostic_severity(d.severity)), - code: Some(lsp_types::Code::String(d.code.as_str().to_owned())), + code: Some(lsp_types::NumberOrString::String(d.code.as_str().to_owned())), code_description: Some(lsp_types::CodeDescription { - href: lsp_types::Uri::parse(&d.code.url()).unwrap(), + href: lsp_types::Url::parse(&d.code.url()).unwrap(), }), source: Some("rust-analyzer".to_owned()), message: d.message, related_information: None, - tags: d.unused.then(|| vec![lsp_types::DiagnosticTag::Unnecessary]), + tags: d.unused.then(|| vec![lsp_types::DiagnosticTag::UNNECESSARY]), data: None, } } diff --git a/crates/rust-analyzer/src/diagnostics/flycheck_to_proto.rs b/crates/rust-analyzer/src/diagnostics/flycheck_to_proto.rs index 750e3fe9cd..602f494c5c 100644 --- a/crates/rust-analyzer/src/diagnostics/flycheck_to_proto.rs +++ b/crates/rust-analyzer/src/diagnostics/flycheck_to_proto.rs @@ -22,8 +22,8 @@ fn diagnostic_severity( code: Option<&crate::flycheck::DiagnosticCode>, ) -> Option<lsp_types::DiagnosticSeverity> { let res = match level { - DiagnosticLevel::Ice => lsp_types::DiagnosticSeverity::Error, - DiagnosticLevel::Error => lsp_types::DiagnosticSeverity::Error, + DiagnosticLevel::Ice => lsp_types::DiagnosticSeverity::ERROR, + DiagnosticLevel::Error => lsp_types::DiagnosticSeverity::ERROR, DiagnosticLevel::Warning => match code { // HACK: special case for `warnings` rustc lint. Some(code) @@ -31,7 +31,7 @@ fn diagnostic_severity( lint == "warnings" || ide_db::helpers::lint_eq_or_in_group(&code.code, lint) }) => { - lsp_types::DiagnosticSeverity::Hint + lsp_types::DiagnosticSeverity::HINT } // HACK: special case for `warnings` rustc lint. Some(code) @@ -39,12 +39,12 @@ fn diagnostic_severity( lint == "warnings" || ide_db::helpers::lint_eq_or_in_group(&code.code, lint) }) => { - lsp_types::DiagnosticSeverity::Information + lsp_types::DiagnosticSeverity::INFORMATION } - _ => lsp_types::DiagnosticSeverity::Warning, + _ => lsp_types::DiagnosticSeverity::WARNING, }, - DiagnosticLevel::Note => lsp_types::DiagnosticSeverity::Information, - DiagnosticLevel::Help => lsp_types::DiagnosticSeverity::Hint, + DiagnosticLevel::Note => lsp_types::DiagnosticSeverity::INFORMATION, + DiagnosticLevel::Help => lsp_types::DiagnosticSeverity::HINT, _ => return None, }; Some(res) @@ -192,7 +192,7 @@ fn map_rust_child_diagnostic( return MappedRustChildDiagnostic::MessageLine(rd.message.clone()); } - let mut edit_map: FxHashMap<lsp_types::Uri, Vec<lsp_types::TextEdit>> = FxHashMap::default(); + let mut edit_map: FxHashMap<lsp_types::Url, Vec<lsp_types::TextEdit>> = FxHashMap::default(); let mut suggested_replacements = Vec::new(); let mut is_preferred = true; for &span in &spans { @@ -239,7 +239,7 @@ fn map_rust_child_diagnostic( action: lsp_ext::CodeAction { title: message.clone(), group: None, - kind: Some(lsp_types::CodeActionKind::QuickFix), + kind: Some(lsp_types::CodeActionKind::QUICKFIX), edit: Some(lsp_ext::SnippetWorkspaceEdit { // FIXME: there's no good reason to use edit_map here.... changes: Some(edit_map), @@ -263,7 +263,7 @@ fn map_rust_child_diagnostic( #[derive(Debug)] pub(crate) struct MappedRustDiagnostic { - pub(crate) url: lsp_types::Uri, + pub(crate) url: lsp_types::Url, pub(crate) diagnostic: lsp_types::Diagnostic, pub(crate) fix: Option<Box<Fix>>, } @@ -351,10 +351,10 @@ pub(crate) fn map_rust_diagnostic_to_lsp( match &*code.code { "dead_code" | "unknown_lints" | "unreachable_code" | "unused_attributes" | "unused_imports" | "unused_macros" | "unused_variables" => { - tag = Some(lsp_types::DiagnosticTag::Unnecessary); + tag = Some(lsp_types::DiagnosticTag::UNNECESSARY); } "deprecated" => { - tag = Some(lsp_types::DiagnosticTag::Deprecated); + tag = Some(lsp_types::DiagnosticTag::DEPRECATED); } _ => {} } @@ -418,13 +418,13 @@ pub(crate) fn map_rust_diagnostic_to_lsp( let diagnostic = lsp_types::Diagnostic { range: secondary_location.range, // downgrade to hint if we're pointing at the macro - severity: Some(lsp_types::DiagnosticSeverity::Hint), - code: code.map(ToOwned::to_owned).map(lsp_types::Code::String), + severity: Some(lsp_types::DiagnosticSeverity::HINT), + code: code.map(ToOwned::to_owned).map(lsp_types::NumberOrString::String), code_description: code_description.clone(), source: Some(source.to_owned()), message: message.clone(), related_information: Some(information_for_additional_diagnostic), - tags: tag.map(|tag| vec![tag]), + tags: tag.clone().map(|tag| vec![tag]), data: Some(serde_json::json!({ "rendered": rendered })), }; diagnostics.push(MappedRustDiagnostic { @@ -440,7 +440,7 @@ pub(crate) fn map_rust_diagnostic_to_lsp( diagnostic: lsp_types::Diagnostic { range: primary_location.range, severity, - code: code.map(ToOwned::to_owned).map(lsp_types::Code::String), + code: code.map(ToOwned::to_owned).map(lsp_types::NumberOrString::String), code_description: code_description.clone(), source: Some(source.to_owned()), message, @@ -452,7 +452,7 @@ pub(crate) fn map_rust_diagnostic_to_lsp( .collect::<Vec<_>>(); if info.is_empty() { None } else { Some(info) } }, - tags: tag.map(|tag| vec![tag]), + tags: tag.clone().map(|tag| vec![tag]), data: Some(serde_json::json!({ "rendered": rendered })), }, // i dont like it. @@ -472,8 +472,8 @@ pub(crate) fn map_rust_diagnostic_to_lsp( fix: sub.suggested_fix.clone(), diagnostic: lsp_types::Diagnostic { range: sub.related.location.range, - severity: Some(lsp_types::DiagnosticSeverity::Hint), - code: code.map(ToOwned::to_owned).map(lsp_types::Code::String), + severity: Some(lsp_types::DiagnosticSeverity::HINT), + code: code.map(ToOwned::to_owned).map(lsp_types::NumberOrString::String), code_description: code_description.clone(), source: Some(source.to_owned()), message: sub.related.message.clone(), @@ -495,7 +495,7 @@ fn rustc_code_description(code: Option<&str>) -> Option<lsp_types::CodeDescripti && chars.next().is_none() }) .and_then(|code| { - lsp_types::Uri::parse(&format!("https://doc.rust-lang.org/error-index.html#{code}")) + lsp_types::Url::parse(&format!("https://doc.rust-lang.org/error-index.html#{code}")) .ok() .map(|href| lsp_types::CodeDescription { href }) }) @@ -503,7 +503,7 @@ fn rustc_code_description(code: Option<&str>) -> Option<lsp_types::CodeDescripti fn clippy_code_description(code: Option<&str>) -> Option<lsp_types::CodeDescription> { code.and_then(|code| { - lsp_types::Uri::parse(&format!( + lsp_types::Url::parse(&format!( "https://rust-lang.github.io/rust-clippy/master/index.html#{code}" )) .ok() diff --git a/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt b/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt index 71f99874b1..c3b540e31f 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/clippy_pass_by_ref.txt @@ -55,7 +55,6 @@ "clippy", ), message: "this argument is passed by reference, but would be more efficient if passed by value\n#[warn(clippy::trivially_copy_pass_by_ref)] implied by #[warn(clippy::all)]\nfor further information visit https://rust-lang.github.io/rust-clippy/master/index.html#trivially_copy_pass_by_ref", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -112,6 +111,7 @@ }, ], ), + tags: None, data: None, }, fix: None, @@ -172,7 +172,6 @@ "clippy", ), message: "lint level defined here", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -203,6 +202,7 @@ }, ], ), + tags: None, data: None, }, fix: None, @@ -263,7 +263,6 @@ "clippy", ), message: "consider passing by value instead: `self`", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -294,6 +293,7 @@ }, ], ), + tags: None, data: None, }, fix: None, diff --git a/crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt b/crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt index bd1abfe921..989e5cf66d 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/handles_macro_location.txt @@ -55,8 +55,8 @@ "rustc", ), message: "can't compare `{integer}` with `&str`\nthe trait `std::cmp::PartialEq<&str>` is not implemented for `{integer}`", - tags: None, related_information: None, + tags: None, data: None, }, fix: None, diff --git a/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt b/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt index cc870c48af..b44569b493 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/macro_compiler_error.txt @@ -31,7 +31,6 @@ "rustc", ), message: "Please register your known path in the path module", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -62,6 +61,7 @@ }, ], ), + tags: None, data: None, }, fix: None, @@ -98,7 +98,6 @@ "rustc", ), message: "Please register your known path in the path module", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -129,6 +128,7 @@ }, ], ), + tags: None, data: None, }, fix: None, @@ -165,7 +165,6 @@ "rustc", ), message: "Please register your known path in the path module", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -222,6 +221,7 @@ }, ], ), + tags: None, data: None, }, fix: None, diff --git a/crates/rust-analyzer/src/diagnostics/test_data/reasonable_line_numbers_from_empty_file.txt b/crates/rust-analyzer/src/diagnostics/test_data/reasonable_line_numbers_from_empty_file.txt index 176d7198ac..df00b330b6 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/reasonable_line_numbers_from_empty_file.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/reasonable_line_numbers_from_empty_file.txt @@ -55,8 +55,8 @@ "rustc", ), message: "`main` function not found in crate `current`\nconsider adding a `main` function to `src/bin/current.rs`", - tags: None, related_information: None, + tags: None, data: None, }, fix: None, diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_incompatible_type_for_trait.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_incompatible_type_for_trait.txt index e78ac4b27d..dc36aa761c 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_incompatible_type_for_trait.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_incompatible_type_for_trait.txt @@ -55,8 +55,8 @@ "rustc", ), message: "method `next` has an incompatible type for trait\nexpected type `fn(&mut ty::list_iter::ListIterator<'list, M>) -> std::option::Option<&ty::Ref<M>>`\n found type `fn(&ty::list_iter::ListIterator<'list, M>) -> std::option::Option<&'list ty::Ref<M>>`", - tags: None, related_information: None, + tags: None, data: None, }, fix: None, diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_mismatched_type.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_mismatched_type.txt index add343d245..d557196c2b 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_mismatched_type.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_mismatched_type.txt @@ -55,8 +55,8 @@ "rustc", ), message: "mismatched types\nexpected usize, found u32", - tags: None, related_information: None, + tags: None, data: None, }, fix: None, diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_range_map_lsp_position.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_range_map_lsp_position.txt index a510943965..a100fa07ff 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_range_map_lsp_position.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_range_map_lsp_position.txt @@ -55,7 +55,6 @@ "rustc", ), message: "mismatched types\nexpected `u32`, found `&str`", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -86,6 +85,7 @@ }, ], ), + tags: None, data: None, }, fix: None, @@ -146,7 +146,6 @@ "rustc", ), message: "expected due to this", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -177,6 +176,7 @@ }, ], ), + tags: None, data: None, }, fix: None, diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt index f5bf2dce30..1c5c336223 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt @@ -35,11 +35,6 @@ "rustc", ), message: "unused variable: `foo`\n#[warn(unused_variables)] on by default", - tags: Some( - [ - Unnecessary, - ], - ), related_information: Some( [ DiagnosticRelatedInformation { @@ -70,6 +65,11 @@ }, ], ), + tags: Some( + [ + Unnecessary, + ], + ), data: None, }, fix: None, @@ -110,7 +110,6 @@ "rustc", ), message: "consider prefixing with an underscore: `_foo`", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -141,6 +140,7 @@ }, ], ), + tags: None, data: None, }, fix: Some( @@ -161,7 +161,9 @@ title: "consider prefixing with an underscore: `_foo`", group: None, kind: Some( - QuickFix, + CodeActionKind( + "quickfix", + ), ), command: None, edit: Some( diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt index 5f4aa71576..3ab3412d97 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt @@ -35,11 +35,6 @@ "rustc", ), message: "unused variable: `foo`\n#[warn(unused_variables)] on by default", - tags: Some( - [ - Unnecessary, - ], - ), related_information: Some( [ DiagnosticRelatedInformation { @@ -70,6 +65,11 @@ }, ], ), + tags: Some( + [ + Unnecessary, + ], + ), data: None, }, fix: None, @@ -110,7 +110,6 @@ "rustc", ), message: "consider prefixing with an underscore: `_foo`", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -141,6 +140,7 @@ }, ], ), + tags: None, data: None, }, fix: Some( @@ -161,7 +161,9 @@ title: "consider prefixing with an underscore: `_foo`", group: None, kind: Some( - QuickFix, + CodeActionKind( + "quickfix", + ), ), command: None, edit: Some( diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt index 26adf53118..0702420aa5 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt @@ -35,11 +35,6 @@ "rustc", ), message: "unused variable: `foo`\n#[warn(unused_variables)] on by default", - tags: Some( - [ - Unnecessary, - ], - ), related_information: Some( [ DiagnosticRelatedInformation { @@ -70,6 +65,11 @@ }, ], ), + tags: Some( + [ + Unnecessary, + ], + ), data: None, }, fix: None, @@ -110,7 +110,6 @@ "rustc", ), message: "consider prefixing with an underscore: `_foo`", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -141,6 +140,7 @@ }, ], ), + tags: None, data: None, }, fix: Some( @@ -161,7 +161,9 @@ title: "consider prefixing with an underscore: `_foo`", group: None, kind: Some( - QuickFix, + CodeActionKind( + "quickfix", + ), ), command: None, edit: Some( diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_wrong_number_of_parameters.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_wrong_number_of_parameters.txt index cd3c24f0c3..8ec92888ce 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_wrong_number_of_parameters.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_wrong_number_of_parameters.txt @@ -55,7 +55,6 @@ "rustc", ), message: "this function takes 2 parameters but 3 parameters were supplied\nexpected 2 parameters", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -86,6 +85,7 @@ }, ], ), + tags: None, data: None, }, fix: None, @@ -146,7 +146,6 @@ "rustc", ), message: "defined here", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -177,6 +176,7 @@ }, ], ), + tags: None, data: None, }, fix: None, diff --git a/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt b/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt index a977d14cf7..4365e450df 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt @@ -55,7 +55,6 @@ "clippy", ), message: "returning the result of a let binding from a block\n`#[warn(clippy::let_and_return)]` on by default\nfor further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -112,6 +111,7 @@ }, ], ), + tags: None, data: None, }, fix: None, @@ -172,7 +172,6 @@ "clippy", ), message: "unnecessary let binding", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -203,6 +202,7 @@ }, ], ), + tags: None, data: None, }, fix: None, @@ -263,7 +263,6 @@ "clippy", ), message: "return the expression directly: `(0..10).collect()`", - tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -294,6 +293,7 @@ }, ], ), + tags: None, data: None, }, fix: Some( @@ -324,7 +324,9 @@ title: "return the expression directly: `(0..10).collect()`", group: None, kind: Some( - QuickFix, + CodeActionKind( + "quickfix", + ), ), command: None, edit: Some( diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 2d01aa4d51..f91e9532aa 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs @@ -18,7 +18,7 @@ use ide_db::{ }; use itertools::Itertools; use load_cargo::SourceRootConfig; -use lsp_types::{Notification, SemanticTokens, Uri}; +use lsp_types::{SemanticTokens, Url}; use parking_lot::{ MappedRwLockReadGuard, Mutex, RwLock, RwLockReadGuard, RwLockUpgradableReadGuard, RwLockWriteGuard, @@ -97,7 +97,7 @@ pub(crate) struct GlobalState { pub(crate) source_root_config: SourceRootConfig, /// A mapping that maps a local source root's `SourceRootId` to it parent's `SourceRootId`, if it has one. pub(crate) local_roots_parent_map: Arc<FxHashMap<SourceRootId, SourceRootId>>, - pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Uri, SemanticTokens>>>, + pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>, // status pub(crate) shutdown_requested: bool, @@ -209,7 +209,7 @@ pub(crate) struct GlobalStateSnapshot { pub(crate) analysis: Analysis, pub(crate) check_fixes: CheckFixes, mem_docs: MemDocs, - pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Uri, SemanticTokens>>>, + pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>, vfs: Arc<RwLock<(vfs::Vfs, FxHashMap<FileId, LineEndings>)>>, pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>, // used to signal semantic highlighting to fall back to syntax based highlighting until @@ -580,12 +580,12 @@ impl GlobalState { } } - pub(crate) fn send_request<R: lsp_types::Request>( + pub(crate) fn send_request<R: lsp_types::request::Request>( &mut self, params: R::Params, handler: ReqHandler, ) { - let request = self.req_queue.outgoing.register(R::METHOD.into(), params, handler); + let request = self.req_queue.outgoing.register(R::METHOD.to_owned(), params, handler); self.send(request.into()); } @@ -598,8 +598,11 @@ impl GlobalState { handler(self, response) } - pub(crate) fn send_notification<N: lsp_types::Notification>(&self, params: N::Params) { - let not = lsp_server::Notification::new(N::METHOD.into(), params); + pub(crate) fn send_notification<N: lsp_types::notification::Notification>( + &self, + params: N::Params, + ) { + let not = lsp_server::Notification::new(N::METHOD.to_owned(), params); self.send(not.into()); } @@ -644,7 +647,7 @@ impl GlobalState { pub(crate) fn publish_diagnostics( &mut self, - uri: Uri, + uri: Url, version: Option<i32>, mut diagnostics: Vec<lsp_types::Diagnostic>, ) { @@ -677,7 +680,7 @@ impl GlobalState { } let not = lsp_server::Notification::new( - lsp_types::PublishDiagnosticsNotification::METHOD.into(), + <lsp_types::notification::PublishDiagnostics as lsp_types::notification::Notification>::METHOD.to_owned(), lsp_types::PublishDiagnosticsParams { uri, diagnostics, version }, ); _ = sender.send(not.into()); @@ -741,11 +744,11 @@ impl GlobalStateSnapshot { } /// Returns `None` if the file was excluded. - pub(crate) fn url_to_file_id(&self, url: &Uri) -> anyhow::Result<Option<FileId>> { + pub(crate) fn url_to_file_id(&self, url: &Url) -> anyhow::Result<Option<FileId>> { url_to_file_id(&self.vfs_read(), url) } - pub(crate) fn file_id_to_url(&self, id: FileId) -> Uri { + pub(crate) fn file_id_to_url(&self, id: FileId) -> Url { file_id_to_url(&self.vfs_read(), id) } @@ -765,12 +768,12 @@ impl GlobalStateSnapshot { Some(self.mem_docs.get(self.vfs_read().file_path(file_id))?.version) } - pub(crate) fn url_file_version(&self, url: &Uri) -> Option<i32> { + pub(crate) fn url_file_version(&self, url: &Url) -> Option<i32> { let path = from_proto::vfs_path(url).ok()?; Some(self.mem_docs.get(&path)?.version) } - pub(crate) fn anchored_path(&self, path: &AnchoredPathBuf) -> Uri { + pub(crate) fn anchored_path(&self, path: &AnchoredPathBuf) -> Url { let mut base = self.vfs_read().file_path(path.anchor).clone(); base.pop(); let path = base.join(&path.path).unwrap(); @@ -895,14 +898,14 @@ impl GlobalStateSnapshot { } } -pub(crate) fn file_id_to_url(vfs: &vfs::Vfs, id: FileId) -> Uri { +pub(crate) fn file_id_to_url(vfs: &vfs::Vfs, id: FileId) -> Url { let path = vfs.file_path(id); let path = path.as_path().unwrap(); url_from_abs_path(path) } /// Returns `None` if the file was excluded. -pub(crate) fn url_to_file_id(vfs: &vfs::Vfs, url: &Uri) -> anyhow::Result<Option<FileId>> { +pub(crate) fn url_to_file_id(vfs: &vfs::Vfs, url: &Url) -> anyhow::Result<Option<FileId>> { let path = from_proto::vfs_path(url)?; vfs_path_to_file_id(vfs, &path) } diff --git a/crates/rust-analyzer/src/handlers/dispatch.rs b/crates/rust-analyzer/src/handlers/dispatch.rs index 8bb730827e..f3b24bf0e7 100644 --- a/crates/rust-analyzer/src/handlers/dispatch.rs +++ b/crates/rust-analyzer/src/handlers/dispatch.rs @@ -47,7 +47,7 @@ impl RequestDispatcher<'_> { f: fn(&mut GlobalState, R::Params) -> anyhow::Result<R::Result>, ) -> &mut Self where - R: lsp_types::Request, + R: lsp_types::request::Request, R::Params: DeserializeOwned + panic::UnwindSafe + fmt::Debug, R::Result: Serialize, { @@ -75,7 +75,7 @@ impl RequestDispatcher<'_> { f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result<R::Result>, ) -> &mut Self where - R: lsp_types::Request, + R: lsp_types::request::Request, R::Params: DeserializeOwned + panic::UnwindSafe + fmt::Debug, R::Result: Serialize, { @@ -107,14 +107,14 @@ impl RequestDispatcher<'_> { f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result<R::Result>, ) -> &mut Self where - R: lsp_types::Request< + R: lsp_types::request::Request< Params: DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug, Result: Serialize + Default, > + 'static, { if !self.global_state.vfs_done { if let Some(lsp_server::Request { id, .. }) = - self.req.take_if(|it| it.method.as_str() == R::METHOD.as_str()) + self.req.take_if(|it| it.method == R::METHOD) { self.global_state.respond(lsp_server::Response::new_ok(id, R::Result::default())); } @@ -136,14 +136,14 @@ impl RequestDispatcher<'_> { on_cancelled: fn() -> ResponseError, ) -> &mut Self where - R: lsp_types::Request< + R: lsp_types::request::Request< Params: DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug, Result: Serialize, > + 'static, { if !self.global_state.vfs_done || self.global_state.incomplete_crate_graph { if let Some(lsp_server::Request { id, .. }) = - self.req.take_if(|it| it.method.as_str() == R::METHOD.as_str()) + self.req.take_if(|it| it.method == R::METHOD) { self.global_state.respond(lsp_server::Response::new_ok(id, default())); } @@ -159,7 +159,7 @@ impl RequestDispatcher<'_> { f: fn(GlobalStateSnapshot, Params) -> anyhow::Result<R::Result>, ) -> &mut Self where - R: lsp_types::Request<Params = Params, Result = Params> + 'static, + R: lsp_types::request::Request<Params = Params, Result = Params> + 'static, Params: Serialize + DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug, { if !self.global_state.vfs_done { @@ -182,14 +182,14 @@ impl RequestDispatcher<'_> { f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result<R::Result>, ) -> &mut Self where - R: lsp_types::Request< + R: lsp_types::request::Request< Params: DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug, Result: Serialize + Default, > + 'static, { if !self.global_state.vfs_done { if let Some(lsp_server::Request { id, .. }) = - self.req.take_if(|it| it.method.as_str() == R::METHOD.as_str()) + self.req.take_if(|it| it.method == R::METHOD) { self.global_state.respond(lsp_server::Response::new_ok(id, R::Result::default())); } @@ -210,7 +210,7 @@ impl RequestDispatcher<'_> { f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result<R::Result>, ) -> &mut Self where - R: lsp_types::Request + 'static, + R: lsp_types::request::Request + 'static, R::Params: DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug, R::Result: Serialize, { @@ -240,7 +240,7 @@ impl RequestDispatcher<'_> { on_cancelled: fn() -> ResponseError, ) -> &mut Self where - R: lsp_types::Request + 'static, + R: lsp_types::request::Request + 'static, R::Params: DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug, R::Result: Serialize, { @@ -278,11 +278,11 @@ impl RequestDispatcher<'_> { fn parse<R>(&mut self) -> Option<(lsp_server::Request, R::Params, String)> where - R: lsp_types::Request, + R: lsp_types::request::Request, R::Params: DeserializeOwned + fmt::Debug, { - let req = self.req.take_if(|it| it.method.as_str() == R::METHOD.as_str())?; - let res = crate::from_json(R::METHOD.as_str(), &req.params); + let req = self.req.take_if(|it| it.method == R::METHOD)?; + let res = crate::from_json(R::METHOD, &req.params); match res { Ok(params) => { let panic_context = @@ -334,7 +334,7 @@ fn thread_result_to_response<R>( result: thread::Result<anyhow::Result<R::Result>>, ) -> Result<lsp_server::Response, HandlerCancelledError> where - R: lsp_types::Request, + R: lsp_types::request::Request, R::Params: DeserializeOwned, R::Result: Serialize, { @@ -369,7 +369,7 @@ fn result_to_response<R>( result: anyhow::Result<R::Result>, ) -> Result<lsp_server::Response, HandlerCancelledError> where - R: lsp_types::Request, + R: lsp_types::request::Request, R::Params: DeserializeOwned, R::Result: Serialize, { @@ -401,7 +401,7 @@ impl NotificationDispatcher<'_> { f: fn(&mut GlobalState, N::Params) -> anyhow::Result<()>, ) -> &mut Self where - N: lsp_types::Notification, + N: lsp_types::notification::Notification, N::Params: DeserializeOwned + Send + Debug, { let not = match self.not.take() { @@ -411,7 +411,7 @@ impl NotificationDispatcher<'_> { let _guard = tracing::info_span!("notification", method = ?not.method).entered(); - let params = match not.extract::<N::Params>(N::METHOD.as_str()) { + let params = match not.extract::<N::Params>(N::METHOD) { Ok(it) => it, Err(ExtractError::JsonError { method, error }) => { tracing::error!(method = %method, error = %error, "invalid notification"); diff --git a/crates/rust-analyzer/src/handlers/notification.rs b/crates/rust-analyzer/src/handlers/notification.rs index d392c1ecbf..09b6794e4f 100644 --- a/crates/rust-analyzer/src/handlers/notification.rs +++ b/crates/rust-analyzer/src/handlers/notification.rs @@ -30,8 +30,8 @@ use crate::{ pub(crate) fn handle_cancel(state: &mut GlobalState, params: CancelParams) -> anyhow::Result<()> { let id: lsp_server::RequestId = match params.id { - lsp_types::Id::Int(id) => id.into(), - lsp_types::Id::String(id) => id.into(), + lsp_types::NumberOrString::Number(id) => id.into(), + lsp_types::NumberOrString::String(id) => id.into(), }; state.cancel(id); Ok(()) @@ -41,7 +41,7 @@ pub(crate) fn handle_work_done_progress_cancel( state: &mut GlobalState, params: WorkDoneProgressCancelParams, ) -> anyhow::Result<()> { - if let lsp_types::ProgressToken::String(s) = ¶ms.token + if let lsp_types::NumberOrString::String(s) = ¶ms.token && let Some(id) = s.strip_prefix("rust-analyzer/flycheck/") && let Ok(id) = id.parse::<u32>() && let Some(flycheck) = state.flycheck.get(id as usize) @@ -103,7 +103,7 @@ pub(crate) fn handle_did_change_text_document( ) -> anyhow::Result<()> { let _p = tracing::info_span!("handle_did_change_text_document").entered(); - if let Ok(path) = from_proto::vfs_path(¶ms.text_document.text_document_identifier.uri) { + if let Ok(path) = from_proto::vfs_path(¶ms.text_document.uri) { let Some(DocumentData { version, data }) = state.mem_docs.get_mut(&path) else { tracing::error!(?path, "unexpected DidChangeTextDocument"); return Ok(()); @@ -215,7 +215,7 @@ pub(crate) fn handle_did_change_configuration( ) -> anyhow::Result<()> { // As stated in https://github.com/microsoft/language-server-protocol/issues/676, // this notification's parameters should be ignored and the actual config queried separately. - state.send_request::<lsp_types::ConfigurationRequest>( + state.send_request::<lsp_types::request::WorkspaceConfiguration>( lsp_types::ConfigurationParams { items: vec![lsp_types::ConfigurationItem { scope_uri: None, @@ -553,7 +553,7 @@ pub(crate) fn handle_run_flycheck( pub(crate) fn handle_abort_run_test(state: &mut GlobalState, _: ()) -> anyhow::Result<()> { if state.test_run_session.take().is_some() { - state.send_notification::<lsp_ext::EndRunTestNotification>(()); + state.send_notification::<lsp_ext::EndRunTest>(()); } Ok(()) } diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index c835af0073..558bfb5998 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs @@ -18,11 +18,11 @@ use lsp_server::ErrorCode; use lsp_types::{ CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem, CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams, - CodeLens, CompletionItem, Contents, DocumentChange, FoldingRange, FoldingRangeParams, - InlayHint, InlayHintParams, Location, LocationLink, Position, PrepareRenameResult, Range, - RenameParams, ResourceOperationKind, SemanticTokens, SemanticTokensDeltaParams, - SemanticTokensDeltaResponse, SemanticTokensParams, SemanticTokensRangeParams, - SymbolInformation, SymbolTag, TextDocumentIdentifier, Uri, WorkspaceEdit, + CodeLens, CompletionItem, FoldingRange, FoldingRangeParams, HoverContents, InlayHint, + InlayHintParams, Location, LocationLink, Position, PrepareRenameResponse, Range, RenameParams, + ResourceOp, ResourceOperationKind, SemanticTokensDeltaParams, SemanticTokensFullDeltaResult, + SemanticTokensParams, SemanticTokensRangeParams, SemanticTokensRangeResult, + SemanticTokensResult, SymbolInformation, SymbolTag, TextDocumentIdentifier, Url, WorkspaceEdit, }; use paths::Utf8PathBuf; use project_model::{CargoWorkspace, ManifestPath, ProjectWorkspaceKind, TargetKind}; @@ -172,7 +172,7 @@ pub(crate) fn handle_view_hir( params: lsp_types::TextDocumentPositionParams, ) -> anyhow::Result<String> { let _p = tracing::info_span!("handle_view_hir").entered(); - let position = try_default!(from_proto::file_position(&snap, ¶ms)?); + let position = try_default!(from_proto::file_position(&snap, params)?); let res = snap.analysis.view_hir(position)?; Ok(res) } @@ -182,7 +182,7 @@ pub(crate) fn handle_view_mir( params: lsp_types::TextDocumentPositionParams, ) -> anyhow::Result<String> { let _p = tracing::info_span!("handle_view_mir").entered(); - let position = try_default!(from_proto::file_position(&snap, ¶ms)?); + let position = try_default!(from_proto::file_position(&snap, params)?); let res = snap.analysis.view_mir(position)?; Ok(res) } @@ -192,7 +192,7 @@ pub(crate) fn handle_interpret_function( params: lsp_types::TextDocumentPositionParams, ) -> anyhow::Result<String> { let _p = tracing::info_span!("handle_interpret_function").entered(); - let position = try_default!(from_proto::file_position(&snap, ¶ms)?); + let position = try_default!(from_proto::file_position(&snap, params)?); let res = snap.analysis.interpret_function(position)?; Ok(res) } @@ -252,7 +252,7 @@ pub(crate) fn handle_run_test( params: lsp_ext::RunTestParams, ) -> anyhow::Result<()> { if let Some(_session) = state.test_run_session.take() { - state.send_notification::<lsp_ext::EndRunTestNotification>(()); + state.send_notification::<lsp_ext::EndRunTest>(()); } let mut handles = vec![]; @@ -358,9 +358,9 @@ pub(crate) fn handle_selection_range( let line_index = snap.file_line_index(file_id)?; let res: anyhow::Result<Vec<lsp_types::SelectionRange>> = params .positions - .iter() + .into_iter() .map(|position| { - let offset = from_proto::offset(&line_index, *position)?; + let offset = from_proto::offset(&line_index, position)?; let mut ranges = Vec::new(); { let mut range = TextRange::new(offset, offset); @@ -401,9 +401,9 @@ pub(crate) fn handle_matching_brace( let line_index = snap.file_line_index(file_id)?; params .positions - .iter() + .into_iter() .map(|position| { - let offset = from_proto::offset(&line_index, *position); + let offset = from_proto::offset(&line_index, position); offset.map(|offset| { match snap.analysis.matching_brace(FilePosition { file_id, offset }) { Ok(Some(x)) => Some(to_proto::position(&line_index, x)), @@ -444,7 +444,7 @@ pub(crate) fn handle_on_enter( params: lsp_types::TextDocumentPositionParams, ) -> anyhow::Result<Option<Vec<lsp_ext::SnippetTextEdit>>> { let _p = tracing::info_span!("handle_on_enter").entered(); - let position = try_default!(from_proto::file_position(&snap, ¶ms)?); + let position = try_default!(from_proto::file_position(&snap, params)?); let edit = match snap.analysis.on_enter(position)? { None => return Ok(None), Some(it) => it, @@ -468,11 +468,9 @@ pub(crate) fn handle_on_type_formatting( if !snap.config.typing_trigger_chars().contains(char_typed) { return Ok(None); } - let tdpp = lsp_types::TextDocumentPositionParams { - text_document: params.text_document, - position: params.position, - }; - let mut position = try_default!(from_proto::file_position(&snap, &tdpp)?); + + let mut position = + try_default!(from_proto::file_position(&snap, params.text_document_position)?); let line_index = snap.file_line_index(position.file_id)?; // in `ide`, the `on_type` invariant is that @@ -503,8 +501,8 @@ pub(crate) fn handle_on_type_formatting( Ok(Some(change)) } -pub(crate) fn empty_diagnostic_report() -> lsp_types::DocumentDiagnosticReport { - lsp_types::DocumentDiagnosticReport::RelatedFullDocumentDiagnosticReport( +pub(crate) fn empty_diagnostic_report() -> lsp_types::DocumentDiagnosticReportResult { + lsp_types::DocumentDiagnosticReportResult::Report(lsp_types::DocumentDiagnosticReport::Full( lsp_types::RelatedFullDocumentDiagnosticReport { related_documents: None, full_document_diagnostic_report: lsp_types::FullDocumentDiagnosticReport { @@ -512,13 +510,13 @@ pub(crate) fn empty_diagnostic_report() -> lsp_types::DocumentDiagnosticReport { items: vec![], }, }, - ) + )) } pub(crate) fn handle_document_diagnostics( snap: GlobalStateSnapshot, params: lsp_types::DocumentDiagnosticParams, -) -> anyhow::Result<lsp_types::DocumentDiagnosticReport> { +) -> anyhow::Result<lsp_types::DocumentDiagnosticReportResult> { let file_id = match from_proto::file_id(&snap, ¶ms.text_document.uri)? { Some(it) => it, None => return Ok(empty_diagnostic_report()), @@ -555,8 +553,8 @@ pub(crate) fn handle_document_diagnostics( } None }); - Ok(lsp_types::DocumentDiagnosticReport::RelatedFullDocumentDiagnosticReport( - lsp_types::RelatedFullDocumentDiagnosticReport { + Ok(lsp_types::DocumentDiagnosticReportResult::Report( + lsp_types::DocumentDiagnosticReport::Full(lsp_types::RelatedFullDocumentDiagnosticReport { full_document_diagnostic_report: lsp_types::FullDocumentDiagnosticReport { result_id: Some("rust-analyzer".to_owned()), items: diagnostics.collect(), @@ -567,7 +565,7 @@ pub(crate) fn handle_document_diagnostics( .map(|(id, (items, _))| { ( to_proto::url(&snap, id), - lsp_types::RelatedDocument::FullDocumentDiagnosticReport( + lsp_types::DocumentDiagnosticReportKind::Full( lsp_types::FullDocumentDiagnosticReport { result_id: Some("rust-analyzer".to_owned()), items, @@ -577,7 +575,7 @@ pub(crate) fn handle_document_diagnostics( }) .collect() }), - }, + }), )) } @@ -601,7 +599,7 @@ pub(crate) fn handle_document_symbol( for node in structure_nodes { let mut tags = Vec::new(); if node.deprecated { - tags.push(SymbolTag::Deprecated) + tags.push(SymbolTag::DEPRECATED) }; #[allow(deprecated)] @@ -651,19 +649,17 @@ pub(crate) fn handle_document_symbol( fn flatten_document_symbol( symbol: &lsp_types::DocumentSymbol, container_name: Option<String>, - url: &Uri, + url: &Url, res: &mut Vec<SymbolInformation>, ) { #[allow(deprecated)] res.push(SymbolInformation { + name: symbol.name.clone(), + kind: symbol.kind, + tags: symbol.tags.clone(), deprecated: symbol.deprecated, location: Location::new(url.clone(), symbol.range), - base_symbol_information: lsp_types::BaseSymbolInformation { - name: symbol.name.clone(), - kind: symbol.kind, - tags: symbol.tags.clone(), - container_name, - }, + container_name, }); for child in symbol.children.iter().flatten() { @@ -700,7 +696,7 @@ pub(crate) fn handle_workspace_symbol( res = exec_query(&snap, Query::new(params.query), config.search_limit)?; } - return Ok(Some(lsp_types::WorkspaceSymbolResponse::WorkspaceSymbolList(res))); + return Ok(Some(lsp_types::WorkspaceSymbolResponse::Nested(res))); fn decide_search_kind_and_scope( params: &WorkspaceSymbolParams, @@ -747,23 +743,19 @@ pub(crate) fn handle_workspace_symbol( let container_name = nav.container_name.as_ref().map(|v| v.to_string()); let info = lsp_types::WorkspaceSymbol { - location: lsp_types::WorkspaceSymbolLocation::Location( - to_proto::location_from_nav(snap, &nav)?, - ), - data: None, - base_symbol_information: lsp_types::BaseSymbolInformation { - name: match &nav.alias { - Some(alias) => format!("{} (alias for {})", alias, nav.name), - None => nav.name.to_string(), - }, - kind: nav - .kind - .map(to_proto::symbol_kind) - .unwrap_or(lsp_types::SymbolKind::Variable), - // FIXME: Set deprecation - tags: None, - container_name, + name: match &nav.alias { + Some(alias) => format!("{} (alias for {})", alias, nav.name), + None => format!("{}", nav.name), }, + kind: nav + .kind + .map(to_proto::symbol_kind) + .unwrap_or(lsp_types::SymbolKind::VARIABLE), + // FIXME: Set deprecation + tags: None, + container_name, + location: lsp_types::OneOf::Left(to_proto::location_from_nav(snap, nav)?), + data: None, }; res.push(info); } @@ -781,8 +773,8 @@ pub(crate) fn handle_will_rename_files( .files .into_iter() .filter_map(|file_rename| { - let from = Uri::parse(&file_rename.old_uri).ok()?; - let to = Uri::parse(&file_rename.new_uri).ok()?; + let from = Url::parse(&file_rename.old_uri).ok()?; + let to = Url::parse(&file_rename.new_uri).ok()?; let from_path = from.to_file_path().ok()?; let to_path = to.to_file_path().ok()?; @@ -839,11 +831,11 @@ pub(crate) fn handle_will_rename_files( pub(crate) fn handle_goto_definition( snap: GlobalStateSnapshot, - params: lsp_types::DefinitionParams, -) -> anyhow::Result<Option<lsp_types::DefinitionResponse>> { + params: lsp_types::GotoDefinitionParams, +) -> anyhow::Result<Option<lsp_types::GotoDefinitionResponse>> { let _p = tracing::info_span!("handle_goto_definition").entered(); let position = - try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); + try_default!(from_proto::file_position(&snap, params.text_document_position_params)?); let config = snap.config.goto_definition(snap.minicore()); let nav_info = match snap.analysis.goto_definition(position, &config)? { None => return Ok(None), @@ -856,84 +848,60 @@ pub(crate) fn handle_goto_definition( pub(crate) fn handle_goto_declaration( snap: GlobalStateSnapshot, - params: lsp_types::DeclarationParams, -) -> anyhow::Result<Option<lsp_types::DeclarationResponse>> { + params: lsp_types::request::GotoDeclarationParams, +) -> anyhow::Result<Option<lsp_types::request::GotoDeclarationResponse>> { let _p = tracing::info_span!("handle_goto_declaration").entered(); - let position = - try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); + let position = try_default!(from_proto::file_position( + &snap, + params.text_document_position_params.clone() + )?); let config = snap.config.goto_definition(snap.minicore()); let nav_info = match snap.analysis.goto_declaration(position, &config)? { - None => { - // fallback to goto definition - let params = lsp_types::DefinitionParams { - work_done_progress_params: params.work_done_progress_params, - partial_result_params: params.partial_result_params, - text_document_position_params: params.text_document_position_params, - }; - return match handle_goto_definition(snap, params) { - Ok(Some(x)) => match x { - lsp_types::DefinitionResponse::Definition(definition) => { - Ok(Some(lsp_types::DeclarationResponse::Declaration(match definition { - lsp_types::Definition::Location(location) => { - lsp_types::Declaration::Location(location) - } - lsp_types::Definition::LocationList(locations) => { - lsp_types::Declaration::LocationList(locations) - } - }))) - } - lsp_types::DefinitionResponse::DefinitionLinkList(location_links) => Ok(Some( - lsp_types::DeclarationResponse::DeclarationLinkList(location_links), - )), - }, - Ok(None) => Ok(None), - Err(error) => Err(error), - }; - } + None => return handle_goto_definition(snap, params), Some(it) => it, }; let src = FileRange { file_id: position.file_id, range: nav_info.range }; - let res = to_proto::goto_declaration_response(&snap, Some(src), nav_info.info)?; + let res = to_proto::goto_definition_response(&snap, Some(src), nav_info.info)?; Ok(Some(res)) } pub(crate) fn handle_goto_implementation( snap: GlobalStateSnapshot, - params: lsp_types::ImplementationParams, -) -> anyhow::Result<Option<lsp_types::ImplementationResponse>> { + params: lsp_types::request::GotoImplementationParams, +) -> anyhow::Result<Option<lsp_types::request::GotoImplementationResponse>> { let _p = tracing::info_span!("handle_goto_implementation").entered(); let position = - try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); + try_default!(from_proto::file_position(&snap, params.text_document_position_params)?); let nav_info = match snap.analysis.goto_implementation(&snap.config.goto_implementation(), position)? { None => return Ok(None), Some(it) => it, }; let src = FileRange { file_id: position.file_id, range: nav_info.range }; - let res = to_proto::goto_implementation_response(&snap, Some(src), nav_info.info)?; + let res = to_proto::goto_definition_response(&snap, Some(src), nav_info.info)?; Ok(Some(res)) } pub(crate) fn handle_goto_type_definition( snap: GlobalStateSnapshot, - params: lsp_types::TypeDefinitionParams, -) -> anyhow::Result<Option<lsp_types::TypeDefinitionResponse>> { + params: lsp_types::request::GotoTypeDefinitionParams, +) -> anyhow::Result<Option<lsp_types::request::GotoTypeDefinitionResponse>> { let _p = tracing::info_span!("handle_goto_type_definition").entered(); let position = - try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); + try_default!(from_proto::file_position(&snap, params.text_document_position_params)?); let nav_info = match snap.analysis.goto_type_definition(position)? { None => return Ok(None), Some(it) => it, }; let src = FileRange { file_id: position.file_id, range: nav_info.range }; - let res = to_proto::goto_type_definition_response(&snap, Some(src), nav_info.info)?; + let res = to_proto::goto_definition_response(&snap, Some(src), nav_info.info)?; Ok(Some(res)) } pub(crate) fn handle_parent_module( snap: GlobalStateSnapshot, params: lsp_types::TextDocumentPositionParams, -) -> anyhow::Result<Option<lsp_types::DefinitionResponse>> { +) -> anyhow::Result<Option<lsp_types::GotoDefinitionResponse>> { let _p = tracing::info_span!("handle_parent_module").entered(); if let Ok(file_path) = ¶ms.text_document.uri.to_file_path() { if file_path.file_name().unwrap_or_default() == "Cargo.toml" { @@ -997,7 +965,7 @@ pub(crate) fn handle_parent_module( } // locate parent module by semantics - let position = try_default!(from_proto::file_position(&snap, ¶ms)?); + let position = try_default!(from_proto::file_position(&snap, params)?); let navs = snap.analysis.parent_module(position)?; let res = to_proto::goto_definition_response(&snap, None, navs)?; Ok(Some(res)) @@ -1006,10 +974,10 @@ pub(crate) fn handle_parent_module( pub(crate) fn handle_child_modules( snap: GlobalStateSnapshot, params: lsp_types::TextDocumentPositionParams, -) -> anyhow::Result<Option<lsp_types::DefinitionResponse>> { +) -> anyhow::Result<Option<lsp_types::GotoDefinitionResponse>> { let _p = tracing::info_span!("handle_child_modules").entered(); // locate child module by semantics - let position = try_default!(from_proto::file_position(&snap, ¶ms)?); + let position = try_default!(from_proto::file_position(&snap, params)?); let navs = snap.analysis.child_modules(position)?; let res = to_proto::goto_definition_response(&snap, None, navs)?; Ok(Some(res)) @@ -1143,7 +1111,7 @@ pub(crate) fn handle_related_tests( params: lsp_types::TextDocumentPositionParams, ) -> anyhow::Result<Vec<lsp_ext::TestInfo>> { let _p = tracing::info_span!("handle_related_tests").entered(); - let position = try_default!(from_proto::file_position(&snap, ¶ms)?); + let position = try_default!(from_proto::file_position(&snap, params)?); let tests = snap.analysis.related_tests(position, None)?; let mut res = Vec::new(); @@ -1159,14 +1127,14 @@ pub(crate) fn handle_related_tests( pub(crate) fn handle_completion( snap: GlobalStateSnapshot, lsp_types::CompletionParams { - text_document_position_params, + text_document_position, context, .. }: lsp_types::CompletionParams, ) -> anyhow::Result<Option<lsp_types::CompletionResponse>> { let _p = tracing::info_span!("handle_completion").entered(); let mut position = - try_default!(from_proto::file_position(&snap, &text_document_position_params)?); + try_default!(from_proto::file_position(&snap, text_document_position.clone())?); let line_index = snap.file_line_index(position.file_id)?; let completion_trigger_character = context.and_then(|ctx| ctx.trigger_character).and_then(|s| s.chars().next()); @@ -1189,17 +1157,12 @@ pub(crate) fn handle_completion( &completion_config.fields_to_resolve, &line_index, snap.file_version(position.file_id), - &text_document_position_params, + text_document_position, completion_trigger_character, items, ); - let completion_list = lsp_types::CompletionList { - is_incomplete: true, - items, - item_defaults: None, - apply_kind: None, - }; + let completion_list = lsp_types::CompletionList { is_incomplete: true, items }; Ok(Some(completion_list.into())) } @@ -1262,7 +1225,7 @@ pub(crate) fn handle_completion_resolve( &forced_resolve_completions_config.fields_to_resolve, &line_index, snap.file_version(position.file_id), - &resolve_data.position, + resolve_data.position, resolve_data.trigger_character, vec![corresponding_completion], ); @@ -1332,7 +1295,7 @@ pub(crate) fn handle_signature_help( ) -> anyhow::Result<Option<lsp_types::SignatureHelp>> { let _p = tracing::info_span!("handle_signature_help").entered(); let position = - try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); + try_default!(from_proto::file_position(&snap, params.text_document_position_params)?); let help = match snap.analysis.signature_help(position)? { Some(it) => it, None => return Ok(None), @@ -1364,7 +1327,7 @@ pub(crate) fn handle_hover( let markup_kind = hover.format; let hover = lsp_ext::Hover { hover: lsp_types::Hover { - contents: Contents::MarkupContent(to_proto::markup_content( + contents: HoverContents::Markup(to_proto::markup_content( info.info.markup, markup_kind, )), @@ -1382,17 +1345,16 @@ pub(crate) fn handle_hover( pub(crate) fn handle_prepare_rename( snap: GlobalStateSnapshot, - params: lsp_types::PrepareRenameParams, -) -> anyhow::Result<Option<PrepareRenameResult>> { + params: lsp_types::TextDocumentPositionParams, +) -> anyhow::Result<Option<PrepareRenameResponse>> { let _p = tracing::info_span!("handle_prepare_rename").entered(); - let position = - try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); + let position = try_default!(from_proto::file_position(&snap, params)?); let change = snap.analysis.prepare_rename(position)?.map_err(to_proto::rename_error)?; let line_index = snap.file_line_index(position.file_id)?; let range = to_proto::range(&line_index, change.range); - Ok(Some(PrepareRenameResult::Range(range))) + Ok(Some(PrepareRenameResponse::Range(range))) } pub(crate) fn handle_rename( @@ -1400,8 +1362,7 @@ pub(crate) fn handle_rename( params: RenameParams, ) -> anyhow::Result<Option<WorkspaceEdit>> { let _p = tracing::info_span!("handle_rename").entered(); - let position = - try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); + let position = try_default!(from_proto::file_position(&snap, params.text_document_position)?); let source_root = snap.analysis.source_root_id(position.file_id).ok(); let config = snap.config.rename(source_root); @@ -1422,9 +1383,13 @@ pub(crate) fn handle_rename( let workspace_edit = to_proto::workspace_edit(&snap, change)?; - if let Some(changes) = workspace_edit.document_changes.as_ref() { - for change in changes { - resource_ops_supported(&snap.config, change)?; + if let Some(lsp_types::DocumentChanges::Operations(ops)) = + workspace_edit.document_changes.as_ref() + { + for op in ops { + if let lsp_types::DocumentChangeOperation::Op(doc_change_op) = op { + resource_ops_supported(&snap.config, resolve_resource_op(doc_change_op))? + } } } @@ -1436,8 +1401,7 @@ pub(crate) fn handle_references( params: lsp_types::ReferenceParams, ) -> anyhow::Result<Option<Vec<Location>>> { let _p = tracing::info_span!("handle_references").entered(); - let position = - try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); + let position = try_default!(from_proto::file_position(&snap, params.text_document_position)?); let exclude_imports = snap.config.find_all_refs_exclude_imports(); let exclude_tests = snap.config.find_all_refs_exclude_tests(); @@ -1486,7 +1450,7 @@ pub(crate) fn handle_formatting( ) -> anyhow::Result<Option<Vec<lsp_types::TextEdit>>> { let _p = tracing::info_span!("handle_formatting").entered(); - run_rustfmt(&snap, ¶ms.text_document, None) + run_rustfmt(&snap, params.text_document, None) } pub(crate) fn handle_range_formatting( @@ -1495,7 +1459,7 @@ pub(crate) fn handle_range_formatting( ) -> anyhow::Result<Option<Vec<lsp_types::TextEdit>>> { let _p = tracing::info_span!("handle_range_formatting").entered(); - run_rustfmt(&snap, ¶ms.text_document, Some(params.range)) + run_rustfmt(&snap, params.text_document, Some(params.range)) } pub(crate) fn handle_code_action( @@ -1550,8 +1514,8 @@ pub(crate) fn handle_code_action( let changes = code_action.edit.as_ref().and_then(|it| it.document_changes.as_ref()); if let Some(changes) = changes { for change in changes { - if let lsp_ext::SnippetDocumentChangeOperation::Change(change) = change { - resource_ops_supported(&snap.config, change)? + if let lsp_ext::SnippetDocumentChangeOperation::Op(res_op) = change { + resource_ops_supported(&snap.config, resolve_resource_op(res_op))? } } } @@ -1654,8 +1618,8 @@ pub(crate) fn handle_code_action_resolve( && let Some(changes) = edit.document_changes.as_ref() { for change in changes { - if let lsp_ext::SnippetDocumentChangeOperation::Change(change) = change { - resource_ops_supported(&snap.config, change)? + if let lsp_ext::SnippetDocumentChangeOperation::Op(res_op) = change { + resource_ops_supported(&snap.config, resolve_resource_op(res_op))? } } } @@ -1762,7 +1726,7 @@ pub(crate) fn handle_document_highlight( ) -> anyhow::Result<Option<Vec<lsp_types::DocumentHighlight>>> { let _p = tracing::info_span!("handle_document_highlight").entered(); let position = - try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); + try_default!(from_proto::file_position(&snap, params.text_document_position_params)?); let line_index = snap.file_line_index(position.file_id)?; let source_root = snap.analysis.source_root_id(position.file_id)?; @@ -1795,7 +1759,7 @@ pub(crate) fn handle_ssr( .map(|range| from_proto::file_range(&snap, ¶ms.position.text_document, *range)) .collect::<Result<Option<Vec<_>>, _>>()? ); - let position = try_default!(from_proto::file_position(&snap, ¶ms.position)?); + let position = try_default!(from_proto::file_position(&snap, params.position)?); let source_change = snap.analysis.structural_search_replace( ¶ms.query, params.parse_only, @@ -1900,7 +1864,7 @@ pub(crate) fn handle_call_hierarchy_prepare( ) -> anyhow::Result<Option<Vec<CallHierarchyItem>>> { let _p = tracing::info_span!("handle_call_hierarchy_prepare").entered(); let position = - try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); + try_default!(from_proto::file_position(&snap, params.text_document_position_params)?); let config = snap.config.call_hierarchy(snap.minicore()); let nav_info = match snap.analysis.call_hierarchy(position, &config)? { @@ -1935,26 +1899,25 @@ pub(crate) fn handle_call_hierarchy_incoming( Some(it) => it, }; - Ok(Some( - call_items - .into_iter() - .map(|call_item| { - let file_id = call_item.target.file_id; - let line_index = snap.file_line_index(file_id)?; - let item = to_proto::call_hierarchy_item(&snap, call_item.target)?; - Ok(CallHierarchyIncomingCall { - from: item, - from_ranges: call_item - .ranges - .iter() - // This is the range relative to the item - .filter(|it| it.file_id == file_id) - .map(|it| to_proto::range(&line_index, it.range)) - .collect(), - }) - }) - .collect::<anyhow::Result<_>>()?, - )) + let mut res = vec![]; + + for call_item in call_items.into_iter() { + let file_id = call_item.target.file_id; + let line_index = snap.file_line_index(file_id)?; + let item = to_proto::call_hierarchy_item(&snap, call_item.target)?; + res.push(CallHierarchyIncomingCall { + from: item, + from_ranges: call_item + .ranges + .into_iter() + // This is the range relative to the item + .filter(|it| it.file_id == file_id) + .map(|it| to_proto::range(&line_index, it.range)) + .collect(), + }); + } + + Ok(Some(res)) } pub(crate) fn handle_call_hierarchy_outgoing( @@ -1997,7 +1960,7 @@ pub(crate) fn handle_call_hierarchy_outgoing( pub(crate) fn handle_semantic_tokens_full( snap: GlobalStateSnapshot, params: SemanticTokensParams, -) -> anyhow::Result<Option<SemanticTokens>> { +) -> anyhow::Result<Option<SemanticTokensResult>> { let _p = tracing::info_span!("handle_semantic_tokens_full").entered(); let file_id = try_default!(from_proto::file_id(&snap, ¶ms.text_document.uri)?); @@ -2021,13 +1984,13 @@ pub(crate) fn handle_semantic_tokens_full( // Unconditionally cache the tokens snap.semantic_tokens_cache.lock().insert(params.text_document.uri, semantic_tokens.clone()); - Ok(Some(semantic_tokens)) + Ok(Some(semantic_tokens.into())) } pub(crate) fn handle_semantic_tokens_full_delta( snap: GlobalStateSnapshot, params: SemanticTokensDeltaParams, -) -> anyhow::Result<Option<SemanticTokensDeltaResponse>> { +) -> anyhow::Result<Option<SemanticTokensFullDeltaResult>> { let _p = tracing::info_span!("handle_semantic_tokens_full_delta").entered(); let file_id = try_default!(from_proto::file_id(&snap, ¶ms.text_document.uri)?); @@ -2069,7 +2032,7 @@ pub(crate) fn handle_semantic_tokens_full_delta( pub(crate) fn handle_semantic_tokens_range( snap: GlobalStateSnapshot, params: SemanticTokensRangeParams, -) -> anyhow::Result<Option<SemanticTokens>> { +) -> anyhow::Result<Option<SemanticTokensRangeResult>> { let _p = tracing::info_span!("handle_semantic_tokens_range").entered(); let frange = try_default!(from_proto::file_range(&snap, ¶ms.text_document, params.range)?); @@ -2089,7 +2052,7 @@ pub(crate) fn handle_semantic_tokens_range( snap.config.semantics_tokens_augments_syntax_tokens(), snap.config.highlighting_non_standard_tokens(), ); - Ok(Some(semantic_tokens)) + Ok(Some(semantic_tokens.into())) } pub(crate) fn handle_open_docs( @@ -2097,7 +2060,7 @@ pub(crate) fn handle_open_docs( params: lsp_types::TextDocumentPositionParams, ) -> anyhow::Result<ExternalDocsResponse> { let _p = tracing::info_span!("handle_open_docs").entered(); - let position = try_default!(from_proto::file_position(&snap, ¶ms)?); + let position = try_default!(from_proto::file_position(&snap, params)?); let ws_and_sysroot = snap.workspaces.iter().find_map(|ws| match &ws.kind { ProjectWorkspaceKind::Cargo { cargo, .. } @@ -2124,8 +2087,8 @@ pub(crate) fn handle_open_docs( }; }; - let web = remote_urls.web_url.and_then(|it| Uri::parse(&it).ok()); - let local = remote_urls.local_url.and_then(|it| Uri::parse(&it).ok()); + let web = remote_urls.web_url.and_then(|it| Url::parse(&it).ok()); + let local = remote_urls.local_url.and_then(|it| Url::parse(&it).ok()); if snap.config.local_docs() { Ok(ExternalDocsResponse::WithLocal(ExternalDocsPair { web, local })) @@ -2137,7 +2100,7 @@ pub(crate) fn handle_open_docs( pub(crate) fn handle_open_cargo_toml( snap: GlobalStateSnapshot, params: lsp_ext::OpenCargoTomlParams, -) -> anyhow::Result<Option<lsp_types::DefinitionResponse>> { +) -> anyhow::Result<Option<lsp_types::GotoDefinitionResponse>> { let _p = tracing::info_span!("handle_open_cargo_toml").entered(); let file_id = try_default!(from_proto::file_id(&snap, ¶ms.text_document.uri)?); @@ -2147,9 +2110,8 @@ pub(crate) fn handle_open_cargo_toml( }; let cargo_toml_url = to_proto::url_from_abs_path(&cargo_spec.cargo_toml); - let res = lsp_types::DefinitionResponse::Definition(lsp_types::Definition::Location( - Location::new(cargo_toml_url, Range::default()), - )); + let res: lsp_types::GotoDefinitionResponse = + Location::new(cargo_toml_url, Range::default()).into(); Ok(Some(res)) } @@ -2231,7 +2193,7 @@ fn show_impl_command_link( let locations: Vec<_> = nav_data .info .into_iter() - .filter_map(|nav| to_proto::location_from_nav(snap, &nav).ok()) + .filter_map(|nav| to_proto::location_from_nav(snap, nav).ok()) .collect(); let title = to_proto::implementation_title(locations.len()); let command = to_proto::command::show_references(title, &uri, position, locations); @@ -2406,7 +2368,7 @@ fn should_skip_target(runnable: &Runnable, cargo_spec: Option<&TargetSpec>) -> b fn run_rustfmt( snap: &GlobalStateSnapshot, - text_document: &TextDocumentIdentifier, + text_document: TextDocumentIdentifier, range: Option<lsp_types::Range>, ) -> anyhow::Result<Option<Vec<lsp_types::TextEdit>>> { let file_id = try_default!(from_proto::file_id(snap, &text_document.uri)?); @@ -2472,7 +2434,7 @@ fn run_rustfmt( .into()); } - let frange = try_default!(from_proto::file_range(snap, text_document, range)?); + let frange = try_default!(from_proto::file_range(snap, &text_document, range)?); let start_line = line_index.index.line_col(frange.range.start()).line; let end_line = line_index.index.line_col(frange.range.end()).line; @@ -2703,26 +2665,20 @@ fn crate_path(root_file_path: &VfsPath) -> Option<VfsPath> { None } -fn to_url(path: VfsPath) -> Option<Uri> { +fn to_url(path: VfsPath) -> Option<Url> { let path = path.as_path()?; let str_path = path.as_os_str().to_str()?; - Uri::from_file_path(str_path).ok() + Url::from_file_path(str_path).ok() } -fn resource_ops_supported(config: &Config, kind: &DocumentChange) -> anyhow::Result<()> { - let op = match kind { - lsp_types::DocumentChange::CreateFile(_) => ResourceOperationKind::Create, - lsp_types::DocumentChange::RenameFile(_) => ResourceOperationKind::Rename, - lsp_types::DocumentChange::DeleteFile(_) => ResourceOperationKind::Delete, - lsp_types::DocumentChange::TextDocumentEdit(_) => return Ok(()), - }; - if !matches!(config.workspace_edit_resource_operations(), Some(resops) if resops.contains(&op)) +fn resource_ops_supported(config: &Config, kind: ResourceOperationKind) -> anyhow::Result<()> { + if !matches!(config.workspace_edit_resource_operations(), Some(resops) if resops.contains(&kind)) { return Err(LspError::new( ErrorCode::RequestFailed as i32, format!( "Client does not support {} capability.", - match op { + match kind { ResourceOperationKind::Create => "create", ResourceOperationKind::Rename => "rename", ResourceOperationKind::Delete => "delete", @@ -2735,6 +2691,14 @@ fn resource_ops_supported(config: &Config, kind: &DocumentChange) -> anyhow::Res Ok(()) } +fn resolve_resource_op(op: &ResourceOp) -> ResourceOperationKind { + match op { + ResourceOp::Create(_) => ResourceOperationKind::Create, + ResourceOp::Rename(_) => ResourceOperationKind::Rename, + ResourceOp::Delete(_) => ResourceOperationKind::Delete, + } +} + pub(crate) fn diff(left: &str, right: &str) -> TextEdit { use dissimilar::Chunk; diff --git a/crates/rust-analyzer/src/lib.rs b/crates/rust-analyzer/src/lib.rs index d161c2b464..5152d3c754 100644 --- a/crates/rust-analyzer/src/lib.rs +++ b/crates/rust-analyzer/src/lib.rs @@ -60,7 +60,6 @@ pub mod tracing { pub mod config; mod global_state; pub mod lsp; - use self::lsp::ext as lsp_ext; #[cfg(test)] @@ -73,7 +72,10 @@ pub use crate::{ version::version, }; -pub fn from_json<T: DeserializeOwned>(what: &str, json: &serde_json::Value) -> anyhow::Result<T> { +pub fn from_json<T: DeserializeOwned>( + what: &'static str, + json: &serde_json::Value, +) -> anyhow::Result<T> { serde_json::from_value(json.clone()) .map_err(|e| anyhow::format_err!("Failed to deserialize {what}: {e}; {json}")) } diff --git a/crates/rust-analyzer/src/lsp/capabilities.rs b/crates/rust-analyzer/src/lsp/capabilities.rs index 1f35079b10..3ad4cb70b4 100644 --- a/crates/rust-analyzer/src/lsp/capabilities.rs +++ b/crates/rust-analyzer/src/lsp/capabilities.rs @@ -2,18 +2,17 @@ use ide::{CompletionFieldsToResolve, InlayFieldsToResolve}; use ide_db::{FxHashSet, line_index::WideEncoding}; use lsp_types::{ - CallHierarchyProvider, ChangeNotifications, CodeActionKind, CodeActionOptions, - CodeActionProvider, CodeLensOptions, CompletionOptions, DeclarationProvider, - DefinitionProvider, DocumentFormattingProvider, DocumentHighlightProvider, - DocumentOnTypeFormattingOptions, DocumentRangeFormattingProvider, DocumentSymbolProvider, - FileOperationFilter, FileOperationOptions, FileOperationPattern, FileOperationPatternKind, - FileOperationRegistrationOptions, FoldingRangeProvider, Full, HoverProvider, - ImplementationProvider, InlayHintOptions, InlayHintProvider, PositionEncodingKind, - ReferencesProvider, RenameOptions, RenameProvider, SaveOptions, SelectionRangeProvider, - SemanticTokensLegend, SemanticTokensOptions, ServerCapabilities, ServerCompletionItemOptions, - SignatureHelpOptions, TextDocumentSync, TextDocumentSyncKind, TextDocumentSyncOptions, - TypeDefinitionProvider, WorkDoneProgressOptions, WorkspaceFoldersServerCapabilities, - WorkspaceOptions, WorkspaceSymbolProvider, + CallHierarchyServerCapability, CodeActionKind, CodeActionOptions, CodeActionProviderCapability, + CodeLensOptions, CompletionOptions, CompletionOptionsCompletionItem, DeclarationCapability, + DocumentOnTypeFormattingOptions, FileOperationFilter, FileOperationPattern, + FileOperationPatternKind, FileOperationRegistrationOptions, FoldingRangeProviderCapability, + HoverProviderCapability, ImplementationProviderCapability, InlayHintOptions, + InlayHintServerCapabilities, OneOf, PositionEncodingKind, RenameOptions, SaveOptions, + SelectionRangeProviderCapability, SemanticTokensFullOptions, SemanticTokensLegend, + SemanticTokensOptions, ServerCapabilities, SignatureHelpOptions, TextDocumentSyncCapability, + TextDocumentSyncKind, TextDocumentSyncOptions, TypeDefinitionProviderCapability, + WorkDoneProgressOptions, WorkspaceFileOperationsServerCapabilities, + WorkspaceFoldersServerCapabilities, WorkspaceServerCapabilities, }; use serde_json::json; @@ -33,9 +32,9 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities { _ => None, }, }, - text_document_sync: Some(TextDocumentSync::Options(TextDocumentSyncOptions { + text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions { open_close: Some(true), - change: Some(TextDocumentSyncKind::Incremental), + change: Some(TextDocumentSyncKind::INCREMENTAL), will_save: None, will_save_wait_until: None, save: if config.caps().did_save_text_document_dynamic_registration() { @@ -44,9 +43,7 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities { Some(SaveOptions::default().into()) }, })), - notebook_document_sync: None, - selection_range_provider: Some(SelectionRangeProvider::Bool(true)), - hover_provider: Some(HoverProvider::Bool(true)), + hover_provider: Some(HoverProviderCapability::Simple(true)), completion_provider: Some(CompletionOptions { resolve_provider: if config.client_is_neovim() { config.has_completion_item_resolve_additionalTextEdits().then_some(true) @@ -68,24 +65,20 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities { retrigger_characters: None, work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, }), - definition_provider: Some(DefinitionProvider::Bool(true)), - type_definition_provider: Some(TypeDefinitionProvider::Bool(true)), - implementation_provider: Some(ImplementationProvider::Bool(true)), - references_provider: Some(ReferencesProvider::Bool(true)), - document_highlight_provider: Some(DocumentHighlightProvider::Bool(true)), - document_symbol_provider: Some(DocumentSymbolProvider::Bool(true)), - workspace_symbol_provider: Some(WorkspaceSymbolProvider::Bool(true)), + declaration_provider: Some(DeclarationCapability::Simple(true)), + definition_provider: Some(OneOf::Left(true)), + type_definition_provider: Some(TypeDefinitionProviderCapability::Simple(true)), + implementation_provider: Some(ImplementationProviderCapability::Simple(true)), + references_provider: Some(OneOf::Left(true)), + document_highlight_provider: Some(OneOf::Left(true)), + document_symbol_provider: Some(OneOf::Left(true)), + workspace_symbol_provider: Some(OneOf::Left(true)), code_action_provider: Some(config.caps().code_action_capabilities()), - code_lens_provider: Some(CodeLensOptions { - resolve_provider: Some(true), - work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, - }), - document_formatting_provider: Some(DocumentFormattingProvider::Bool(true)), + code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }), + document_formatting_provider: Some(OneOf::Left(true)), document_range_formatting_provider: match config.rustfmt(None) { - RustfmtConfig::Rustfmt { enable_range_formatting: true, .. } => { - Some(DocumentRangeFormattingProvider::Bool(true)) - } - _ => Some(DocumentRangeFormattingProvider::Bool(false)), + RustfmtConfig::Rustfmt { enable_range_formatting: true, .. } => Some(OneOf::Left(true)), + _ => Some(OneOf::Left(false)), }, document_on_type_formatting_provider: Some({ let mut chars = ide::Analysis::SUPPORTED_TRIGGER_CHARS.iter(); @@ -94,21 +87,22 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities { more_trigger_character: Some(chars.map(|c| c.to_string()).collect()), } }), - rename_provider: Some(RenameProvider::RenameOptions(RenameOptions { + selection_range_provider: Some(SelectionRangeProviderCapability::Simple(true)), + folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)), + rename_provider: Some(OneOf::Right(RenameOptions { prepare_provider: Some(true), work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, })), + linked_editing_range_provider: None, document_link_provider: None, color_provider: None, - folding_range_provider: Some(FoldingRangeProvider::Bool(true)), - declaration_provider: Some(DeclarationProvider::Bool(true)), execute_command_provider: None, - workspace: Some(WorkspaceOptions { + workspace: Some(WorkspaceServerCapabilities { workspace_folders: Some(WorkspaceFoldersServerCapabilities { supported: Some(true), - change_notifications: Some(ChangeNotifications::Bool(true)), + change_notifications: Some(OneOf::Left(true)), }), - file_operations: Some(FileOperationOptions { + file_operations: Some(WorkspaceFileOperationsServerCapabilities { did_create: None, will_create: None, did_rename: None, @@ -135,45 +129,29 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities { did_delete: None, will_delete: None, }), - text_document_content: None, }), - call_hierarchy_provider: Some(CallHierarchyProvider::Bool(true)), + call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)), semantic_tokens_provider: Some( SemanticTokensOptions { legend: SemanticTokensLegend { - token_types: semantic_tokens::SupportedType::iter() - .map(|semantic_token_type| semantic_token_type.to_string()) - .collect(), - token_modifiers: semantic_tokens::SupportedModifiers::iter() - .map(|semantic_token_type| semantic_token_type.to_string()) - .collect(), + token_types: semantic_tokens::SUPPORTED_TYPES.to_vec(), + token_modifiers: semantic_tokens::SUPPORTED_MODIFIERS.to_vec(), }, - full: Some(Full::SemanticTokensFullDelta(lsp_types::SemanticTokensFullDelta { - delta: Some(true), - })), - range: Some(lsp_types::SemanticTokensOptionsRange::Bool(true)), + full: Some(SemanticTokensFullOptions::Delta { delta: Some(true) }), + range: Some(true), work_done_progress_options: Default::default(), } .into(), ), moniker_provider: None, - linked_editing_range_provider: None, - inline_value_provider: None, - inlay_hint_provider: Some(InlayHintProvider::InlayHintOptions(InlayHintOptions { - work_done_progress_options: Default::default(), - resolve_provider: Some(config.caps().inlay_hints_resolve_provider()), - })), - diagnostic_provider: Some(lsp_types::DiagnosticProvider::DiagnosticOptions( - lsp_types::DiagnosticOptions { - identifier: Some("rust-analyzer".to_owned()), - inter_file_dependencies: true, - // FIXME - workspace_diagnostics: false, - work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, + inlay_hint_provider: Some(OneOf::Right(InlayHintServerCapabilities::Options( + InlayHintOptions { + work_done_progress_options: Default::default(), + resolve_provider: Some(config.caps().inlay_hints_resolve_provider()), }, - )), - inline_completion_provider: None, + ))), + inline_value_provider: None, experimental: Some(json!({ "externalDocs": true, "hoverRange": true, @@ -190,7 +168,16 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities { "ssr": true, "workspaceSymbolScopeKindFiltering": true, })), - type_hierarchy_provider: None, + diagnostic_provider: Some(lsp_types::DiagnosticServerCapabilities::Options( + lsp_types::DiagnosticOptions { + identifier: Some("rust-analyzer".to_owned()), + inter_file_dependencies: true, + // FIXME + workspace_diagnostics: false, + work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, + }, + )), + inline_completion_provider: None, } } @@ -257,34 +244,33 @@ impl ClientCapabilities { })() == Some(true) } - fn completion_item(&self) -> Option<ServerCompletionItemOptions> { - Some(ServerCompletionItemOptions { + fn completion_item(&self) -> Option<CompletionOptionsCompletionItem> { + Some(CompletionOptionsCompletionItem { label_details_support: Some(self.completion_label_details_support()), }) } - fn code_action_capabilities(&self) -> CodeActionProvider { + fn code_action_capabilities(&self) -> CodeActionProviderCapability { self.0 .text_document .as_ref() .and_then(|it| it.code_action.as_ref()) .and_then(|it| it.code_action_literal_support.as_ref()) - .map_or(CodeActionProvider::Bool(true), |_| { - CodeActionProvider::CodeActionOptions(CodeActionOptions { + .map_or(CodeActionProviderCapability::Simple(true), |_| { + CodeActionProviderCapability::Options(CodeActionOptions { // Advertise support for all built-in CodeActionKinds. // Ideally we would base this off of the client capabilities // but the client is supposed to fall back gracefully for unknown values. code_action_kinds: Some(vec![ - CodeActionKind::Empty, - CodeActionKind::QuickFix, - CodeActionKind::Refactor, - CodeActionKind::RefactorExtract, - CodeActionKind::RefactorInline, - CodeActionKind::RefactorRewrite, + CodeActionKind::EMPTY, + CodeActionKind::QUICKFIX, + CodeActionKind::REFACTOR, + CodeActionKind::REFACTOR_EXTRACT, + CodeActionKind::REFACTOR_INLINE, + CodeActionKind::REFACTOR_REWRITE, ]), resolve_provider: Some(true), work_done_progress_options: Default::default(), - documentation: None, }) }) } @@ -321,8 +307,8 @@ impl ClientCapabilities { } pub fn did_save_text_document_dynamic_registration(&self) -> bool { - let caps = - (|| -> _ { self.0.text_document.as_ref()?.synchronization })().unwrap_or_default(); + let caps = (|| -> _ { self.0.text_document.as_ref()?.synchronization.clone() })() + .unwrap_or_default(); caps.did_save == Some(true) && caps.dynamic_registration == Some(true) } @@ -515,7 +501,7 @@ impl ClientCapabilities { } pub fn diagnostics_refresh(&self) -> bool { - (|| -> _ { self.0.workspace.as_ref()?.diagnostics.as_ref()?.refresh_support })() + (|| -> _ { self.0.workspace.as_ref()?.diagnostic.as_ref()?.refresh_support })() .unwrap_or_default() } diff --git a/crates/rust-analyzer/src/lsp/ext.rs b/crates/rust-analyzer/src/lsp/ext.rs index 584e2031eb..c94e7db104 100644 --- a/crates/rust-analyzer/src/lsp/ext.rs +++ b/crates/rust-analyzer/src/lsp/ext.rs @@ -8,16 +8,17 @@ use std::ops; +use lsp_types::Url; +use lsp_types::request::Request; use lsp_types::{ - CodeActionKind, DocumentOnTypeFormattingParams, LspNotificationMethod, LspRequestMethod, - MessageDirection, Notification, PartialResultParams, Position, Range, Request, - TextDocumentIdentifier, Uri, WorkDoneProgressParams, + CodeActionKind, DocumentOnTypeFormattingParams, PartialResultParams, Position, Range, + TextDocumentIdentifier, WorkDoneProgressParams, notification::Notification, }; use paths::Utf8PathBuf; use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; -pub enum InternalTestingFetchConfigRequest {} +pub enum InternalTestingFetchConfig {} #[derive(Deserialize, Serialize, Debug)] pub enum InternalTestingFetchConfigOption { @@ -31,13 +32,11 @@ pub enum InternalTestingFetchConfigResponse { CheckWorkspace(bool), } -impl Request for InternalTestingFetchConfigRequest { +impl Request for InternalTestingFetchConfig { type Params = InternalTestingFetchConfigParams; // Option is solely to circumvent Default bound. type Result = Option<InternalTestingFetchConfigResponse>; - const METHOD: LspRequestMethod = - LspRequestMethod::new("rust-analyzer-internal/internalTestingFetchConfig"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer-internal/internalTestingFetchConfig"; } #[derive(Deserialize, Serialize, Debug)] @@ -46,13 +45,12 @@ pub struct InternalTestingFetchConfigParams { pub text_document: Option<TextDocumentIdentifier>, pub config: InternalTestingFetchConfigOption, } -pub enum AnalyzerStatusRequest {} +pub enum AnalyzerStatus {} -impl Request for AnalyzerStatusRequest { +impl Request for AnalyzerStatus { type Params = AnalyzerStatusParams; type Result = String; - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/analyzerStatus"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/analyzerStatus"; } #[derive(Deserialize, Serialize, Debug)] @@ -66,15 +64,14 @@ pub struct AnalyzerStatusParams { pub struct CrateInfoResult { pub name: Option<String>, pub version: Option<String>, - pub path: Uri, + pub path: Url, } -pub enum FetchDependencyListRequest {} +pub enum FetchDependencyList {} -impl Request for FetchDependencyListRequest { +impl Request for FetchDependencyList { type Params = FetchDependencyListParams; type Result = FetchDependencyListResult; - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/fetchDependencyList"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/fetchDependencyList"; } #[derive(Deserialize, Serialize, Debug)] @@ -87,40 +84,36 @@ pub struct FetchDependencyListResult { pub crates: Vec<CrateInfoResult>, } -pub enum MemoryUsageRequest {} +pub enum MemoryUsage {} -impl Request for MemoryUsageRequest { +impl Request for MemoryUsage { type Params = (); type Result = String; - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/memoryUsage"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/memoryUsage"; } -pub enum ReloadWorkspaceRequest {} +pub enum ReloadWorkspace {} -impl Request for ReloadWorkspaceRequest { +impl Request for ReloadWorkspace { type Params = (); type Result = (); - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/reloadWorkspace"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/reloadWorkspace"; } -pub enum RebuildProcMacrosRequest {} +pub enum RebuildProcMacros {} -impl Request for RebuildProcMacrosRequest { +impl Request for RebuildProcMacros { type Params = (); type Result = (); - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/rebuildProcMacros"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/rebuildProcMacros"; } -pub enum ViewSyntaxTreeRequest {} +pub enum ViewSyntaxTree {} -impl Request for ViewSyntaxTreeRequest { +impl Request for ViewSyntaxTree { type Params = ViewSyntaxTreeParams; type Result = String; - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/viewSyntaxTree"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/viewSyntaxTree"; } #[derive(Deserialize, Serialize, Debug)] @@ -129,40 +122,36 @@ pub struct ViewSyntaxTreeParams { pub text_document: TextDocumentIdentifier, } -pub enum ViewHirRequest {} +pub enum ViewHir {} -impl Request for ViewHirRequest { +impl Request for ViewHir { type Params = lsp_types::TextDocumentPositionParams; type Result = String; - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/viewHir"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/viewHir"; } -pub enum ViewMirRequest {} +pub enum ViewMir {} -impl Request for ViewMirRequest { +impl Request for ViewMir { type Params = lsp_types::TextDocumentPositionParams; type Result = String; - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/viewMir"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/viewMir"; } -pub enum InterpretFunctionRequest {} +pub enum InterpretFunction {} -impl Request for InterpretFunctionRequest { +impl Request for InterpretFunction { type Params = lsp_types::TextDocumentPositionParams; type Result = String; - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/interpretFunction"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/interpretFunction"; } -pub enum ViewFileTextRequest {} +pub enum ViewFileText {} -impl Request for ViewFileTextRequest { +impl Request for ViewFileText { type Params = lsp_types::TextDocumentIdentifier; type Result = String; - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/viewFileText"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/viewFileText"; } #[derive(Deserialize, Serialize, Debug)] @@ -172,13 +161,12 @@ pub struct ViewCrateGraphParams { pub full: bool, } -pub enum ViewCrateGraphRequest {} +pub enum ViewCrateGraph {} -impl Request for ViewCrateGraphRequest { +impl Request for ViewCrateGraph { type Params = ViewCrateGraphParams; type Result = String; - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/viewCrateGraph"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/viewCrateGraph"; } #[derive(Deserialize, Serialize, Debug)] @@ -187,13 +175,12 @@ pub struct ViewItemTreeParams { pub text_document: TextDocumentIdentifier, } -pub enum ViewItemTreeRequest {} +pub enum ViewItemTree {} -impl Request for ViewItemTreeRequest { +impl Request for ViewItemTree { type Params = ViewItemTreeParams; type Result = String; - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/viewItemTree"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/viewItemTree"; } #[derive(Deserialize, Serialize, Debug)] @@ -231,22 +218,19 @@ pub struct DiscoverTestResults { pub scope_file: Option<Vec<TextDocumentIdentifier>>, } -pub enum DiscoverTestRequest {} +pub enum DiscoverTest {} -impl Request for DiscoverTestRequest { +impl Request for DiscoverTest { type Params = DiscoverTestParams; type Result = DiscoverTestResults; - const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/discoverTest"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/discoverTest"; } -pub enum DiscoveredTestsNotification {} +pub enum DiscoveredTests {} -impl Notification for DiscoveredTestsNotification { +impl Notification for DiscoveredTests { type Params = DiscoverTestResults; - const METHOD: LspNotificationMethod = - LspNotificationMethod::new("experimental/discoveredTests"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/discoveredTests"; } #[derive(Deserialize, Serialize, Debug)] @@ -256,39 +240,34 @@ pub struct RunTestParams { pub exclude: Option<Vec<String>>, } -pub enum RunTestRequest {} +pub enum RunTest {} -impl Request for RunTestRequest { +impl Request for RunTest { type Params = RunTestParams; type Result = (); - const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/runTest"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/runTest"; } #[derive(Debug)] -pub enum EndRunTestNotification {} +pub enum EndRunTest {} -impl Notification for EndRunTestNotification { +impl Notification for EndRunTest { type Params = (); - const METHOD: LspNotificationMethod = LspNotificationMethod::new("experimental/endRunTest"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/endRunTest"; } -pub enum AppendOutputToRunTestNotification {} +pub enum AppendOutputToRunTest {} -impl Notification for AppendOutputToRunTestNotification { +impl Notification for AppendOutputToRunTest { type Params = String; - const METHOD: LspNotificationMethod = - LspNotificationMethod::new("experimental/appendOutputToRunTest"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/appendOutputToRunTest"; } -pub enum AbortRunTestNotification {} +pub enum AbortRunTest {} -impl Notification for AbortRunTestNotification { +impl Notification for AbortRunTest { type Params = (); - const METHOD: LspNotificationMethod = LspNotificationMethod::new("experimental/abortRunTest"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/abortRunTest"; } #[derive(Deserialize, Serialize, Debug)] @@ -308,22 +287,19 @@ pub struct ChangeTestStateParams { pub state: TestState, } -pub enum ChangeTestStateNotification {} +pub enum ChangeTestState {} -impl Notification for ChangeTestStateNotification { +impl Notification for ChangeTestState { type Params = ChangeTestStateParams; - const METHOD: LspNotificationMethod = - LspNotificationMethod::new("experimental/changeTestState"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/changeTestState"; } -pub enum ExpandMacroRequest {} +pub enum ExpandMacro {} -impl Request for ExpandMacroRequest { +impl Request for ExpandMacro { type Params = ExpandMacroParams; type Result = Option<ExpandedMacro>; - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/expandMacro"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/expandMacro"; } #[derive(Deserialize, Serialize, Debug)] @@ -340,14 +316,12 @@ pub struct ExpandedMacro { pub expansion: String, } -pub enum ViewRecursiveMemoryLayoutRequest {} +pub enum ViewRecursiveMemoryLayout {} -impl Request for ViewRecursiveMemoryLayoutRequest { +impl Request for ViewRecursiveMemoryLayout { type Params = lsp_types::TextDocumentPositionParams; type Result = Option<RecursiveMemoryLayout>; - const METHOD: LspRequestMethod = - LspRequestMethod::new("rust-analyzer/viewRecursiveMemoryLayout"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/viewRecursiveMemoryLayout"; } #[derive(Deserialize, Serialize, Debug)] @@ -369,38 +343,32 @@ pub struct MemoryLayoutNode { pub children_len: u64, } -pub enum CancelFlycheckNotification {} +pub enum CancelFlycheck {} -impl Notification for CancelFlycheckNotification { +impl Notification for CancelFlycheck { type Params = (); - const METHOD: LspNotificationMethod = - LspNotificationMethod::new("rust-analyzer/cancelFlycheck"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/cancelFlycheck"; } -pub enum RunFlycheckNotification {} +pub enum RunFlycheck {} -impl Notification for RunFlycheckNotification { +impl Notification for RunFlycheck { type Params = RunFlycheckParams; - const METHOD: LspNotificationMethod = LspNotificationMethod::new("rust-analyzer/runFlycheck"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/runFlycheck"; } -pub enum ClearFlycheckNotification {} +pub enum ClearFlycheck {} -impl Notification for ClearFlycheckNotification { +impl Notification for ClearFlycheck { type Params = (); - const METHOD: LspNotificationMethod = LspNotificationMethod::new("rust-analyzer/clearFlycheck"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/clearFlycheck"; } -pub enum OpenServerLogsNotification {} +pub enum OpenServerLogs {} -impl Notification for OpenServerLogsNotification { +impl Notification for OpenServerLogs { type Params = (); - const METHOD: LspNotificationMethod = - LspNotificationMethod::new("rust-analyzer/openServerLogs"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/openServerLogs"; } #[derive(Deserialize, Serialize, Debug)] @@ -409,13 +377,12 @@ pub struct RunFlycheckParams { pub text_document: Option<TextDocumentIdentifier>, } -pub enum MatchingBraceRequest {} +pub enum MatchingBrace {} -impl Request for MatchingBraceRequest { +impl Request for MatchingBrace { type Params = MatchingBraceParams; type Result = Vec<Position>; - const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/matchingBrace"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/matchingBrace"; } #[derive(Deserialize, Serialize, Debug)] @@ -425,31 +392,28 @@ pub struct MatchingBraceParams { pub positions: Vec<Position>, } -pub enum ParentModuleRequest {} +pub enum ParentModule {} -impl Request for ParentModuleRequest { +impl Request for ParentModule { type Params = lsp_types::TextDocumentPositionParams; - type Result = Option<lsp_types::DefinitionResponse>; - const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/parentModule"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + type Result = Option<lsp_types::GotoDefinitionResponse>; + const METHOD: &'static str = "experimental/parentModule"; } -pub enum ChildModulesRequest {} +pub enum ChildModules {} -impl Request for ChildModulesRequest { +impl Request for ChildModules { type Params = lsp_types::TextDocumentPositionParams; - type Result = Option<lsp_types::DefinitionResponse>; - const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/childModules"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + type Result = Option<lsp_types::GotoDefinitionResponse>; + const METHOD: &'static str = "experimental/childModules"; } -pub enum JoinLinesRequest {} +pub enum JoinLines {} -impl Request for JoinLinesRequest { +impl Request for JoinLines { type Params = JoinLinesParams; type Result = Vec<lsp_types::TextEdit>; - const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/joinLines"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/joinLines"; } #[derive(Deserialize, Serialize, Debug)] @@ -459,22 +423,20 @@ pub struct JoinLinesParams { pub ranges: Vec<Range>, } -pub enum OnEnterRequest {} +pub enum OnEnter {} -impl Request for OnEnterRequest { +impl Request for OnEnter { type Params = lsp_types::TextDocumentPositionParams; type Result = Option<Vec<SnippetTextEdit>>; - const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/onEnter"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/onEnter"; } -pub enum RunnablesRequest {} +pub enum Runnables {} -impl Request for RunnablesRequest { +impl Request for Runnables { type Params = RunnablesParams; type Result = Vec<Runnable>; - const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/runnables"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/runnables"; } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -527,13 +489,12 @@ pub struct ShellRunnableArgs { pub args: Vec<String>, } -pub enum RelatedTestsRequest {} +pub enum RelatedTests {} -impl Request for RelatedTestsRequest { +impl Request for RelatedTests { type Params = lsp_types::TextDocumentPositionParams; type Result = Vec<TestInfo>; - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/relatedTests"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/relatedTests"; } #[derive(Debug, Deserialize, Serialize)] @@ -541,13 +502,12 @@ pub struct TestInfo { pub runnable: Runnable, } -pub enum SsrRequest {} +pub enum Ssr {} -impl Request for SsrRequest { +impl Request for Ssr { type Params = SsrParams; type Result = lsp_types::WorkspaceEdit; - const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/ssr"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/ssr"; } #[derive(Debug, Deserialize, Serialize)] @@ -569,8 +529,7 @@ pub enum ServerStatusNotification {} impl Notification for ServerStatusNotification { type Params = ServerStatusParams; - const METHOD: LspNotificationMethod = LspNotificationMethod::new("experimental/serverStatus"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/serverStatus"; } #[derive(Deserialize, Serialize, PartialEq, Eq, Clone)] @@ -604,8 +563,7 @@ pub enum CodeActionRequest {} impl Request for CodeActionRequest { type Params = lsp_types::CodeActionParams; type Result = Option<Vec<CodeAction>>; - const METHOD: LspRequestMethod = LspRequestMethod::new("textDocument/codeAction"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "textDocument/codeAction"; } pub enum CodeActionResolveRequest {} @@ -613,8 +571,7 @@ pub enum CodeActionResolveRequest {} impl Request for CodeActionResolveRequest { type Params = CodeAction; type Result = CodeAction; - const METHOD: LspRequestMethod = LspRequestMethod::new("codeAction/resolve"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "codeAction/resolve"; } #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)] @@ -648,7 +605,7 @@ pub struct CodeActionData { #[serde(rename_all = "camelCase")] pub struct SnippetWorkspaceEdit { #[serde(skip_serializing_if = "Option::is_none")] - pub changes: Option<FxHashMap<Uri, Vec<lsp_types::TextEdit>>>, + pub changes: Option<FxHashMap<lsp_types::Url, Vec<lsp_types::TextEdit>>>, #[serde(skip_serializing_if = "Option::is_none")] pub document_changes: Option<Vec<SnippetDocumentChangeOperation>>, #[serde(skip_serializing_if = "Option::is_none")] @@ -663,7 +620,7 @@ pub struct SnippetWorkspaceEdit { #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] #[serde(untagged, rename_all = "lowercase")] pub enum SnippetDocumentChangeOperation { - Change(lsp_types::DocumentChange), + Op(lsp_types::ResourceOp), Edit(SnippetTextDocumentEdit), } @@ -679,8 +636,7 @@ pub enum HoverRequest {} impl Request for HoverRequest { type Params = HoverParams; type Result = Option<Hover>; - const METHOD: LspRequestMethod = lsp_types::HoverRequest::METHOD; - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = lsp_types::request::HoverRequest::METHOD; } #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] @@ -724,19 +680,18 @@ pub struct CommandLink { pub tooltip: Option<String>, } -pub enum ExternalDocsRequest {} +pub enum ExternalDocs {} -impl Request for ExternalDocsRequest { +impl Request for ExternalDocs { type Params = lsp_types::TextDocumentPositionParams; type Result = ExternalDocsResponse; - const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/externalDocs"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/externalDocs"; } #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] #[serde(untagged)] pub enum ExternalDocsResponse { - Simple(Option<lsp_types::Uri>), + Simple(Option<lsp_types::Url>), WithLocal(ExternalDocsPair), } @@ -749,17 +704,16 @@ impl Default for ExternalDocsResponse { #[derive(Debug, Default, PartialEq, Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] pub struct ExternalDocsPair { - pub web: Option<lsp_types::Uri>, - pub local: Option<lsp_types::Uri>, + pub web: Option<lsp_types::Url>, + pub local: Option<lsp_types::Url>, } -pub enum OpenCargoTomlRequest {} +pub enum OpenCargoToml {} -impl Request for OpenCargoTomlRequest { +impl Request for OpenCargoToml { type Params = OpenCargoTomlParams; - type Result = Option<lsp_types::DefinitionResponse>; - const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/openCargoToml"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + type Result = Option<lsp_types::GotoDefinitionResponse>; + const METHOD: &'static str = "experimental/openCargoToml"; } #[derive(Serialize, Deserialize, Debug)] @@ -779,17 +733,16 @@ pub struct CodeLensResolveData { #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum CodeLensResolveDataKind { - Impls(lsp_types::ImplementationParams), + Impls(lsp_types::request::GotoImplementationParams), References(lsp_types::TextDocumentPositionParams), } -pub enum MoveItemRequest {} +pub enum MoveItem {} -impl Request for MoveItemRequest { +impl Request for MoveItem { type Params = MoveItemParams; type Result = Vec<SnippetTextEdit>; - const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/moveItem"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "experimental/moveItem"; } #[derive(Serialize, Deserialize, Debug)] @@ -807,13 +760,12 @@ pub enum MoveItemDirection { } #[derive(Debug)] -pub enum WorkspaceSymbolRequest {} +pub enum WorkspaceSymbol {} -impl Request for WorkspaceSymbolRequest { +impl Request for WorkspaceSymbol { type Params = WorkspaceSymbolParams; type Result = Option<lsp_types::WorkspaceSymbolResponse>; - const METHOD: LspRequestMethod = LspRequestMethod::new("workspace/symbol"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "workspace/symbol"; } #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] @@ -849,16 +801,15 @@ pub enum WorkspaceSymbolSearchKind { /// The document on type formatting request is sent from the client to /// the server to format parts of the document during typing. This is -/// almost same as [`lsp_types::DocumentOnTypeFormattingRequest`], but the +/// almost same as lsp_types::request::OnTypeFormatting, but the /// result has SnippetTextEdit in it instead of TextEdit. #[derive(Debug)] -pub enum DocumentOnTypeFormattingRequest {} +pub enum OnTypeFormatting {} -impl Request for DocumentOnTypeFormattingRequest { +impl Request for OnTypeFormatting { type Params = DocumentOnTypeFormattingParams; type Result = Option<Vec<SnippetTextEdit>>; - const METHOD: LspRequestMethod = LspRequestMethod::new("textDocument/onTypeFormatting"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "textDocument/onTypeFormatting"; } #[derive(Debug, Serialize, Deserialize)] @@ -897,7 +848,7 @@ pub struct ClientCommandOptions { pub commands: Vec<String>, } -pub enum EvaluatePredicateRequest {} +pub enum EvaluatePredicate {} #[derive(Deserialize, Serialize, Debug)] #[serde(rename_all = "camelCase")] @@ -924,14 +875,13 @@ pub enum PredicateEvaluationStatus { Unsupported, } -impl Request for EvaluatePredicateRequest { +impl Request for EvaluatePredicate { type Params = EvaluatePredicateParams; type Result = EvaluatePredicateResult; - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/evaluatePredicate"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/evaluatePredicate"; } -pub enum GetFailedObligationsRequest {} +pub enum GetFailedObligations {} #[derive(Deserialize, Serialize, Debug)] #[serde(rename_all = "camelCase")] @@ -940,11 +890,10 @@ pub struct GetFailedObligationsParams { pub position: Position, } -impl Request for GetFailedObligationsRequest { +impl Request for GetFailedObligations { type Params = GetFailedObligationsParams; type Result = String; - const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/getFailedObligations"); - const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; + const METHOD: &'static str = "rust-analyzer/getFailedObligations"; } #[cfg(test)] diff --git a/crates/rust-analyzer/src/lsp/from_proto.rs b/crates/rust-analyzer/src/lsp/from_proto.rs index a27e5fcf61..333826a179 100644 --- a/crates/rust-analyzer/src/lsp/from_proto.rs +++ b/crates/rust-analyzer/src/lsp/from_proto.rs @@ -1,5 +1,4 @@ //! Conversion lsp_types types to rust-analyzer specific ones. - use anyhow::format_err; use ide::{Annotation, AnnotationKind, AssistKind, LineCol}; use ide_db::{FileId, FilePosition, FileRange, line_index::WideLineCol}; @@ -13,12 +12,12 @@ use crate::{ lsp_ext, try_default, }; -pub(crate) fn abs_path(url: &lsp_types::Uri) -> anyhow::Result<AbsPathBuf> { +pub(crate) fn abs_path(url: &lsp_types::Url) -> anyhow::Result<AbsPathBuf> { let path = url.to_file_path().map_err(|()| anyhow::format_err!("url is not a file"))?; Ok(AbsPathBuf::try_from(Utf8PathBuf::from_path_buf(path).unwrap()).unwrap()) } -pub(crate) fn vfs_path(url: &lsp_types::Uri) -> anyhow::Result<vfs::VfsPath> { +pub(crate) fn vfs_path(url: &lsp_types::Url) -> anyhow::Result<vfs::VfsPath> { abs_path(url).map(vfs::VfsPath::from) } @@ -66,7 +65,7 @@ pub(crate) fn text_range( /// Returns `None` if the file was excluded. pub(crate) fn file_id( snap: &GlobalStateSnapshot, - url: &lsp_types::Uri, + url: &lsp_types::Url, ) -> anyhow::Result<Option<FileId>> { snap.url_to_file_id(url) } @@ -74,7 +73,7 @@ pub(crate) fn file_id( /// Returns `None` if the file was excluded. pub(crate) fn file_position( snap: &GlobalStateSnapshot, - tdpp: &lsp_types::TextDocumentPositionParams, + tdpp: lsp_types::TextDocumentPositionParams, ) -> anyhow::Result<Option<FilePosition>> { let file_id = try_default!(file_id(snap, &tdpp.text_document.uri)?); let line_index = snap.file_line_index(file_id)?; @@ -94,7 +93,7 @@ pub(crate) fn file_range( /// Returns `None` if the file was excluded. pub(crate) fn file_range_uri( snap: &GlobalStateSnapshot, - document: &lsp_types::Uri, + document: &lsp_types::Url, range: lsp_types::Range, ) -> anyhow::Result<Option<FileRange>> { let file_id = try_default!(file_id(snap, document)?); @@ -105,12 +104,12 @@ pub(crate) fn file_range_uri( pub(crate) fn assist_kind(kind: lsp_types::CodeActionKind) -> Option<AssistKind> { let assist_kind = match &kind { - k if k == &lsp_types::CodeActionKind::Empty => AssistKind::Generate, - k if k == &lsp_types::CodeActionKind::QuickFix => AssistKind::QuickFix, - k if k == &lsp_types::CodeActionKind::Refactor => AssistKind::Refactor, - k if k == &lsp_types::CodeActionKind::RefactorExtract => AssistKind::RefactorExtract, - k if k == &lsp_types::CodeActionKind::RefactorInline => AssistKind::RefactorInline, - k if k == &lsp_types::CodeActionKind::RefactorRewrite => AssistKind::RefactorRewrite, + k if k == &lsp_types::CodeActionKind::EMPTY => AssistKind::Generate, + k if k == &lsp_types::CodeActionKind::QUICKFIX => AssistKind::QuickFix, + k if k == &lsp_types::CodeActionKind::REFACTOR => AssistKind::Refactor, + k if k == &lsp_types::CodeActionKind::REFACTOR_EXTRACT => AssistKind::RefactorExtract, + k if k == &lsp_types::CodeActionKind::REFACTOR_INLINE => AssistKind::RefactorInline, + k if k == &lsp_types::CodeActionKind::REFACTOR_REWRITE => AssistKind::RefactorRewrite, _ => return None, }; @@ -131,7 +130,7 @@ pub(crate) fn annotation( return Ok(None); } let pos @ FilePosition { file_id, .. } = - try_default!(file_position(snap, ¶ms.text_document_position_params)?); + try_default!(file_position(snap, params.text_document_position_params)?); let line_index = snap.file_line_index(file_id)?; Ok(Annotation { @@ -143,7 +142,7 @@ pub(crate) fn annotation( if snap.url_file_version(¶ms.text_document.uri) != Some(data.version) { return Ok(None); } - let pos @ FilePosition { file_id, .. } = try_default!(file_position(snap, ¶ms)?); + let pos @ FilePosition { file_id, .. } = try_default!(file_position(snap, params)?); let line_index = snap.file_line_index(file_id)?; Ok(Annotation { diff --git a/crates/rust-analyzer/src/lsp/semantic_tokens.rs b/crates/rust-analyzer/src/lsp/semantic_tokens.rs index 7819806423..9bfdea8a16 100644 --- a/crates/rust-analyzer/src/lsp/semantic_tokens.rs +++ b/crates/rust-analyzer/src/lsp/semantic_tokens.rs @@ -1,261 +1,170 @@ //! Semantic Tokens helpers -use std::{fmt, ops, slice::Iter}; +use std::ops; -use lsp_types::{Range, SemanticTokenModifiers, SemanticTokens, SemanticTokensEdit}; +use lsp_types::{ + Range, SemanticToken, SemanticTokenModifier, SemanticTokenType, SemanticTokens, + SemanticTokensEdit, +}; -macro_rules! declare_enum { +macro_rules! define_semantic_token_types { ( - $(#[$attrs:meta])* - $visibility:vis enum $name:ident { - $($variant:ident),* $(,)? + standard { + $($standard:ident),*$(,)? } + custom { + $(($custom:ident, $string:literal) $(=> $fallback:ident)?),*$(,)? + } + ) => { - $(#[$attrs])* - $visibility enum $name { - $($variant,)* + pub(crate) mod types { + use super::SemanticTokenType; + $(pub(crate) const $standard: SemanticTokenType = SemanticTokenType::$standard;)* + $(pub(crate) const $custom: SemanticTokenType = SemanticTokenType::new($string);)* } - impl $name { - pub(crate) fn iter() -> Iter<'static, Self> { - static ITEMS: &[$name] = &[ - $( - $name::$variant, - )* - ]; - ITEMS.iter() - } + pub(crate) const SUPPORTED_TYPES: &[SemanticTokenType] = &[ + $(self::types::$standard,)* + $(self::types::$custom),* + ]; + + pub(crate) fn standard_fallback_type(token: SemanticTokenType) -> Option<SemanticTokenType> { + use self::types::*; + $( + if token == $custom { + None $(.or(Some(self::types::$fallback)))? + } else + )* + { Some(token )} } }; } -declare_enum! { - #[repr(u32)] - #[derive(Debug, PartialEq, Clone, Copy)] - pub(crate) enum SupportedType { - Comment, - Decorator, - EnumMember, - Enum, - Function, - Interface, - Keyword, - Macro, - Method, - Namespace, - Number, - Operator, - Parameter, - Property, - String, - Struct, - TypeParameter, - Variable, - Type, - Label, - Angle, - Arithmetic, - AttributeBracket, - Attribute, - Bitwise, - Boolean, - Brace, - Bracket, - BuiltinAttribute, - BuiltinType, - Char, - Colon, - Comma, - Comparison, - ConstParameter, - Const, - DeriveHelper, - Derive, - Dot, - EscapeSequence, - FormatSpecifier, - Generic, - InvalidEscapeSequence, - Lifetime, - Logical, - MacroBang, - Negation, - Parenthesis, - ProcMacro, - Punctuation, - SelfKeyword, - SelfTypeKeyword, - Semicolon, - Static, - ToolModule, - TypeAlias, - Union, - UnresolvedReference, +define_semantic_token_types![ + standard { + COMMENT, + DECORATOR, + ENUM_MEMBER, + ENUM, + FUNCTION, + INTERFACE, + KEYWORD, + MACRO, + METHOD, + NAMESPACE, + NUMBER, + OPERATOR, + PARAMETER, + PROPERTY, + STRING, + STRUCT, + TYPE_PARAMETER, + VARIABLE, + TYPE, } -} -declare_enum! { - #[repr(u32)] - #[derive(Debug, PartialEq, Clone, Copy)] - pub(crate) enum SupportedModifiers { - Async, - Documentation, - Declaration, - Static, - DefaultLibrary, - Deprecated, - Associated, - AttributeModifier, - Callable, - Constant, - Consuming, - ControlFlow, - CrateRoot, - Injected, - IntraDocLink, - Library, - MacroModifier, - Mutable, - ProcMacroModifier, - Public, - Reference, - TraitModifier, - Unsafe, + custom { + (ANGLE, "angle"), + (ARITHMETIC, "arithmetic") => OPERATOR, + (ATTRIBUTE_BRACKET, "attributeBracket") => DECORATOR, + (ATTRIBUTE, "attribute") => DECORATOR, + (BITWISE, "bitwise") => OPERATOR, + (BOOLEAN, "boolean"), + (BRACE, "brace"), + (BRACKET, "bracket"), + (BUILTIN_ATTRIBUTE, "builtinAttribute") => DECORATOR, + (BUILTIN_TYPE, "builtinType") => TYPE, + (CHAR, "character") => STRING, + (COLON, "colon"), + (COMMA, "comma"), + (COMPARISON, "comparison") => OPERATOR, + (CONST_PARAMETER, "constParameter"), + (CONST, "const") => VARIABLE, + (DERIVE_HELPER, "deriveHelper") => DECORATOR, + (DERIVE, "derive") => DECORATOR, + (DOT, "dot"), + (ESCAPE_SEQUENCE, "escapeSequence") => STRING, + (FORMAT_SPECIFIER, "formatSpecifier") => STRING, + (GENERIC, "generic") => TYPE_PARAMETER, + (INVALID_ESCAPE_SEQUENCE, "invalidEscapeSequence") => STRING, + (LABEL, "label"), + (LIFETIME, "lifetime"), + (LOGICAL, "logical") => OPERATOR, + (MACRO_BANG, "macroBang") => MACRO, + (NEGATION, "negation") => OPERATOR, + (PARENTHESIS, "parenthesis"), + (PROC_MACRO, "procMacro") => MACRO, + (PUNCTUATION, "punctuation"), + (SELF_KEYWORD, "selfKeyword") => KEYWORD, + (SELF_TYPE_KEYWORD, "selfTypeKeyword") => KEYWORD, + (SEMICOLON, "semicolon"), + (STATIC, "static") => VARIABLE, + (TOOL_MODULE, "toolModule") => DECORATOR, + (TYPE_ALIAS, "typeAlias") => TYPE, + (UNION, "union") => TYPE, + (UNRESOLVED_REFERENCE, "unresolvedReference"), } -} +]; -impl fmt::Display for SupportedType { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let string = match self { - SupportedType::Comment => ::lsp_types::SemanticTokenTypes::Comment.as_str(), - SupportedType::Decorator => ::lsp_types::SemanticTokenTypes::Decorator.as_str(), - SupportedType::EnumMember => ::lsp_types::SemanticTokenTypes::EnumMember.as_str(), - SupportedType::Enum => ::lsp_types::SemanticTokenTypes::Enum.as_str(), - SupportedType::Function => ::lsp_types::SemanticTokenTypes::Function.as_str(), - SupportedType::Interface => ::lsp_types::SemanticTokenTypes::Interface.as_str(), - SupportedType::Keyword => ::lsp_types::SemanticTokenTypes::Keyword.as_str(), - SupportedType::Macro => ::lsp_types::SemanticTokenTypes::Macro.as_str(), - SupportedType::Method => ::lsp_types::SemanticTokenTypes::Method.as_str(), - SupportedType::Namespace => ::lsp_types::SemanticTokenTypes::Namespace.as_str(), - SupportedType::Number => ::lsp_types::SemanticTokenTypes::Number.as_str(), - SupportedType::Operator => ::lsp_types::SemanticTokenTypes::Operator.as_str(), - SupportedType::Parameter => ::lsp_types::SemanticTokenTypes::Parameter.as_str(), - SupportedType::Property => ::lsp_types::SemanticTokenTypes::Property.as_str(), - SupportedType::String => ::lsp_types::SemanticTokenTypes::String.as_str(), - SupportedType::Struct => ::lsp_types::SemanticTokenTypes::Struct.as_str(), - SupportedType::TypeParameter => ::lsp_types::SemanticTokenTypes::TypeParameter.as_str(), - SupportedType::Variable => ::lsp_types::SemanticTokenTypes::Variable.as_str(), - SupportedType::Type => ::lsp_types::SemanticTokenTypes::Type.as_str(), - SupportedType::Label => ::lsp_types::SemanticTokenTypes::Label.as_str(), - SupportedType::Angle => "angle", - SupportedType::Arithmetic => "arithmetic", - SupportedType::AttributeBracket => "attributeBracket", - SupportedType::Attribute => "attribute", - SupportedType::Bitwise => "bitwise", - SupportedType::Boolean => "boolean", - SupportedType::Brace => "brace", - SupportedType::Bracket => "bracket", - SupportedType::BuiltinAttribute => "builtinAttribute", - SupportedType::BuiltinType => "builtinType", - SupportedType::Char => "character", - SupportedType::Colon => "colon", - SupportedType::Comma => "comma", - SupportedType::Comparison => "comparison", - SupportedType::ConstParameter => "constParameter", - SupportedType::Const => "const", - SupportedType::DeriveHelper => "deriveHelper", - SupportedType::Derive => "derive", - SupportedType::Dot => "dot", - SupportedType::EscapeSequence => "escapeSequence", - SupportedType::FormatSpecifier => "formatSpecifier", - SupportedType::Generic => "generic", - SupportedType::InvalidEscapeSequence => "invalidEscapeSequence", - SupportedType::Lifetime => "lifetime", - SupportedType::Logical => "logical", - SupportedType::MacroBang => "macroBang", - SupportedType::Negation => "negation", - SupportedType::Parenthesis => "parenthesis", - SupportedType::ProcMacro => "procMacro", - SupportedType::Punctuation => "punctuation", - SupportedType::SelfKeyword => "selfKeyword", - SupportedType::SelfTypeKeyword => "selfTypeKeyword", - SupportedType::Semicolon => "semicolon", - SupportedType::Static => "static", - SupportedType::ToolModule => "toolModule", - SupportedType::TypeAlias => "typeAlias", - SupportedType::Union => "union", - SupportedType::UnresolvedReference => "unresolvedReference", - }; - f.write_str(string) - } +macro_rules! count_tts { + () => {0usize}; + ($_head:tt $($tail:tt)*) => {1usize + count_tts!($($tail)*)}; } +macro_rules! define_semantic_token_modifiers { + ( + standard { + $($standard:ident),*$(,)? + } + custom { + $(($custom:ident, $string:literal)),*$(,)? + } -pub(crate) fn standard_fallback_type(token: SupportedType) -> Option<SupportedType> { - Some(match token { - SupportedType::Comment => SupportedType::Comment, - SupportedType::Decorator => SupportedType::Decorator, - SupportedType::EnumMember => SupportedType::EnumMember, - SupportedType::Enum => SupportedType::Enum, - SupportedType::Function => SupportedType::Function, - SupportedType::Interface => SupportedType::Interface, - SupportedType::Keyword => SupportedType::Keyword, - SupportedType::Macro => SupportedType::Macro, - SupportedType::Method => SupportedType::Method, - SupportedType::Namespace => SupportedType::Namespace, - SupportedType::Number => SupportedType::Number, - SupportedType::Operator => SupportedType::Operator, - SupportedType::Parameter => SupportedType::Parameter, - SupportedType::Property => SupportedType::Property, - SupportedType::String => SupportedType::String, - SupportedType::Struct => SupportedType::Struct, - SupportedType::TypeParameter => SupportedType::TypeParameter, - SupportedType::Variable => SupportedType::Variable, - SupportedType::Type => SupportedType::Type, - SupportedType::Label => SupportedType::Label, - _ => return None, - }) -} + ) => { + pub(crate) mod modifiers { + use super::SemanticTokenModifier; -impl fmt::Display for SupportedModifiers { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let string = match self { - SupportedModifiers::Async => SemanticTokenModifiers::Async.as_str(), - SupportedModifiers::Documentation => SemanticTokenModifiers::Documentation.as_str(), - SupportedModifiers::Declaration => SemanticTokenModifiers::Declaration.as_str(), - SupportedModifiers::Static => SemanticTokenModifiers::Static.as_str(), - SupportedModifiers::DefaultLibrary => SemanticTokenModifiers::DefaultLibrary.as_str(), - SupportedModifiers::Deprecated => SemanticTokenModifiers::Deprecated.as_str(), - SupportedModifiers::Associated => "associated", - SupportedModifiers::AttributeModifier => "attribute", - SupportedModifiers::Callable => "callable", - SupportedModifiers::Constant => "constant", - SupportedModifiers::Consuming => "consuming", - SupportedModifiers::ControlFlow => "controlFlow", - SupportedModifiers::CrateRoot => "crateRoot", - SupportedModifiers::Injected => "injected", - SupportedModifiers::IntraDocLink => "intraDocLink", - SupportedModifiers::Library => "library", - SupportedModifiers::MacroModifier => "macro", - SupportedModifiers::Mutable => "mutable", - SupportedModifiers::ProcMacroModifier => "procMacro", - SupportedModifiers::Public => "public", - SupportedModifiers::Reference => "reference", - SupportedModifiers::TraitModifier => "trait", - SupportedModifiers::Unsafe => "unsafe", - }; - f.write_str(string) - } + $(pub(crate) const $standard: SemanticTokenModifier = SemanticTokenModifier::$standard;)* + $(pub(crate) const $custom: SemanticTokenModifier = SemanticTokenModifier::new($string);)* + } + + pub(crate) const SUPPORTED_MODIFIERS: &[SemanticTokenModifier] = &[ + $(SemanticTokenModifier::$standard,)* + $(self::modifiers::$custom),* + ]; + + const LAST_STANDARD_MOD: usize = count_tts!($($standard)*); + }; } -const STANDARD_MOD: [SupportedModifiers; 6] = [ - SupportedModifiers::Async, - SupportedModifiers::Documentation, - SupportedModifiers::Declaration, - SupportedModifiers::Static, - SupportedModifiers::DefaultLibrary, - SupportedModifiers::Deprecated, +define_semantic_token_modifiers![ + standard { + ASYNC, + DOCUMENTATION, + DECLARATION, + STATIC, + DEFAULT_LIBRARY, + DEPRECATED, + } + custom { + (ASSOCIATED, "associated"), + (ATTRIBUTE_MODIFIER, "attribute"), + (CALLABLE, "callable"), + (CONSTANT, "constant"), + (CONSUMING, "consuming"), + (CONTROL_FLOW, "controlFlow"), + (CRATE_ROOT, "crateRoot"), + (INJECTED, "injected"), + (INTRA_DOC_LINK, "intraDocLink"), + (LIBRARY, "library"), + (MACRO_MODIFIER, "macro"), + (MUTABLE, "mutable"), + (PROC_MACRO_MODIFIER, "procMacro"), + (PUBLIC, "public"), + (REFERENCE, "reference"), + (TRAIT_MODIFIER, "trait"), + (UNSAFE, "unsafe"), + } ]; -const LAST_STANDARD_MOD: usize = STANDARD_MOD.len() - 1; #[derive(Default)] pub(crate) struct ModifierSet(pub(crate) u32); @@ -267,9 +176,9 @@ impl ModifierSet { } } -impl ops::BitOrAssign<SupportedModifiers> for ModifierSet { - fn bitor_assign(&mut self, rhs: SupportedModifiers) { - let idx = SupportedModifiers::iter().position(|it| *it == rhs).unwrap(); +impl ops::BitOrAssign<SemanticTokenModifier> for ModifierSet { + fn bitor_assign(&mut self, rhs: SemanticTokenModifier) { + let idx = SUPPORTED_MODIFIERS.iter().position(|it| it == &rhs).unwrap(); self.0 |= 1 << idx; } } @@ -281,12 +190,12 @@ pub(crate) struct SemanticTokensBuilder { id: String, prev_line: u32, prev_char: u32, - data: Vec<lsp_types::SemanticToken>, + data: Vec<SemanticToken>, } impl SemanticTokensBuilder { pub(crate) fn new(id: String) -> Self { - SemanticTokensBuilder { id, prev_line: 0, prev_char: 0, data: Vec::new() } + SemanticTokensBuilder { id, prev_line: 0, prev_char: 0, data: Default::default() } } /// Push a new token onto the builder @@ -304,7 +213,7 @@ impl SemanticTokensBuilder { // A token cannot be multiline let token_len = range.end.character - range.start.character; - let token = lsp_types::SemanticToken { + let token = SemanticToken { delta_line: push_line, delta_start: push_char, length: token_len, @@ -323,10 +232,7 @@ impl SemanticTokensBuilder { } } -pub(crate) fn diff_tokens( - old: &[lsp_types::SemanticToken], - new: &[lsp_types::SemanticToken], -) -> Vec<SemanticTokensEdit> { +pub(crate) fn diff_tokens(old: &[SemanticToken], new: &[SemanticToken]) -> Vec<SemanticTokensEdit> { let offset = new.iter().zip(old.iter()).take_while(|&(n, p)| n == p).count(); let (_, old) = old.split_at(offset); @@ -352,16 +258,16 @@ pub(crate) fn diff_tokens( } } -pub(crate) fn type_index(kind: SupportedType) -> u32 { - kind as u32 +pub(crate) fn type_index(ty: SemanticTokenType) -> u32 { + SUPPORTED_TYPES.iter().position(|it| *it == ty).unwrap() as u32 } #[cfg(test)] mod tests { use super::*; - fn from(t: (u32, u32, u32, u32, u32)) -> lsp_types::SemanticToken { - lsp_types::SemanticToken { + fn from(t: (u32, u32, u32, u32, u32)) -> SemanticToken { + SemanticToken { delta_line: t.0, delta_start: t.1, length: t.2, diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs index db963d9dc5..482d14c0e8 100644 --- a/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/crates/rust-analyzer/src/lsp/to_proto.rs @@ -73,28 +73,28 @@ pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind { SymbolKind::DeriveHelper => lsp_types::SymbolKind::DERIVE_HELPER, SymbolKind::Module | SymbolKind::ToolModule => lsp_types::SymbolKind::MODULE, SymbolKind::TypeAlias | SymbolKind::TypeParam | SymbolKind::SelfType => { - lsp_types::SymbolKind::TypeParameter + lsp_types::SymbolKind::TYPE_PARAMETER } - SymbolKind::Field => lsp_types::SymbolKind::Field, - SymbolKind::Static => lsp_types::SymbolKind::Constant, - SymbolKind::Const => lsp_types::SymbolKind::Constant, - SymbolKind::ConstParam => lsp_types::SymbolKind::Constant, - SymbolKind::Impl => lsp_types::SymbolKind::Object, + SymbolKind::Field => lsp_types::SymbolKind::FIELD, + SymbolKind::Static => lsp_types::SymbolKind::CONSTANT, + SymbolKind::Const => lsp_types::SymbolKind::CONSTANT, + SymbolKind::ConstParam => lsp_types::SymbolKind::CONSTANT, + SymbolKind::Impl => lsp_types::SymbolKind::OBJECT, SymbolKind::Local | SymbolKind::SelfParam | SymbolKind::LifetimeParam | SymbolKind::ValueParam - | SymbolKind::Label => lsp_types::SymbolKind::Variable, - SymbolKind::Union => lsp_types::SymbolKind::Struct, - SymbolKind::InlineAsmRegOrRegClass => lsp_types::SymbolKind::Variable, + | SymbolKind::Label => lsp_types::SymbolKind::VARIABLE, + SymbolKind::Union => lsp_types::SymbolKind::STRUCT, + SymbolKind::InlineAsmRegOrRegClass => lsp_types::SymbolKind::VARIABLE, } } pub(crate) fn structure_node_kind(kind: StructureNodeKind) -> lsp_types::SymbolKind { match kind { StructureNodeKind::SymbolKind(symbol) => symbol_kind(symbol), - StructureNodeKind::Region => lsp_types::SymbolKind::Namespace, - StructureNodeKind::ExternBlock => lsp_types::SymbolKind::Namespace, + StructureNodeKind::Region => lsp_types::SymbolKind::NAMESPACE, + StructureNodeKind::ExternBlock => lsp_types::SymbolKind::NAMESPACE, } } @@ -102,21 +102,21 @@ pub(crate) fn document_highlight_kind( category: ReferenceCategory, ) -> Option<lsp_types::DocumentHighlightKind> { if category.contains(ReferenceCategory::WRITE) { - return Some(lsp_types::DocumentHighlightKind::Write); + return Some(lsp_types::DocumentHighlightKind::WRITE); } if category.contains(ReferenceCategory::READ) { - return Some(lsp_types::DocumentHighlightKind::Read); + return Some(lsp_types::DocumentHighlightKind::READ); } None } pub(crate) fn diagnostic_severity(severity: Severity) -> lsp_types::DiagnosticSeverity { match severity { - Severity::Error => lsp_types::DiagnosticSeverity::Error, - Severity::Warning => lsp_types::DiagnosticSeverity::Warning, - Severity::WeakWarning => lsp_types::DiagnosticSeverity::Hint, + Severity::Error => lsp_types::DiagnosticSeverity::ERROR, + Severity::Warning => lsp_types::DiagnosticSeverity::WARNING, + Severity::WeakWarning => lsp_types::DiagnosticSeverity::HINT, // unreachable - Severity::Allow => lsp_types::DiagnosticSeverity::Information, + Severity::Allow => lsp_types::DiagnosticSeverity::INFORMATION, } } @@ -130,44 +130,44 @@ pub(crate) fn completion_item_kind( completion_item_kind: CompletionItemKind, ) -> lsp_types::CompletionItemKind { match completion_item_kind { - CompletionItemKind::Binding => lsp_types::CompletionItemKind::Variable, - CompletionItemKind::BuiltinType => lsp_types::CompletionItemKind::Struct, - CompletionItemKind::InferredType => lsp_types::CompletionItemKind::Snippet, - CompletionItemKind::Keyword => lsp_types::CompletionItemKind::Keyword, - CompletionItemKind::Snippet => lsp_types::CompletionItemKind::Snippet, - CompletionItemKind::UnresolvedReference => lsp_types::CompletionItemKind::Reference, - CompletionItemKind::Expression => lsp_types::CompletionItemKind::Snippet, + CompletionItemKind::Binding => lsp_types::CompletionItemKind::VARIABLE, + CompletionItemKind::BuiltinType => lsp_types::CompletionItemKind::STRUCT, + CompletionItemKind::InferredType => lsp_types::CompletionItemKind::SNIPPET, + CompletionItemKind::Keyword => lsp_types::CompletionItemKind::KEYWORD, + CompletionItemKind::Snippet => lsp_types::CompletionItemKind::SNIPPET, + CompletionItemKind::UnresolvedReference => lsp_types::CompletionItemKind::REFERENCE, + CompletionItemKind::Expression => lsp_types::CompletionItemKind::SNIPPET, CompletionItemKind::SymbolKind(symbol) => match symbol { - SymbolKind::Attribute => lsp_types::CompletionItemKind::Function, - SymbolKind::Method => lsp_types::CompletionItemKind::Method, - SymbolKind::Const => lsp_types::CompletionItemKind::Constant, - SymbolKind::ConstParam => lsp_types::CompletionItemKind::TypeParameter, - SymbolKind::CrateRoot => lsp_types::CompletionItemKind::Module, - SymbolKind::Derive => lsp_types::CompletionItemKind::Function, - SymbolKind::DeriveHelper => lsp_types::CompletionItemKind::Function, - SymbolKind::Enum => lsp_types::CompletionItemKind::Enum, - SymbolKind::Field => lsp_types::CompletionItemKind::Field, - SymbolKind::Function => lsp_types::CompletionItemKind::Function, - SymbolKind::Impl => lsp_types::CompletionItemKind::Text, - SymbolKind::Label => lsp_types::CompletionItemKind::Variable, - SymbolKind::LifetimeParam => lsp_types::CompletionItemKind::TypeParameter, - SymbolKind::Local => lsp_types::CompletionItemKind::Variable, - SymbolKind::Macro => lsp_types::CompletionItemKind::Function, - SymbolKind::ProcMacro => lsp_types::CompletionItemKind::Function, - SymbolKind::Module => lsp_types::CompletionItemKind::Module, - SymbolKind::SelfParam => lsp_types::CompletionItemKind::Value, - SymbolKind::SelfType => lsp_types::CompletionItemKind::TypeParameter, - SymbolKind::Static => lsp_types::CompletionItemKind::Value, - SymbolKind::Struct => lsp_types::CompletionItemKind::Struct, - SymbolKind::Trait => lsp_types::CompletionItemKind::Interface, - SymbolKind::TypeAlias => lsp_types::CompletionItemKind::Struct, - SymbolKind::TypeParam => lsp_types::CompletionItemKind::TypeParameter, - SymbolKind::Union => lsp_types::CompletionItemKind::Struct, - SymbolKind::ValueParam => lsp_types::CompletionItemKind::Value, - SymbolKind::Variant => lsp_types::CompletionItemKind::EnumMember, - SymbolKind::BuiltinAttr => lsp_types::CompletionItemKind::Function, - SymbolKind::ToolModule => lsp_types::CompletionItemKind::Module, - SymbolKind::InlineAsmRegOrRegClass => lsp_types::CompletionItemKind::Keyword, + SymbolKind::Attribute => lsp_types::CompletionItemKind::FUNCTION, + SymbolKind::Method => lsp_types::CompletionItemKind::METHOD, + SymbolKind::Const => lsp_types::CompletionItemKind::CONSTANT, + SymbolKind::ConstParam => lsp_types::CompletionItemKind::TYPE_PARAMETER, + SymbolKind::CrateRoot => lsp_types::CompletionItemKind::MODULE, + SymbolKind::Derive => lsp_types::CompletionItemKind::FUNCTION, + SymbolKind::DeriveHelper => lsp_types::CompletionItemKind::FUNCTION, + SymbolKind::Enum => lsp_types::CompletionItemKind::ENUM, + SymbolKind::Field => lsp_types::CompletionItemKind::FIELD, + SymbolKind::Function => lsp_types::CompletionItemKind::FUNCTION, + SymbolKind::Impl => lsp_types::CompletionItemKind::TEXT, + SymbolKind::Label => lsp_types::CompletionItemKind::VARIABLE, + SymbolKind::LifetimeParam => lsp_types::CompletionItemKind::TYPE_PARAMETER, + SymbolKind::Local => lsp_types::CompletionItemKind::VARIABLE, + SymbolKind::Macro => lsp_types::CompletionItemKind::FUNCTION, + SymbolKind::ProcMacro => lsp_types::CompletionItemKind::FUNCTION, + SymbolKind::Module => lsp_types::CompletionItemKind::MODULE, + SymbolKind::SelfParam => lsp_types::CompletionItemKind::VALUE, + SymbolKind::SelfType => lsp_types::CompletionItemKind::TYPE_PARAMETER, + SymbolKind::Static => lsp_types::CompletionItemKind::VALUE, + SymbolKind::Struct => lsp_types::CompletionItemKind::STRUCT, + SymbolKind::Trait => lsp_types::CompletionItemKind::INTERFACE, + SymbolKind::TypeAlias => lsp_types::CompletionItemKind::STRUCT, + SymbolKind::TypeParam => lsp_types::CompletionItemKind::TYPE_PARAMETER, + SymbolKind::Union => lsp_types::CompletionItemKind::STRUCT, + SymbolKind::ValueParam => lsp_types::CompletionItemKind::VALUE, + SymbolKind::Variant => lsp_types::CompletionItemKind::ENUM_MEMBER, + SymbolKind::BuiltinAttr => lsp_types::CompletionItemKind::FUNCTION, + SymbolKind::ToolModule => lsp_types::CompletionItemKind::MODULE, + SymbolKind::InlineAsmRegOrRegClass => lsp_types::CompletionItemKind::KEYWORD, }, } } @@ -185,7 +185,7 @@ pub(crate) fn completion_text_edit( line_index: &LineIndex, insert_replace_support: Option<lsp_types::Position>, indel: Indel, -) -> lsp_types::CompletionItemTextEdit { +) -> lsp_types::CompletionTextEdit { let text_edit = text_edit(line_index, indel); match insert_replace_support { Some(cursor_pos) => lsp_types::InsertReplaceEdit { @@ -208,7 +208,7 @@ pub(crate) fn snippet_text_edit( let annotation_id = annotation.filter(|_| client_supports_annotations).map(|it| it.to_string()); let text_edit = text_edit(line_index, indel); let insert_text_format = - if is_snippet { Some(lsp_types::InsertTextFormat::Snippet) } else { None }; + if is_snippet { Some(lsp_types::InsertTextFormat::SNIPPET) } else { None }; lsp_ext::SnippetTextEdit { range: text_edit.range, new_text: text_edit.new_text, @@ -250,7 +250,7 @@ pub(crate) fn completion_items( fields_to_resolve: &CompletionFieldsToResolve, line_index: &LineIndex, version: Option<i32>, - tdpp: &lsp_types::TextDocumentPositionParams, + tdpp: lsp_types::TextDocumentPositionParams, completion_trigger_character: Option<char>, mut items: Vec<CompletionItem>, ) -> Vec<lsp_types::CompletionItem> { @@ -269,7 +269,7 @@ pub(crate) fn completion_items( fields_to_resolve, line_index, version, - tdpp, + &tdpp, max_relevance, completion_trigger_character, item, @@ -340,12 +340,12 @@ fn completion_item( Some(text_edit.unwrap()) }; - let insert_text_format = item.is_snippet.then_some(lsp_types::InsertTextFormat::Snippet); + let insert_text_format = item.is_snippet.then_some(lsp_types::InsertTextFormat::SNIPPET); let tags = if fields_to_resolve.resolve_tags { something_to_resolve |= item.deprecated; None } else { - item.deprecated.then(|| vec![lsp_types::CompletionItemTag::Deprecated]) + item.deprecated.then(|| vec![lsp_types::CompletionItemTag::DEPRECATED]) }; let command = if item.trigger_call_info && client_commands.trigger_parameter_hints { if fields_to_resolve.resolve_command { @@ -383,7 +383,6 @@ fn completion_item( .not() .then_some(additional_text_edits), documentation, - #[expect(deprecated, reason = "we do use tags")] deprecated: item.deprecated.then_some(item.deprecated), tags, command, @@ -492,7 +491,7 @@ pub(crate) fn signature_help( let params = call_info .parameter_labels() .map(|label| lsp_types::ParameterInformation { - label: lsp_types::ParameterInformationLabel::String(label.to_owned()), + label: lsp_types::ParameterLabel::Simple(label.to_owned()), documentation: None, }) .collect::<Vec<_>>(); @@ -514,10 +513,10 @@ pub(crate) fn signature_help( .chars() .map(|c| c.len_utf16()) .sum::<usize>() as u32; - (start, end) + [start, end] }) .map(|label_offsets| lsp_types::ParameterInformation { - label: lsp_types::ParameterInformationLabel::Tuple(label_offsets), + label: lsp_types::ParameterLabel::LabelOffsets(label_offsets), documentation: None, }) .collect::<Vec<_>>(); @@ -536,7 +535,7 @@ pub(crate) fn signature_help( label.push_str(param); let end = label.len() as u32; params.push(lsp_types::ParameterInformation { - label: lsp_types::ParameterInformationLabel::Tuple((start, end)), + label: lsp_types::ParameterLabel::LabelOffsets([start, end]), documentation: None, }); } @@ -552,8 +551,7 @@ pub(crate) fn signature_help( }) }); - let active_parameter = - call_info.active_parameter.map(|it| lsp_types::ActiveParameter::Int(it as u32)); + let active_parameter = call_info.active_parameter.map(|it| it as u32); let signature = lsp_types::SignatureInformation { label, @@ -641,9 +639,9 @@ pub(crate) fn inlay_hint( padding_right: Some(inlay_hint.pad_right), kind: match inlay_hint.kind { InlayKind::Parameter | InlayKind::GenericParameter => { - Some(lsp_types::InlayHintKind::Parameter) + Some(lsp_types::InlayHintKind::PARAMETER) } - InlayKind::Type | InlayKind::Chaining => Some(lsp_types::InlayHintKind::Type), + InlayKind::Type | InlayKind::Chaining => Some(lsp_types::InlayHintKind::TYPE), _ => None, }, text_edits, @@ -659,7 +657,7 @@ fn inlay_hint_label( something_to_resolve: &mut bool, needs_resolve: bool, mut label: InlayHintLabel, -) -> Cancellable<(lsp_types::Label, Option<lsp_types::Tooltip>)> { +) -> Cancellable<(lsp_types::InlayHintLabel, Option<lsp_types::InlayHintTooltip>)> { let (label, tooltip) = match &*label.parts { [InlayHintLabelPart { linked_location: None, .. }] => { let InlayHintLabelPart { text, tooltip, .. } = label.parts.pop().unwrap(); @@ -672,16 +670,16 @@ fn inlay_hint_label( } }); let hint_tooltip = match tooltip { - Some(ide::InlayTooltip::String(s)) => Some(lsp_types::Tooltip::String(s)), + Some(ide::InlayTooltip::String(s)) => Some(lsp_types::InlayHintTooltip::String(s)), Some(ide::InlayTooltip::Markdown(s)) => { - Some(lsp_types::Tooltip::MarkupContent(lsp_types::MarkupContent { + Some(lsp_types::InlayHintTooltip::MarkupContent(lsp_types::MarkupContent { kind: lsp_types::MarkupKind::Markdown, value: s, })) } None => None, }; - (lsp_types::Label::String(text), hint_tooltip) + (lsp_types::InlayHintLabel::String(text), hint_tooltip) } _ => { let parts = label @@ -696,12 +694,16 @@ fn inlay_hint_label( } }); let tooltip = match tooltip { - Some(ide::InlayTooltip::String(s)) => Some(lsp_types::Tooltip::String(s)), + Some(ide::InlayTooltip::String(s)) => { + Some(lsp_types::InlayHintLabelPartTooltip::String(s)) + } Some(ide::InlayTooltip::Markdown(s)) => { - Some(lsp_types::Tooltip::MarkupContent(lsp_types::MarkupContent { - kind: lsp_types::MarkupKind::Markdown, - value: s, - })) + Some(lsp_types::InlayHintLabelPartTooltip::MarkupContent( + lsp_types::MarkupContent { + kind: lsp_types::MarkupKind::Markdown, + value: s, + }, + )) } None => None, }; @@ -724,7 +726,7 @@ fn inlay_hint_label( }) }) .collect::<Cancellable<_>>()?; - (lsp_types::Label::InlayHintLabelPartList(parts), None) + (lsp_types::InlayHintLabel::LabelParts(parts), None) } }; Ok((label, tooltip)) @@ -771,11 +773,11 @@ pub(crate) fn semantic_tokens( if !non_standard_tokens { ty = match standard_fallback_type(ty) { - Some(fallback) => fallback, + Some(ty) => ty, None => continue, }; mods.standard_fallback(); - }; + } let token_index = semantic_tokens::type_index(ty); let modifier_bitset = mods.0; @@ -803,106 +805,106 @@ pub(crate) fn semantic_token_delta( fn semantic_token_type_and_modifiers( highlight: Highlight, -) -> (semantic_tokens::SupportedType, semantic_tokens::ModifierSet) { - use semantic_tokens::{SupportedModifiers, SupportedType}; +) -> (lsp_types::SemanticTokenType, semantic_tokens::ModifierSet) { + use semantic_tokens::{modifiers as mods, types}; let mut mods = semantic_tokens::ModifierSet::default(); let ty = match highlight.tag { HlTag::Symbol(symbol) => match symbol { - SymbolKind::Attribute => SupportedType::Decorator, - SymbolKind::Derive => SupportedType::Derive, - SymbolKind::DeriveHelper => SupportedType::DeriveHelper, + SymbolKind::Attribute => types::DECORATOR, + SymbolKind::Derive => types::DERIVE, + SymbolKind::DeriveHelper => types::DERIVE_HELPER, SymbolKind::CrateRoot => { - mods |= SupportedModifiers::CrateRoot; - SupportedType::Namespace + mods |= mods::CRATE_ROOT; + types::NAMESPACE } - SymbolKind::Module => SupportedType::Namespace, - SymbolKind::Impl => SupportedType::TypeAlias, - SymbolKind::Field => SupportedType::Property, - SymbolKind::TypeParam => SupportedType::TypeParameter, - SymbolKind::ConstParam => SupportedType::ConstParameter, - SymbolKind::LifetimeParam => SupportedType::Lifetime, - SymbolKind::Label => SupportedType::Label, - SymbolKind::ValueParam => SupportedType::Parameter, - SymbolKind::SelfParam => SupportedType::SelfKeyword, - SymbolKind::SelfType => SupportedType::SelfTypeKeyword, - SymbolKind::Local => SupportedType::Variable, - SymbolKind::Method => SupportedType::Method, - SymbolKind::Function => SupportedType::Function, - SymbolKind::Const => SupportedType::Const, - SymbolKind::Static => SupportedType::Static, - SymbolKind::Struct => SupportedType::Struct, - SymbolKind::Enum => SupportedType::Enum, - SymbolKind::Variant => SupportedType::EnumMember, - SymbolKind::Union => SupportedType::Union, - SymbolKind::TypeAlias => SupportedType::TypeAlias, - SymbolKind::Trait => SupportedType::Interface, - SymbolKind::Macro => SupportedType::Macro, - SymbolKind::ProcMacro => SupportedType::ProcMacro, - SymbolKind::BuiltinAttr => SupportedType::BuiltinAttribute, - SymbolKind::ToolModule => SupportedType::ToolModule, - SymbolKind::InlineAsmRegOrRegClass => SupportedType::Keyword, + SymbolKind::Module => types::NAMESPACE, + SymbolKind::Impl => types::TYPE_ALIAS, + SymbolKind::Field => types::PROPERTY, + SymbolKind::TypeParam => types::TYPE_PARAMETER, + SymbolKind::ConstParam => types::CONST_PARAMETER, + SymbolKind::LifetimeParam => types::LIFETIME, + SymbolKind::Label => types::LABEL, + SymbolKind::ValueParam => types::PARAMETER, + SymbolKind::SelfParam => types::SELF_KEYWORD, + SymbolKind::SelfType => types::SELF_TYPE_KEYWORD, + SymbolKind::Local => types::VARIABLE, + SymbolKind::Method => types::METHOD, + SymbolKind::Function => types::FUNCTION, + SymbolKind::Const => types::CONST, + SymbolKind::Static => types::STATIC, + SymbolKind::Struct => types::STRUCT, + SymbolKind::Enum => types::ENUM, + SymbolKind::Variant => types::ENUM_MEMBER, + SymbolKind::Union => types::UNION, + SymbolKind::TypeAlias => types::TYPE_ALIAS, + SymbolKind::Trait => types::INTERFACE, + SymbolKind::Macro => types::MACRO, + SymbolKind::ProcMacro => types::PROC_MACRO, + SymbolKind::BuiltinAttr => types::BUILTIN_ATTRIBUTE, + SymbolKind::ToolModule => types::TOOL_MODULE, + SymbolKind::InlineAsmRegOrRegClass => types::KEYWORD, }, - HlTag::AttributeBracket => SupportedType::AttributeBracket, - HlTag::BoolLiteral => SupportedType::Boolean, - HlTag::BuiltinType => SupportedType::BuiltinType, - HlTag::ByteLiteral | HlTag::NumericLiteral => SupportedType::Number, - HlTag::CharLiteral => SupportedType::Char, - HlTag::Comment => SupportedType::Comment, - HlTag::EscapeSequence => SupportedType::EscapeSequence, - HlTag::InvalidEscapeSequence => SupportedType::InvalidEscapeSequence, - HlTag::FormatSpecifier => SupportedType::FormatSpecifier, - HlTag::Keyword => SupportedType::Keyword, - HlTag::None => SupportedType::Generic, + HlTag::AttributeBracket => types::ATTRIBUTE_BRACKET, + HlTag::BoolLiteral => types::BOOLEAN, + HlTag::BuiltinType => types::BUILTIN_TYPE, + HlTag::ByteLiteral | HlTag::NumericLiteral => types::NUMBER, + HlTag::CharLiteral => types::CHAR, + HlTag::Comment => types::COMMENT, + HlTag::EscapeSequence => types::ESCAPE_SEQUENCE, + HlTag::InvalidEscapeSequence => types::INVALID_ESCAPE_SEQUENCE, + HlTag::FormatSpecifier => types::FORMAT_SPECIFIER, + HlTag::Keyword => types::KEYWORD, + HlTag::None => types::GENERIC, HlTag::Operator(op) => match op { - HlOperator::Bitwise => SupportedType::Bitwise, - HlOperator::Arithmetic => SupportedType::Arithmetic, - HlOperator::Logical => SupportedType::Logical, - HlOperator::Negation => SupportedType::Negation, - HlOperator::Comparison => SupportedType::Comparison, - HlOperator::Other => SupportedType::Operator, + HlOperator::Bitwise => types::BITWISE, + HlOperator::Arithmetic => types::ARITHMETIC, + HlOperator::Logical => types::LOGICAL, + HlOperator::Negation => types::NEGATION, + HlOperator::Comparison => types::COMPARISON, + HlOperator::Other => types::OPERATOR, }, - HlTag::StringLiteral => SupportedType::String, - HlTag::UnresolvedReference => SupportedType::UnresolvedReference, + HlTag::StringLiteral => types::STRING, + HlTag::UnresolvedReference => types::UNRESOLVED_REFERENCE, HlTag::Punctuation(punct) => match punct { - HlPunct::Bracket => SupportedType::Bracket, - HlPunct::Brace => SupportedType::Brace, - HlPunct::Parenthesis => SupportedType::Parenthesis, - HlPunct::Angle => SupportedType::Angle, - HlPunct::Comma => SupportedType::Comma, - HlPunct::Dot => SupportedType::Dot, - HlPunct::Colon => SupportedType::Colon, - HlPunct::Semi => SupportedType::Semicolon, - HlPunct::Other => SupportedType::Punctuation, - HlPunct::MacroBang => SupportedType::MacroBang, + HlPunct::Bracket => types::BRACKET, + HlPunct::Brace => types::BRACE, + HlPunct::Parenthesis => types::PARENTHESIS, + HlPunct::Angle => types::ANGLE, + HlPunct::Comma => types::COMMA, + HlPunct::Dot => types::DOT, + HlPunct::Colon => types::COLON, + HlPunct::Semi => types::SEMICOLON, + HlPunct::Other => types::PUNCTUATION, + HlPunct::MacroBang => types::MACRO_BANG, }, }; for modifier in highlight.mods.iter() { let modifier = match modifier { - HlMod::Associated => SupportedModifiers::Associated, - HlMod::Async => SupportedModifiers::Async, - HlMod::Attribute => SupportedModifiers::AttributeModifier, - HlMod::Callable => SupportedModifiers::Callable, - HlMod::Const => SupportedModifiers::Constant, - HlMod::Consuming => SupportedModifiers::Consuming, - HlMod::ControlFlow => SupportedModifiers::ControlFlow, - HlMod::CrateRoot => SupportedModifiers::CrateRoot, - HlMod::DefaultLibrary => SupportedModifiers::DefaultLibrary, - HlMod::Deprecated => SupportedModifiers::Deprecated, - HlMod::Definition => SupportedModifiers::Declaration, - HlMod::Documentation => SupportedModifiers::Documentation, - HlMod::Injected => SupportedModifiers::Injected, - HlMod::IntraDocLink => SupportedModifiers::IntraDocLink, - HlMod::Library => SupportedModifiers::Library, - HlMod::Macro => SupportedModifiers::MacroModifier, - HlMod::ProcMacro => SupportedModifiers::ProcMacroModifier, - HlMod::Mutable => SupportedModifiers::Mutable, - HlMod::Public => SupportedModifiers::Public, - HlMod::Reference => SupportedModifiers::Reference, - HlMod::Static => SupportedModifiers::Static, - HlMod::Trait => SupportedModifiers::TraitModifier, - HlMod::Unsafe => SupportedModifiers::Unsafe, + HlMod::Associated => mods::ASSOCIATED, + HlMod::Async => mods::ASYNC, + HlMod::Attribute => mods::ATTRIBUTE_MODIFIER, + HlMod::Callable => mods::CALLABLE, + HlMod::Const => mods::CONSTANT, + HlMod::Consuming => mods::CONSUMING, + HlMod::ControlFlow => mods::CONTROL_FLOW, + HlMod::CrateRoot => mods::CRATE_ROOT, + HlMod::DefaultLibrary => mods::DEFAULT_LIBRARY, + HlMod::Deprecated => mods::DEPRECATED, + HlMod::Definition => mods::DECLARATION, + HlMod::Documentation => mods::DOCUMENTATION, + HlMod::Injected => mods::INJECTED, + HlMod::IntraDocLink => mods::INTRA_DOC_LINK, + HlMod::Library => mods::LIBRARY, + HlMod::Macro => mods::MACRO_MODIFIER, + HlMod::ProcMacro => mods::PROC_MACRO_MODIFIER, + HlMod::Mutable => mods::MUTABLE, + HlMod::Public => mods::PUBLIC, + HlMod::Reference => mods::REFERENCE, + HlMod::Static => mods::STATIC, + HlMod::Trait => mods::TRAIT_MODIFIER, + HlMod::Unsafe => mods::UNSAFE, }; mods |= modifier; } @@ -981,16 +983,16 @@ pub(crate) fn folding_range( } } -pub(crate) fn url(snap: &GlobalStateSnapshot, file_id: FileId) -> lsp_types::Uri { +pub(crate) fn url(snap: &GlobalStateSnapshot, file_id: FileId) -> lsp_types::Url { snap.file_id_to_url(file_id) } -/// Returns a `Uri` object from a given path, will lowercase drive letters if present. +/// Returns a `Url` object from a given path, will lowercase drive letters if present. /// This will only happen when processing windows paths. /// -/// When processing non-windows path, this is essentially the same as [`lsp_types::Uri::from_file_path`]. -pub(crate) fn url_from_abs_path(path: &AbsPath) -> lsp_types::Uri { - let url = lsp_types::Uri::from_file_path(path).unwrap(); +/// When processing non-windows path, this is essentially the same as `Url::from_file_path`. +pub(crate) fn url_from_abs_path(path: &AbsPath) -> lsp_types::Url { + let url = lsp_types::Url::from_file_path(path).unwrap(); match path.components().next() { Some(Utf8Component::Prefix(prefix)) if matches!(prefix.kind(), Utf8Prefix::Disk(_) | Utf8Prefix::VerbatimDisk(_)) => @@ -1014,19 +1016,16 @@ pub(crate) fn url_from_abs_path(path: &AbsPath) -> lsp_types::Uri { // string in place. let mut url: String = url.into(); url[driver_letter_range].make_ascii_lowercase(); - lsp_types::Uri::parse(&url).unwrap() + lsp_types::Url::parse(&url).unwrap() } pub(crate) fn optional_versioned_text_document_identifier( snap: &GlobalStateSnapshot, file_id: FileId, ) -> lsp_types::OptionalVersionedTextDocumentIdentifier { - let uri = url(snap, file_id); - let version = snap.url_file_version(&uri); - lsp_types::OptionalVersionedTextDocumentIdentifier { - text_document_identifier: lsp_types::TextDocumentIdentifier { uri }, - version, - } + let url = url(snap, file_id); + let version = snap.url_file_version(&url); + lsp_types::OptionalVersionedTextDocumentIdentifier { uri: url, version } } pub(crate) fn location( @@ -1043,7 +1042,7 @@ pub(crate) fn location( /// Prefer using `location_link`, if the client has the cap. pub(crate) fn location_from_nav( snap: &GlobalStateSnapshot, - nav: &NavigationTarget, + nav: NavigationTarget, ) -> Cancellable<lsp_types::Location> { let url = url(snap, nav.file_id); let line_index = snap.file_line_index(nav.file_id)?; @@ -1078,7 +1077,7 @@ pub(crate) fn location_link( fn location_info( snap: &GlobalStateSnapshot, target: NavigationTarget, -) -> Cancellable<(lsp_types::Uri, lsp_types::Range, lsp_types::Range)> { +) -> Cancellable<(lsp_types::Url, lsp_types::Range, lsp_types::Range)> { let line_index = snap.file_line_index(target.file_id)?; let target_uri = url(snap, target.file_id); @@ -1092,90 +1091,25 @@ pub(crate) fn goto_definition_response( snap: &GlobalStateSnapshot, src: Option<FileRange>, targets: Vec<NavigationTarget>, -) -> Cancellable<lsp_types::DefinitionResponse> { - if snap.config.location_link() { - let links = targets_to_links(snap, src, targets)?; - Ok(links.into()) - } else { - let locations = targets_to_locations(snap, targets)?; - Ok(lsp_types::DefinitionResponse::Definition(lsp_types::Definition::LocationList( - locations, - ))) - } -} - -pub(crate) fn goto_declaration_response( - snap: &GlobalStateSnapshot, - src: Option<FileRange>, - targets: Vec<NavigationTarget>, -) -> Cancellable<lsp_types::DeclarationResponse> { +) -> Cancellable<lsp_types::GotoDefinitionResponse> { if snap.config.location_link() { - let links = targets_to_links(snap, src, targets)?; - Ok(links.into()) - } else { - let locations = targets_to_locations(snap, targets)?; - Ok(lsp_types::DeclarationResponse::Declaration(lsp_types::Declaration::LocationList( - locations, - ))) - } -} - -pub(crate) fn goto_implementation_response( - snap: &GlobalStateSnapshot, - src: Option<FileRange>, - targets: Vec<NavigationTarget>, -) -> Cancellable<lsp_types::ImplementationResponse> { - if snap.config.location_link() { - let links = targets_to_links(snap, src, targets)?; - Ok(links.into()) - } else { - let locations = targets_to_locations(snap, targets)?; - Ok(lsp_types::ImplementationResponse::Definition(lsp_types::Definition::LocationList( - locations, - ))) - } -} - -pub(crate) fn goto_type_definition_response( - snap: &GlobalStateSnapshot, - src: Option<FileRange>, - targets: Vec<NavigationTarget>, -) -> Cancellable<lsp_types::TypeDefinitionResponse> { - if snap.config.location_link() { - let links = targets_to_links(snap, src, targets)?; + let links = targets + .into_iter() + .unique_by(|nav| (nav.file_id, nav.full_range, nav.focus_range)) + .map(|nav| location_link(snap, src, nav)) + .collect::<Cancellable<Vec<_>>>()?; Ok(links.into()) } else { - let locations = targets_to_locations(snap, targets)?; - Ok(lsp_types::TypeDefinitionResponse::Definition(lsp_types::Definition::LocationList( - locations, - ))) + let locations = targets + .into_iter() + .map(|nav| FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() }) + .unique() + .map(|range| location(snap, range)) + .collect::<Cancellable<Vec<_>>>()?; + Ok(locations.into()) } } -fn targets_to_links( - snap: &GlobalStateSnapshot, - src: Option<hir::FileRangeWrapper<FileId>>, - targets: Vec<NavigationTarget>, -) -> Result<Vec<lsp_types::LocationLink>, ide_db::base_db::salsa::Cancelled> { - targets - .into_iter() - .unique_by(|nav| (nav.file_id, nav.full_range, nav.focus_range)) - .map(|nav| location_link(snap, src, nav)) - .collect::<Cancellable<Vec<_>>>() -} - -fn targets_to_locations( - snap: &GlobalStateSnapshot, - targets: Vec<NavigationTarget>, -) -> Result<Vec<lsp_types::Location>, ide_db::base_db::salsa::Cancelled> { - targets - .into_iter() - .map(|nav| FileRange { file_id: nav.file_id, range: nav.focus_or_full_range() }) - .unique() - .map(|range| location(snap, range)) - .collect::<Cancellable<Vec<_>>>() -} - fn outside_workspace_annotation_id() -> String { String::from("OutsideWorkspace") } @@ -1384,21 +1318,19 @@ pub(crate) fn snippet_text_document_ops( match file_system_edit { FileSystemEdit::CreateFile { dst, initial_contents } => { let uri = snap.anchored_path(&dst); - let create_file = lsp_types::DocumentChange::CreateFile(lsp_types::CreateFile { + let create_file = lsp_types::ResourceOp::Create(lsp_types::CreateFile { uri: uri.clone(), options: None, annotation_id: None, }); - ops.push(lsp_ext::SnippetDocumentChangeOperation::Change(create_file)); + ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(create_file)); if !initial_contents.is_empty() { - let text_document = lsp_types::OptionalVersionedTextDocumentIdentifier { - text_document_identifier: lsp_types::TextDocumentIdentifier { uri }, - version: None, - }; + let text_document = + lsp_types::OptionalVersionedTextDocumentIdentifier { uri, version: None }; let text_edit = lsp_ext::SnippetTextEdit { range: lsp_types::Range::default(), new_text: initial_contents, - insert_text_format: Some(lsp_types::InsertTextFormat::PlainText), + insert_text_format: Some(lsp_types::InsertTextFormat::PLAIN_TEXT), annotation_id: None, }; let edit_file = @@ -1416,9 +1348,9 @@ pub(crate) fn snippet_text_document_ops( { rename_file.annotation_id = Some(outside_workspace_annotation_id()) } - ops.push(lsp_ext::SnippetDocumentChangeOperation::Change( - lsp_types::DocumentChange::RenameFile(rename_file), - )) + ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(lsp_types::ResourceOp::Rename( + rename_file, + ))) } FileSystemEdit::MoveDir { src, src_id, dst } => { let old_uri = snap.anchored_path(&src); @@ -1430,9 +1362,9 @@ pub(crate) fn snippet_text_document_ops( { rename_file.annotation_id = Some(outside_workspace_annotation_id()) } - ops.push(lsp_ext::SnippetDocumentChangeOperation::Change( - lsp_types::DocumentChange::RenameFile(rename_file), - )) + ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(lsp_types::ResourceOp::Rename( + rename_file, + ))) } } Ok(ops) @@ -1517,38 +1449,42 @@ impl From<lsp_ext::SnippetWorkspaceEdit> for lsp_types::WorkspaceEdit { lsp_types::WorkspaceEdit { changes: None, document_changes: snippet_workspace_edit.document_changes.map(|changes| { - changes - .into_iter() - .map(|change| match change { - lsp_ext::SnippetDocumentChangeOperation::Change(op) => op, - lsp_ext::SnippetDocumentChangeOperation::Edit(edit) => { - lsp_types::DocumentChange::TextDocumentEdit( - lsp_types::TextDocumentEdit { - text_document: edit.text_document, - edits: edit.edits.into_iter().map(From::from).collect(), - }, - ) - } - }) - .collect() + lsp_types::DocumentChanges::Operations( + changes + .into_iter() + .map(|change| match change { + lsp_ext::SnippetDocumentChangeOperation::Op(op) => { + lsp_types::DocumentChangeOperation::Op(op) + } + lsp_ext::SnippetDocumentChangeOperation::Edit(edit) => { + lsp_types::DocumentChangeOperation::Edit( + lsp_types::TextDocumentEdit { + text_document: edit.text_document, + edits: edit.edits.into_iter().map(From::from).collect(), + }, + ) + } + }) + .collect(), + ) }), change_annotations: snippet_workspace_edit.change_annotations, } } } -impl From<lsp_ext::SnippetTextEdit> for lsp_types::Edit { +impl From<lsp_ext::SnippetTextEdit> + for lsp_types::OneOf<lsp_types::TextEdit, lsp_types::AnnotatedTextEdit> +{ fn from( lsp_ext::SnippetTextEdit { annotation_id, insert_text_format:_, new_text, range }: lsp_ext::SnippetTextEdit, ) -> Self { match annotation_id { - Some(annotation_id) => { - lsp_types::Edit::AnnotatedTextEdit(lsp_types::AnnotatedTextEdit { - text_edit: lsp_types::TextEdit { range, new_text }, - annotation_id, - }) - } - None => lsp_types::Edit::TextEdit(lsp_types::TextEdit { range, new_text }), + Some(annotation_id) => lsp_types::OneOf::Right(lsp_types::AnnotatedTextEdit { + text_edit: lsp_types::TextEdit { range, new_text }, + annotation_id, + }), + None => lsp_types::OneOf::Left(lsp_types::TextEdit { range, new_text }), } } } @@ -1559,7 +1495,7 @@ pub(crate) fn call_hierarchy_item( ) -> Cancellable<lsp_types::CallHierarchyItem> { let name = target.name.to_string(); let detail = target.description.clone(); - let kind = target.kind.map(symbol_kind).unwrap_or(lsp_types::SymbolKind::Function); + let kind = target.kind.map(symbol_kind).unwrap_or(lsp_types::SymbolKind::FUNCTION); let (uri, range, selection_range) = location_info(snap, target)?; Ok(lsp_types::CallHierarchyItem { name, @@ -1575,12 +1511,12 @@ pub(crate) fn call_hierarchy_item( pub(crate) fn code_action_kind(kind: AssistKind) -> lsp_types::CodeActionKind { match kind { - AssistKind::Generate => lsp_types::CodeActionKind::Empty, - AssistKind::QuickFix => lsp_types::CodeActionKind::QuickFix, - AssistKind::Refactor => lsp_types::CodeActionKind::Refactor, - AssistKind::RefactorExtract => lsp_types::CodeActionKind::RefactorExtract, - AssistKind::RefactorInline => lsp_types::CodeActionKind::RefactorInline, - AssistKind::RefactorRewrite => lsp_types::CodeActionKind::RefactorRewrite, + AssistKind::Generate => lsp_types::CodeActionKind::EMPTY, + AssistKind::QuickFix => lsp_types::CodeActionKind::QUICKFIX, + AssistKind::Refactor => lsp_types::CodeActionKind::REFACTOR, + AssistKind::RefactorExtract => lsp_types::CodeActionKind::REFACTOR_EXTRACT, + AssistKind::RefactorInline => lsp_types::CodeActionKind::REFACTOR_INLINE, + AssistKind::RefactorRewrite => lsp_types::CodeActionKind::REFACTOR_REWRITE, } } @@ -1825,7 +1761,7 @@ pub(crate) fn code_lens( let doc_pos = lsp_types::TextDocumentPositionParams::new(id, pos); - let goto_params = lsp_types::ImplementationParams { + let goto_params = lsp_types::request::GotoImplementationParams { text_document_position_params: doc_pos, work_done_progress_params: Default::default(), partial_result_params: Default::default(), @@ -1955,7 +1891,7 @@ pub(crate) mod command { pub(crate) fn show_references( title: String, - uri: &lsp_types::Uri, + uri: &lsp_types::Url, position: lsp_types::Position, locations: Vec<lsp_types::Location>, ) -> lsp_types::Command { @@ -1971,7 +1907,6 @@ pub(crate) mod command { to_value(position).unwrap(), to_value(locations).unwrap(), ]), - tooltip: None, } } @@ -1980,7 +1915,6 @@ pub(crate) mod command { title: title.to_owned(), command: "rust-analyzer.runSingle".into(), arguments: Some(vec![to_value(runnable).unwrap()]), - tooltip: None, } } @@ -1989,7 +1923,6 @@ pub(crate) mod command { title: "âš™\u{fe0e} Debug".into(), command: "rust-analyzer.debugSingle".into(), arguments: Some(vec![to_value(runnable).unwrap()]), - tooltip: None, } } @@ -1999,7 +1932,6 @@ pub(crate) mod command { command: "rust-analyzer.interpretFunction".into(), // FIXME: use the `_runnable` here. arguments: Some(vec![]), - tooltip: None, } } @@ -2020,7 +1952,6 @@ pub(crate) mod command { title: nav.name.to_string(), command: "rust-analyzer.gotoLocation".into(), arguments: Some(vec![value]), - tooltip: None, }) } @@ -2029,7 +1960,6 @@ pub(crate) mod command { title: "triggerParameterHints".into(), command: "rust-analyzer.triggerParameterHints".into(), arguments: None, - tooltip: None, } } @@ -2038,7 +1968,6 @@ pub(crate) mod command { title: "rename".into(), command: "rust-analyzer.rename".into(), arguments: None, - tooltip: None, } } } @@ -3152,7 +3081,7 @@ struct ProcMacro { ) } - // `Uri` is not able to parse windows paths on unix machines. + // `Url` is not able to parse windows paths on unix machines. #[test] #[cfg(target_os = "windows")] fn test_lowercase_drive_letter() { diff --git a/crates/rust-analyzer/src/lsp/utils.rs b/crates/rust-analyzer/src/lsp/utils.rs index ebec0f990a..5bea7084fd 100644 --- a/crates/rust-analyzer/src/lsp/utils.rs +++ b/crates/rust-analyzer/src/lsp/utils.rs @@ -1,8 +1,8 @@ //! Utilities for LSP-related boilerplate code. -use std::{mem, ops::Range, vec}; +use std::{mem, ops::Range}; use lsp_server::Notification; -use lsp_types::{MessageActionItem, Request}; +use lsp_types::request::Request; use triomphe::Arc; use crate::{ @@ -16,8 +16,10 @@ pub(crate) fn invalid_params_error(message: String) -> LspError { LspError { code: lsp_server::ErrorCode::InvalidParams as i32, message } } -pub(crate) fn notification_is<N: lsp_types::Notification>(notification: &Notification) -> bool { - notification.method.as_str() == N::METHOD.as_str() +pub(crate) fn notification_is<N: lsp_types::notification::Notification>( + notification: &Notification, +) -> bool { + notification.method == N::METHOD } #[derive(Debug, Eq, PartialEq)] @@ -37,34 +39,37 @@ impl Progress { impl GlobalState { pub(crate) fn show_message( &mut self, - kind: lsp_types::MessageType, + typ: lsp_types::MessageType, message: String, show_open_log_button: bool, ) { - match self.config.open_server_logs() && show_open_log_button { - true => self.send_request::<lsp_types::ShowMessageRequest>( + match self.config.open_server_logs() && show_open_log_button { + true => self.send_request::<lsp_types::request::ShowMessageRequest>( lsp_types::ShowMessageRequestParams { - kind, + typ, message, actions: Some(vec![lsp_types::MessageActionItem { title: "Open server logs".to_owned(), + properties: Default::default(), }]), }, |this, resp| { let lsp_server::Response { error: None, result: Some(result), .. } = resp - else { - return; - }; - if let Ok(Some(_item)) = crate::from_json::<Option<MessageActionItem>>( - lsp_types::ShowMessageRequest::METHOD.as_str(), - &result, + else { return }; + if let Ok(Some(_item)) = crate::from_json::< + <lsp_types::request::ShowMessageRequest as lsp_types::request::Request>::Result, + >( + lsp_types::request::ShowMessageRequest::METHOD, &result ) { - this.send_notification::<lsp_ext::OpenServerLogsNotification>(()); + this.send_notification::<lsp_ext::OpenServerLogs>(()); } }, ), - false => self.send_notification::<lsp_types::ShowMessageNotification>( - lsp_types::ShowMessageParams { kind, message }, + false => self.send_notification::<lsp_types::notification::ShowMessage>( + lsp_types::ShowMessageParams { + typ, + message, + }, ), } } @@ -76,15 +81,15 @@ impl GlobalState { Some(additional_info) => { tracing::error!("{message}:\n{additional_info}"); self.show_message( - lsp_types::MessageType::Error, + lsp_types::MessageType::ERROR, message, tracing::enabled!(tracing::Level::ERROR), ); } None => { tracing::error!("{message}"); - self.send_notification::<lsp_types::ShowMessageNotification>( - lsp_types::ShowMessageParams { kind: lsp_types::MessageType::Error, message }, + self.send_notification::<lsp_types::notification::ShowMessage>( + lsp_types::ShowMessageParams { typ: lsp_types::MessageType::ERROR, message }, ); } } @@ -128,49 +133,35 @@ impl GlobalState { cancel_token.unwrap_or_else(|| format!("rustAnalyzer/{title}")), ); tracing::debug!(?token, ?state, "report_progress {message:?}"); - match state { + let work_done_progress = match state { Progress::Begin => { - self.send_request::<lsp_types::WorkDoneProgressCreateRequest>( + self.send_request::<lsp_types::request::WorkDoneProgressCreate>( lsp_types::WorkDoneProgressCreateParams { token: token.clone() }, |_, _| (), ); - self.send_notification::<lsp_types::ProgressNotification>( - lsp_types::ProgressParams { - token, - value: serde_json::to_value(lsp_types::WorkDoneProgressBegin { - title: title.into(), - cancellable, - message, - percentage, - }) - .unwrap(), - }, - ); + lsp_types::WorkDoneProgress::Begin(lsp_types::WorkDoneProgressBegin { + title: title.into(), + cancellable, + message, + percentage, + }) } Progress::Report => { - self.send_notification::<lsp_types::ProgressNotification>( - lsp_types::ProgressParams { - token, - value: serde_json::to_value(lsp_types::WorkDoneProgressReport { - cancellable, - message, - percentage, - }) - .unwrap(), - }, - ); + lsp_types::WorkDoneProgress::Report(lsp_types::WorkDoneProgressReport { + cancellable, + message, + percentage, + }) } Progress::End => { - self.send_notification::<lsp_types::ProgressNotification>( - lsp_types::ProgressParams { - token, - value: serde_json::to_value(lsp_types::WorkDoneProgressEnd { message }) - .unwrap(), - }, - ); + lsp_types::WorkDoneProgress::End(lsp_types::WorkDoneProgressEnd { message }) } - } + }; + self.send_notification::<lsp_types::notification::Progress>(lsp_types::ProgressParams { + token, + value: lsp_types::ProgressParamsValue::WorkDone(work_done_progress), + }); } } @@ -181,26 +172,15 @@ pub(crate) fn apply_document_changes( ) -> String { // If at least one of the changes is a full document change, use the last // of them as the starting point and ignore all previous changes. - let (mut text, r_partial_changes); - match content_changes.iter_mut().rev().try_fold(Vec::new(), |mut acc, change| match change { - lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangePartial(partial) => { - acc.push(partial); - Ok(acc) - } - lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( - whole, - ) => Err((whole, acc)), - }) { - Err((whole_document, reversed_partial_changes)) => { - text = mem::take(&mut whole_document.text); - r_partial_changes = reversed_partial_changes; - } - Ok(partials) => { - text = file_contents.to_owned(); - r_partial_changes = partials; - } - } - if r_partial_changes.is_empty() { + let (mut text, content_changes) = + match content_changes.iter().rposition(|change| change.range.is_none()) { + Some(idx) => { + let text = mem::take(&mut content_changes[idx].text); + (text, &content_changes[idx + 1..]) + } + None => (file_contents.to_owned(), &content_changes[..]), + }; + if content_changes.is_empty() { return text; } @@ -218,13 +198,16 @@ pub(crate) fn apply_document_changes( // remember the last valid line in the index and only rebuild it if needed. // The VFS will normalize the end of lines to `\n`. let mut index_valid = !0u32; - for change in r_partial_changes.iter().rev() { - if index_valid <= change.range.end.line { - *Arc::make_mut(&mut line_index.index) = ide::LineIndex::new(&text); - } - index_valid = change.range.start.line; - if let Ok(range) = from_proto::text_range(&line_index, change.range) { - text.replace_range(Range::<usize>::from(range), &change.text); + for change in content_changes { + // The None case can't happen as we have handled it above already + if let Some(range) = change.range { + if index_valid <= range.end.line { + *Arc::make_mut(&mut line_index.index) = ide::LineIndex::new(&text); + } + index_valid = range.start.line; + if let Ok(range) = from_proto::text_range(&line_index, range) { + text.replace_range(Range::<usize>::from(range), &change.text); + } } } text @@ -238,10 +221,10 @@ pub(crate) fn all_edits_are_disjoint( ) -> bool { let mut edit_ranges = Vec::new(); match completion.text_edit.as_ref() { - Some(lsp_types::CompletionItemTextEdit::TextEdit(edit)) => { + Some(lsp_types::CompletionTextEdit::Edit(edit)) => { edit_ranges.push(edit.range); } - Some(lsp_types::CompletionItemTextEdit::InsertReplaceEdit(edit)) => { + Some(lsp_types::CompletionTextEdit::InsertAndReplace(edit)) => { let replace = edit.replace; let insert = edit.insert; if replace.start != insert.start @@ -269,7 +252,10 @@ pub(crate) fn all_edits_are_disjoint( #[cfg(test)] mod tests { use ide_db::line_index::WideEncoding; - use lsp_types::{CompletionItem, InsertReplaceEdit, Position, Range}; + use lsp_types::{ + CompletionItem, CompletionTextEdit, InsertReplaceEdit, Position, Range, + TextDocumentContentChangeEvent, + }; use super::*; @@ -277,14 +263,14 @@ mod tests { fn test_apply_document_changes() { macro_rules! c { [$($sl:expr, $sc:expr; $el:expr, $ec:expr => $text:expr),+] => { - vec![$(::lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangePartial(lsp_types::TextDocumentContentChangePartial { - range: Range { + vec![$(TextDocumentContentChangeEvent { + range: Some(Range { start: Position { line: $sl, character: $sc }, end: Position { line: $el, character: $ec }, - }, + }), + range_length: None, text: String::from($text), - ..Default::default() - })),+] + }),+] }; } @@ -294,11 +280,11 @@ mod tests { let text = apply_document_changes( encoding, &text, - vec![ - lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( - lsp_types::TextDocumentContentChangeWholeDocument { text: String::from("the") }, - ), - ], + vec![TextDocumentContentChangeEvent { + range: None, + range_length: None, + text: String::from("the"), + }], ); assert_eq!(text, "the"); let text = apply_document_changes(encoding, &text, c![0, 3; 0, 3 => " quick"]); @@ -346,11 +332,7 @@ mod tests { #[test] fn empty_completion_disjoint_tests() { - let empty_completion = CompletionItem { - label: "label".to_owned(), - detail: Some("detail".to_owned()), - ..Default::default() - }; + let empty_completion = CompletionItem::new_simple("label".to_owned(), "detail".to_owned()); let disjoint_edit_1 = lsp_types::TextEdit::new( Range::new(Position::new(2, 2), Position::new(3, 3)), @@ -402,19 +384,17 @@ mod tests { "new_text".to_owned(), ); - let mut completion_with_joint_edits = CompletionItem { - label: "label".to_owned(), - detail: Some("detail".to_owned()), - additional_text_edits: Some(vec![disjoint_edit.clone(), joint_edit.clone()]), - ..Default::default() - }; + let mut completion_with_joint_edits = + CompletionItem::new_simple("label".to_owned(), "detail".to_owned()); + completion_with_joint_edits.additional_text_edits = + Some(vec![disjoint_edit.clone(), joint_edit.clone()]); assert!( !all_edits_are_disjoint(&completion_with_joint_edits, &[]), "Completion with disjoint edits fails the validation even with empty extra edits" ); completion_with_joint_edits.text_edit = - Some(lsp_types::CompletionItemTextEdit::TextEdit(disjoint_edit.clone())); + Some(CompletionTextEdit::Edit(disjoint_edit.clone())); completion_with_joint_edits.additional_text_edits = Some(vec![joint_edit.clone()]); assert!( !all_edits_are_disjoint(&completion_with_joint_edits, &[]), @@ -422,7 +402,7 @@ mod tests { ); completion_with_joint_edits.text_edit = - Some(lsp_types::CompletionItemTextEdit::InsertReplaceEdit(InsertReplaceEdit { + Some(CompletionTextEdit::InsertAndReplace(InsertReplaceEdit { new_text: "new_text".to_owned(), insert: disjoint_edit.range, replace: disjoint_edit_2.range, @@ -449,12 +429,10 @@ mod tests { "new_text".to_owned(), ); - let completion_with_disjoint_edits = CompletionItem { - label: "label".to_owned(), - detail: Some("detail".to_owned()), - text_edit: Some(lsp_types::CompletionItemTextEdit::TextEdit(disjoint_edit)), - ..Default::default() - }; + let mut completion_with_disjoint_edits = + CompletionItem::new_simple("label".to_owned(), "detail".to_owned()); + completion_with_disjoint_edits.text_edit = Some(CompletionTextEdit::Edit(disjoint_edit)); + let completion_with_disjoint_edits = completion_with_disjoint_edits; assert!( all_edits_are_disjoint(&completion_with_disjoint_edits, &[]), diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index fd72a0a584..6ef1be2304 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs @@ -11,7 +11,7 @@ use std::{ use crossbeam_channel::{Receiver, never, select}; use ide_db::base_db::{SourceDatabase, VfsPath}; use lsp_server::{Connection, Notification, Request}; -use lsp_types::{Notification as _, TextDocumentIdentifier}; +use lsp_types::{TextDocumentIdentifier, notification::Notification as _}; use stdx::thread::ThreadIntent; use tracing::{Level, error, span}; use vfs::{AbsPathBuf, FileId, loader::LoadingProgress}; @@ -99,7 +99,7 @@ impl fmt::Display for Event { #[derive(Debug)] pub(crate) enum DeferredTask { - CheckIfIndexed(lsp_types::Uri), + CheckIfIndexed(lsp_types::Url), CheckProcMacroSources(Vec<FileId>), } @@ -145,8 +145,8 @@ impl fmt::Debug for Event { match self { Event::Lsp(lsp_server::Message::Notification(not)) - if (notification_is::<lsp_types::DidOpenTextDocumentNotification>(not) - || notification_is::<lsp_types::DidChangeTextDocumentNotification>(not)) => + if (notification_is::<lsp_types::notification::DidOpenTextDocument>(not) + || notification_is::<lsp_types::notification::DidChangeTextDocument>(not)) => { return debug_non_verbose(not, f); } @@ -207,7 +207,7 @@ impl GlobalState { if matches!( &event, Event::Lsp(lsp_server::Message::Notification(Notification { method, .. })) - if method == lsp_types::ExitNotification::METHOD.as_str() + if method == lsp_types::notification::Exit::METHOD ) { return Ok(()); } @@ -218,43 +218,33 @@ impl GlobalState { } fn register_did_save_capability(&mut self, additional_patterns: impl Iterator<Item = String>) { - let additional_filters = additional_patterns.map(|pattern| { - lsp_types::DocumentFilter::TextDocumentFilter(lsp_types::TextDocumentFilter::Pattern( - lsp_types::TextDocumentFilterPattern { - language: None, - scheme: None, - pattern: pattern.into(), - }, - )) + let additional_filters = additional_patterns.map(|pattern| lsp_types::DocumentFilter { + language: None, + scheme: None, + pattern: (Some(pattern)), }); let mut selectors = vec![ - lsp_types::DocumentFilter::TextDocumentFilter(lsp_types::TextDocumentFilter::Pattern( - lsp_types::TextDocumentFilterPattern { - language: None, - scheme: None, - pattern: "**/*.rs".to_owned().into(), - }, - )), - lsp_types::DocumentFilter::TextDocumentFilter(lsp_types::TextDocumentFilter::Pattern( - lsp_types::TextDocumentFilterPattern { - language: None, - scheme: None, - pattern: "**/Cargo.toml".to_owned().into(), - }, - )), - lsp_types::DocumentFilter::TextDocumentFilter(lsp_types::TextDocumentFilter::Pattern( - lsp_types::TextDocumentFilterPattern { - language: None, - scheme: None, - pattern: "**/Cargo.lock".to_owned().into(), - }, - )), + lsp_types::DocumentFilter { + language: None, + scheme: None, + pattern: Some("**/*.rs".into()), + }, + lsp_types::DocumentFilter { + language: None, + scheme: None, + pattern: Some("**/Cargo.toml".into()), + }, + lsp_types::DocumentFilter { + language: None, + scheme: None, + pattern: Some("**/Cargo.lock".into()), + }, ]; selectors.extend(additional_filters); let save_registration_options = lsp_types::TextDocumentSaveRegistrationOptions { - save_options: lsp_types::SaveOptions { include_text: Some(false) }, + include_text: Some(false), text_document_registration_options: lsp_types::TextDocumentRegistrationOptions { document_selector: Some(selectors), }, @@ -265,7 +255,7 @@ impl GlobalState { method: "textDocument/didSave".to_owned(), register_options: Some(serde_json::to_value(save_registration_options).unwrap()), }; - self.send_request::<lsp_types::RegistrationRequest>( + self.send_request::<lsp_types::request::RegisterCapability>( lsp_types::RegistrationParams { registrations: vec![registration] }, |_, _| (), ); @@ -472,7 +462,10 @@ impl GlobalState { self.handle_flycheck_msg(message, &mut cargo_finished); } if cargo_finished { - self.send_request::<lsp_types::DiagnosticRefreshRequest>((), |_, _| ()); + self.send_request::<lsp_types::request::WorkspaceDiagnosticRefresh>( + (), + |_, _| (), + ); } } Event::TestResult(message) => { @@ -549,21 +542,24 @@ impl GlobalState { // Refresh semantic tokens if the client supports it. if self.config.semantic_tokens_refresh() { self.semantic_tokens_cache.lock().clear(); - self.send_request::<lsp_types::SemanticTokensRefreshRequest>((), |_, _| ()); + self.send_request::<lsp_types::request::SemanticTokensRefresh>((), |_, _| ()); } // Refresh code lens if the client supports it. if self.config.code_lens_refresh() { - self.send_request::<lsp_types::CodeLensRefreshRequest>((), |_, _| ()); + self.send_request::<lsp_types::request::CodeLensRefresh>((), |_, _| ()); } // Refresh inlay hints if the client supports it. if self.config.inlay_hints_refresh() { - self.send_request::<lsp_types::InlayHintRefreshRequest>((), |_, _| ()); + self.send_request::<lsp_types::request::InlayHintRefreshRequest>((), |_, _| ()); } if self.config.diagnostics_refresh() { - self.send_request::<lsp_types::DiagnosticRefreshRequest>((), |_, _| ()); + self.send_request::<lsp_types::request::WorkspaceDiagnosticRefresh>( + (), + |_, _| (), + ); } } @@ -837,9 +833,9 @@ impl GlobalState { || self.fetch_workspace_error().is_err()); self.show_message( match health { - lsp_ext::Health::Ok => lsp_types::MessageType::Info, - lsp_ext::Health::Warning => lsp_types::MessageType::Warning, - lsp_ext::Health::Error => lsp_types::MessageType::Error, + lsp_ext::Health::Ok => lsp_types::MessageType::INFO, + lsp_ext::Health::Warning => lsp_types::MessageType::WARNING, + lsp_ext::Health::Error => lsp_types::MessageType::ERROR, }, message.clone(), open_log_button, @@ -920,7 +916,7 @@ impl GlobalState { self.discover_handles.push(handle) } Err(e) => self.show_message( - lsp_types::MessageType::Error, + lsp_types::MessageType::ERROR, format!("Failed to spawn project discovery command: {e:#}"), false, ), @@ -969,7 +965,7 @@ impl GlobalState { } Task::BuildDepsHaveChanged => self.build_deps_changed = true, Task::DiscoverTest(tests) => { - self.send_notification::<lsp_ext::DiscoveredTestsNotification>(tests); + self.send_notification::<lsp_ext::DiscoveredTests>(tests); } } cancellation_time @@ -1183,7 +1179,7 @@ impl GlobalState { // The notification requires the namespace form (with underscores) of the target let test_id = format!("{}::{name}", message.target.target.replace('-', "_")); - self.send_notification::<lsp_ext::ChangeTestStateNotification>( + self.send_notification::<lsp_ext::ChangeTestState>( lsp_ext::ChangeTestStateParams { test_id, state }, ); } @@ -1191,12 +1187,12 @@ impl GlobalState { CargoTestOutput::Finished => { self.test_run_remaining_jobs = self.test_run_remaining_jobs.saturating_sub(1); if self.test_run_remaining_jobs == 0 { - self.send_notification::<lsp_ext::EndRunTestNotification>(()); + self.send_notification::<lsp_ext::EndRunTest>(()); self.test_run_session = None; } } CargoTestOutput::Custom { text } => { - self.send_notification::<lsp_ext::AppendOutputToRunTestNotification>(text); + self.send_notification::<lsp_ext::AppendOutputToRunTest>(text); } } } @@ -1317,7 +1313,7 @@ impl GlobalState { /// Handles a request. fn on_request(&mut self, req: Request) { let mut dispatcher = RequestDispatcher { req: Some(req), global_state: self }; - dispatcher.on_sync_mut::<lsp_types::ShutdownRequest>(|s, ()| { + dispatcher.on_sync_mut::<lsp_types::request::Shutdown>(|s, ()| { s.shutdown_requested = true; s.proc_macro_clients = std::iter::repeat_with(|| None).take(s.proc_macro_clients.len()).collect(); @@ -1339,6 +1335,7 @@ impl GlobalState { } use crate::handlers::request as handlers; + use lsp_types::request as lsp_request; const RETRY: bool = true; const NO_RETRY: bool = false; @@ -1347,91 +1344,91 @@ impl GlobalState { dispatcher // Request handlers that must run on the main thread // because they mutate GlobalState: - .on_sync_mut::<lsp_ext::ReloadWorkspaceRequest>(handlers::handle_workspace_reload) - .on_sync_mut::<lsp_ext::RebuildProcMacrosRequest>(handlers::handle_proc_macros_rebuild) - .on_sync_mut::<lsp_ext::MemoryUsageRequest>(handlers::handle_memory_usage) - .on_sync_mut::<lsp_ext::RunTestRequest>(handlers::handle_run_test) + .on_sync_mut::<lsp_ext::ReloadWorkspace>(handlers::handle_workspace_reload) + .on_sync_mut::<lsp_ext::RebuildProcMacros>(handlers::handle_proc_macros_rebuild) + .on_sync_mut::<lsp_ext::MemoryUsage>(handlers::handle_memory_usage) + .on_sync_mut::<lsp_ext::RunTest>(handlers::handle_run_test) // Request handlers which are related to the user typing // are run on the main thread to reduce latency: - .on_sync::<lsp_ext::JoinLinesRequest>(handlers::handle_join_lines) - .on_sync::<lsp_ext::OnEnterRequest>(handlers::handle_on_enter) - .on_sync::<lsp_types::SelectionRangeRequest>(handlers::handle_selection_range) - .on_sync::<lsp_ext::MatchingBraceRequest>(handlers::handle_matching_brace) - .on_sync::<lsp_ext::DocumentOnTypeFormattingRequest>(handlers::handle_on_type_formatting) + .on_sync::<lsp_ext::JoinLines>(handlers::handle_join_lines) + .on_sync::<lsp_ext::OnEnter>(handlers::handle_on_enter) + .on_sync::<lsp_request::SelectionRangeRequest>(handlers::handle_selection_range) + .on_sync::<lsp_ext::MatchingBrace>(handlers::handle_matching_brace) + .on_sync::<lsp_ext::OnTypeFormatting>(handlers::handle_on_type_formatting) // Formatting should be done immediately as the editor might wait on it, but we can't // put it on the main thread as we do not want the main thread to block on rustfmt. // So we have an extra thread just for formatting requests to make sure it gets handled // as fast as possible. - .on_fmt_thread::<lsp_types::DocumentFormattingRequest>(handlers::handle_formatting) - .on_fmt_thread::<lsp_types::DocumentRangeFormattingRequest>(handlers::handle_range_formatting) + .on_fmt_thread::<lsp_request::Formatting>(handlers::handle_formatting) + .on_fmt_thread::<lsp_request::RangeFormatting>(handlers::handle_range_formatting) // We can’t run latency-sensitive request handlers which do semantic // analysis on the main thread because that would block other // requests. Instead, we run these request handlers on higher priority // threads in the threadpool. // FIXME: Retrying can make the result of this stale? - .on_latency_sensitive::<RETRY, lsp_types::CompletionRequest>(handlers::handle_completion) + .on_latency_sensitive::<RETRY, lsp_request::Completion>(handlers::handle_completion) // FIXME: Retrying can make the result of this stale - .on_latency_sensitive::<RETRY, lsp_types::CompletionResolveRequest>(handlers::handle_completion_resolve) - .on_latency_sensitive::<RETRY, lsp_types::SemanticTokensRequest>(handlers::handle_semantic_tokens_full) - .on_latency_sensitive::<RETRY, lsp_types::SemanticTokensDeltaRequest>(handlers::handle_semantic_tokens_full_delta) - .on_latency_sensitive::<NO_RETRY, lsp_types::SemanticTokensRangeRequest>(handlers::handle_semantic_tokens_range) + .on_latency_sensitive::<RETRY, lsp_request::ResolveCompletionItem>(handlers::handle_completion_resolve) + .on_latency_sensitive::<RETRY, lsp_request::SemanticTokensFullRequest>(handlers::handle_semantic_tokens_full) + .on_latency_sensitive::<RETRY, lsp_request::SemanticTokensFullDeltaRequest>(handlers::handle_semantic_tokens_full_delta) + .on_latency_sensitive::<NO_RETRY, lsp_request::SemanticTokensRangeRequest>(handlers::handle_semantic_tokens_range) // FIXME: Some of these NO_RETRY could be retries if the file they are interested didn't change. // All other request handlers - .on_with_vfs_default::<lsp_types::DocumentDiagnosticRequest>(handlers::handle_document_diagnostics, empty_diagnostic_report, || lsp_server::ResponseError { + .on_with_vfs_default::<lsp_request::DocumentDiagnosticRequest>(handlers::handle_document_diagnostics, empty_diagnostic_report, || lsp_server::ResponseError { code: lsp_server::ErrorCode::ServerCancelled as i32, message: "server cancelled the request".to_owned(), data: serde_json::to_value(lsp_types::DiagnosticServerCancellationData { retrigger_request: true }).ok(), }) - .on::<RETRY, lsp_types::DocumentSymbolRequest>(handlers::handle_document_symbol) - .on::<RETRY, lsp_types::FoldingRangeRequest>(handlers::handle_folding_range) - .on::<NO_RETRY, lsp_types::SignatureHelpRequest>(handlers::handle_signature_help) - .on::<RETRY, lsp_types::WillRenameFilesRequest>(handlers::handle_will_rename_files) - .on::<NO_RETRY, lsp_types::DefinitionRequest>(handlers::handle_goto_definition) - .on::<NO_RETRY, lsp_types::DeclarationRequest>(handlers::handle_goto_declaration) - .on::<NO_RETRY, lsp_types::ImplementationRequest>(handlers::handle_goto_implementation) - .on::<NO_RETRY, lsp_types::TypeDefinitionRequest>(handlers::handle_goto_type_definition) - .on::<NO_RETRY, lsp_types::InlayHintRequest>(handlers::handle_inlay_hints) - .on_identity::<NO_RETRY, lsp_types::InlayHintResolveRequest, _>(handlers::handle_inlay_hints_resolve) - .on::<NO_RETRY, lsp_types::CodeLensRequest>(handlers::handle_code_lens) - .on_identity::<NO_RETRY, lsp_types::CodeLensResolveRequest, _>(handlers::handle_code_lens_resolve) - .on::<NO_RETRY, lsp_types::PrepareRenameRequest>(handlers::handle_prepare_rename) - .on::<NO_RETRY, lsp_types::RenameRequest>(handlers::handle_rename) - .on::<NO_RETRY, lsp_types::ReferencesRequest>(handlers::handle_references) - .on::<NO_RETRY, lsp_types::DocumentHighlightRequest>(handlers::handle_document_highlight) - .on::<NO_RETRY, lsp_types::CallHierarchyPrepareRequest>(handlers::handle_call_hierarchy_prepare) - .on::<NO_RETRY, lsp_types::CallHierarchyIncomingCallsRequest>(handlers::handle_call_hierarchy_incoming) - .on::<NO_RETRY, lsp_types::CallHierarchyOutgoingCallsRequest>(handlers::handle_call_hierarchy_outgoing) + .on::<RETRY, lsp_request::DocumentSymbolRequest>(handlers::handle_document_symbol) + .on::<RETRY, lsp_request::FoldingRangeRequest>(handlers::handle_folding_range) + .on::<NO_RETRY, lsp_request::SignatureHelpRequest>(handlers::handle_signature_help) + .on::<RETRY, lsp_request::WillRenameFiles>(handlers::handle_will_rename_files) + .on::<NO_RETRY, lsp_request::GotoDefinition>(handlers::handle_goto_definition) + .on::<NO_RETRY, lsp_request::GotoDeclaration>(handlers::handle_goto_declaration) + .on::<NO_RETRY, lsp_request::GotoImplementation>(handlers::handle_goto_implementation) + .on::<NO_RETRY, lsp_request::GotoTypeDefinition>(handlers::handle_goto_type_definition) + .on::<NO_RETRY, lsp_request::InlayHintRequest>(handlers::handle_inlay_hints) + .on_identity::<NO_RETRY, lsp_request::InlayHintResolveRequest, _>(handlers::handle_inlay_hints_resolve) + .on::<NO_RETRY, lsp_request::CodeLensRequest>(handlers::handle_code_lens) + .on_identity::<NO_RETRY, lsp_request::CodeLensResolve, _>(handlers::handle_code_lens_resolve) + .on::<NO_RETRY, lsp_request::PrepareRenameRequest>(handlers::handle_prepare_rename) + .on::<NO_RETRY, lsp_request::Rename>(handlers::handle_rename) + .on::<NO_RETRY, lsp_request::References>(handlers::handle_references) + .on::<NO_RETRY, lsp_request::DocumentHighlightRequest>(handlers::handle_document_highlight) + .on::<NO_RETRY, lsp_request::CallHierarchyPrepare>(handlers::handle_call_hierarchy_prepare) + .on::<NO_RETRY, lsp_request::CallHierarchyIncomingCalls>(handlers::handle_call_hierarchy_incoming) + .on::<NO_RETRY, lsp_request::CallHierarchyOutgoingCalls>(handlers::handle_call_hierarchy_outgoing) // All other request handlers (lsp extension) - .on::<RETRY, lsp_ext::FetchDependencyListRequest>(handlers::fetch_dependency_list) - .on::<RETRY, lsp_ext::AnalyzerStatusRequest>(handlers::handle_analyzer_status) - .on::<RETRY, lsp_ext::ViewFileTextRequest>(handlers::handle_view_file_text) - .on::<RETRY, lsp_ext::ViewCrateGraphRequest>(handlers::handle_view_crate_graph) - .on::<RETRY, lsp_ext::ViewItemTreeRequest>(handlers::handle_view_item_tree) - .on::<RETRY, lsp_ext::DiscoverTestRequest>(handlers::handle_discover_test) - .on::<RETRY, lsp_ext::WorkspaceSymbolRequest>(handlers::handle_workspace_symbol) - .on::<NO_RETRY, lsp_ext::SsrRequest>(handlers::handle_ssr) - .on::<NO_RETRY, lsp_ext::ViewRecursiveMemoryLayoutRequest>(handlers::handle_view_recursive_memory_layout) - .on::<NO_RETRY, lsp_ext::ViewSyntaxTreeRequest>(handlers::handle_view_syntax_tree) - .on::<NO_RETRY, lsp_ext::ViewHirRequest>(handlers::handle_view_hir) - .on::<NO_RETRY, lsp_ext::ViewMirRequest>(handlers::handle_view_mir) - .on::<NO_RETRY, lsp_ext::InterpretFunctionRequest>(handlers::handle_interpret_function) - .on::<NO_RETRY, lsp_ext::ExpandMacroRequest>(handlers::handle_expand_macro) - .on::<NO_RETRY, lsp_ext::ParentModuleRequest>(handlers::handle_parent_module) - .on::<NO_RETRY, lsp_ext::ChildModulesRequest>(handlers::handle_child_modules) - .on::<NO_RETRY, lsp_ext::RunnablesRequest>(handlers::handle_runnables) - .on::<NO_RETRY, lsp_ext::RelatedTestsRequest>(handlers::handle_related_tests) + .on::<RETRY, lsp_ext::FetchDependencyList>(handlers::fetch_dependency_list) + .on::<RETRY, lsp_ext::AnalyzerStatus>(handlers::handle_analyzer_status) + .on::<RETRY, lsp_ext::ViewFileText>(handlers::handle_view_file_text) + .on::<RETRY, lsp_ext::ViewCrateGraph>(handlers::handle_view_crate_graph) + .on::<RETRY, lsp_ext::ViewItemTree>(handlers::handle_view_item_tree) + .on::<RETRY, lsp_ext::DiscoverTest>(handlers::handle_discover_test) + .on::<RETRY, lsp_ext::WorkspaceSymbol>(handlers::handle_workspace_symbol) + .on::<NO_RETRY, lsp_ext::Ssr>(handlers::handle_ssr) + .on::<NO_RETRY, lsp_ext::ViewRecursiveMemoryLayout>(handlers::handle_view_recursive_memory_layout) + .on::<NO_RETRY, lsp_ext::ViewSyntaxTree>(handlers::handle_view_syntax_tree) + .on::<NO_RETRY, lsp_ext::ViewHir>(handlers::handle_view_hir) + .on::<NO_RETRY, lsp_ext::ViewMir>(handlers::handle_view_mir) + .on::<NO_RETRY, lsp_ext::InterpretFunction>(handlers::handle_interpret_function) + .on::<NO_RETRY, lsp_ext::ExpandMacro>(handlers::handle_expand_macro) + .on::<NO_RETRY, lsp_ext::ParentModule>(handlers::handle_parent_module) + .on::<NO_RETRY, lsp_ext::ChildModules>(handlers::handle_child_modules) + .on::<NO_RETRY, lsp_ext::Runnables>(handlers::handle_runnables) + .on::<NO_RETRY, lsp_ext::RelatedTests>(handlers::handle_related_tests) .on::<NO_RETRY, lsp_ext::CodeActionRequest>(handlers::handle_code_action) .on_identity::<RETRY, lsp_ext::CodeActionResolveRequest, _>(handlers::handle_code_action_resolve) .on::<NO_RETRY, lsp_ext::HoverRequest>(handlers::handle_hover) - .on::<NO_RETRY, lsp_ext::ExternalDocsRequest>(handlers::handle_open_docs) - .on::<NO_RETRY, lsp_ext::OpenCargoTomlRequest>(handlers::handle_open_cargo_toml) - .on::<NO_RETRY, lsp_ext::MoveItemRequest>(handlers::handle_move_item) + .on::<NO_RETRY, lsp_ext::ExternalDocs>(handlers::handle_open_docs) + .on::<NO_RETRY, lsp_ext::OpenCargoToml>(handlers::handle_open_cargo_toml) + .on::<NO_RETRY, lsp_ext::MoveItem>(handlers::handle_move_item) // - .on::<NO_RETRY, lsp_ext::InternalTestingFetchConfigRequest>(handlers::internal_testing_fetch_config) - .on::<RETRY, lsp_ext::EvaluatePredicateRequest>(handlers::handle_evaluate_predicate) - .on::<RETRY, lsp_ext::GetFailedObligationsRequest>(handlers::get_failed_obligations) + .on::<NO_RETRY, lsp_ext::InternalTestingFetchConfig>(handlers::internal_testing_fetch_config) + .on::<RETRY, lsp_ext::EvaluatePredicate>(handlers::handle_evaluate_predicate) + .on::<RETRY, lsp_ext::GetFailedObligations>(handlers::get_failed_obligations) .finish(); } @@ -1440,37 +1437,28 @@ impl GlobalState { let _p = span!(Level::INFO, "GlobalState::on_notification", not.method = ?not.method).entered(); use crate::handlers::notification as handlers; + use lsp_types::notification as notifs; NotificationDispatcher { not: Some(not), global_state: self } - .on_sync_mut::<lsp_types::CancelNotification>(handlers::handle_cancel) - .on_sync_mut::<lsp_types::WorkDoneProgressCancelNotification>( + .on_sync_mut::<notifs::Cancel>(handlers::handle_cancel) + .on_sync_mut::<notifs::WorkDoneProgressCancel>( handlers::handle_work_done_progress_cancel, ) - .on_sync_mut::<lsp_types::DidOpenTextDocumentNotification>( - handlers::handle_did_open_text_document, - ) - .on_sync_mut::<lsp_types::DidChangeTextDocumentNotification>( - handlers::handle_did_change_text_document, - ) - .on_sync_mut::<lsp_types::DidCloseTextDocumentNotification>( - handlers::handle_did_close_text_document, - ) - .on_sync_mut::<lsp_types::DidSaveTextDocumentNotification>( - handlers::handle_did_save_text_document, - ) - .on_sync_mut::<lsp_types::DidChangeConfigurationNotification>( + .on_sync_mut::<notifs::DidOpenTextDocument>(handlers::handle_did_open_text_document) + .on_sync_mut::<notifs::DidChangeTextDocument>(handlers::handle_did_change_text_document) + .on_sync_mut::<notifs::DidCloseTextDocument>(handlers::handle_did_close_text_document) + .on_sync_mut::<notifs::DidSaveTextDocument>(handlers::handle_did_save_text_document) + .on_sync_mut::<notifs::DidChangeConfiguration>( handlers::handle_did_change_configuration, ) - .on_sync_mut::<lsp_types::DidChangeWorkspaceFoldersNotification>( + .on_sync_mut::<notifs::DidChangeWorkspaceFolders>( handlers::handle_did_change_workspace_folders, ) - .on_sync_mut::<lsp_types::DidChangeWatchedFilesNotification>( - handlers::handle_did_change_watched_files, - ) - .on_sync_mut::<lsp_ext::CancelFlycheckNotification>(handlers::handle_cancel_flycheck) - .on_sync_mut::<lsp_ext::ClearFlycheckNotification>(handlers::handle_clear_flycheck) - .on_sync_mut::<lsp_ext::RunFlycheckNotification>(handlers::handle_run_flycheck) - .on_sync_mut::<lsp_ext::AbortRunTestNotification>(handlers::handle_abort_run_test) + .on_sync_mut::<notifs::DidChangeWatchedFiles>(handlers::handle_did_change_watched_files) + .on_sync_mut::<lsp_ext::CancelFlycheck>(handlers::handle_cancel_flycheck) + .on_sync_mut::<lsp_ext::ClearFlycheck>(handlers::handle_clear_flycheck) + .on_sync_mut::<lsp_ext::RunFlycheck>(handlers::handle_run_flycheck) + .on_sync_mut::<lsp_ext::AbortRunTest>(handlers::handle_abort_run_test) .finish(); } } diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index ace44b02fe..a466b172e7 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs @@ -540,8 +540,8 @@ impl GlobalState { // FIXME: can we abort the build scripts here if they are already running? self.workspaces = Arc::new(workspaces); self.check_workspaces_msrv().for_each(|message| { - self.send_notification::<lsp_types::ShowMessageNotification>( - lsp_types::ShowMessageParams { kind: lsp_types::MessageType::Warning, message }, + self.send_notification::<lsp_types::notification::ShowMessage>( + lsp_types::ShowMessageParams { typ: lsp_types::MessageType::WARNING, message }, ); }); @@ -581,10 +581,10 @@ impl GlobalState { }) }) .map(|(base, pat)| lsp_types::FileSystemWatcher { - glob_pattern: lsp_types::GlobPattern::RelativePattern( + glob_pattern: lsp_types::GlobPattern::Relative( lsp_types::RelativePattern { - base_uri: lsp_types::BaseUri::Uri( - lsp_types::Uri::from_file_path(base).unwrap(), + base_uri: lsp_types::OneOf::Right( + lsp_types::Url::from_file_path(base).unwrap(), ), pattern: pat.to_owned(), }, @@ -606,7 +606,7 @@ impl GlobalState { }) }) .map(|glob_pattern| lsp_types::FileSystemWatcher { - glob_pattern: lsp_types::GlobPattern::Pattern(glob_pattern), + glob_pattern: lsp_types::GlobPattern::String(glob_pattern), kind: None, }) .collect() @@ -620,7 +620,7 @@ impl GlobalState { continue; }; watchers.push(lsp_types::FileSystemWatcher { - glob_pattern: lsp_types::GlobPattern::Pattern( + glob_pattern: lsp_types::GlobPattern::String( build.build_file.to_string(), ), kind: None, @@ -634,7 +634,7 @@ impl GlobalState { .chain(self.workspaces.iter().map(|ws| ws.manifest().map(ManifestPath::as_ref))) .flatten() .map(|glob_pattern| lsp_types::FileSystemWatcher { - glob_pattern: lsp_types::GlobPattern::Pattern(glob_pattern.to_string()), + glob_pattern: lsp_types::GlobPattern::String(glob_pattern.to_string()), kind: None, }), ); @@ -646,7 +646,7 @@ impl GlobalState { method: "workspace/didChangeWatchedFiles".to_owned(), register_options: Some(serde_json::to_value(registration_options).unwrap()), }; - self.send_request::<lsp_types::RegistrationRequest>( + self.send_request::<lsp_types::request::RegisterCapability>( lsp_types::RegistrationParams { registrations: vec![registration] }, |_, _| (), ); diff --git a/crates/rust-analyzer/tests/slow-tests/main.rs b/crates/rust-analyzer/tests/slow-tests/main.rs index 9edb1df447..b91bde8428 100644 --- a/crates/rust-analyzer/tests/slow-tests/main.rs +++ b/crates/rust-analyzer/tests/slow-tests/main.rs @@ -20,19 +20,23 @@ mod ratoml; mod support; mod testdir; -use std::{path::PathBuf, time::Instant}; +use std::{collections::HashMap, path::PathBuf, time::Instant}; use ide_db::FxHashMap; use lsp_types::{ - CodeActionContext, CodeActionParams, CodeActionRequest, CompletionParams, CompletionRequest, - DidOpenTextDocumentNotification, DidOpenTextDocumentParams, DocumentFormattingParams, - DocumentFormattingRequest, DocumentRangeFormattingParams, DocumentRangeFormattingRequest, - FileRename, FormattingOptions, HoverParams, HoverRequest, InlayHint, InlayHintParams, - InlayHintRequest, InlayHintResolveRequest, Label, LanguageKind, PartialResultParams, Position, - Range, RenameFilesParams, TextDocumentItem, TextDocumentPositionParams, TypeDefinitionParams, - TypeDefinitionRequest, WillRenameFilesRequest, WorkDoneProgressParams, WorkspaceSymbolRequest, + CodeActionContext, CodeActionParams, CompletionParams, DidOpenTextDocumentParams, + DocumentFormattingParams, DocumentRangeFormattingParams, FileRename, FormattingOptions, + GotoDefinitionParams, HoverParams, InlayHint, InlayHintLabel, InlayHintParams, + PartialResultParams, Position, Range, RenameFilesParams, TextDocumentItem, + TextDocumentPositionParams, WorkDoneProgressParams, + notification::DidOpenTextDocument, + request::{ + CodeActionRequest, Completion, Formatting, GotoTypeDefinition, HoverRequest, + InlayHintRequest, InlayHintResolveRequest, RangeFormatting, WillRenameFiles, + WorkspaceSymbolRequest, + }, }; -use rust_analyzer::lsp::ext::{OnEnterRequest, RunnablesParams, RunnablesRequest}; +use rust_analyzer::lsp::ext::{OnEnter, Runnables, RunnablesParams}; use serde_json::json; use stdx::format_to_acc; @@ -64,8 +68,8 @@ use std::collections::Spam; .server() .wait_until_workspace_is_loaded(); - let res = server.send_request::<CompletionRequest>(CompletionParams { - text_document_position_params: TextDocumentPositionParams::new( + let res = server.send_request::<Completion>(CompletionParams { + text_document_position: TextDocumentPositionParams::new( server.doc_id("src/lib.rs"), Position::new(0, 23), ), @@ -108,13 +112,13 @@ fn f() { let hint = hints.pop().unwrap(); assert!(hint.data.is_some()); assert!( - matches!(&hint.label, Label::InlayHintLabelPartList(parts) if parts[1].location.is_none()) + matches!(&hint.label, InlayHintLabel::LabelParts(parts) if parts[1].location.is_none()) ); let res = server.send_request::<InlayHintResolveRequest>(hint); let hint = serde_json::from_value::<InlayHint>(res).unwrap(); assert!(hint.data.is_none()); assert!( - matches!(&hint.label, Label::InlayHintLabelPartList(parts) if parts[1].location.is_some()) + matches!(&hint.label, InlayHintLabel::LabelParts(parts) if parts[1].location.is_some()) ); } @@ -156,8 +160,8 @@ use dependency2::Spam; .server() .wait_until_workspace_is_loaded(); - let res = server.send_request::<CompletionRequest>(CompletionParams { - text_document_position_params: TextDocumentPositionParams::new( + let res = server.send_request::<Completion>(CompletionParams { + text_document_position: TextDocumentPositionParams::new( server.doc_id("src/lib.rs"), Position::new(5, 18), ), @@ -167,8 +171,8 @@ use dependency2::Spam; }); assert!(res.to_string().contains("SpecialHashMap"), "{}", res.to_string()); - let res = server.send_request::<CompletionRequest>(CompletionParams { - text_document_position_params: TextDocumentPositionParams::new( + let res = server.send_request::<Completion>(CompletionParams { + text_document_position: TextDocumentPositionParams::new( server.doc_id("src/lib.rs"), Position::new(6, 18), ), @@ -195,8 +199,8 @@ use dependency2::Spam; std::thread::sleep(std::time::Duration::from_secs(3)); - let res = server.send_request::<CompletionRequest>(CompletionParams { - text_document_position_params: TextDocumentPositionParams::new( + let res = server.send_request::<Completion>(CompletionParams { + text_document_position: TextDocumentPositionParams::new( server.doc_id("src/lib.rs"), Position::new(5, 18), ), @@ -206,8 +210,8 @@ use dependency2::Spam; }); assert!(!res.to_string().contains("SpecialHashMap")); - let res = server.send_request::<CompletionRequest>(CompletionParams { - text_document_position_params: TextDocumentPositionParams::new( + let res = server.send_request::<Completion>(CompletionParams { + text_document_position: TextDocumentPositionParams::new( server.doc_id("src/lib.rs"), Position::new(6, 18), ), @@ -252,7 +256,7 @@ fn main() {} .server() .wait_until_workspace_is_loaded(); - server.request::<RunnablesRequest>( + server.request::<Runnables>( RunnablesParams { text_document: server.doc_id("foo/tests/spam.rs"), position: None }, json!([ { @@ -403,7 +407,7 @@ mod tests { .wait_until_workspace_is_loaded(); for runnable in ["consumer", "dependency", "devdependency"] { - server.request::<RunnablesRequest>( + server.request::<Runnables>( RunnablesParams { text_document: server.doc_id(&format!("{runnable}/src/lib.rs")), position: None, @@ -468,7 +472,7 @@ fn otherpkg() {} .server() .wait_until_workspace_is_loaded(); - server.request::<RunnablesRequest>( + server.request::<Runnables>( RunnablesParams { text_document: server.doc_id("foo/mainpkg/src/main.rs"), position: None }, json!([ "{...}", @@ -493,7 +497,7 @@ fn otherpkg() {} ]), ); - server.request::<RunnablesRequest>( + server.request::<Runnables>( RunnablesParams { text_document: server.doc_id("foo/otherpkg/src/lib.rs"), position: None }, json!([ "{...}", @@ -543,7 +547,7 @@ pub use std::collections::HashMap; ) .wait_until_workspace_is_loaded(); - server.request::<DocumentFormattingRequest>( + server.request::<Formatting>( DocumentFormattingParams { text_document: server.doc_id("src/lib.rs"), options: FormattingOptions { @@ -552,6 +556,7 @@ pub use std::collections::HashMap; insert_final_newline: None, trim_final_newlines: None, trim_trailing_whitespace: None, + properties: HashMap::new(), }, work_done_progress_params: WorkDoneProgressParams::default(), }, @@ -595,12 +600,13 @@ pub use std::collections::HashMap; ) .wait_until_workspace_is_loaded(); - server.request::<DocumentFormattingRequest>( + server.request::<Formatting>( DocumentFormattingParams { text_document: server.doc_id("src/lib.rs"), options: FormattingOptions { tab_size: 4, insert_spaces: false, + properties: HashMap::new(), insert_final_newline: None, trim_final_newlines: None, trim_trailing_whitespace: None, @@ -645,7 +651,7 @@ fn main() {} ) .wait_until_workspace_is_loaded(); - server.request::<DocumentFormattingRequest>( + server.request::<Formatting>( DocumentFormattingParams { text_document: server.doc_id("src/lib.rs"), options: FormattingOptions { @@ -654,6 +660,7 @@ fn main() {} insert_final_newline: None, trim_final_newlines: None, trim_trailing_whitespace: None, + properties: HashMap::new(), }, work_done_progress_params: WorkDoneProgressParams::default(), }, @@ -700,7 +707,7 @@ fn main() { .server() .wait_until_workspace_is_loaded(); - server.request::<DocumentRangeFormattingRequest>( + server.request::<RangeFormatting>( DocumentRangeFormattingParams { range: Range { end: Position { line: 1, character: 0 }, @@ -713,6 +720,7 @@ fn main() { insert_final_newline: None, trim_final_newlines: None, trim_trailing_whitespace: None, + properties: HashMap::new(), }, work_done_progress_params: WorkDoneProgressParams::default(), }, @@ -920,17 +928,17 @@ fn main() {{}} .wait_until_workspace_is_loaded(); for i in 0..10 { - server.notification::<DidOpenTextDocumentNotification>(DidOpenTextDocumentParams { + server.notification::<DidOpenTextDocument>(DidOpenTextDocumentParams { text_document: TextDocumentItem { uri: server.doc_id(&format!("src/m{i}.rs")).uri, - language_id: LanguageKind::Rust, + language_id: "rust".to_owned(), version: 0, text: "/// Docs\nfn foo() {}".to_owned(), }, }); } let start = Instant::now(); - server.request::<OnEnterRequest>( + server.request::<OnEnter>( TextDocumentPositionParams { text_document: server.doc_id("src/m0.rs"), position: Position { line: 0, character: 5 }, @@ -968,7 +976,7 @@ version = \"0.0.0\" .server() .wait_until_workspace_is_loaded(); - server.request::<OnEnterRequest>( + server.request::<OnEnter>( TextDocumentPositionParams { text_document: server.doc_id("src/main.rs"), position: Position { line: 0, character: 8 }, @@ -1081,8 +1089,8 @@ fn main() { }); assert!(res.to_string().contains("&str")); - server.request::<TypeDefinitionRequest>( - TypeDefinitionParams { + server.request::<GotoTypeDefinition>( + GotoDefinitionParams { text_document_position_params: TextDocumentPositionParams::new( server.doc_id("src/main.rs"), Position::new(28, 9), @@ -1107,8 +1115,8 @@ fn main() { }]), ); - server.request::<TypeDefinitionRequest>( - TypeDefinitionParams { + server.request::<GotoTypeDefinition>( + GotoDefinitionParams { text_document_position_params: TextDocumentPositionParams::new( server.doc_id("src/main.rs"), Position::new(29, 9), @@ -1300,8 +1308,8 @@ use crate::old_folder::nested::foo as bar; let server = Project::with_fixture(code).tmp_dir(tmp_dir).server().wait_until_workspace_is_loaded(); - // rename same level file - server.request::<WillRenameFilesRequest>( + //rename same level file + server.request::<WillRenameFiles>( RenameFilesParams { files: vec![FileRename { old_uri: base_path.join("src/old_file.rs").to_str().unwrap().to_owned(), @@ -1335,8 +1343,8 @@ use crate::old_folder::nested::foo as bar; }), ); - // rename file from mod.rs to foo.rs - server.request::<WillRenameFilesRequest>( + //rename file from mod.rs to foo.rs + server.request::<WillRenameFiles>( RenameFilesParams { files: vec![FileRename { old_uri: base_path.join("src/from_mod/mod.rs").to_str().unwrap().to_owned(), @@ -1346,8 +1354,8 @@ use crate::old_folder::nested::foo as bar; json!(null), ); - // rename file from foo.rs to mod.rs - server.request::<WillRenameFilesRequest>( + //rename file from foo.rs to mod.rs + server.request::<WillRenameFiles>( RenameFilesParams { files: vec![FileRename { old_uri: base_path.join("src/to_mod/foo.rs").to_str().unwrap().to_owned(), @@ -1357,8 +1365,8 @@ use crate::old_folder::nested::foo as bar; json!(null), ); - // rename same level file - server.request::<WillRenameFilesRequest>( + //rename same level file + server.request::<WillRenameFiles>( RenameFilesParams { files: vec![FileRename { old_uri: base_path.join("src/old_folder").to_str().unwrap().to_owned(), @@ -1560,7 +1568,7 @@ fn test<T: Trait>() { .server() .wait_until_workspace_is_loaded(); - let res = server.send_request::<rust_analyzer::lsp::ext::EvaluatePredicateRequest>( + let res = server.send_request::<rust_analyzer::lsp::ext::EvaluatePredicate>( rust_analyzer::lsp::ext::EvaluatePredicateParams { text: "T: Trait".to_owned(), text_document: server.doc_id("src/lib.rs"), @@ -1599,7 +1607,7 @@ fn test() { .server() .wait_until_workspace_is_loaded(); - let res = server.send_request::<rust_analyzer::lsp::ext::GetFailedObligationsRequest>( + let res = server.send_request::<rust_analyzer::lsp::ext::GetFailedObligations>( rust_analyzer::lsp::ext::GetFailedObligationsParams { text_document: server.doc_id("src/lib.rs"), position: Position::new(4, 19), diff --git a/crates/rust-analyzer/tests/slow-tests/ratoml.rs b/crates/rust-analyzer/tests/slow-tests/ratoml.rs index 7ac3465a4a..dd113babff 100644 --- a/crates/rust-analyzer/tests/slow-tests/ratoml.rs +++ b/crates/rust-analyzer/tests/slow-tests/ratoml.rs @@ -1,24 +1,23 @@ use crate::support::{Project, Server}; use crate::testdir::TestDir; use lsp_types::{ - DidChangeTextDocumentNotification, DidChangeTextDocumentParams, - DidOpenTextDocumentNotification, DidOpenTextDocumentParams, DidSaveTextDocumentNotification, - DidSaveTextDocumentParams, TextDocumentContentChangeEvent, - TextDocumentContentChangeWholeDocument, TextDocumentIdentifier, TextDocumentItem, Uri, + DidChangeTextDocumentParams, DidOpenTextDocumentParams, DidSaveTextDocumentParams, + TextDocumentContentChangeEvent, TextDocumentIdentifier, TextDocumentItem, Url, VersionedTextDocumentIdentifier, + notification::{DidChangeTextDocument, DidOpenTextDocument, DidSaveTextDocument}, }; use paths::Utf8PathBuf; use rust_analyzer::config::Config; use rust_analyzer::lsp::ext::{ - InternalTestingFetchConfigOption, InternalTestingFetchConfigParams, - InternalTestingFetchConfigRequest, InternalTestingFetchConfigResponse, + InternalTestingFetchConfig, InternalTestingFetchConfigOption, InternalTestingFetchConfigParams, + InternalTestingFetchConfigResponse, }; use serde_json::json; use test_utils::skip_slow_tests; struct RatomlTest { - urls: Vec<Uri>, + urls: Vec<Url>, server: Server, tmp_path: Utf8PathBuf, } @@ -55,7 +54,7 @@ impl RatomlTest { case } - fn fixture_path(&self, fixture: &str) -> Uri { + fn fixture_path(&self, fixture: &str) -> Url { let mut lines = fixture.trim().split('\n'); let mut path = @@ -82,7 +81,7 @@ impl RatomlTest { path = path.join(piece); } - Uri::parse( + Url::parse( format!("file://{}", path.into_string().replace("C:\\", "/c:/").replace('\\', "/")) .as_str(), ) @@ -90,75 +89,65 @@ impl RatomlTest { } fn create(&mut self, fixture_path: &str, text: String) { - let uri = self.fixture_path(fixture_path); + let url = self.fixture_path(fixture_path); - self.server.notification::<DidOpenTextDocumentNotification>(DidOpenTextDocumentParams { + self.server.notification::<DidOpenTextDocument>(DidOpenTextDocumentParams { text_document: TextDocumentItem { - uri: uri.clone(), - language_id: lsp_types::LanguageKind::Rust, + uri: url.clone(), + language_id: "rust".to_owned(), version: 0, text: String::new(), }, }); - self.server.notification::<DidChangeTextDocumentNotification>( - DidChangeTextDocumentParams { - text_document: VersionedTextDocumentIdentifier { - text_document_identifier: TextDocumentIdentifier { uri }, - version: 0, - }, - - content_changes: vec![ - TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( - TextDocumentContentChangeWholeDocument { text }, - ), - ], - }, - ); + self.server.notification::<DidChangeTextDocument>(DidChangeTextDocumentParams { + text_document: VersionedTextDocumentIdentifier { uri: url, version: 0 }, + content_changes: vec![TextDocumentContentChangeEvent { + range: None, + range_length: None, + text, + }], + }); } fn delete(&mut self, file_idx: usize) { - self.server.notification::<DidOpenTextDocumentNotification>(DidOpenTextDocumentParams { + self.server.notification::<DidOpenTextDocument>(DidOpenTextDocumentParams { text_document: TextDocumentItem { uri: self.urls[file_idx].clone(), - language_id: lsp_types::LanguageKind::Rust, + language_id: "rust".to_owned(), version: 0, text: "".to_owned(), }, }); // See if deleting ratoml file will make the config of interest to return to its default value. - self.server.notification::<DidSaveTextDocumentNotification>(DidSaveTextDocumentParams { + self.server.notification::<DidSaveTextDocument>(DidSaveTextDocumentParams { text_document: TextDocumentIdentifier { uri: self.urls[file_idx].clone() }, text: Some("".to_owned()), }); } fn edit(&mut self, file_idx: usize, text: String) { - self.server.notification::<DidOpenTextDocumentNotification>(DidOpenTextDocumentParams { + self.server.notification::<DidOpenTextDocument>(DidOpenTextDocumentParams { text_document: TextDocumentItem { uri: self.urls[file_idx].clone(), - language_id: lsp_types::LanguageKind::Rust, + language_id: "rust".to_owned(), version: 0, text: String::new(), }, }); - self.server.notification::<DidChangeTextDocumentNotification>( - DidChangeTextDocumentParams { - text_document: VersionedTextDocumentIdentifier { - text_document_identifier: TextDocumentIdentifier { - uri: self.urls[file_idx].clone(), - }, - version: 0, - }, - content_changes: vec![ - TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( - TextDocumentContentChangeWholeDocument { text }, - ), - ], + self.server.notification::<DidChangeTextDocument>(DidChangeTextDocumentParams { + text_document: VersionedTextDocumentIdentifier { + uri: self.urls[file_idx].clone(), + version: 0, }, - ); + content_changes: vec![TextDocumentContentChangeEvent { + range: None, + range_length: None, + text, + }], + }); } fn query( @@ -167,7 +156,7 @@ impl RatomlTest { source_file_idx: usize, expected: InternalTestingFetchConfigResponse, ) { - let res = self.server.send_request::<InternalTestingFetchConfigRequest>( + let res = self.server.send_request::<InternalTestingFetchConfig>( InternalTestingFetchConfigParams { text_document: Some(TextDocumentIdentifier { uri: self.urls[source_file_idx].clone(), diff --git a/crates/rust-analyzer/tests/slow-tests/support.rs b/crates/rust-analyzer/tests/slow-tests/support.rs index c3568ce950..2c4b978a4d 100644 --- a/crates/rust-analyzer/tests/slow-tests/support.rs +++ b/crates/rust-analyzer/tests/slow-tests/support.rs @@ -9,7 +9,7 @@ use crossbeam_channel::{Receiver, after, select}; use itertools::Itertools; use lsp_server::{Connection, Message, Notification, Request}; use lsp_types::{ - ExitNotification, PublishDiagnosticsParams, ShutdownRequest, TextDocumentIdentifier, Uri, + PublishDiagnosticsParams, TextDocumentIdentifier, Url, notification::Exit, request::Shutdown, }; use parking_lot::{Mutex, MutexGuard}; use paths::{Utf8Path, Utf8PathBuf}; @@ -229,13 +229,13 @@ impl Project<'_> { ..Default::default() }), text_document: Some(lsp_types::TextDocumentClientCapabilities { - definition: Some(lsp_types::DefinitionClientCapabilities { + definition: Some(lsp_types::GotoCapability { link_support: Some(true), ..Default::default() }), code_action: Some(lsp_types::CodeActionClientCapabilities { code_action_literal_support: Some( - lsp_types::ClientCodeActionLiteralOptions::default(), + lsp_types::CodeActionLiteralSupport::default(), ), ..Default::default() }), @@ -244,7 +244,7 @@ impl Project<'_> { ..Default::default() }), inlay_hint: Some(lsp_types::InlayHintClientCapabilities { - resolve_support: Some(lsp_types::ClientInlayHintResolveOptions { + resolve_support: Some(lsp_types::InlayHintResolveClientCapabilities { properties: vec![ "textEdits".to_owned(), "tooltip".to_owned(), @@ -321,22 +321,22 @@ impl Server { pub(crate) fn doc_id(&self, rel_path: &str) -> TextDocumentIdentifier { let path = self.dir.path().join(rel_path); - TextDocumentIdentifier { uri: Uri::from_file_path(path).unwrap() } + TextDocumentIdentifier { uri: Url::from_file_path(path).unwrap() } } pub(crate) fn notification<N>(&self, params: N::Params) where - N: lsp_types::Notification, + N: lsp_types::notification::Notification, N::Params: Serialize, { - let r = Notification::new(N::METHOD.into(), params); + let r = Notification::new(N::METHOD.to_owned(), params); self.send_notification(r) } #[track_caller] pub(crate) fn request<R>(&self, params: R::Params, expected_resp: Value) where - R: lsp_types::Request, + R: lsp_types::request::Request, R::Params: Serialize, { let actual = self.send_request::<R>(params); @@ -354,13 +354,13 @@ impl Server { #[track_caller] pub(crate) fn send_request<R>(&self, params: R::Params) -> Value where - R: lsp_types::Request, + R: lsp_types::request::Request, R::Params: Serialize, { let id = self.req_id.get(); self.req_id.set(id.wrapping_add(1)); - let r = Request::new(id.into(), R::METHOD.into(), params); + let r = Request::new(id.into(), R::METHOD.to_owned(), params); self.send_request_(r) } #[track_caller] @@ -494,7 +494,7 @@ impl Server { pub(crate) fn write_file_and_save(&self, path: &str, text: String) { fs::write(self.dir.path().join(path), &text).unwrap(); - self.notification::<lsp_types::DidSaveTextDocumentNotification>( + self.notification::<lsp_types::notification::DidSaveTextDocument>( lsp_types::DidSaveTextDocumentParams { text_document: self.doc_id(path), text: Some(text), @@ -505,8 +505,8 @@ impl Server { impl Drop for Server { fn drop(&mut self) { - self.request::<ShutdownRequest>((), Value::Null); - self.notification::<ExitNotification>(()); + self.request::<Shutdown>((), Value::Null); + self.notification::<Exit>(()); } } diff --git a/docs/book/src/contributing/lsp-extensions.md b/docs/book/src/contributing/lsp-extensions.md index 6902bce83e..a3189402a9 100644 --- a/docs/book/src/contributing/lsp-extensions.md +++ b/docs/book/src/contributing/lsp-extensions.md @@ -1,5 +1,5 @@ <!--- -lsp/ext.rs hash: ca646d2ad3d38ccd +lsp/ext.rs hash: cec81c987f189e83 If you need to change the above hash to make the test pass, please check if you need to adjust this doc as well and ping this issue: @@ -31,10 +31,9 @@ At the same time some essential configuration parameters are needed early on, be For this reason, we ask that `initializationOptions` contains the configuration, as if the server did make a `"workspace/configuration"` request. If a language client does not know about `rust-analyzer`'s configuration options it can get sensible defaults by doing any of the following: - -* Not sending `initializationOptions` -* Sending `"initializationOptions": null` -* Sending `"initializationOptions": {}` + * Not sending `initializationOptions` + * Sending `"initializationOptions": null` + * Sending `"initializationOptions": {}` ## Snippet `TextEdit` @@ -132,6 +131,7 @@ This request is sent from client to server to handle "Goto Parent Module" editor **Response:** `Location | Location[] | LocationLink[] | null` + ### Example ```rust @@ -671,6 +671,7 @@ interface RunFlycheckParams { Triggers the flycheck processes. + **Method:** `rust-analyzer/clearFlycheck` **Notification:** @@ -848,7 +849,6 @@ interface CommandLinkGroup { ``` Such actions on the client side are appended to a hover bottom as command links: - ``` +-----------------------------+ | Hover content | @@ -875,6 +875,7 @@ This request is sent from client to server to open the current project's Cargo.t **Response:** `Location | null` + ### Example ```rust @@ -918,7 +919,6 @@ interface HoverParams extends WorkDoneProgressParams { position: Range | Position; } ``` - Whenever the client sends a `Range`, it is understood as the current selection and any hover included in the range will show the type of the expression if possible. ### Example @@ -965,6 +965,7 @@ export const enum Direction { Extends the existing `workspace/symbol` request with ability to filter symbols by broad scope and kind of symbol. If this capability is set, `workspace/symbol` parameter gains two new optional fields: + ```typescript interface WorkspaceSymbolParams { /** @@ -1001,6 +1002,7 @@ However, the server doesn't know which commands are available on the client. This extensions allows the client to communicate this info. + ```typescript export interface ClientCommandOptions { /** @@ -1048,7 +1050,6 @@ export interface FetchDependencyListParams {} ``` **Response:** - ```typescript export interface FetchDependencyListResult { crates: { @@ -1058,7 +1059,6 @@ export interface FetchDependencyListResult { }[]; } ``` - Returns all crates from this workspace, so it can be used create a viewTree to help navigate the dependency tree. ## View Recursive Memory Layout @@ -1100,8 +1100,8 @@ If `RecursiveMemoryLayout::nodes::length == 0` we could not find a suitable type Generic Types do not give anything because they are incomplete. Fully specified generic types do not give anything if they are selected directly but do work when a child of other types [this is consistent with other behavior](https://github.com/rust-lang/rust-analyzer/issues/15010). -### Unresolved questions +### Unresolved questions: -* How should enums/unions be represented? currently they do not produce any children because they have multiple distinct sets of children. -* Should niches be represented? currently they are not reported. -* A visual representation of the memory layout is not specified, see the provided implementation for an example, however it may not translate well to terminal based editors or other such things. +- How should enums/unions be represented? currently they do not produce any children because they have multiple distinct sets of children. +- Should niches be represented? currently they are not reported. +- A visual representation of the memory layout is not specified, see the provided implementation for an example, however it may not translate well to terminal based editors or other such things. diff --git a/lib/lsp-server/Cargo.toml b/lib/lsp-server/Cargo.toml index 358cd2f168..03a4f08108 100644 --- a/lib/lsp-server/Cargo.toml +++ b/lib/lsp-server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lsp-server" -version = "0.8.0" +version = "0.7.9" description = "Generic LSP server scaffold." license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/lsp-server" @@ -16,7 +16,6 @@ lsp-types = { git = "https://git.bendn.org/helix", package = "helix-lsp-types" } [dev-dependencies] lsp-types = { git = "https://git.bendn.org/helix", package = "helix-lsp-types" } - ctrlc = "3.4.7" anyhow.workspace = true rustc-hash.workspace = true diff --git a/lib/lsp-server/examples/minimal_lsp.rs b/lib/lsp-server/examples/minimal_lsp.rs index b7dcef9bfa..5eef999e06 100644 --- a/lib/lsp-server/examples/minimal_lsp.rs +++ b/lib/lsp-server/examples/minimal_lsp.rs @@ -67,15 +67,6 @@ use std::{error::Error, io::Write}; -use lsp_types::{ - CompletionItem, CompletionItemKind, CompletionOptions, CompletionRequest, CompletionResponse, - Contents, DefinitionRequest, Diagnostic, DiagnosticSeverity, DidChangeTextDocumentNotification, - DidChangeTextDocumentParams, DidOpenTextDocumentNotification, DidOpenTextDocumentParams, - DocumentFormattingParams, DocumentFormattingRequest, Hover, HoverProvider, HoverRequest, - InitializeParams, LspNotificationMethod, LspRequestMethod, MarkedString, Notification, - Position, PublishDiagnosticsNotification, PublishDiagnosticsParams, Range, Request, - ServerCapabilities, TextDocumentSync, TextEdit, Uri, -}; use rustc_hash::FxHashMap; // fast hash map use std::process::Stdio; use toolchain::command; // clippy-approved wrapper @@ -83,6 +74,39 @@ use toolchain::command; // clippy-approved wrapper #[allow(clippy::print_stderr, clippy::disallowed_types, clippy::disallowed_methods)] use anyhow::{Context, Result, anyhow, bail}; use lsp_server::{Connection, Message, Request as ServerRequest, RequestId, Response}; +use lsp_types::notification::Notification as _; // for METHOD consts +use lsp_types::request::Request as _; +use lsp_types::{ + CompletionItem, + CompletionItemKind, + // capability helpers + CompletionOptions, + CompletionResponse, + Diagnostic, + DiagnosticSeverity, + DidChangeTextDocumentParams, + DidOpenTextDocumentParams, + DocumentFormattingParams, + Hover, + HoverContents, + HoverProviderCapability, + // core + InitializeParams, + MarkedString, + OneOf, + Position, + PublishDiagnosticsParams, + Range, + ServerCapabilities, + TextDocumentSyncCapability, + TextDocumentSyncKind, + TextEdit, + Url, + // notifications + notification::{DidChangeTextDocument, DidOpenTextDocument, PublishDiagnostics}, + // requests + request::{Completion, Formatting, GotoDefinition, HoverRequest}, +}; // for METHOD consts // ===================================================================== // main @@ -97,11 +121,11 @@ fn main() -> std::result::Result<(), Box<dyn Error + Sync + Send>> { // advertised capabilities let caps = ServerCapabilities { - text_document_sync: Some(TextDocumentSync::Kind(lsp_types::TextDocumentSyncKind::Full)), + text_document_sync: Some(TextDocumentSyncCapability::Kind(TextDocumentSyncKind::FULL)), completion_provider: Some(CompletionOptions::default()), - definition_provider: Some(lsp_types::DefinitionProvider::Bool(true)), - hover_provider: Some(HoverProvider::Bool(true)), - document_formatting_provider: Some(lsp_types::DocumentFormattingProvider::Bool(true)), + definition_provider: Some(OneOf::Left(true)), + hover_provider: Some(HoverProviderCapability::Simple(true)), + document_formatting_provider: Some(OneOf::Left(true)), ..Default::default() }; let init_value = serde_json::json!({ @@ -125,7 +149,7 @@ fn main_loop( params: serde_json::Value, ) -> std::result::Result<(), Box<dyn Error + Sync + Send>> { let _init: InitializeParams = serde_json::from_value(params)?; - let mut docs: FxHashMap<Uri, String> = FxHashMap::default(); + let mut docs: FxHashMap<Url, String> = FxHashMap::default(); for msg in &connection.receiver { match msg { @@ -155,25 +179,20 @@ fn main_loop( fn handle_notification( conn: &Connection, note: &lsp_server::Notification, - docs: &mut FxHashMap<Uri, String>, + docs: &mut FxHashMap<Url, String>, ) -> Result<()> { - let method: LspNotificationMethod = note.method.clone().into(); - match method { - DidOpenTextDocumentNotification::METHOD => { + match note.method.as_str() { + DidOpenTextDocument::METHOD => { let p: DidOpenTextDocumentParams = serde_json::from_value(note.params.clone())?; let uri = p.text_document.uri; docs.insert(uri.clone(), p.text_document.text); publish_dummy_diag(conn, &uri)?; } - DidChangeTextDocumentNotification::METHOD => { + DidChangeTextDocument::METHOD => { let p: DidChangeTextDocumentParams = serde_json::from_value(note.params.clone())?; if let Some(change) = p.content_changes.into_iter().next() { - let uri = p.text_document.text_document_identifier.uri; - let text = match change { - lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangePartial(partial) => partial.text, - lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument(whole) => whole.text, - }; - docs.insert(uri.clone(), text); + let uri = p.text_document.uri; + docs.insert(uri.clone(), change.text); publish_dummy_diag(conn, &uri)?; } } @@ -189,43 +208,31 @@ fn handle_notification( fn handle_request( conn: &Connection, req: &ServerRequest, - docs: &mut FxHashMap<Uri, String>, + docs: &mut FxHashMap<Url, String>, ) -> Result<()> { - let parsed: LspRequestMethod = req.method.clone().into(); - match parsed { - DefinitionRequest::METHOD => { - send_ok( - conn, - req.id.clone(), - &lsp_types::DefinitionResponse::DefinitionLinkList(Vec::new()), - )?; + match req.method.as_str() { + GotoDefinition::METHOD => { + send_ok(conn, req.id.clone(), &lsp_types::GotoDefinitionResponse::Array(Vec::new()))?; } - CompletionRequest::METHOD => { + Completion::METHOD => { let item = CompletionItem { label: "HelloFromLSP".into(), - kind: Some(CompletionItemKind::Function), + kind: Some(CompletionItemKind::FUNCTION), detail: Some("dummy completion".into()), ..Default::default() }; - let items = vec![item]; - let completion_list = CompletionResponse::CompletionList(lsp_types::CompletionList { - is_incomplete: false, - item_defaults: None, - apply_kind: None, - items, - }); - send_ok(conn, req.id.clone(), &completion_list)?; + send_ok(conn, req.id.clone(), &CompletionResponse::Array(vec![item]))?; } HoverRequest::METHOD => { let hover = Hover { - contents: Contents::MarkedString(MarkedString::String( + contents: HoverContents::Scalar(MarkedString::String( "Hello from *minimal_lsp*".into(), )), range: None, }; send_ok(conn, req.id.clone(), &hover)?; } - DocumentFormattingRequest::METHOD => { + Formatting::METHOD => { let p: DocumentFormattingParams = serde_json::from_value(req.params.clone())?; let uri = p.text_document.uri; let text = docs @@ -248,10 +255,10 @@ fn handle_request( // ===================================================================== // diagnostics // ===================================================================== -fn publish_dummy_diag(conn: &Connection, uri: &Uri) -> Result<()> { +fn publish_dummy_diag(conn: &Connection, uri: &Url) -> Result<()> { let diag = Diagnostic { range: Range::new(Position::new(0, 0), Position::new(0, 1)), - severity: Some(DiagnosticSeverity::Information), + severity: Some(DiagnosticSeverity::INFORMATION), code: None, code_description: None, source: Some("minimal_lsp".into()), @@ -263,7 +270,7 @@ fn publish_dummy_diag(conn: &Connection, uri: &Uri) -> Result<()> { let params = PublishDiagnosticsParams { uri: uri.clone(), diagnostics: vec![diag], version: None }; conn.sender.send(Message::Notification(lsp_server::Notification::new( - PublishDiagnosticsNotification::METHOD.into(), + PublishDiagnostics::METHOD.to_owned(), params, )))?; Ok(()) diff --git a/lib/lsp-server/src/lib.rs b/lib/lsp-server/src/lib.rs index cef1c3e140..66ecbf8c33 100644 --- a/lib/lsp-server/src/lib.rs +++ b/lib/lsp-server/src/lib.rs @@ -379,10 +379,9 @@ impl Connection { #[cfg(test)] mod tests { use crossbeam_channel::unbounded; - use lsp_types::{ - ExitNotification, InitializeParams, InitializeRequest, InitializedNotification, - InitializedParams, Notification as _, Request as _, - }; + use lsp_types::notification::{Exit, Initialized, Notification}; + use lsp_types::request::{Initialize, Request}; + use lsp_types::{InitializeParams, InitializedParams}; use serde_json::to_value; use crate::{Connection, Message, ProtocolError, RequestId}; @@ -410,7 +409,7 @@ mod tests { #[test] fn not_exit_notification() { let notification = crate::Notification { - method: InitializedNotification::METHOD.to_string(), + method: Initialized::METHOD.to_owned(), params: to_value(InitializedParams {}).unwrap(), }; @@ -418,7 +417,7 @@ mod tests { let req_id = RequestId::from(234); let request = crate::Request { id: req_id.clone(), - method: InitializeRequest::METHOD.to_string(), + method: Initialize::METHOD.to_owned(), params: params_as_value.clone(), }; @@ -430,10 +429,8 @@ mod tests { #[test] fn exit_notification() { - let notification = crate::Notification { - method: ExitNotification::METHOD.to_string(), - params: to_value(()).unwrap(), - }; + let notification = + crate::Notification { method: Exit::METHOD.to_owned(), params: to_value(()).unwrap() }; let notification_msg = Message::from(notification); initialize_start_test(TestCase { |