Merge ref '7fb284d9037f' from rust-lang/rust Pull recent changes from https://github.com/rust-lang/rust via Josh. Upstream ref: rust-lang/rust@7fb284d9037fa54f6a9b24261c82b394472cbfd7 Filtered ref: rust-lang/rust-analyzer@a5454c1cd90c24a48670f429816f6c703a1c0e62 Upstream diff: https://github.com/rust-lang/rust/compare/942ac9ce4116d4ea784c9882659372b34978b1f8...7fb284d9037fa54f6a9b24261c82b394472cbfd7 This merge was created using https://github.com/rust-lang/josh-sync.
diff --git a/Cargo.lock b/Cargo.lock index 602af6f..60c23e9 100644 --- a/Cargo.lock +++ b/Cargo.lock
@@ -139,12 +139,6 @@ [[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" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a" @@ -538,7 +532,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" dependencies = [ - "bitflags 2.12.1", + "bitflags", "block2", "libc", "objc2", @@ -725,6 +719,17 @@ ] [[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" @@ -803,15 +808,6 @@ [[package]] name = "hashbrown" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" -dependencies = [ - "foldhash 0.2.0", -] - -[[package]] -name = "hashbrown" version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" @@ -823,11 +819,11 @@ [[package]] name = "hashlink" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0b22561a9c04a7cb1a302c013e0259cd3b4bb619f145b32f72b8b4bcbed230" +checksum = "a5081f264ed7adee96ea4b4778b6bb9da0a7228b084587aa3bd3ff05da7c5a3b" dependencies = [ - "hashbrown 0.16.1", + "hashbrown 0.17.1", ] [[package]] @@ -894,7 +890,7 @@ dependencies = [ "arrayvec", "base-db", - "bitflags 2.12.1", + "bitflags", "cfg", "cov-mark", "drop_bomb", @@ -960,7 +956,7 @@ dependencies = [ "arrayvec", "base-db", - "bitflags 2.12.1", + "bitflags", "cov-mark", "either", "ena", @@ -1169,7 +1165,7 @@ dependencies = [ "arrayvec", "base-db", - "bitflags 2.12.1", + "bitflags", "cov-mark", "crossbeam-channel", "either", @@ -1273,7 +1269,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "533e68a5842e734946fe159fb03fc9bbbb254f590dd0d8ad321ae5ff7beca2c1" dependencies = [ - "bitflags 2.12.1", + "bitflags", "inotify-sys", "libc", ] @@ -1375,7 +1371,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07293a4e297ac234359b510362495713f75ea345d5307140414f20c69ffeb087" dependencies = [ - "bitflags 2.12.1", + "bitflags", "libc", ] @@ -1493,22 +1489,6 @@ [[package]] name = "lsp-server" version = "0.7.9" -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.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d6ada348dbc2703cbe7637b2dda05cff84d3da2819c24abcb305dd613e0ba2e" dependencies = [ @@ -1520,16 +1500,19 @@ ] [[package]] -name = "lsp-types" -version = "0.95.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "158c1911354ef73e8fe42da6b10c0484cb65c7f1007f28022e847706c1ab6984" +name = "lsp-server" +version = "0.8.0" dependencies = [ - "bitflags 1.3.2", + "anyhow", + "crossbeam-channel", + "ctrlc", + "gen-lsp-types", + "log", + "rustc-hash 2.1.2", "serde", + "serde_derive", "serde_json", - "serde_repr", - "url", + "toolchain", ] [[package]] @@ -1547,7 +1530,7 @@ version = "0.0.0" dependencies = [ "arrayvec", - "bitflags 2.12.1", + "bitflags", "cov-mark", "expect-test", "intern", @@ -1631,7 +1614,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ - "bitflags 2.12.1", + "bitflags", "cfg-if", "cfg_aliases", "libc", @@ -1649,7 +1632,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4d3d07927151ff8575b7087f245456e549fea62edf0ec4e565a5ee50c8402bc3" dependencies = [ - "bitflags 2.12.1", + "bitflags", "fsevent-sys", "inotify", "kqueue", @@ -1667,7 +1650,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42b8cfee0e339a0337359f3c88165702ac6e600dc01c0cc9579a92d62b08477a" dependencies = [ - "bitflags 2.12.1", + "bitflags", ] [[package]] @@ -2050,7 +2033,7 @@ dependencies = [ "bit-set", "bit-vec", - "bitflags 2.12.1", + "bitflags", "num-traits", "rand", "rand_chacha", @@ -2087,7 +2070,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.12.1", + "bitflags", "memchr", "unicase", ] @@ -2146,7 +2129,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f25a779e21ca3bba6795193b16508c8ab159f96ee4b07349893fd272065b525" dependencies = [ - "bitflags 2.12.1", + "bitflags", "ra-ap-rustc_hashes", "ra-ap-rustc_index", "tracing", @@ -2241,7 +2224,7 @@ checksum = "8c5d9a4d3e7bee7313599bc6d794037247ac0165f03857379cf4fc3097199e05" dependencies = [ "arrayvec", - "bitflags 2.12.1", + "bitflags", "derive-where", "ena", "indexmap", @@ -2331,7 +2314,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.12.1", + "bitflags", ] [[package]] @@ -2400,6 +2383,7 @@ "dirs", "dissimilar", "expect-test", + "gen-lsp-types", "hir", "hir-def", "hir-ty", @@ -2411,8 +2395,7 @@ "intern", "itertools 0.14.0", "load-cargo", - "lsp-server 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", - "lsp-types", + "lsp-server 0.7.9", "memchr", "mimalloc", "num_cpus", @@ -2490,7 +2473,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "486c2179b4796f65bfe2ee33679acf0927ac83ecf583ad6c91c3b4570911b9ad" dependencies = [ - "bitflags 2.12.1", + "bitflags", "smallvec", ] @@ -2509,7 +2492,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.12.1", + "bitflags", "errno", "libc", "linux-raw-sys", @@ -2536,9 +2519,9 @@ [[package]] name = "salsa" -version = "0.27.0" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adfc1e32b8d1a486e3a45a5480fb5dca7912f49262a8916a67378064da4fe1ab" +checksum = "ffbaab832e2ea754afda4a738f987dd1e8bd30c9e5d8c981ee6a3934386095e2" dependencies = [ "boxcar", "crossbeam-queue", @@ -2562,15 +2545,15 @@ [[package]] name = "salsa-macro-rules" -version = "0.27.0" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67dad477a3e3a484a7c2311c1d25160fb270214981be24022de7de8a206a3300" +checksum = "de6872462ac73d39969a836273c24163e6a26a4e08f5114fcd80e25af30ea9c6" [[package]] name = "salsa-macros" -version = "0.27.0" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "943f70e101fb3bd599960e79e719e70d85142730e5b45f3269246086ed218562" +checksum = "76bc78ffaf65b1a9175818592c5130aa10b1bb245a905722fd4db87cea8a8457" dependencies = [ "proc-macro2", "quote", @@ -2644,9 +2627,9 @@ [[package]] name = "serde_json" -version = "1.0.150" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "indexmap", "itoa", @@ -2657,17 +2640,6 @@ ] [[package]] -name = "serde_repr" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] name = "serde_spanned" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3427,7 +3399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.12.1", + "bitflags", "hashbrown 0.15.5", "indexmap", "semver", @@ -3721,7 +3693,7 @@ checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.12.1", + "bitflags", "indexmap", "log", "serde",
diff --git a/crates/hir-def/src/expr_store/tests/body.rs b/crates/hir-def/src/expr_store/tests/body.rs index da412a6..98cbcb2 100644 --- a/crates/hir-def/src/expr_store/tests/body.rs +++ b/crates/hir-def/src/expr_store/tests/body.rs
@@ -690,7 +690,7 @@ } #[test] -fn foo() { +fn block_tail_cfg() { pretty_print( r#" macro_rules! foo {
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs index a916cda..95ebae2 100644 --- a/crates/hir-def/src/nameres/collector.rs +++ b/crates/hir-def/src/nameres/collector.rs
@@ -81,7 +81,7 @@ let proc_macros = if krate.is_proc_macro { db.proc_macros_for_crate(def_map.krate) .and_then(|proc_macros| { - proc_macros.list(db.syntax_context(tree_id.file_id(), krate.edition)) + proc_macros.list(tree_id.file_id().syntax_context(db, krate.edition)) }) .unwrap_or_default() } else {
diff --git a/crates/hir-expand/src/db.rs b/crates/hir-expand/src/db.rs index 33672d1..8b4b86c 100644 --- a/crates/hir-expand/src/db.rs +++ b/crates/hir-expand/src/db.rs
@@ -2,7 +2,7 @@ use base_db::{Crate, SourceDatabase}; use mbe::MatchedArmIndex; -use span::{AstIdMap, Edition, Span, SyntaxContext}; +use span::{AstIdMap, Span}; use std::borrow::Cow; use syntax::{AstNode, Parse, SyntaxError, SyntaxNode, SyntaxToken, T, ast}; use syntax_bridge::{DocCommentDesugarMode, syntax_node_to_token_tree}; @@ -136,19 +136,6 @@ &self, macro_call: MacroCallId, ) -> Option<ExpandResult<Arc<[SyntaxError]>>>; - - #[salsa::transparent] - fn syntax_context(&self, file: HirFileId, edition: Edition) -> SyntaxContext; -} - -fn syntax_context(db: &dyn ExpandDatabase, file: HirFileId, edition: Edition) -> SyntaxContext { - match file { - HirFileId::FileId(_) => SyntaxContext::root(edition), - HirFileId::MacroFile(m) => { - let kind = &m.loc(db).kind; - db.macro_arg_considering_derives(m, kind).2.ctx - } - } } fn resolve_span(db: &dyn ExpandDatabase, Span { range, anchor, ctx: _ }: Span) -> FileRange {
diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs index 9c5714b..3386e22 100644 --- a/crates/hir-expand/src/lib.rs +++ b/crates/hir-expand/src/lib.rs
@@ -1128,6 +1128,16 @@ HirFileId::MacroFile(_) => None, } } + + pub fn syntax_context(self, db: &dyn ExpandDatabase, edition: Edition) -> SyntaxContext { + match self { + HirFileId::FileId(_) => SyntaxContext::root(edition), + HirFileId::MacroFile(m) => { + let kind = &m.loc(db).kind; + db.macro_arg_considering_derives(m, kind).2.ctx + } + } + } } impl PartialEq<EditionedFileId> for HirFileId {
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs index ab290aa..5d0a010 100644 --- a/crates/hir-ty/src/display.rs +++ b/crates/hir-ty/src/display.rs
@@ -746,26 +746,33 @@ ConstKind::Value(value) => render_const_scalar_from_valtree(f, value.ty, value.value), ConstKind::Unevaluated(unev) => { let c = unev.def.0; - match c { - GeneralConstId::ConstId(id) => match &ConstSignature::of(f.db, id).name { - Some(name) => { - f.start_location_link(id.into()); - write!(f, "{}", name.display(f.db, f.edition()))?; - f.end_location_link(); + let generic_def = match c { + GeneralConstId::ConstId(id) => { + match &ConstSignature::of(f.db, id).name { + Some(name) => { + f.start_location_link(id.into()); + write!(f, "{}", name.display(f.db, f.edition()))?; + f.end_location_link(); + } + None => f.write_str("_")?, } - None => f.write_str("_")?, - }, + Some(id.into()) + } GeneralConstId::StaticId(id) => { let name = &StaticSignature::of(f.db, id).name; f.start_location_link(id.into()); write!(f, "{}", name.display(f.db, f.edition()))?; f.end_location_link(); + Some(id.into()) } GeneralConstId::AnonConstId(_) => { - f.write_str(if f.display_kind.is_source_code() { "_" } else { "{const}" })? + f.write_str(if f.display_kind.is_source_code() { "_" } else { "{const}" })?; + None } }; - hir_fmt_generics(f, unev.args.as_slice(), c.generic_def(f.db), None)?; + if let Some(generic_def) = generic_def { + hir_fmt_generics(f, unev.args.as_slice(), Some(generic_def), None)?; + } Ok(()) } ConstKind::Error(..) => f.write_char('_'),
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs index 616701f..a09dcaa 100644 --- a/crates/hir-ty/src/infer.rs +++ b/crates/hir-ty/src/infer.rs
@@ -409,6 +409,10 @@ expr: ExprId, found: StoredTy, }, + MutRefInImmRefPat { + #[type_visitable(ignore)] + pat: PatId, + }, CannotImplicitlyDerefTraitObject { #[type_visitable(ignore)] pat: PatId,
diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs index 915da94..81ba377 100644 --- a/crates/hir-ty/src/infer/pat.rs +++ b/crates/hir-ty/src/infer/pat.rs
@@ -916,7 +916,7 @@ if matches!(bm.0, ByRef::Yes(Mutability::Mut)) && let MutblCap::WeaklyNot = pat_info.max_ref_mutbl { - // FIXME: Emit an error: cannot borrow as mutable inside an `&` pattern. + self.push_diagnostic(InferenceDiagnostic::MutRefInImmRefPat { pat }); } // ...and store it in a side table:
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs index ed073cb..616b063 100644 --- a/crates/hir/src/diagnostics.rs +++ b/crates/hir/src/diagnostics.rs
@@ -135,6 +135,7 @@ MissingMatchArms, MissingUnsafe, MovedOutOfRef<'db>, + MutRefInImmRefPat, MutableRefBinding, NeedMut, NonExhaustiveLet, @@ -338,6 +339,11 @@ } #[derive(Debug)] +pub struct MutRefInImmRefPat { + pub pat: InFile<ExprOrPatPtr>, +} + +#[derive(Debug)] pub struct CannotImplicitlyDerefTraitObject<'db> { pub pat: InFile<ExprOrPatPtr>, pub found: Type<'db>, @@ -960,6 +966,10 @@ let expr = expr_syntax(*expr)?; CannotBeDereferenced { expr, found: new_ty(found.as_ref()) }.into() } + InferenceDiagnostic::MutRefInImmRefPat { pat } => { + let pat = pat_syntax(*pat)?.map(Into::into); + MutRefInImmRefPat { pat }.into() + } InferenceDiagnostic::CannotImplicitlyDerefTraitObject { pat, found } => { let pat = pat_syntax(*pat)?.map(Into::into); CannotImplicitlyDerefTraitObject { pat, found: new_ty(found.as_ref()) }.into()
diff --git a/crates/ide-assists/src/handlers/unmerge_match_arm.rs b/crates/ide-assists/src/handlers/unmerge_match_arm.rs index 555d3d2..b1ea0c8 100644 --- a/crates/ide-assists/src/handlers/unmerge_match_arm.rs +++ b/crates/ide-assists/src/handlers/unmerge_match_arm.rs
@@ -86,7 +86,7 @@ // - After the arm. In this case we always want to insert a comma after the newly // inserted arm. // - Missing after the arm, with no arms after. In this case we want to insert a - // comma before the newly inserted arm. It can not be necessary if there arm + // comma before the newly inserted arm. It can not be necessary if the arm // body is a block, but we don't bother to check that. // - Missing after the arm with arms after, if the arm body is a block. In this case // we don't want to insert a comma at all.
diff --git a/crates/ide-diagnostics/src/handlers/mut_ref_in_imm_ref_pat.rs b/crates/ide-diagnostics/src/handlers/mut_ref_in_imm_ref_pat.rs new file mode 100644 index 0000000..d3c83be --- /dev/null +++ b/crates/ide-diagnostics/src/handlers/mut_ref_in_imm_ref_pat.rs
@@ -0,0 +1,37 @@ +use crate::{Diagnostic, DiagnosticCode, DiagnosticsContext}; + +// Diagnostic: mut-ref-in-imm-ref-pat +// +// This diagnostic is triggered when a binding tries to mutably borrow through +// an `&` pattern. +pub(crate) fn mut_ref_in_imm_ref_pat( + ctx: &DiagnosticsContext<'_, '_>, + d: &hir::MutRefInImmRefPat, +) -> Diagnostic { + Diagnostic::new_with_syntax_node_ptr( + ctx, + DiagnosticCode::RustcHardError("E0596"), + "cannot borrow as mutable inside an `&` pattern", + d.pat.map(Into::into), + ) + .stable() +} + +#[cfg(test)] +mod tests { + use crate::tests::check_diagnostics; + + #[test] + fn mut_ref_in_imm_ref_pat() { + check_diagnostics( + r#" +#![feature(ref_pat_eat_one_layer_2024)] + +fn main() { + let &ref mut _x = &mut 0; + //^^^^^^^^^^ error: cannot borrow as mutable inside an `&` pattern +} +"#, + ); + } +}
diff --git a/crates/ide-diagnostics/src/handlers/type_mismatch.rs b/crates/ide-diagnostics/src/handlers/type_mismatch.rs index 5a1856c..da6fc20 100644 --- a/crates/ide-diagnostics/src/handlers/type_mismatch.rs +++ b/crates/ide-diagnostics/src/handlers/type_mismatch.rs
@@ -74,6 +74,7 @@ remove_unnecessary_wrapper(ctx, d, expr_ptr, &mut fixes); remove_semicolon(ctx, d, expr_ptr, &mut fixes); str_ref_to_owned(ctx, d, expr_ptr, &mut fixes); + add_await(ctx, d, expr_ptr, &mut fixes); } if fixes.is_empty() { None } else { Some(fixes) } @@ -377,6 +378,30 @@ Some(()) } +fn add_await( + ctx: &DiagnosticsContext<'_, '_>, + d: &hir::TypeMismatch<'_>, + expr_ptr: &InFile<AstPtr<ast::Expr>>, + acc: &mut Vec<Assist>, +) -> Option<()> { + let output = d.actual.clone().future_output(ctx.db())?; + // XXX: maybe should check if ctx is async + let is_applicable = output.could_coerce_to(ctx.db(), &d.expected); + if !is_applicable { + return None; + } + + let root = ctx.db().parse_or_expand(expr_ptr.file_id); + let expr = expr_ptr.value.to_node(&root); + let hir::FileRange { file_id, range } = ctx.sema.original_range_opt(expr.syntax())?; + + let edit = TextEdit::insert(range.end(), ".await".to_owned()); + let source_change = SourceChange::from_text_edit(file_id.file_id(ctx.db()), edit); + acc.push(fix("add_await", "Add .await here", source_change, range)); + + Some(()) +} + #[cfg(test)] mod tests { use crate::tests::{ @@ -1395,6 +1420,47 @@ } #[test] + fn add_await() { + check_fix( + r#" +//- minicore: future +async fn foo() -> u32 { 2 } +async fn test() { + let x: u32 = foo()$0; +} + "#, + r#" +async fn foo() -> u32 { 2 } +async fn test() { + let x: u32 = foo().await; +} + "#, + ); + + check_fix( + r#" +//- minicore: future +macro_rules! identity { ($($t:tt)*) => ($($t)*) } +async fn foo() -> u32 { 2 } +identity! { + async fn test() { + let x: u32 = foo()$0; + } +} + "#, + r#" +macro_rules! identity { ($($t:tt)*) => ($($t)*) } +async fn foo() -> u32 { 2 } +identity! { + async fn test() { + let x: u32 = foo().await; + } +} + "#, + ); + } + + #[test] fn type_mismatch_range_adjustment() { cov_mark::check!(type_mismatch_range_adjustment); check_diagnostics(
diff --git a/crates/ide-diagnostics/src/lib.rs b/crates/ide-diagnostics/src/lib.rs index ea0d2d9..e7d7425 100644 --- a/crates/ide-diagnostics/src/lib.rs +++ b/crates/ide-diagnostics/src/lib.rs
@@ -65,6 +65,7 @@ pub(crate) mod missing_match_arms; pub(crate) mod missing_unsafe; pub(crate) mod moved_out_of_ref; + pub(crate) mod mut_ref_in_imm_ref_pat; pub(crate) mod mutability_errors; pub(crate) mod mutable_ref; pub(crate) mod no_such_field; @@ -479,6 +480,7 @@ AnyDiagnostic::MissingMatchArms(d) => handlers::missing_match_arms::missing_match_arms(&ctx, &d), AnyDiagnostic::MissingUnsafe(d) => handlers::missing_unsafe::missing_unsafe(&ctx, &d), AnyDiagnostic::MovedOutOfRef(d) => handlers::moved_out_of_ref::moved_out_of_ref(&ctx, &d), + AnyDiagnostic::MutRefInImmRefPat(d) => handlers::mut_ref_in_imm_ref_pat::mut_ref_in_imm_ref_pat(&ctx, &d), AnyDiagnostic::MutableRefBinding(d) => handlers::mutable_ref::mutable_ref_binding(&ctx, &d), AnyDiagnostic::NeedMut(d) => match handlers::mutability_errors::need_mut(&ctx, &d) { Some(it) => it,
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs index 30644fe..2bd79d7 100644 --- a/crates/ide/src/hover/tests.rs +++ b/crates/ide/src/hover/tests.rs
@@ -9422,6 +9422,27 @@ } #[test] +fn hover_impl_trait_arg_with_anon_const_arg_does_not_recurse() { + check( + r#" +trait Tr<const N: usize> {} +pub fn f(x$0: impl Tr<{ 0 }>) {} +"#, + expect![[r#" + *x* + + ```rust + x: impl Tr<{const}> + ?Sized + ``` + + --- + + type param may need Drop + "#]], + ); +} + +#[test] fn hover_struct_default_arg_self() { check( r#"
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 27d9576..dd8649e 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml
@@ -29,7 +29,7 @@ indexmap.workspace = true itertools.workspace = true scip = "0.7.1" -lsp-types = { version = "=0.95.0", features = ["proposed"] } +lsp-types = { version = "0.4.0", package = "gen-lsp-types", features=["url"] } parking_lot = "0.12.4" xflags = "0.3.2" oorandom = "11.1.5"
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index 44c442f..f175bb0 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs
@@ -207,25 +207,15 @@ tracing::info!("InitializeParams: {}", initialize_params); let lsp_types::InitializeParams { + #[expect(deprecated, reason = "compatibility with old clients")] root_uri, - mut capabilities, - workspace_folders, + capabilities, + workspace_folders_initialize_params, 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) @@ -247,7 +237,14 @@ ); } - let workspace_roots = workspace_folders + 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, + }) .map(|workspaces| { workspaces .into_iter() @@ -269,12 +266,11 @@ if !error_sink.is_empty() { use lsp_types::{ - MessageType, ShowMessageParams, - notification::{Notification, ShowMessage}, + MessageType, Notification as _, ShowMessageNotification, ShowMessageParams, }; let not = lsp_server::Notification::new( - ShowMessage::METHOD.to_owned(), - ShowMessageParams { typ: MessageType::WARNING, message: error_sink.to_string() }, + ShowMessageNotification::METHOD.into(), + ShowMessageParams { kind: MessageType::Warning, message: error_sink.to_string() }, ); connection.sender.send(lsp_server::Message::Notification(not)).unwrap(); } @@ -288,7 +284,6 @@ name: String::from("rust-analyzer"), version: Some(rust_analyzer::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 4f6de68..8a1d5f3 100644 --- a/crates/rust-analyzer/src/cli/lsif.rs +++ b/crates/rust-analyzer/src/cli/lsif.rs
@@ -1,5 +1,4 @@ //! LSIF (language server index format) generator - use std::env; use std::time::Instant; @@ -10,12 +9,14 @@ }; 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}, @@ -38,9 +39,9 @@ #[derive(Clone, Copy)] struct Id(i32); -impl From<Id> for lsp_types::NumberOrString { +impl From<Id> for lsp_types::Code { fn from(Id(it): Id) -> Self { - lsp_types::NumberOrString::Number(it) + lsp_types::Code::Int(it) } } @@ -145,7 +146,7 @@ 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::Url::from_file_path(path).unwrap(), + uri: lsp_types::Uri::from_file_path(path).unwrap(), })); self.file_map.insert(id, doc_id); doc_id @@ -156,7 +157,7 @@ if let Some(hover) = token.hover { let hover_id = self.add_vertex(lsif::Vertex::HoverResult { result: lsp_types::Hover { - contents: lsp_types::HoverContents::Markup(to_proto::markup_content( + contents: lsp_types::Contents::MarkupContent(to_proto::markup_content( hover.markup, ide::HoverDocFormat::Markdown, )), @@ -211,7 +212,7 @@ out_v: result_set_id.into(), })); let mut edges = token.references.iter().fold( - FxHashMap::<_, Vec<lsp_types::NumberOrString>>::default(), + FxHashMap::<_, Vec<lsp_types::Code>>::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()); @@ -321,9 +322,9 @@ 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::Url::from_file_path(path).unwrap(), + project_root: lsp_types::Uri::from_file_path(path).unwrap(), position_encoding: lsif::Encoding::Utf16, - tool_info: Some(lsp_types::lsif::ToolInfo { + tool_info: Some(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 new file mode 100644 index 0000000..cad2514 --- /dev/null +++ b/crates/rust-analyzer/src/cli/lsif/vendored.rs
@@ -0,0 +1,338 @@ +//! 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 4ea4473..64411bf 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs
@@ -1127,7 +1127,7 @@ default_config: &'static DefaultConfigData, /// Config node that obtains its initial value during the server initialization and - /// by receiving a `lsp_types::notification::DidChangeConfiguration`. + /// by receiving a [`lsp_types::DidChangeConfigurationNotification`]. 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 8d0f524..889d20a 100644 --- a/crates/rust-analyzer/src/diagnostics.rs +++ b/crates/rust-analyzer/src/diagnostics.rs
@@ -357,14 +357,14 @@ 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::NumberOrString::String(d.code.as_str().to_owned())), + code: Some(lsp_types::Code::String(d.code.as_str().to_owned())), code_description: Some(lsp_types::CodeDescription { - href: lsp_types::Url::parse(&d.code.url()).unwrap(), + href: lsp_types::Uri::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 a6d7bcb..8568f47 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 @@ 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 @@ 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 @@ 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 @@ return MappedRustChildDiagnostic::MessageLine(rd.message.clone()); } - let mut edit_map: FxHashMap<lsp_types::Url, Vec<lsp_types::TextEdit>> = FxHashMap::default(); + let mut edit_map: FxHashMap<lsp_types::Uri, 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 @@ 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 @@ #[derive(Debug)] pub(crate) struct MappedRustDiagnostic { - pub(crate) url: lsp_types::Url, + pub(crate) url: lsp_types::Uri, pub(crate) diagnostic: lsp_types::Diagnostic, pub(crate) fix: Option<Box<Fix>>, } @@ -351,10 +351,10 @@ 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 @@ 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::NumberOrString::String), + severity: Some(lsp_types::DiagnosticSeverity::Hint), + code: code.map(ToOwned::to_owned).map(lsp_types::Code::String), code_description: code_description.clone(), source: Some(source.to_owned()), message: message.clone(), related_information: Some(information_for_additional_diagnostic), - tags: tag.clone().map(|tag| vec![tag]), + tags: tag.map(|tag| vec![tag]), data: Some(serde_json::json!({ "rendered": rendered })), }; diagnostics.push(MappedRustDiagnostic { @@ -440,7 +440,7 @@ diagnostic: lsp_types::Diagnostic { range: primary_location.range, severity, - code: code.map(ToOwned::to_owned).map(lsp_types::NumberOrString::String), + code: code.map(ToOwned::to_owned).map(lsp_types::Code::String), code_description: code_description.clone(), source: Some(source.to_owned()), message, @@ -452,7 +452,7 @@ .collect::<Vec<_>>(); if info.is_empty() { None } else { Some(info) } }, - tags: tag.clone().map(|tag| vec![tag]), + tags: tag.map(|tag| vec![tag]), data: Some(serde_json::json!({ "rendered": rendered })), }, fix: None, @@ -471,8 +471,8 @@ 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::NumberOrString::String), + severity: Some(lsp_types::DiagnosticSeverity::Hint), + code: code.map(ToOwned::to_owned).map(lsp_types::Code::String), code_description: code_description.clone(), source: Some(source.to_owned()), message: sub.related.message.clone(), @@ -494,7 +494,7 @@ && chars.next().is_none() }) .and_then(|code| { - lsp_types::Url::parse(&format!("https://doc.rust-lang.org/error-index.html#{code}")) + lsp_types::Uri::parse(&format!("https://doc.rust-lang.org/error-index.html#{code}")) .ok() .map(|href| lsp_types::CodeDescription { href }) }) @@ -502,7 +502,7 @@ fn clippy_code_description(code: Option<&str>) -> Option<lsp_types::CodeDescription> { code.and_then(|code| { - lsp_types::Url::parse(&format!( + lsp_types::Uri::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 c3b540e..71f9987 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,6 +55,7 @@ "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 { @@ -111,7 +112,6 @@ }, ], ), - tags: None, data: None, }, fix: None, @@ -172,6 +172,7 @@ "clippy", ), message: "lint level defined here", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -202,7 +203,6 @@ }, ], ), - tags: None, data: None, }, fix: None, @@ -263,6 +263,7 @@ "clippy", ), message: "consider passing by value instead: `self`", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -293,7 +294,6 @@ }, ], ), - 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 989e5cf..bd1abfe 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}`", - related_information: None, tags: None, + related_information: 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 b44569b..cc870c4 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,6 +31,7 @@ "rustc", ), message: "Please register your known path in the path module", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -61,7 +62,6 @@ }, ], ), - tags: None, data: None, }, fix: None, @@ -98,6 +98,7 @@ "rustc", ), message: "Please register your known path in the path module", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -128,7 +129,6 @@ }, ], ), - tags: None, data: None, }, fix: None, @@ -165,6 +165,7 @@ "rustc", ), message: "Please register your known path in the path module", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -221,7 +222,6 @@ }, ], ), - 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 df00b33..176d719 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`", - related_information: None, tags: None, + related_information: 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 dc36aa7..e78ac4b 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>>`", - related_information: None, tags: None, + related_information: 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 d557196..add343d 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", - related_information: None, tags: None, + related_information: 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 a100fa0..a510943 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,6 +55,7 @@ "rustc", ), message: "mismatched types\nexpected `u32`, found `&str`", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -85,7 +86,6 @@ }, ], ), - tags: None, data: None, }, fix: None, @@ -146,6 +146,7 @@ "rustc", ), message: "expected due to this", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -176,7 +177,6 @@ }, ], ), - 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 1c5c336..f5bf2dc 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,6 +35,11 @@ "rustc", ), message: "unused variable: `foo`\n#[warn(unused_variables)] on by default", + tags: Some( + [ + Unnecessary, + ], + ), related_information: Some( [ DiagnosticRelatedInformation { @@ -65,11 +70,6 @@ }, ], ), - tags: Some( - [ - Unnecessary, - ], - ), data: None, }, fix: None, @@ -110,6 +110,7 @@ "rustc", ), message: "consider prefixing with an underscore: `_foo`", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -140,7 +141,6 @@ }, ], ), - tags: None, data: None, }, fix: Some( @@ -161,9 +161,7 @@ title: "consider prefixing with an underscore: `_foo`", group: None, kind: Some( - CodeActionKind( - "quickfix", - ), + 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 3ab3412..5f4aa71 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,6 +35,11 @@ "rustc", ), message: "unused variable: `foo`\n#[warn(unused_variables)] on by default", + tags: Some( + [ + Unnecessary, + ], + ), related_information: Some( [ DiagnosticRelatedInformation { @@ -65,11 +70,6 @@ }, ], ), - tags: Some( - [ - Unnecessary, - ], - ), data: None, }, fix: None, @@ -110,6 +110,7 @@ "rustc", ), message: "consider prefixing with an underscore: `_foo`", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -140,7 +141,6 @@ }, ], ), - tags: None, data: None, }, fix: Some( @@ -161,9 +161,7 @@ title: "consider prefixing with an underscore: `_foo`", group: None, kind: Some( - CodeActionKind( - "quickfix", - ), + 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 0702420..26adf53 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,6 +35,11 @@ "rustc", ), message: "unused variable: `foo`\n#[warn(unused_variables)] on by default", + tags: Some( + [ + Unnecessary, + ], + ), related_information: Some( [ DiagnosticRelatedInformation { @@ -65,11 +70,6 @@ }, ], ), - tags: Some( - [ - Unnecessary, - ], - ), data: None, }, fix: None, @@ -110,6 +110,7 @@ "rustc", ), message: "consider prefixing with an underscore: `_foo`", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -140,7 +141,6 @@ }, ], ), - tags: None, data: None, }, fix: Some( @@ -161,9 +161,7 @@ title: "consider prefixing with an underscore: `_foo`", group: None, kind: Some( - CodeActionKind( - "quickfix", - ), + 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 8ec9288..cd3c24f 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,6 +55,7 @@ "rustc", ), message: "this function takes 2 parameters but 3 parameters were supplied\nexpected 2 parameters", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -85,7 +86,6 @@ }, ], ), - tags: None, data: None, }, fix: None, @@ -146,6 +146,7 @@ "rustc", ), message: "defined here", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -176,7 +177,6 @@ }, ], ), - 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 4365e45..a977d14 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,6 +55,7 @@ "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 { @@ -111,7 +112,6 @@ }, ], ), - tags: None, data: None, }, fix: None, @@ -172,6 +172,7 @@ "clippy", ), message: "unnecessary let binding", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -202,7 +203,6 @@ }, ], ), - tags: None, data: None, }, fix: None, @@ -263,6 +263,7 @@ "clippy", ), message: "return the expression directly: `(0..10).collect()`", + tags: None, related_information: Some( [ DiagnosticRelatedInformation { @@ -293,7 +294,6 @@ }, ], ), - tags: None, data: None, }, fix: Some( @@ -324,9 +324,7 @@ title: "return the expression directly: `(0..10).collect()`", group: None, kind: Some( - CodeActionKind( - "quickfix", - ), + QuickFix, ), command: None, edit: Some(
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index f91e953..2d01aa4 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs
@@ -18,7 +18,7 @@ }; use itertools::Itertools; use load_cargo::SourceRootConfig; -use lsp_types::{SemanticTokens, Url}; +use lsp_types::{Notification, SemanticTokens, Uri}; use parking_lot::{ MappedRwLockReadGuard, Mutex, RwLock, RwLockReadGuard, RwLockUpgradableReadGuard, RwLockWriteGuard, @@ -97,7 +97,7 @@ 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<Url, SemanticTokens>>>, + pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Uri, SemanticTokens>>>, // status pub(crate) shutdown_requested: bool, @@ -209,7 +209,7 @@ pub(crate) analysis: Analysis, pub(crate) check_fixes: CheckFixes, mem_docs: MemDocs, - pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Url, SemanticTokens>>>, + pub(crate) semantic_tokens_cache: Arc<Mutex<FxHashMap<Uri, 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 @@ } } - pub(crate) fn send_request<R: lsp_types::request::Request>( + pub(crate) fn send_request<R: lsp_types::Request>( &mut self, params: R::Params, handler: ReqHandler, ) { - let request = self.req_queue.outgoing.register(R::METHOD.to_owned(), params, handler); + let request = self.req_queue.outgoing.register(R::METHOD.into(), params, handler); self.send(request.into()); } @@ -598,11 +598,8 @@ handler(self, response) } - 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); + pub(crate) fn send_notification<N: lsp_types::Notification>(&self, params: N::Params) { + let not = lsp_server::Notification::new(N::METHOD.into(), params); self.send(not.into()); } @@ -647,7 +644,7 @@ pub(crate) fn publish_diagnostics( &mut self, - uri: Url, + uri: Uri, version: Option<i32>, mut diagnostics: Vec<lsp_types::Diagnostic>, ) { @@ -680,7 +677,7 @@ } let not = lsp_server::Notification::new( - <lsp_types::notification::PublishDiagnostics as lsp_types::notification::Notification>::METHOD.to_owned(), + lsp_types::PublishDiagnosticsNotification::METHOD.into(), lsp_types::PublishDiagnosticsParams { uri, diagnostics, version }, ); _ = sender.send(not.into()); @@ -744,11 +741,11 @@ } /// Returns `None` if the file was excluded. - pub(crate) fn url_to_file_id(&self, url: &Url) -> anyhow::Result<Option<FileId>> { + pub(crate) fn url_to_file_id(&self, url: &Uri) -> anyhow::Result<Option<FileId>> { url_to_file_id(&self.vfs_read(), url) } - pub(crate) fn file_id_to_url(&self, id: FileId) -> Url { + pub(crate) fn file_id_to_url(&self, id: FileId) -> Uri { file_id_to_url(&self.vfs_read(), id) } @@ -768,12 +765,12 @@ Some(self.mem_docs.get(self.vfs_read().file_path(file_id))?.version) } - pub(crate) fn url_file_version(&self, url: &Url) -> Option<i32> { + pub(crate) fn url_file_version(&self, url: &Uri) -> 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) -> Url { + pub(crate) fn anchored_path(&self, path: &AnchoredPathBuf) -> Uri { let mut base = self.vfs_read().file_path(path.anchor).clone(); base.pop(); let path = base.join(&path.path).unwrap(); @@ -898,14 +895,14 @@ } } -pub(crate) fn file_id_to_url(vfs: &vfs::Vfs, id: FileId) -> Url { +pub(crate) fn file_id_to_url(vfs: &vfs::Vfs, id: FileId) -> Uri { 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: &Url) -> anyhow::Result<Option<FileId>> { +pub(crate) fn url_to_file_id(vfs: &vfs::Vfs, url: &Uri) -> 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 67bd643..82a2212 100644 --- a/crates/rust-analyzer/src/handlers/dispatch.rs +++ b/crates/rust-analyzer/src/handlers/dispatch.rs
@@ -47,7 +47,7 @@ f: fn(&mut GlobalState, R::Params) -> anyhow::Result<R::Result>, ) -> &mut Self where - R: lsp_types::request::Request, + R: lsp_types::Request, R::Params: DeserializeOwned + panic::UnwindSafe + fmt::Debug, R::Result: Serialize, { @@ -75,7 +75,7 @@ f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result<R::Result>, ) -> &mut Self where - R: lsp_types::request::Request, + R: lsp_types::Request, R::Params: DeserializeOwned + panic::UnwindSafe + fmt::Debug, R::Result: Serialize, { @@ -107,14 +107,14 @@ f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result<R::Result>, ) -> &mut Self where - R: lsp_types::request::Request< + R: lsp_types::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 == R::METHOD) + self.req.take_if(|it| it.method.as_str() == R::METHOD.as_str()) { self.global_state.respond(lsp_server::Response::new_ok(id, R::Result::default())); } @@ -136,14 +136,14 @@ on_cancelled: fn() -> ResponseError, ) -> &mut Self where - R: lsp_types::request::Request< + R: lsp_types::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 == R::METHOD) + self.req.take_if(|it| it.method.as_str() == R::METHOD.as_str()) { self.global_state.respond(lsp_server::Response::new_ok(id, default())); } @@ -159,7 +159,7 @@ f: fn(GlobalStateSnapshot, Params) -> anyhow::Result<R::Result>, ) -> &mut Self where - R: lsp_types::request::Request<Params = Params, Result = Params> + 'static, + R: lsp_types::Request<Params = Params, Result = Params> + 'static, Params: Serialize + DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug, { if !self.global_state.vfs_done { @@ -182,14 +182,14 @@ f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result<R::Result>, ) -> &mut Self where - R: lsp_types::request::Request< + R: lsp_types::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 == R::METHOD) + self.req.take_if(|it| it.method.as_str() == R::METHOD.as_str()) { self.global_state.respond(lsp_server::Response::new_ok(id, R::Result::default())); } @@ -210,7 +210,7 @@ f: fn(GlobalStateSnapshot, R::Params) -> anyhow::Result<R::Result>, ) -> &mut Self where - R: lsp_types::request::Request + 'static, + R: lsp_types::Request + 'static, R::Params: DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug, R::Result: Serialize, { @@ -240,7 +240,7 @@ on_cancelled: fn() -> ResponseError, ) -> &mut Self where - R: lsp_types::request::Request + 'static, + R: lsp_types::Request + 'static, R::Params: DeserializeOwned + panic::UnwindSafe + Send + fmt::Debug, R::Result: Serialize, { @@ -278,11 +278,11 @@ fn parse<R>(&mut self) -> Option<(lsp_server::Request, R::Params, String)> where - R: lsp_types::request::Request, + R: lsp_types::Request, R::Params: DeserializeOwned + fmt::Debug, { - let req = self.req.take_if(|it| it.method == R::METHOD)?; - let res = crate::from_json(R::METHOD, &req.params); + 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); match res { Ok(params) => { let panic_context = @@ -334,7 +334,7 @@ result: thread::Result<anyhow::Result<R::Result>>, ) -> Result<lsp_server::Response, HandlerCancelledError> where - R: lsp_types::request::Request, + R: lsp_types::Request, R::Params: DeserializeOwned, R::Result: Serialize, { @@ -369,7 +369,7 @@ result: anyhow::Result<R::Result>, ) -> Result<lsp_server::Response, HandlerCancelledError> where - R: lsp_types::request::Request, + R: lsp_types::Request, R::Params: DeserializeOwned, R::Result: Serialize, { @@ -401,7 +401,7 @@ f: fn(&mut GlobalState, N::Params) -> anyhow::Result<()>, ) -> &mut Self where - N: lsp_types::notification::Notification, + N: lsp_types::Notification, N::Params: DeserializeOwned + Send + Debug, { let not = match self.not.take() { @@ -411,7 +411,7 @@ let _guard = tracing::info_span!("notification", method = ?not.method).entered(); - let params = match not.extract::<N::Params>(N::METHOD) { + let params = match not.extract::<N::Params>(N::METHOD.as_str()) { 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 09b6794..d392c1e 100644 --- a/crates/rust-analyzer/src/handlers/notification.rs +++ b/crates/rust-analyzer/src/handlers/notification.rs
@@ -30,8 +30,8 @@ pub(crate) fn handle_cancel(state: &mut GlobalState, params: CancelParams) -> anyhow::Result<()> { let id: lsp_server::RequestId = match params.id { - lsp_types::NumberOrString::Number(id) => id.into(), - lsp_types::NumberOrString::String(id) => id.into(), + lsp_types::Id::Int(id) => id.into(), + lsp_types::Id::String(id) => id.into(), }; state.cancel(id); Ok(()) @@ -41,7 +41,7 @@ state: &mut GlobalState, params: WorkDoneProgressCancelParams, ) -> anyhow::Result<()> { - if let lsp_types::NumberOrString::String(s) = ¶ms.token + if let lsp_types::ProgressToken::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 @@ ) -> anyhow::Result<()> { let _p = tracing::info_span!("handle_did_change_text_document").entered(); - if let Ok(path) = from_proto::vfs_path(¶ms.text_document.uri) { + if let Ok(path) = from_proto::vfs_path(¶ms.text_document.text_document_identifier.uri) { let Some(DocumentData { version, data }) = state.mem_docs.get_mut(&path) else { tracing::error!(?path, "unexpected DidChangeTextDocument"); return Ok(()); @@ -215,7 +215,7 @@ ) -> 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::request::WorkspaceConfiguration>( + state.send_request::<lsp_types::ConfigurationRequest>( lsp_types::ConfigurationParams { items: vec![lsp_types::ConfigurationItem { scope_uri: None, @@ -553,7 +553,7 @@ 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::EndRunTest>(()); + state.send_notification::<lsp_ext::EndRunTestNotification>(()); } Ok(()) }
diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs index cf85db3..9710a19 100644 --- a/crates/rust-analyzer/src/handlers/request.rs +++ b/crates/rust-analyzer/src/handlers/request.rs
@@ -18,11 +18,11 @@ use lsp_types::{ CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem, CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams, - 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, + 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, }; use paths::Utf8PathBuf; use project_model::{CargoWorkspace, ManifestPath, ProjectWorkspaceKind, TargetKind}; @@ -172,7 +172,7 @@ 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, params)?); + let position = try_default!(from_proto::file_position(&snap, ¶ms)?); let res = snap.analysis.view_hir(position)?; Ok(res) } @@ -182,7 +182,7 @@ 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, params)?); + let position = try_default!(from_proto::file_position(&snap, ¶ms)?); let res = snap.analysis.view_mir(position)?; Ok(res) } @@ -192,7 +192,7 @@ 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, params)?); + let position = try_default!(from_proto::file_position(&snap, ¶ms)?); let res = snap.analysis.interpret_function(position)?; Ok(res) } @@ -252,7 +252,7 @@ params: lsp_ext::RunTestParams, ) -> anyhow::Result<()> { if let Some(_session) = state.test_run_session.take() { - state.send_notification::<lsp_ext::EndRunTest>(()); + state.send_notification::<lsp_ext::EndRunTestNotification>(()); } let mut handles = vec![]; @@ -358,9 +358,9 @@ let line_index = snap.file_line_index(file_id)?; let res: anyhow::Result<Vec<lsp_types::SelectionRange>> = params .positions - .into_iter() + .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 @@ let line_index = snap.file_line_index(file_id)?; params .positions - .into_iter() + .iter() .map(|position| { - let offset = from_proto::offset(&line_index, position); + let offset = from_proto::offset(&line_index, *position); offset.map(|offset| { let offset = match snap.analysis.matching_brace(FilePosition { file_id, offset }) { Ok(Some(matching_brace_offset)) => matching_brace_offset, @@ -445,7 +445,7 @@ 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, params)?); + let position = try_default!(from_proto::file_position(&snap, ¶ms)?); let edit = match snap.analysis.on_enter(position)? { None => return Ok(None), Some(it) => it, @@ -469,9 +469,11 @@ if !snap.config.typing_trigger_chars().contains(char_typed) { return Ok(None); } - - let mut position = - try_default!(from_proto::file_position(&snap, params.text_document_position)?); + 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 line_index = snap.file_line_index(position.file_id)?; // in `ide`, the `on_type` invariant is that @@ -502,8 +504,8 @@ Ok(Some(change)) } -pub(crate) fn empty_diagnostic_report() -> lsp_types::DocumentDiagnosticReportResult { - lsp_types::DocumentDiagnosticReportResult::Report(lsp_types::DocumentDiagnosticReport::Full( +pub(crate) fn empty_diagnostic_report() -> lsp_types::DocumentDiagnosticReport { + lsp_types::DocumentDiagnosticReport::RelatedFullDocumentDiagnosticReport( lsp_types::RelatedFullDocumentDiagnosticReport { related_documents: None, full_document_diagnostic_report: lsp_types::FullDocumentDiagnosticReport { @@ -511,13 +513,13 @@ items: vec![], }, }, - )) + ) } pub(crate) fn handle_document_diagnostics( snap: GlobalStateSnapshot, params: lsp_types::DocumentDiagnosticParams, -) -> anyhow::Result<lsp_types::DocumentDiagnosticReportResult> { +) -> anyhow::Result<lsp_types::DocumentDiagnosticReport> { let file_id = match from_proto::file_id(&snap, ¶ms.text_document.uri)? { Some(it) => it, None => return Ok(empty_diagnostic_report()), @@ -554,8 +556,8 @@ } None }); - Ok(lsp_types::DocumentDiagnosticReportResult::Report( - lsp_types::DocumentDiagnosticReport::Full(lsp_types::RelatedFullDocumentDiagnosticReport { + Ok(lsp_types::DocumentDiagnosticReport::RelatedFullDocumentDiagnosticReport( + lsp_types::RelatedFullDocumentDiagnosticReport { full_document_diagnostic_report: lsp_types::FullDocumentDiagnosticReport { result_id: Some("rust-analyzer".to_owned()), items: diagnostics.collect(), @@ -566,7 +568,7 @@ .map(|(id, (items, _))| { ( to_proto::url(&snap, id), - lsp_types::DocumentDiagnosticReportKind::Full( + lsp_types::RelatedDocument::FullDocumentDiagnosticReport( lsp_types::FullDocumentDiagnosticReport { result_id: Some("rust-analyzer".to_owned()), items, @@ -576,7 +578,7 @@ }) .collect() }), - }), + }, )) } @@ -600,7 +602,7 @@ for node in structure_nodes { let mut tags = Vec::new(); if node.deprecated { - tags.push(SymbolTag::DEPRECATED) + tags.push(SymbolTag::Deprecated) }; #[allow(deprecated)] @@ -649,17 +651,19 @@ fn flatten_document_symbol( symbol: &lsp_types::DocumentSymbol, container_name: Option<String>, - url: &Url, + url: &Uri, 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), - container_name, + base_symbol_information: lsp_types::BaseSymbolInformation { + name: symbol.name.clone(), + kind: symbol.kind, + tags: symbol.tags.clone(), + container_name, + }, }); for child in symbol.children.iter().flatten() { @@ -696,7 +700,7 @@ res = exec_query(&snap, Query::new(params.query), config.search_limit)?; } - return Ok(Some(lsp_types::WorkspaceSymbolResponse::Nested(res))); + return Ok(Some(lsp_types::WorkspaceSymbolResponse::WorkspaceSymbolList(res))); fn decide_search_kind_and_scope( params: &WorkspaceSymbolParams, @@ -743,19 +747,23 @@ let container_name = nav.container_name.as_ref().map(|v| v.to_string()); let info = lsp_types::WorkspaceSymbol { - 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)?), + 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, + }, }; res.push(info); } @@ -773,8 +781,8 @@ .files .into_iter() .filter_map(|file_rename| { - let from = Url::parse(&file_rename.old_uri).ok()?; - let to = Url::parse(&file_rename.new_uri).ok()?; + let from = Uri::parse(&file_rename.old_uri).ok()?; + let to = Uri::parse(&file_rename.new_uri).ok()?; let from_path = from.to_file_path().ok()?; let to_path = to.to_file_path().ok()?; @@ -831,11 +839,11 @@ pub(crate) fn handle_goto_definition( snap: GlobalStateSnapshot, - params: lsp_types::GotoDefinitionParams, -) -> anyhow::Result<Option<lsp_types::GotoDefinitionResponse>> { + params: lsp_types::DefinitionParams, +) -> anyhow::Result<Option<lsp_types::DefinitionResponse>> { let _p = tracing::info_span!("handle_goto_definition").entered(); let position = - try_default!(from_proto::file_position(&snap, params.text_document_position_params)?); + try_default!(from_proto::file_position(&snap, ¶ms.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), @@ -848,60 +856,84 @@ pub(crate) fn handle_goto_declaration( snap: GlobalStateSnapshot, - params: lsp_types::request::GotoDeclarationParams, -) -> anyhow::Result<Option<lsp_types::request::GotoDeclarationResponse>> { + params: lsp_types::DeclarationParams, +) -> anyhow::Result<Option<lsp_types::DeclarationResponse>> { let _p = tracing::info_span!("handle_goto_declaration").entered(); - let position = try_default!(from_proto::file_position( - &snap, - params.text_document_position_params.clone() - )?); + let position = + try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); let config = snap.config.goto_definition(snap.minicore()); let nav_info = match snap.analysis.goto_declaration(position, &config)? { - None => return handle_goto_definition(snap, params), + 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), + }; + } Some(it) => it, }; let src = FileRange { file_id: position.file_id, range: nav_info.range }; - let res = to_proto::goto_definition_response(&snap, Some(src), nav_info.info)?; + let res = to_proto::goto_declaration_response(&snap, Some(src), nav_info.info)?; Ok(Some(res)) } pub(crate) fn handle_goto_implementation( snap: GlobalStateSnapshot, - params: lsp_types::request::GotoImplementationParams, -) -> anyhow::Result<Option<lsp_types::request::GotoImplementationResponse>> { + params: lsp_types::ImplementationParams, +) -> anyhow::Result<Option<lsp_types::ImplementationResponse>> { let _p = tracing::info_span!("handle_goto_implementation").entered(); let position = - try_default!(from_proto::file_position(&snap, params.text_document_position_params)?); + try_default!(from_proto::file_position(&snap, ¶ms.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_definition_response(&snap, Some(src), nav_info.info)?; + let res = to_proto::goto_implementation_response(&snap, Some(src), nav_info.info)?; Ok(Some(res)) } pub(crate) fn handle_goto_type_definition( snap: GlobalStateSnapshot, - params: lsp_types::request::GotoTypeDefinitionParams, -) -> anyhow::Result<Option<lsp_types::request::GotoTypeDefinitionResponse>> { + params: lsp_types::TypeDefinitionParams, +) -> anyhow::Result<Option<lsp_types::TypeDefinitionResponse>> { let _p = tracing::info_span!("handle_goto_type_definition").entered(); let position = - try_default!(from_proto::file_position(&snap, params.text_document_position_params)?); + try_default!(from_proto::file_position(&snap, ¶ms.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_definition_response(&snap, Some(src), nav_info.info)?; + let res = to_proto::goto_type_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::GotoDefinitionResponse>> { +) -> anyhow::Result<Option<lsp_types::DefinitionResponse>> { 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" { @@ -965,7 +997,7 @@ } // locate parent module by semantics - let position = try_default!(from_proto::file_position(&snap, params)?); + let position = try_default!(from_proto::file_position(&snap, ¶ms)?); let navs = snap.analysis.parent_module(position)?; let res = to_proto::goto_definition_response(&snap, None, navs)?; Ok(Some(res)) @@ -974,10 +1006,10 @@ pub(crate) fn handle_child_modules( snap: GlobalStateSnapshot, params: lsp_types::TextDocumentPositionParams, -) -> anyhow::Result<Option<lsp_types::GotoDefinitionResponse>> { +) -> anyhow::Result<Option<lsp_types::DefinitionResponse>> { let _p = tracing::info_span!("handle_child_modules").entered(); // locate child module by semantics - let position = try_default!(from_proto::file_position(&snap, params)?); + let position = try_default!(from_proto::file_position(&snap, ¶ms)?); let navs = snap.analysis.child_modules(position)?; let res = to_proto::goto_definition_response(&snap, None, navs)?; Ok(Some(res)) @@ -1103,7 +1135,7 @@ 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, params)?); + let position = try_default!(from_proto::file_position(&snap, ¶ms)?); let tests = snap.analysis.related_tests(position, None)?; let mut res = Vec::new(); @@ -1119,14 +1151,14 @@ pub(crate) fn handle_completion( snap: GlobalStateSnapshot, lsp_types::CompletionParams { - text_document_position, + text_document_position_params, 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.clone())?); + try_default!(from_proto::file_position(&snap, &text_document_position_params)?); 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()); @@ -1149,12 +1181,17 @@ &completion_config.fields_to_resolve, &line_index, snap.file_version(position.file_id), - text_document_position, + &text_document_position_params, completion_trigger_character, items, ); - let completion_list = lsp_types::CompletionList { is_incomplete: true, items }; + let completion_list = lsp_types::CompletionList { + is_incomplete: true, + items, + item_defaults: None, + apply_kind: None, + }; Ok(Some(completion_list.into())) } @@ -1217,7 +1254,7 @@ &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], ); @@ -1287,7 +1324,7 @@ ) -> anyhow::Result<Option<lsp_types::SignatureHelp>> { let _p = tracing::info_span!("handle_signature_help").entered(); let position = - try_default!(from_proto::file_position(&snap, params.text_document_position_params)?); + try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); let help = match snap.analysis.signature_help(position)? { Some(it) => it, None => return Ok(None), @@ -1319,7 +1356,7 @@ let markup_kind = hover.format; let hover = lsp_ext::Hover { hover: lsp_types::Hover { - contents: HoverContents::Markup(to_proto::markup_content( + contents: Contents::MarkupContent(to_proto::markup_content( info.info.markup, markup_kind, )), @@ -1337,16 +1374,17 @@ pub(crate) fn handle_prepare_rename( snap: GlobalStateSnapshot, - params: lsp_types::TextDocumentPositionParams, -) -> anyhow::Result<Option<PrepareRenameResponse>> { + params: lsp_types::PrepareRenameParams, +) -> anyhow::Result<Option<PrepareRenameResult>> { let _p = tracing::info_span!("handle_prepare_rename").entered(); - let position = try_default!(from_proto::file_position(&snap, params)?); + let position = + try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_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(PrepareRenameResponse::Range(range))) + Ok(Some(PrepareRenameResult::Range(range))) } pub(crate) fn handle_rename( @@ -1354,7 +1392,8 @@ params: RenameParams, ) -> anyhow::Result<Option<WorkspaceEdit>> { let _p = tracing::info_span!("handle_rename").entered(); - let position = try_default!(from_proto::file_position(&snap, params.text_document_position)?); + let position = + try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); let source_root = snap.analysis.source_root_id(position.file_id).ok(); let config = snap.config.rename(source_root); @@ -1375,13 +1414,9 @@ let workspace_edit = to_proto::workspace_edit(&snap, 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))? - } + if let Some(changes) = workspace_edit.document_changes.as_ref() { + for change in changes { + resource_ops_supported(&snap.config, change)?; } } @@ -1393,7 +1428,8 @@ 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, params.text_document_position)?); + let position = + try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); let exclude_imports = snap.config.find_all_refs_exclude_imports(); let exclude_tests = snap.config.find_all_refs_exclude_tests(); @@ -1442,7 +1478,7 @@ ) -> anyhow::Result<Option<Vec<lsp_types::TextEdit>>> { let _p = tracing::info_span!("handle_formatting").entered(); - run_rustfmt(&snap, params.text_document, None) + run_rustfmt(&snap, ¶ms.text_document, None) } pub(crate) fn handle_range_formatting( @@ -1451,7 +1487,7 @@ ) -> anyhow::Result<Option<Vec<lsp_types::TextEdit>>> { let _p = tracing::info_span!("handle_range_formatting").entered(); - run_rustfmt(&snap, params.text_document, Some(params.range)) + run_rustfmt(&snap, ¶ms.text_document, Some(params.range)) } pub(crate) fn handle_code_action( @@ -1506,8 +1542,8 @@ 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::Op(res_op) = change { - resource_ops_supported(&snap.config, resolve_resource_op(res_op))? + if let lsp_ext::SnippetDocumentChangeOperation::Change(change) = change { + resource_ops_supported(&snap.config, change)? } } } @@ -1609,8 +1645,8 @@ && let Some(changes) = edit.document_changes.as_ref() { for change in changes { - if let lsp_ext::SnippetDocumentChangeOperation::Op(res_op) = change { - resource_ops_supported(&snap.config, resolve_resource_op(res_op))? + if let lsp_ext::SnippetDocumentChangeOperation::Change(change) = change { + resource_ops_supported(&snap.config, change)? } } } @@ -1717,7 +1753,7 @@ ) -> 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, params.text_document_position_params)?); + try_default!(from_proto::file_position(&snap, ¶ms.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)?; @@ -1750,7 +1786,7 @@ .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, params.position)?); + let position = try_default!(from_proto::file_position(&snap, ¶ms.position)?); let source_change = snap.analysis.structural_search_replace( ¶ms.query, params.parse_only, @@ -1855,7 +1891,7 @@ ) -> anyhow::Result<Option<Vec<CallHierarchyItem>>> { let _p = tracing::info_span!("handle_call_hierarchy_prepare").entered(); let position = - try_default!(from_proto::file_position(&snap, params.text_document_position_params)?); + try_default!(from_proto::file_position(&snap, ¶ms.text_document_position_params)?); let config = snap.config.call_hierarchy(snap.minicore()); let nav_info = match snap.analysis.call_hierarchy(position, &config)? { @@ -1890,25 +1926,26 @@ Some(it) => it, }; - 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)) + 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<_>>()?, + )) } pub(crate) fn handle_call_hierarchy_outgoing( @@ -1951,7 +1988,7 @@ pub(crate) fn handle_semantic_tokens_full( snap: GlobalStateSnapshot, params: SemanticTokensParams, -) -> anyhow::Result<Option<SemanticTokensResult>> { +) -> anyhow::Result<Option<SemanticTokens>> { let _p = tracing::info_span!("handle_semantic_tokens_full").entered(); let file_id = try_default!(from_proto::file_id(&snap, ¶ms.text_document.uri)?); @@ -1975,13 +2012,13 @@ // Unconditionally cache the tokens snap.semantic_tokens_cache.lock().insert(params.text_document.uri, semantic_tokens.clone()); - Ok(Some(semantic_tokens.into())) + Ok(Some(semantic_tokens)) } pub(crate) fn handle_semantic_tokens_full_delta( snap: GlobalStateSnapshot, params: SemanticTokensDeltaParams, -) -> anyhow::Result<Option<SemanticTokensFullDeltaResult>> { +) -> anyhow::Result<Option<SemanticTokensDeltaResponse>> { 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)?); @@ -2023,7 +2060,7 @@ pub(crate) fn handle_semantic_tokens_range( snap: GlobalStateSnapshot, params: SemanticTokensRangeParams, -) -> anyhow::Result<Option<SemanticTokensRangeResult>> { +) -> anyhow::Result<Option<SemanticTokens>> { let _p = tracing::info_span!("handle_semantic_tokens_range").entered(); let frange = try_default!(from_proto::file_range(&snap, ¶ms.text_document, params.range)?); @@ -2043,7 +2080,7 @@ snap.config.semantics_tokens_augments_syntax_tokens(), snap.config.highlighting_non_standard_tokens(), ); - Ok(Some(semantic_tokens.into())) + Ok(Some(semantic_tokens)) } pub(crate) fn handle_open_docs( @@ -2051,7 +2088,7 @@ 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, params)?); + let position = try_default!(from_proto::file_position(&snap, ¶ms)?); let ws_and_sysroot = snap.workspaces.iter().find_map(|ws| match &ws.kind { ProjectWorkspaceKind::Cargo { cargo, .. } @@ -2078,8 +2115,8 @@ }; }; - 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()); + 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()); if snap.config.local_docs() { Ok(ExternalDocsResponse::WithLocal(ExternalDocsPair { web, local })) @@ -2091,7 +2128,7 @@ pub(crate) fn handle_open_cargo_toml( snap: GlobalStateSnapshot, params: lsp_ext::OpenCargoTomlParams, -) -> anyhow::Result<Option<lsp_types::GotoDefinitionResponse>> { +) -> anyhow::Result<Option<lsp_types::DefinitionResponse>> { let _p = tracing::info_span!("handle_open_cargo_toml").entered(); let file_id = try_default!(from_proto::file_id(&snap, ¶ms.text_document.uri)?); @@ -2101,8 +2138,9 @@ }; let cargo_toml_url = to_proto::url_from_abs_path(&cargo_spec.cargo_toml); - let res: lsp_types::GotoDefinitionResponse = - Location::new(cargo_toml_url, Range::default()).into(); + let res = lsp_types::DefinitionResponse::Definition(lsp_types::Definition::Location( + Location::new(cargo_toml_url, Range::default()), + )); Ok(Some(res)) } @@ -2184,7 +2222,7 @@ 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); @@ -2359,7 +2397,7 @@ 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)?); @@ -2425,7 +2463,7 @@ .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; @@ -2656,20 +2694,26 @@ None } -fn to_url(path: VfsPath) -> Option<Url> { +fn to_url(path: VfsPath) -> Option<Uri> { let path = path.as_path()?; let str_path = path.as_os_str().to_str()?; - Url::from_file_path(str_path).ok() + Uri::from_file_path(str_path).ok() } -fn resource_ops_supported(config: &Config, kind: ResourceOperationKind) -> anyhow::Result<()> { - if !matches!(config.workspace_edit_resource_operations(), Some(resops) if resops.contains(&kind)) +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)) { return Err(LspError::new( ErrorCode::RequestFailed as i32, format!( "Client does not support {} capability.", - match kind { + match op { ResourceOperationKind::Create => "create", ResourceOperationKind::Rename => "rename", ResourceOperationKind::Delete => "delete", @@ -2682,14 +2726,6 @@ 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 4a37bb3..950592c 100644 --- a/crates/rust-analyzer/src/lib.rs +++ b/crates/rust-analyzer/src/lib.rs
@@ -60,6 +60,7 @@ pub mod config; mod global_state; pub mod lsp; + use self::lsp::ext as lsp_ext; #[cfg(test)] @@ -72,10 +73,7 @@ version::version, }; -pub fn from_json<T: DeserializeOwned>( - what: &'static str, - json: &serde_json::Value, -) -> anyhow::Result<T> { +pub fn from_json<T: DeserializeOwned>(what: &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 3ad4cb7..1f35079 100644 --- a/crates/rust-analyzer/src/lsp/capabilities.rs +++ b/crates/rust-analyzer/src/lsp/capabilities.rs
@@ -2,17 +2,18 @@ use ide::{CompletionFieldsToResolve, InlayFieldsToResolve}; use ide_db::{FxHashSet, line_index::WideEncoding}; use lsp_types::{ - 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, + 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, }; use serde_json::json; @@ -32,9 +33,9 @@ _ => None, }, }, - text_document_sync: Some(TextDocumentSyncCapability::Options(TextDocumentSyncOptions { + text_document_sync: Some(TextDocumentSync::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() { @@ -43,7 +44,9 @@ Some(SaveOptions::default().into()) }, })), - hover_provider: Some(HoverProviderCapability::Simple(true)), + notebook_document_sync: None, + selection_range_provider: Some(SelectionRangeProvider::Bool(true)), + hover_provider: Some(HoverProvider::Bool(true)), completion_provider: Some(CompletionOptions { resolve_provider: if config.client_is_neovim() { config.has_completion_item_resolve_additionalTextEdits().then_some(true) @@ -65,20 +68,24 @@ retrigger_characters: None, work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None }, }), - 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)), + 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)), code_action_provider: Some(config.caps().code_action_capabilities()), - code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }), - document_formatting_provider: Some(OneOf::Left(true)), + 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)), document_range_formatting_provider: match config.rustfmt(None) { - RustfmtConfig::Rustfmt { enable_range_formatting: true, .. } => Some(OneOf::Left(true)), - _ => Some(OneOf::Left(false)), + RustfmtConfig::Rustfmt { enable_range_formatting: true, .. } => { + Some(DocumentRangeFormattingProvider::Bool(true)) + } + _ => Some(DocumentRangeFormattingProvider::Bool(false)), }, document_on_type_formatting_provider: Some({ let mut chars = ide::Analysis::SUPPORTED_TRIGGER_CHARS.iter(); @@ -87,22 +94,21 @@ more_trigger_character: Some(chars.map(|c| c.to_string()).collect()), } }), - selection_range_provider: Some(SelectionRangeProviderCapability::Simple(true)), - folding_range_provider: Some(FoldingRangeProviderCapability::Simple(true)), - rename_provider: Some(OneOf::Right(RenameOptions { + rename_provider: Some(RenameProvider::RenameOptions(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(WorkspaceServerCapabilities { + workspace: Some(WorkspaceOptions { workspace_folders: Some(WorkspaceFoldersServerCapabilities { supported: Some(true), - change_notifications: Some(OneOf::Left(true)), + change_notifications: Some(ChangeNotifications::Bool(true)), }), - file_operations: Some(WorkspaceFileOperationsServerCapabilities { + file_operations: Some(FileOperationOptions { did_create: None, will_create: None, did_rename: None, @@ -129,29 +135,45 @@ did_delete: None, will_delete: None, }), + text_document_content: None, }), - call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)), + call_hierarchy_provider: Some(CallHierarchyProvider::Bool(true)), semantic_tokens_provider: Some( SemanticTokensOptions { legend: SemanticTokensLegend { - token_types: semantic_tokens::SUPPORTED_TYPES.to_vec(), - token_modifiers: semantic_tokens::SUPPORTED_MODIFIERS.to_vec(), + 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(), }, - full: Some(SemanticTokensFullOptions::Delta { delta: Some(true) }), - range: Some(true), + full: Some(Full::SemanticTokensFullDelta(lsp_types::SemanticTokensFullDelta { + delta: Some(true), + })), + range: Some(lsp_types::SemanticTokensOptionsRange::Bool(true)), work_done_progress_options: Default::default(), } .into(), ), moniker_provider: 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()), - }, - ))), + 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 }, + }, + )), + inline_completion_provider: None, experimental: Some(json!({ "externalDocs": true, "hoverRange": true, @@ -168,16 +190,7 @@ "ssr": true, "workspaceSymbolScopeKindFiltering": true, })), - 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, + type_hierarchy_provider: None, } } @@ -244,33 +257,34 @@ })() == Some(true) } - fn completion_item(&self) -> Option<CompletionOptionsCompletionItem> { - Some(CompletionOptionsCompletionItem { + fn completion_item(&self) -> Option<ServerCompletionItemOptions> { + Some(ServerCompletionItemOptions { label_details_support: Some(self.completion_label_details_support()), }) } - fn code_action_capabilities(&self) -> CodeActionProviderCapability { + fn code_action_capabilities(&self) -> CodeActionProvider { 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(CodeActionProviderCapability::Simple(true), |_| { - CodeActionProviderCapability::Options(CodeActionOptions { + .map_or(CodeActionProvider::Bool(true), |_| { + CodeActionProvider::CodeActionOptions(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::REFACTOR_EXTRACT, - CodeActionKind::REFACTOR_INLINE, - CodeActionKind::REFACTOR_REWRITE, + CodeActionKind::Empty, + CodeActionKind::QuickFix, + CodeActionKind::Refactor, + CodeActionKind::RefactorExtract, + CodeActionKind::RefactorInline, + CodeActionKind::RefactorRewrite, ]), resolve_provider: Some(true), work_done_progress_options: Default::default(), + documentation: None, }) }) } @@ -307,8 +321,8 @@ } pub fn did_save_text_document_dynamic_registration(&self) -> bool { - let caps = (|| -> _ { self.0.text_document.as_ref()?.synchronization.clone() })() - .unwrap_or_default(); + let caps = + (|| -> _ { self.0.text_document.as_ref()?.synchronization })().unwrap_or_default(); caps.did_save == Some(true) && caps.dynamic_registration == Some(true) } @@ -501,7 +515,7 @@ } pub fn diagnostics_refresh(&self) -> bool { - (|| -> _ { self.0.workspace.as_ref()?.diagnostic.as_ref()?.refresh_support })() + (|| -> _ { self.0.workspace.as_ref()?.diagnostics.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 4447158..3a1945c 100644 --- a/crates/rust-analyzer/src/lsp/ext.rs +++ b/crates/rust-analyzer/src/lsp/ext.rs
@@ -8,17 +8,16 @@ use std::ops; -use lsp_types::Url; -use lsp_types::request::Request; use lsp_types::{ - CodeActionKind, DocumentOnTypeFormattingParams, PartialResultParams, Position, Range, - TextDocumentIdentifier, WorkDoneProgressParams, notification::Notification, + CodeActionKind, DocumentOnTypeFormattingParams, LspNotificationMethod, LspRequestMethod, + MessageDirection, Notification, PartialResultParams, Position, Range, Request, + TextDocumentIdentifier, Uri, WorkDoneProgressParams, }; use paths::Utf8PathBuf; use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; -pub enum InternalTestingFetchConfig {} +pub enum InternalTestingFetchConfigRequest {} #[derive(Deserialize, Serialize, Debug)] pub enum InternalTestingFetchConfigOption { @@ -32,11 +31,13 @@ CheckWorkspace(bool), } -impl Request for InternalTestingFetchConfig { +impl Request for InternalTestingFetchConfigRequest { type Params = InternalTestingFetchConfigParams; // Option is solely to circumvent Default bound. type Result = Option<InternalTestingFetchConfigResponse>; - const METHOD: &'static str = "rust-analyzer-internal/internalTestingFetchConfig"; + const METHOD: LspRequestMethod = + LspRequestMethod::new("rust-analyzer-internal/internalTestingFetchConfig"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, Debug)] @@ -45,12 +46,13 @@ pub text_document: Option<TextDocumentIdentifier>, pub config: InternalTestingFetchConfigOption, } -pub enum AnalyzerStatus {} +pub enum AnalyzerStatusRequest {} -impl Request for AnalyzerStatus { +impl Request for AnalyzerStatusRequest { type Params = AnalyzerStatusParams; type Result = String; - const METHOD: &'static str = "rust-analyzer/analyzerStatus"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/analyzerStatus"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, Debug)] @@ -64,14 +66,15 @@ pub struct CrateInfoResult { pub name: Option<String>, pub version: Option<String>, - pub path: Url, + pub path: Uri, } -pub enum FetchDependencyList {} +pub enum FetchDependencyListRequest {} -impl Request for FetchDependencyList { +impl Request for FetchDependencyListRequest { type Params = FetchDependencyListParams; type Result = FetchDependencyListResult; - const METHOD: &'static str = "rust-analyzer/fetchDependencyList"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/fetchDependencyList"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, Debug)] @@ -84,36 +87,40 @@ pub crates: Vec<CrateInfoResult>, } -pub enum MemoryUsage {} +pub enum MemoryUsageRequest {} -impl Request for MemoryUsage { +impl Request for MemoryUsageRequest { type Params = (); type Result = String; - const METHOD: &'static str = "rust-analyzer/memoryUsage"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/memoryUsage"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum ReloadWorkspace {} +pub enum ReloadWorkspaceRequest {} -impl Request for ReloadWorkspace { +impl Request for ReloadWorkspaceRequest { type Params = (); type Result = (); - const METHOD: &'static str = "rust-analyzer/reloadWorkspace"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/reloadWorkspace"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum RebuildProcMacros {} +pub enum RebuildProcMacrosRequest {} -impl Request for RebuildProcMacros { +impl Request for RebuildProcMacrosRequest { type Params = (); type Result = (); - const METHOD: &'static str = "rust-analyzer/rebuildProcMacros"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/rebuildProcMacros"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum ViewSyntaxTree {} +pub enum ViewSyntaxTreeRequest {} -impl Request for ViewSyntaxTree { +impl Request for ViewSyntaxTreeRequest { type Params = ViewSyntaxTreeParams; type Result = String; - const METHOD: &'static str = "rust-analyzer/viewSyntaxTree"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/viewSyntaxTree"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, Debug)] @@ -122,36 +129,40 @@ pub text_document: TextDocumentIdentifier, } -pub enum ViewHir {} +pub enum ViewHirRequest {} -impl Request for ViewHir { +impl Request for ViewHirRequest { type Params = lsp_types::TextDocumentPositionParams; type Result = String; - const METHOD: &'static str = "rust-analyzer/viewHir"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/viewHir"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum ViewMir {} +pub enum ViewMirRequest {} -impl Request for ViewMir { +impl Request for ViewMirRequest { type Params = lsp_types::TextDocumentPositionParams; type Result = String; - const METHOD: &'static str = "rust-analyzer/viewMir"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/viewMir"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum InterpretFunction {} +pub enum InterpretFunctionRequest {} -impl Request for InterpretFunction { +impl Request for InterpretFunctionRequest { type Params = lsp_types::TextDocumentPositionParams; type Result = String; - const METHOD: &'static str = "rust-analyzer/interpretFunction"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/interpretFunction"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum ViewFileText {} +pub enum ViewFileTextRequest {} -impl Request for ViewFileText { +impl Request for ViewFileTextRequest { type Params = lsp_types::TextDocumentIdentifier; type Result = String; - const METHOD: &'static str = "rust-analyzer/viewFileText"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/viewFileText"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, Debug)] @@ -161,12 +172,13 @@ pub full: bool, } -pub enum ViewCrateGraph {} +pub enum ViewCrateGraphRequest {} -impl Request for ViewCrateGraph { +impl Request for ViewCrateGraphRequest { type Params = ViewCrateGraphParams; type Result = String; - const METHOD: &'static str = "rust-analyzer/viewCrateGraph"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/viewCrateGraph"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, Debug)] @@ -175,12 +187,13 @@ pub text_document: TextDocumentIdentifier, } -pub enum ViewItemTree {} +pub enum ViewItemTreeRequest {} -impl Request for ViewItemTree { +impl Request for ViewItemTreeRequest { type Params = ViewItemTreeParams; type Result = String; - const METHOD: &'static str = "rust-analyzer/viewItemTree"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/viewItemTree"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, Debug)] @@ -218,19 +231,22 @@ pub scope_file: Option<Vec<TextDocumentIdentifier>>, } -pub enum DiscoverTest {} +pub enum DiscoverTestRequest {} -impl Request for DiscoverTest { +impl Request for DiscoverTestRequest { type Params = DiscoverTestParams; type Result = DiscoverTestResults; - const METHOD: &'static str = "experimental/discoverTest"; + const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/discoverTest"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum DiscoveredTests {} +pub enum DiscoveredTestsNotification {} -impl Notification for DiscoveredTests { +impl Notification for DiscoveredTestsNotification { type Params = DiscoverTestResults; - const METHOD: &'static str = "experimental/discoveredTests"; + const METHOD: LspNotificationMethod = + LspNotificationMethod::new("experimental/discoveredTests"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, Debug)] @@ -240,33 +256,38 @@ pub exclude: Option<Vec<String>>, } -pub enum RunTest {} +pub enum RunTestRequest {} -impl Request for RunTest { +impl Request for RunTestRequest { type Params = RunTestParams; type Result = (); - const METHOD: &'static str = "experimental/runTest"; + const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/runTest"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum EndRunTest {} +pub enum EndRunTestNotification {} -impl Notification for EndRunTest { +impl Notification for EndRunTestNotification { type Params = (); - const METHOD: &'static str = "experimental/endRunTest"; + const METHOD: LspNotificationMethod = LspNotificationMethod::new("experimental/endRunTest"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum AppendOutputToRunTest {} +pub enum AppendOutputToRunTestNotification {} -impl Notification for AppendOutputToRunTest { +impl Notification for AppendOutputToRunTestNotification { type Params = String; - const METHOD: &'static str = "experimental/appendOutputToRunTest"; + const METHOD: LspNotificationMethod = + LspNotificationMethod::new("experimental/appendOutputToRunTest"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum AbortRunTest {} +pub enum AbortRunTestNotification {} -impl Notification for AbortRunTest { +impl Notification for AbortRunTestNotification { type Params = (); - const METHOD: &'static str = "experimental/abortRunTest"; + const METHOD: LspNotificationMethod = LspNotificationMethod::new("experimental/abortRunTest"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, Debug)] @@ -286,19 +307,22 @@ pub state: TestState, } -pub enum ChangeTestState {} +pub enum ChangeTestStateNotification {} -impl Notification for ChangeTestState { +impl Notification for ChangeTestStateNotification { type Params = ChangeTestStateParams; - const METHOD: &'static str = "experimental/changeTestState"; + const METHOD: LspNotificationMethod = + LspNotificationMethod::new("experimental/changeTestState"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum ExpandMacro {} +pub enum ExpandMacroRequest {} -impl Request for ExpandMacro { +impl Request for ExpandMacroRequest { type Params = ExpandMacroParams; type Result = Option<ExpandedMacro>; - const METHOD: &'static str = "rust-analyzer/expandMacro"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/expandMacro"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, Debug)] @@ -315,12 +339,14 @@ pub expansion: String, } -pub enum ViewRecursiveMemoryLayout {} +pub enum ViewRecursiveMemoryLayoutRequest {} -impl Request for ViewRecursiveMemoryLayout { +impl Request for ViewRecursiveMemoryLayoutRequest { type Params = lsp_types::TextDocumentPositionParams; type Result = Option<RecursiveMemoryLayout>; - const METHOD: &'static str = "rust-analyzer/viewRecursiveMemoryLayout"; + const METHOD: LspRequestMethod = + LspRequestMethod::new("rust-analyzer/viewRecursiveMemoryLayout"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, Debug)] @@ -342,32 +368,38 @@ pub children_len: u64, } -pub enum CancelFlycheck {} +pub enum CancelFlycheckNotification {} -impl Notification for CancelFlycheck { +impl Notification for CancelFlycheckNotification { type Params = (); - const METHOD: &'static str = "rust-analyzer/cancelFlycheck"; + const METHOD: LspNotificationMethod = + LspNotificationMethod::new("rust-analyzer/cancelFlycheck"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum RunFlycheck {} +pub enum RunFlycheckNotification {} -impl Notification for RunFlycheck { +impl Notification for RunFlycheckNotification { type Params = RunFlycheckParams; - const METHOD: &'static str = "rust-analyzer/runFlycheck"; + const METHOD: LspNotificationMethod = LspNotificationMethod::new("rust-analyzer/runFlycheck"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum ClearFlycheck {} +pub enum ClearFlycheckNotification {} -impl Notification for ClearFlycheck { +impl Notification for ClearFlycheckNotification { type Params = (); - const METHOD: &'static str = "rust-analyzer/clearFlycheck"; + const METHOD: LspNotificationMethod = LspNotificationMethod::new("rust-analyzer/clearFlycheck"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum OpenServerLogs {} +pub enum OpenServerLogsNotification {} -impl Notification for OpenServerLogs { +impl Notification for OpenServerLogsNotification { type Params = (); - const METHOD: &'static str = "rust-analyzer/openServerLogs"; + const METHOD: LspNotificationMethod = + LspNotificationMethod::new("rust-analyzer/openServerLogs"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, Debug)] @@ -376,12 +408,13 @@ pub text_document: Option<TextDocumentIdentifier>, } -pub enum MatchingBrace {} +pub enum MatchingBraceRequest {} -impl Request for MatchingBrace { +impl Request for MatchingBraceRequest { type Params = MatchingBraceParams; type Result = Vec<Position>; - const METHOD: &'static str = "experimental/matchingBrace"; + const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/matchingBrace"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, Debug)] @@ -391,28 +424,31 @@ pub positions: Vec<Position>, } -pub enum ParentModule {} +pub enum ParentModuleRequest {} -impl Request for ParentModule { +impl Request for ParentModuleRequest { type Params = lsp_types::TextDocumentPositionParams; - type Result = Option<lsp_types::GotoDefinitionResponse>; - const METHOD: &'static str = "experimental/parentModule"; + type Result = Option<lsp_types::DefinitionResponse>; + const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/parentModule"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum ChildModules {} +pub enum ChildModulesRequest {} -impl Request for ChildModules { +impl Request for ChildModulesRequest { type Params = lsp_types::TextDocumentPositionParams; - type Result = Option<lsp_types::GotoDefinitionResponse>; - const METHOD: &'static str = "experimental/childModules"; + type Result = Option<lsp_types::DefinitionResponse>; + const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/childModules"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum JoinLines {} +pub enum JoinLinesRequest {} -impl Request for JoinLines { +impl Request for JoinLinesRequest { type Params = JoinLinesParams; type Result = Vec<lsp_types::TextEdit>; - const METHOD: &'static str = "experimental/joinLines"; + const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/joinLines"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, Debug)] @@ -422,20 +458,22 @@ pub ranges: Vec<Range>, } -pub enum OnEnter {} +pub enum OnEnterRequest {} -impl Request for OnEnter { +impl Request for OnEnterRequest { type Params = lsp_types::TextDocumentPositionParams; type Result = Option<Vec<SnippetTextEdit>>; - const METHOD: &'static str = "experimental/onEnter"; + const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/onEnter"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum Runnables {} +pub enum RunnablesRequest {} -impl Request for Runnables { +impl Request for RunnablesRequest { type Params = RunnablesParams; type Result = Vec<Runnable>; - const METHOD: &'static str = "experimental/runnables"; + const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/runnables"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Serialize, Deserialize, Debug, Clone)] @@ -488,12 +526,13 @@ pub args: Vec<String>, } -pub enum RelatedTests {} +pub enum RelatedTestsRequest {} -impl Request for RelatedTests { +impl Request for RelatedTestsRequest { type Params = lsp_types::TextDocumentPositionParams; type Result = Vec<TestInfo>; - const METHOD: &'static str = "rust-analyzer/relatedTests"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/relatedTests"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Debug, Deserialize, Serialize)] @@ -501,12 +540,13 @@ pub runnable: Runnable, } -pub enum Ssr {} +pub enum SsrRequest {} -impl Request for Ssr { +impl Request for SsrRequest { type Params = SsrParams; type Result = lsp_types::WorkspaceEdit; - const METHOD: &'static str = "experimental/ssr"; + const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/ssr"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Debug, Deserialize, Serialize)] @@ -528,7 +568,8 @@ impl Notification for ServerStatusNotification { type Params = ServerStatusParams; - const METHOD: &'static str = "experimental/serverStatus"; + const METHOD: LspNotificationMethod = LspNotificationMethod::new("experimental/serverStatus"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Deserialize, Serialize, PartialEq, Eq, Clone)] @@ -562,7 +603,8 @@ impl Request for CodeActionRequest { type Params = lsp_types::CodeActionParams; type Result = Option<Vec<CodeAction>>; - const METHOD: &'static str = "textDocument/codeAction"; + const METHOD: LspRequestMethod = LspRequestMethod::new("textDocument/codeAction"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } pub enum CodeActionResolveRequest {} @@ -570,7 +612,8 @@ impl Request for CodeActionResolveRequest { type Params = CodeAction; type Result = CodeAction; - const METHOD: &'static str = "codeAction/resolve"; + const METHOD: LspRequestMethod = LspRequestMethod::new("codeAction/resolve"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Debug, PartialEq, Clone, Default, Deserialize, Serialize)] @@ -604,7 +647,7 @@ #[serde(rename_all = "camelCase")] pub struct SnippetWorkspaceEdit { #[serde(skip_serializing_if = "Option::is_none")] - pub changes: Option<FxHashMap<lsp_types::Url, Vec<lsp_types::TextEdit>>>, + pub changes: Option<FxHashMap<Uri, Vec<lsp_types::TextEdit>>>, #[serde(skip_serializing_if = "Option::is_none")] pub document_changes: Option<Vec<SnippetDocumentChangeOperation>>, #[serde(skip_serializing_if = "Option::is_none")] @@ -619,7 +662,7 @@ #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] #[serde(untagged, rename_all = "lowercase")] pub enum SnippetDocumentChangeOperation { - Op(lsp_types::ResourceOp), + Change(lsp_types::DocumentChange), Edit(SnippetTextDocumentEdit), } @@ -647,7 +690,8 @@ impl Request for HoverRequest { type Params = HoverParams; type Result = Option<Hover>; - const METHOD: &'static str = lsp_types::request::HoverRequest::METHOD; + const METHOD: LspRequestMethod = lsp_types::HoverRequest::METHOD; + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize)] @@ -691,18 +735,19 @@ pub tooltip: Option<String>, } -pub enum ExternalDocs {} +pub enum ExternalDocsRequest {} -impl Request for ExternalDocs { +impl Request for ExternalDocsRequest { type Params = lsp_types::TextDocumentPositionParams; type Result = ExternalDocsResponse; - const METHOD: &'static str = "experimental/externalDocs"; + const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/externalDocs"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] #[serde(untagged)] pub enum ExternalDocsResponse { - Simple(Option<lsp_types::Url>), + Simple(Option<lsp_types::Uri>), WithLocal(ExternalDocsPair), } @@ -715,16 +760,17 @@ #[derive(Debug, Default, PartialEq, Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] pub struct ExternalDocsPair { - pub web: Option<lsp_types::Url>, - pub local: Option<lsp_types::Url>, + pub web: Option<lsp_types::Uri>, + pub local: Option<lsp_types::Uri>, } -pub enum OpenCargoToml {} +pub enum OpenCargoTomlRequest {} -impl Request for OpenCargoToml { +impl Request for OpenCargoTomlRequest { type Params = OpenCargoTomlParams; - type Result = Option<lsp_types::GotoDefinitionResponse>; - const METHOD: &'static str = "experimental/openCargoToml"; + type Result = Option<lsp_types::DefinitionResponse>; + const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/openCargoToml"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Serialize, Deserialize, Debug)] @@ -744,16 +790,17 @@ #[derive(Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub enum CodeLensResolveDataKind { - Impls(lsp_types::request::GotoImplementationParams), + Impls(lsp_types::ImplementationParams), References(lsp_types::TextDocumentPositionParams), } -pub enum MoveItem {} +pub enum MoveItemRequest {} -impl Request for MoveItem { +impl Request for MoveItemRequest { type Params = MoveItemParams; type Result = Vec<SnippetTextEdit>; - const METHOD: &'static str = "experimental/moveItem"; + const METHOD: LspRequestMethod = LspRequestMethod::new("experimental/moveItem"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Serialize, Deserialize, Debug)] @@ -771,12 +818,13 @@ } #[derive(Debug)] -pub enum WorkspaceSymbol {} +pub enum WorkspaceSymbolRequest {} -impl Request for WorkspaceSymbol { +impl Request for WorkspaceSymbolRequest { type Params = WorkspaceSymbolParams; type Result = Option<lsp_types::WorkspaceSymbolResponse>; - const METHOD: &'static str = "workspace/symbol"; + const METHOD: LspRequestMethod = LspRequestMethod::new("workspace/symbol"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Debug, Eq, PartialEq, Clone, Default, Deserialize, Serialize)] @@ -812,15 +860,16 @@ /// 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::request::OnTypeFormatting, but the +/// almost same as [`lsp_types::DocumentOnTypeFormattingRequest`], but the /// result has SnippetTextEdit in it instead of TextEdit. #[derive(Debug)] -pub enum OnTypeFormatting {} +pub enum DocumentOnTypeFormattingRequest {} -impl Request for OnTypeFormatting { +impl Request for DocumentOnTypeFormattingRequest { type Params = DocumentOnTypeFormattingParams; type Result = Option<Vec<SnippetTextEdit>>; - const METHOD: &'static str = "textDocument/onTypeFormatting"; + const METHOD: LspRequestMethod = LspRequestMethod::new("textDocument/onTypeFormatting"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[derive(Debug, Serialize, Deserialize)] @@ -859,7 +908,7 @@ pub commands: Vec<String>, } -pub enum EvaluatePredicate {} +pub enum EvaluatePredicateRequest {} #[derive(Deserialize, Serialize, Debug)] #[serde(rename_all = "camelCase")] @@ -886,13 +935,14 @@ Unsupported, } -impl Request for EvaluatePredicate { +impl Request for EvaluatePredicateRequest { type Params = EvaluatePredicateParams; type Result = EvaluatePredicateResult; - const METHOD: &'static str = "rust-analyzer/evaluatePredicate"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/evaluatePredicate"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } -pub enum GetFailedObligations {} +pub enum GetFailedObligationsRequest {} #[derive(Deserialize, Serialize, Debug)] #[serde(rename_all = "camelCase")] @@ -901,10 +951,11 @@ pub position: Position, } -impl Request for GetFailedObligations { +impl Request for GetFailedObligationsRequest { type Params = GetFailedObligationsParams; type Result = String; - const METHOD: &'static str = "rust-analyzer/getFailedObligations"; + const METHOD: LspRequestMethod = LspRequestMethod::new("rust-analyzer/getFailedObligations"); + const MESSAGE_DIRECTION: MessageDirection = MessageDirection::ClientToServer; } #[cfg(test)]
diff --git a/crates/rust-analyzer/src/lsp/from_proto.rs b/crates/rust-analyzer/src/lsp/from_proto.rs index 333826a..a27e5fc 100644 --- a/crates/rust-analyzer/src/lsp/from_proto.rs +++ b/crates/rust-analyzer/src/lsp/from_proto.rs
@@ -1,4 +1,5 @@ //! 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}; @@ -12,12 +13,12 @@ lsp_ext, try_default, }; -pub(crate) fn abs_path(url: &lsp_types::Url) -> anyhow::Result<AbsPathBuf> { +pub(crate) fn abs_path(url: &lsp_types::Uri) -> 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::Url) -> anyhow::Result<vfs::VfsPath> { +pub(crate) fn vfs_path(url: &lsp_types::Uri) -> anyhow::Result<vfs::VfsPath> { abs_path(url).map(vfs::VfsPath::from) } @@ -65,7 +66,7 @@ /// Returns `None` if the file was excluded. pub(crate) fn file_id( snap: &GlobalStateSnapshot, - url: &lsp_types::Url, + url: &lsp_types::Uri, ) -> anyhow::Result<Option<FileId>> { snap.url_to_file_id(url) } @@ -73,7 +74,7 @@ /// 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)?; @@ -93,7 +94,7 @@ /// Returns `None` if the file was excluded. pub(crate) fn file_range_uri( snap: &GlobalStateSnapshot, - document: &lsp_types::Url, + document: &lsp_types::Uri, range: lsp_types::Range, ) -> anyhow::Result<Option<FileRange>> { let file_id = try_default!(file_id(snap, document)?); @@ -104,12 +105,12 @@ 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::REFACTOR_EXTRACT => AssistKind::RefactorExtract, - k if k == &lsp_types::CodeActionKind::REFACTOR_INLINE => AssistKind::RefactorInline, - k if k == &lsp_types::CodeActionKind::REFACTOR_REWRITE => 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::RefactorExtract => AssistKind::RefactorExtract, + k if k == &lsp_types::CodeActionKind::RefactorInline => AssistKind::RefactorInline, + k if k == &lsp_types::CodeActionKind::RefactorRewrite => AssistKind::RefactorRewrite, _ => return None, }; @@ -130,7 +131,7 @@ return Ok(None); } let pos @ FilePosition { file_id, .. } = - try_default!(file_position(snap, params.text_document_position_params)?); + try_default!(file_position(snap, ¶ms.text_document_position_params)?); let line_index = snap.file_line_index(file_id)?; Ok(Annotation { @@ -142,7 +143,7 @@ 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, params)?); + let pos @ FilePosition { file_id, .. } = try_default!(file_position(snap, ¶ms)?); 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 9bfdea8..7819806 100644 --- a/crates/rust-analyzer/src/lsp/semantic_tokens.rs +++ b/crates/rust-analyzer/src/lsp/semantic_tokens.rs
@@ -1,170 +1,261 @@ //! Semantic Tokens helpers -use std::ops; +use std::{fmt, ops, slice::Iter}; -use lsp_types::{ - Range, SemanticToken, SemanticTokenModifier, SemanticTokenType, SemanticTokens, - SemanticTokensEdit, -}; +use lsp_types::{Range, SemanticTokenModifiers, SemanticTokens, SemanticTokensEdit}; -macro_rules! define_semantic_token_types { +macro_rules! declare_enum { ( - standard { - $($standard:ident),*$(,)? + $(#[$attrs:meta])* + $visibility:vis enum $name:ident { + $($variant:ident),* $(,)? } - custom { - $(($custom:ident, $string:literal) $(=> $fallback:ident)?),*$(,)? - } - ) => { - pub(crate) mod types { - use super::SemanticTokenType; - $(pub(crate) const $standard: SemanticTokenType = SemanticTokenType::$standard;)* - $(pub(crate) const $custom: SemanticTokenType = SemanticTokenType::new($string);)* + $(#[$attrs])* + $visibility enum $name { + $($variant,)* } - 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 )} + impl $name { + pub(crate) fn iter() -> Iter<'static, Self> { + static ITEMS: &[$name] = &[ + $( + $name::$variant, + )* + ]; + ITEMS.iter() + } } }; } -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 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, } - - 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"), - } -]; - -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) mod modifiers { - use super::SemanticTokenModifier; - - $(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)*); - }; } -define_semantic_token_modifiers![ - standard { - ASYNC, - DOCUMENTATION, - DECLARATION, - STATIC, - DEFAULT_LIBRARY, - DEPRECATED, +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 { - (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"), +} + +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) } +} + +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, + }) +} + +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) + } +} + +const STANDARD_MOD: [SupportedModifiers; 6] = [ + SupportedModifiers::Async, + SupportedModifiers::Documentation, + SupportedModifiers::Declaration, + SupportedModifiers::Static, + SupportedModifiers::DefaultLibrary, + SupportedModifiers::Deprecated, ]; +const LAST_STANDARD_MOD: usize = STANDARD_MOD.len() - 1; #[derive(Default)] pub(crate) struct ModifierSet(pub(crate) u32); @@ -176,9 +267,9 @@ } } -impl ops::BitOrAssign<SemanticTokenModifier> for ModifierSet { - fn bitor_assign(&mut self, rhs: SemanticTokenModifier) { - let idx = SUPPORTED_MODIFIERS.iter().position(|it| it == &rhs).unwrap(); +impl ops::BitOrAssign<SupportedModifiers> for ModifierSet { + fn bitor_assign(&mut self, rhs: SupportedModifiers) { + let idx = SupportedModifiers::iter().position(|it| *it == rhs).unwrap(); self.0 |= 1 << idx; } } @@ -190,12 +281,12 @@ id: String, prev_line: u32, prev_char: u32, - data: Vec<SemanticToken>, + data: Vec<lsp_types::SemanticToken>, } impl SemanticTokensBuilder { pub(crate) fn new(id: String) -> Self { - SemanticTokensBuilder { id, prev_line: 0, prev_char: 0, data: Default::default() } + SemanticTokensBuilder { id, prev_line: 0, prev_char: 0, data: Vec::new() } } /// Push a new token onto the builder @@ -213,7 +304,7 @@ // A token cannot be multiline let token_len = range.end.character - range.start.character; - let token = SemanticToken { + let token = lsp_types::SemanticToken { delta_line: push_line, delta_start: push_char, length: token_len, @@ -232,7 +323,10 @@ } } -pub(crate) fn diff_tokens(old: &[SemanticToken], new: &[SemanticToken]) -> Vec<SemanticTokensEdit> { +pub(crate) fn diff_tokens( + old: &[lsp_types::SemanticToken], + new: &[lsp_types::SemanticToken], +) -> Vec<SemanticTokensEdit> { let offset = new.iter().zip(old.iter()).take_while(|&(n, p)| n == p).count(); let (_, old) = old.split_at(offset); @@ -258,16 +352,16 @@ } } -pub(crate) fn type_index(ty: SemanticTokenType) -> u32 { - SUPPORTED_TYPES.iter().position(|it| *it == ty).unwrap() as u32 +pub(crate) fn type_index(kind: SupportedType) -> u32 { + kind as u32 } #[cfg(test)] mod tests { use super::*; - fn from(t: (u32, u32, u32, u32, u32)) -> SemanticToken { - SemanticToken { + fn from(t: (u32, u32, u32, u32, u32)) -> lsp_types::SemanticToken { + lsp_types::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 3e8de07..ce71685 100644 --- a/crates/rust-analyzer/src/lsp/to_proto.rs +++ b/crates/rust-analyzer/src/lsp/to_proto.rs
@@ -58,43 +58,43 @@ pub(crate) fn symbol_kind(symbol_kind: SymbolKind) -> lsp_types::SymbolKind { match symbol_kind { - SymbolKind::Function => lsp_types::SymbolKind::FUNCTION, - SymbolKind::Method => lsp_types::SymbolKind::METHOD, - SymbolKind::Struct => lsp_types::SymbolKind::STRUCT, - SymbolKind::Enum => lsp_types::SymbolKind::ENUM, - SymbolKind::Variant => lsp_types::SymbolKind::ENUM_MEMBER, - SymbolKind::Trait => lsp_types::SymbolKind::INTERFACE, + SymbolKind::Function => lsp_types::SymbolKind::Function, + SymbolKind::Method => lsp_types::SymbolKind::Method, + SymbolKind::Struct => lsp_types::SymbolKind::Struct, + SymbolKind::Enum => lsp_types::SymbolKind::Enum, + SymbolKind::Variant => lsp_types::SymbolKind::EnumMember, + SymbolKind::Trait => lsp_types::SymbolKind::Interface, SymbolKind::Macro | SymbolKind::ProcMacro | SymbolKind::BuiltinAttr | SymbolKind::Attribute | SymbolKind::Derive - | SymbolKind::DeriveHelper => lsp_types::SymbolKind::FUNCTION, - SymbolKind::CrateRoot => lsp_types::SymbolKind::PACKAGE, - SymbolKind::Module | SymbolKind::ToolModule => lsp_types::SymbolKind::MODULE, + | SymbolKind::DeriveHelper => lsp_types::SymbolKind::Function, + SymbolKind::CrateRoot => lsp_types::SymbolKind::Package, + SymbolKind::Module | SymbolKind::ToolModule => lsp_types::SymbolKind::Module, SymbolKind::TypeAlias | SymbolKind::TypeParam | SymbolKind::SelfType => { - lsp_types::SymbolKind::TYPE_PARAMETER + lsp_types::SymbolKind::TypeParameter } - 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 @@ 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 @@ 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::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, + 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, }, } } @@ -185,7 +185,7 @@ line_index: &LineIndex, insert_replace_support: Option<lsp_types::Position>, indel: Indel, -) -> lsp_types::CompletionTextEdit { +) -> lsp_types::CompletionItemTextEdit { let text_edit = text_edit(line_index, indel); match insert_replace_support { Some(cursor_pos) => lsp_types::InsertReplaceEdit { @@ -208,7 +208,7 @@ 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 @@ 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 @@ fields_to_resolve, line_index, version, - &tdpp, + tdpp, max_relevance, completion_trigger_character, item, @@ -340,12 +340,12 @@ 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,6 +383,7 @@ .not() .then_some(additional_text_edits), documentation, + #[expect(deprecated, reason = "we do use tags")] deprecated: item.deprecated.then_some(item.deprecated), tags, command, @@ -491,7 +492,7 @@ let params = call_info .parameter_labels() .map(|label| lsp_types::ParameterInformation { - label: lsp_types::ParameterLabel::Simple(label.to_owned()), + label: lsp_types::ParameterInformationLabel::String(label.to_owned()), documentation: None, }) .collect::<Vec<_>>(); @@ -513,10 +514,10 @@ .chars() .map(|c| c.len_utf16()) .sum::<usize>() as u32; - [start, end] + (start, end) }) .map(|label_offsets| lsp_types::ParameterInformation { - label: lsp_types::ParameterLabel::LabelOffsets(label_offsets), + label: lsp_types::ParameterInformationLabel::Tuple(label_offsets), documentation: None, }) .collect::<Vec<_>>(); @@ -535,7 +536,7 @@ label.push_str(param); let end = label.len() as u32; params.push(lsp_types::ParameterInformation { - label: lsp_types::ParameterLabel::LabelOffsets([start, end]), + label: lsp_types::ParameterInformationLabel::Tuple((start, end)), documentation: None, }); } @@ -551,7 +552,8 @@ }) }); - let active_parameter = call_info.active_parameter.map(|it| it as u32); + let active_parameter = + call_info.active_parameter.map(|it| lsp_types::ActiveParameter::Int(it as u32)); let signature = lsp_types::SignatureInformation { label, @@ -639,9 +641,9 @@ 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, @@ -657,7 +659,7 @@ something_to_resolve: &mut bool, needs_resolve: bool, mut label: InlayHintLabel, -) -> Cancellable<(lsp_types::InlayHintLabel, Option<lsp_types::InlayHintTooltip>)> { +) -> Cancellable<(lsp_types::Label, Option<lsp_types::Tooltip>)> { let (label, tooltip) = match &*label.parts { [InlayHintLabelPart { linked_location: None, .. }] => { let InlayHintLabelPart { text, tooltip, .. } = label.parts.pop().unwrap(); @@ -670,16 +672,16 @@ } }); let hint_tooltip = match tooltip { - Some(ide::InlayTooltip::String(s)) => Some(lsp_types::InlayHintTooltip::String(s)), + Some(ide::InlayTooltip::String(s)) => Some(lsp_types::Tooltip::String(s)), Some(ide::InlayTooltip::Markdown(s)) => { - Some(lsp_types::InlayHintTooltip::MarkupContent(lsp_types::MarkupContent { + Some(lsp_types::Tooltip::MarkupContent(lsp_types::MarkupContent { kind: lsp_types::MarkupKind::Markdown, value: s, })) } None => None, }; - (lsp_types::InlayHintLabel::String(text), hint_tooltip) + (lsp_types::Label::String(text), hint_tooltip) } _ => { let parts = label @@ -694,16 +696,12 @@ } }); let tooltip = match tooltip { - Some(ide::InlayTooltip::String(s)) => { - Some(lsp_types::InlayHintLabelPartTooltip::String(s)) - } + Some(ide::InlayTooltip::String(s)) => Some(lsp_types::Tooltip::String(s)), Some(ide::InlayTooltip::Markdown(s)) => { - Some(lsp_types::InlayHintLabelPartTooltip::MarkupContent( - lsp_types::MarkupContent { - kind: lsp_types::MarkupKind::Markdown, - value: s, - }, - )) + Some(lsp_types::Tooltip::MarkupContent(lsp_types::MarkupContent { + kind: lsp_types::MarkupKind::Markdown, + value: s, + })) } None => None, }; @@ -726,7 +724,7 @@ }) }) .collect::<Cancellable<_>>()?; - (lsp_types::InlayHintLabel::LabelParts(parts), None) + (lsp_types::Label::InlayHintLabelPartList(parts), None) } }; Ok((label, tooltip)) @@ -773,11 +771,11 @@ if !non_standard_tokens { ty = match standard_fallback_type(ty) { - Some(ty) => ty, + Some(fallback) => fallback, None => continue, }; mods.standard_fallback(); - } + }; let token_index = semantic_tokens::type_index(ty); let modifier_bitset = mods.0; @@ -805,106 +803,106 @@ fn semantic_token_type_and_modifiers( highlight: Highlight, -) -> (lsp_types::SemanticTokenType, semantic_tokens::ModifierSet) { - use semantic_tokens::{modifiers as mods, types}; +) -> (semantic_tokens::SupportedType, semantic_tokens::ModifierSet) { + use semantic_tokens::{SupportedModifiers, SupportedType}; let mut mods = semantic_tokens::ModifierSet::default(); let ty = match highlight.tag { HlTag::Symbol(symbol) => match symbol { - SymbolKind::Attribute => types::DECORATOR, - SymbolKind::Derive => types::DERIVE, - SymbolKind::DeriveHelper => types::DERIVE_HELPER, + SymbolKind::Attribute => SupportedType::Decorator, + SymbolKind::Derive => SupportedType::Derive, + SymbolKind::DeriveHelper => SupportedType::DeriveHelper, SymbolKind::CrateRoot => { - mods |= mods::CRATE_ROOT; - types::NAMESPACE + mods |= SupportedModifiers::CrateRoot; + SupportedType::Namespace } - 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, + 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, }, - 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::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::Operator(op) => match op { - HlOperator::Bitwise => types::BITWISE, - HlOperator::Arithmetic => types::ARITHMETIC, - HlOperator::Logical => types::LOGICAL, - HlOperator::Negation => types::NEGATION, - HlOperator::Comparison => types::COMPARISON, - HlOperator::Other => types::OPERATOR, + HlOperator::Bitwise => SupportedType::Bitwise, + HlOperator::Arithmetic => SupportedType::Arithmetic, + HlOperator::Logical => SupportedType::Logical, + HlOperator::Negation => SupportedType::Negation, + HlOperator::Comparison => SupportedType::Comparison, + HlOperator::Other => SupportedType::Operator, }, - HlTag::StringLiteral => types::STRING, - HlTag::UnresolvedReference => types::UNRESOLVED_REFERENCE, + HlTag::StringLiteral => SupportedType::String, + HlTag::UnresolvedReference => SupportedType::UnresolvedReference, HlTag::Punctuation(punct) => match punct { - 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, + 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, }, }; for modifier in highlight.mods.iter() { let modifier = match modifier { - 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, + 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, }; mods |= modifier; } @@ -983,16 +981,16 @@ } } -pub(crate) fn url(snap: &GlobalStateSnapshot, file_id: FileId) -> lsp_types::Url { +pub(crate) fn url(snap: &GlobalStateSnapshot, file_id: FileId) -> lsp_types::Uri { snap.file_id_to_url(file_id) } -/// Returns a `Url` object from a given path, will lowercase drive letters if present. +/// Returns a `Uri` 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 `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(); +/// 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(); match path.components().next() { Some(Utf8Component::Prefix(prefix)) if matches!(prefix.kind(), Utf8Prefix::Disk(_) | Utf8Prefix::VerbatimDisk(_)) => @@ -1016,16 +1014,19 @@ // string in place. let mut url: String = url.into(); url[driver_letter_range].make_ascii_lowercase(); - lsp_types::Url::parse(&url).unwrap() + lsp_types::Uri::parse(&url).unwrap() } pub(crate) fn optional_versioned_text_document_identifier( snap: &GlobalStateSnapshot, file_id: FileId, ) -> lsp_types::OptionalVersionedTextDocumentIdentifier { - let url = url(snap, file_id); - let version = snap.url_file_version(&url); - lsp_types::OptionalVersionedTextDocumentIdentifier { uri: url, version } + let uri = url(snap, file_id); + let version = snap.url_file_version(&uri); + lsp_types::OptionalVersionedTextDocumentIdentifier { + text_document_identifier: lsp_types::TextDocumentIdentifier { uri }, + version, + } } pub(crate) fn location( @@ -1042,7 +1043,7 @@ /// 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)?; @@ -1077,7 +1078,7 @@ fn location_info( snap: &GlobalStateSnapshot, target: NavigationTarget, -) -> Cancellable<(lsp_types::Url, lsp_types::Range, lsp_types::Range)> { +) -> Cancellable<(lsp_types::Uri, lsp_types::Range, lsp_types::Range)> { let line_index = snap.file_line_index(target.file_id)?; let target_uri = url(snap, target.file_id); @@ -1091,25 +1092,90 @@ snap: &GlobalStateSnapshot, src: Option<FileRange>, targets: Vec<NavigationTarget>, -) -> Cancellable<lsp_types::GotoDefinitionResponse> { +) -> Cancellable<lsp_types::DefinitionResponse> { if snap.config.location_link() { - 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<_>>>()?; + let links = targets_to_links(snap, src, targets)?; Ok(links.into()) } else { - 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()) + 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> { + 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)?; + Ok(links.into()) + } else { + let locations = targets_to_locations(snap, targets)?; + Ok(lsp_types::TypeDefinitionResponse::Definition(lsp_types::Definition::LocationList( + locations, + ))) + } +} + +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") } @@ -1318,19 +1384,21 @@ match file_system_edit { FileSystemEdit::CreateFile { dst, initial_contents } => { let uri = snap.anchored_path(&dst); - let create_file = lsp_types::ResourceOp::Create(lsp_types::CreateFile { + let create_file = lsp_types::DocumentChange::CreateFile(lsp_types::CreateFile { uri: uri.clone(), options: None, annotation_id: None, }); - ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(create_file)); + ops.push(lsp_ext::SnippetDocumentChangeOperation::Change(create_file)); if !initial_contents.is_empty() { - let text_document = - lsp_types::OptionalVersionedTextDocumentIdentifier { uri, version: None }; + let text_document = lsp_types::OptionalVersionedTextDocumentIdentifier { + text_document_identifier: lsp_types::TextDocumentIdentifier { 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::PLAIN_TEXT), + insert_text_format: Some(lsp_types::InsertTextFormat::PlainText), annotation_id: None, }; let edit_file = @@ -1348,9 +1416,9 @@ { rename_file.annotation_id = Some(outside_workspace_annotation_id()) } - ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(lsp_types::ResourceOp::Rename( - rename_file, - ))) + ops.push(lsp_ext::SnippetDocumentChangeOperation::Change( + lsp_types::DocumentChange::RenameFile(rename_file), + )) } FileSystemEdit::MoveDir { src, src_id, dst } => { let old_uri = snap.anchored_path(&src); @@ -1362,9 +1430,9 @@ { rename_file.annotation_id = Some(outside_workspace_annotation_id()) } - ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(lsp_types::ResourceOp::Rename( - rename_file, - ))) + ops.push(lsp_ext::SnippetDocumentChangeOperation::Change( + lsp_types::DocumentChange::RenameFile(rename_file), + )) } } Ok(ops) @@ -1449,42 +1517,38 @@ lsp_types::WorkspaceEdit { changes: None, document_changes: snippet_workspace_edit.document_changes.map(|changes| { - 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(), - ) + 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() }), change_annotations: snippet_workspace_edit.change_annotations, } } } -impl From<lsp_ext::SnippetTextEdit> - for lsp_types::OneOf<lsp_types::TextEdit, lsp_types::AnnotatedTextEdit> -{ +impl From<lsp_ext::SnippetTextEdit> for lsp_types::Edit { 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::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 }), + 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 }), } } } @@ -1495,7 +1559,7 @@ ) -> 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, @@ -1511,12 +1575,12 @@ 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::REFACTOR_EXTRACT, - AssistKind::RefactorInline => lsp_types::CodeActionKind::REFACTOR_INLINE, - AssistKind::RefactorRewrite => lsp_types::CodeActionKind::REFACTOR_REWRITE, + 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, } } @@ -1761,7 +1825,7 @@ let doc_pos = lsp_types::TextDocumentPositionParams::new(id, pos); - let goto_params = lsp_types::request::GotoImplementationParams { + let goto_params = lsp_types::ImplementationParams { text_document_position_params: doc_pos, work_done_progress_params: Default::default(), partial_result_params: Default::default(), @@ -1891,7 +1955,7 @@ pub(crate) fn show_references( title: String, - uri: &lsp_types::Url, + uri: &lsp_types::Uri, position: lsp_types::Position, locations: Vec<lsp_types::Location>, ) -> lsp_types::Command { @@ -1907,6 +1971,7 @@ to_value(position).unwrap(), to_value(locations).unwrap(), ]), + tooltip: None, } } @@ -1915,6 +1980,7 @@ title: title.to_owned(), command: "rust-analyzer.runSingle".into(), arguments: Some(vec![to_value(runnable).unwrap()]), + tooltip: None, } } @@ -1923,6 +1989,7 @@ title: "âš™\u{fe0e} Debug".into(), command: "rust-analyzer.debugSingle".into(), arguments: Some(vec![to_value(runnable).unwrap()]), + tooltip: None, } } @@ -1932,6 +1999,7 @@ command: "rust-analyzer.interpretFunction".into(), // FIXME: use the `_runnable` here. arguments: Some(vec![]), + tooltip: None, } } @@ -1952,6 +2020,7 @@ title: nav.name.to_string(), command: "rust-analyzer.gotoLocation".into(), arguments: Some(vec![value]), + tooltip: None, }) } @@ -1960,6 +2029,7 @@ title: "triggerParameterHints".into(), command: "rust-analyzer.triggerParameterHints".into(), arguments: None, + tooltip: None, } } @@ -1968,6 +2038,7 @@ title: "rename".into(), command: "rust-analyzer.rename".into(), arguments: None, + tooltip: None, } } } @@ -3081,7 +3152,7 @@ ) } - // `Url` is not able to parse windows paths on unix machines. + // `Uri` 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 5bea708..ebec0f9 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}; +use std::{mem, ops::Range, vec}; use lsp_server::Notification; -use lsp_types::request::Request; +use lsp_types::{MessageActionItem, Request}; use triomphe::Arc; use crate::{ @@ -16,10 +16,8 @@ LspError { code: lsp_server::ErrorCode::InvalidParams as i32, message } } -pub(crate) fn notification_is<N: lsp_types::notification::Notification>( - notification: &Notification, -) -> bool { - notification.method == N::METHOD +pub(crate) fn notification_is<N: lsp_types::Notification>(notification: &Notification) -> bool { + notification.method.as_str() == N::METHOD.as_str() } #[derive(Debug, Eq, PartialEq)] @@ -39,37 +37,34 @@ impl GlobalState { pub(crate) fn show_message( &mut self, - typ: lsp_types::MessageType, + kind: 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::request::ShowMessageRequest>( + match self.config.open_server_logs() && show_open_log_button { + true => self.send_request::<lsp_types::ShowMessageRequest>( lsp_types::ShowMessageRequestParams { - typ, + kind, 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::< - <lsp_types::request::ShowMessageRequest as lsp_types::request::Request>::Result, - >( - lsp_types::request::ShowMessageRequest::METHOD, &result + else { + return; + }; + if let Ok(Some(_item)) = crate::from_json::<Option<MessageActionItem>>( + lsp_types::ShowMessageRequest::METHOD.as_str(), + &result, ) { - this.send_notification::<lsp_ext::OpenServerLogs>(()); + this.send_notification::<lsp_ext::OpenServerLogsNotification>(()); } }, ), - false => self.send_notification::<lsp_types::notification::ShowMessage>( - lsp_types::ShowMessageParams { - typ, - message, - }, + false => self.send_notification::<lsp_types::ShowMessageNotification>( + lsp_types::ShowMessageParams { kind, message }, ), } } @@ -81,15 +76,15 @@ 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::notification::ShowMessage>( - lsp_types::ShowMessageParams { typ: lsp_types::MessageType::ERROR, message }, + self.send_notification::<lsp_types::ShowMessageNotification>( + lsp_types::ShowMessageParams { kind: lsp_types::MessageType::Error, message }, ); } } @@ -133,35 +128,49 @@ cancel_token.unwrap_or_else(|| format!("rustAnalyzer/{title}")), ); tracing::debug!(?token, ?state, "report_progress {message:?}"); - let work_done_progress = match state { + match state { Progress::Begin => { - self.send_request::<lsp_types::request::WorkDoneProgressCreate>( + self.send_request::<lsp_types::WorkDoneProgressCreateRequest>( lsp_types::WorkDoneProgressCreateParams { token: token.clone() }, |_, _| (), ); - lsp_types::WorkDoneProgress::Begin(lsp_types::WorkDoneProgressBegin { - title: title.into(), - cancellable, - message, - percentage, - }) + 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(), + }, + ); } Progress::Report => { - lsp_types::WorkDoneProgress::Report(lsp_types::WorkDoneProgressReport { - cancellable, - message, - percentage, - }) + self.send_notification::<lsp_types::ProgressNotification>( + lsp_types::ProgressParams { + token, + value: serde_json::to_value(lsp_types::WorkDoneProgressReport { + cancellable, + message, + percentage, + }) + .unwrap(), + }, + ); } Progress::End => { - lsp_types::WorkDoneProgress::End(lsp_types::WorkDoneProgressEnd { message }) + self.send_notification::<lsp_types::ProgressNotification>( + lsp_types::ProgressParams { + token, + value: serde_json::to_value(lsp_types::WorkDoneProgressEnd { message }) + .unwrap(), + }, + ); } - }; - self.send_notification::<lsp_types::notification::Progress>(lsp_types::ProgressParams { - token, - value: lsp_types::ProgressParamsValue::WorkDone(work_done_progress), - }); + } } } @@ -172,15 +181,26 @@ ) -> 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, 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() { + 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() { return text; } @@ -198,16 +218,13 @@ // 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 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); - } + 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); } } text @@ -221,10 +238,10 @@ ) -> bool { let mut edit_ranges = Vec::new(); match completion.text_edit.as_ref() { - Some(lsp_types::CompletionTextEdit::Edit(edit)) => { + Some(lsp_types::CompletionItemTextEdit::TextEdit(edit)) => { edit_ranges.push(edit.range); } - Some(lsp_types::CompletionTextEdit::InsertAndReplace(edit)) => { + Some(lsp_types::CompletionItemTextEdit::InsertReplaceEdit(edit)) => { let replace = edit.replace; let insert = edit.insert; if replace.start != insert.start @@ -252,10 +269,7 @@ #[cfg(test)] mod tests { use ide_db::line_index::WideEncoding; - use lsp_types::{ - CompletionItem, CompletionTextEdit, InsertReplaceEdit, Position, Range, - TextDocumentContentChangeEvent, - }; + use lsp_types::{CompletionItem, InsertReplaceEdit, Position, Range}; use super::*; @@ -263,14 +277,14 @@ fn test_apply_document_changes() { macro_rules! c { [$($sl:expr, $sc:expr; $el:expr, $ec:expr => $text:expr),+] => { - vec![$(TextDocumentContentChangeEvent { - range: Some(Range { + vec![$(::lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangePartial(lsp_types::TextDocumentContentChangePartial { + range: Range { start: Position { line: $sl, character: $sc }, end: Position { line: $el, character: $ec }, - }), - range_length: None, + }, text: String::from($text), - }),+] + ..Default::default() + })),+] }; } @@ -280,11 +294,11 @@ let text = apply_document_changes( encoding, &text, - vec![TextDocumentContentChangeEvent { - range: None, - range_length: None, - text: String::from("the"), - }], + vec![ + lsp_types::TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + lsp_types::TextDocumentContentChangeWholeDocument { text: String::from("the") }, + ), + ], ); assert_eq!(text, "the"); let text = apply_document_changes(encoding, &text, c![0, 3; 0, 3 => " quick"]); @@ -332,7 +346,11 @@ #[test] fn empty_completion_disjoint_tests() { - let empty_completion = CompletionItem::new_simple("label".to_owned(), "detail".to_owned()); + let empty_completion = CompletionItem { + label: "label".to_owned(), + detail: Some("detail".to_owned()), + ..Default::default() + }; let disjoint_edit_1 = lsp_types::TextEdit::new( Range::new(Position::new(2, 2), Position::new(3, 3)), @@ -384,17 +402,19 @@ "new_text".to_owned(), ); - 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()]); + 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() + }; 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(CompletionTextEdit::Edit(disjoint_edit.clone())); + Some(lsp_types::CompletionItemTextEdit::TextEdit(disjoint_edit.clone())); completion_with_joint_edits.additional_text_edits = Some(vec![joint_edit.clone()]); assert!( !all_edits_are_disjoint(&completion_with_joint_edits, &[]), @@ -402,7 +422,7 @@ ); completion_with_joint_edits.text_edit = - Some(CompletionTextEdit::InsertAndReplace(InsertReplaceEdit { + Some(lsp_types::CompletionItemTextEdit::InsertReplaceEdit(InsertReplaceEdit { new_text: "new_text".to_owned(), insert: disjoint_edit.range, replace: disjoint_edit_2.range, @@ -429,10 +449,12 @@ "new_text".to_owned(), ); - 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; + 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() + }; 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 d966e29..fef0d09 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs
@@ -11,7 +11,7 @@ use crossbeam_channel::{Receiver, never, select}; use ide_db::base_db::{SourceDatabase, VfsPath}; use lsp_server::{Connection, Notification, Request}; -use lsp_types::{TextDocumentIdentifier, notification::Notification as _}; +use lsp_types::{Notification as _, TextDocumentIdentifier}; use stdx::thread::ThreadIntent; use tracing::{Level, error, span}; use vfs::{AbsPathBuf, FileId, loader::LoadingProgress}; @@ -99,7 +99,7 @@ #[derive(Debug)] pub(crate) enum DeferredTask { - CheckIfIndexed(lsp_types::Url), + CheckIfIndexed(lsp_types::Uri), CheckProcMacroSources(Vec<FileId>), } @@ -145,8 +145,8 @@ match self { Event::Lsp(lsp_server::Message::Notification(not)) - if (notification_is::<lsp_types::notification::DidOpenTextDocument>(not) - || notification_is::<lsp_types::notification::DidChangeTextDocument>(not)) => + if (notification_is::<lsp_types::DidOpenTextDocumentNotification>(not) + || notification_is::<lsp_types::DidChangeTextDocumentNotification>(not)) => { return debug_non_verbose(not, f); } @@ -207,7 +207,7 @@ if matches!( &event, Event::Lsp(lsp_server::Message::Notification(Notification { method, .. })) - if method == lsp_types::notification::Exit::METHOD + if method == lsp_types::ExitNotification::METHOD.as_str() ) { return Ok(()); } @@ -218,33 +218,43 @@ } fn register_did_save_capability(&mut self, additional_patterns: impl Iterator<Item = String>) { - let additional_filters = additional_patterns.map(|pattern| lsp_types::DocumentFilter { - language: None, - scheme: None, - pattern: (Some(pattern)), + 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 mut selectors = vec![ - 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()), - }, + 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(), + }, + )), ]; selectors.extend(additional_filters); let save_registration_options = lsp_types::TextDocumentSaveRegistrationOptions { - include_text: Some(false), + save_options: lsp_types::SaveOptions { include_text: Some(false) }, text_document_registration_options: lsp_types::TextDocumentRegistrationOptions { document_selector: Some(selectors), }, @@ -255,7 +265,7 @@ method: "textDocument/didSave".to_owned(), register_options: Some(serde_json::to_value(save_registration_options).unwrap()), }; - self.send_request::<lsp_types::request::RegisterCapability>( + self.send_request::<lsp_types::RegistrationRequest>( lsp_types::RegistrationParams { registrations: vec![registration] }, |_, _| (), ); @@ -457,10 +467,7 @@ self.handle_flycheck_msg(message, &mut cargo_finished); } if cargo_finished { - self.send_request::<lsp_types::request::WorkspaceDiagnosticRefresh>( - (), - |_, _| (), - ); + self.send_request::<lsp_types::DiagnosticRefreshRequest>((), |_, _| ()); } } Event::TestResult(message) => { @@ -537,24 +544,21 @@ // 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::request::SemanticTokensRefresh>((), |_, _| ()); + self.send_request::<lsp_types::SemanticTokensRefreshRequest>((), |_, _| ()); } // Refresh code lens if the client supports it. if self.config.code_lens_refresh() { - self.send_request::<lsp_types::request::CodeLensRefresh>((), |_, _| ()); + self.send_request::<lsp_types::CodeLensRefreshRequest>((), |_, _| ()); } // Refresh inlay hints if the client supports it. if self.config.inlay_hints_refresh() { - self.send_request::<lsp_types::request::InlayHintRefreshRequest>((), |_, _| ()); + self.send_request::<lsp_types::InlayHintRefreshRequest>((), |_, _| ()); } if self.config.diagnostics_refresh() { - self.send_request::<lsp_types::request::WorkspaceDiagnosticRefresh>( - (), - |_, _| (), - ); + self.send_request::<lsp_types::DiagnosticRefreshRequest>((), |_, _| ()); } } @@ -828,9 +832,9 @@ || 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, @@ -911,7 +915,7 @@ 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, ), @@ -960,7 +964,7 @@ } Task::BuildDepsHaveChanged => self.build_deps_changed = true, Task::DiscoverTest(tests) => { - self.send_notification::<lsp_ext::DiscoveredTests>(tests); + self.send_notification::<lsp_ext::DiscoveredTestsNotification>(tests); } } cancellation_time @@ -1174,7 +1178,7 @@ // 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::ChangeTestState>( + self.send_notification::<lsp_ext::ChangeTestStateNotification>( lsp_ext::ChangeTestStateParams { test_id, state }, ); } @@ -1182,12 +1186,12 @@ 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::EndRunTest>(()); + self.send_notification::<lsp_ext::EndRunTestNotification>(()); self.test_run_session = None; } } CargoTestOutput::Custom { text } => { - self.send_notification::<lsp_ext::AppendOutputToRunTest>(text); + self.send_notification::<lsp_ext::AppendOutputToRunTestNotification>(text); } } } @@ -1308,7 +1312,7 @@ /// 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::request::Shutdown>(|s, ()| { + dispatcher.on_sync_mut::<lsp_types::ShutdownRequest>(|s, ()| { s.shutdown_requested = true; s.proc_macro_clients = std::iter::repeat_with(|| None).take(s.proc_macro_clients.len()).collect(); @@ -1330,7 +1334,6 @@ } use crate::handlers::request as handlers; - use lsp_types::request as lsp_request; const RETRY: bool = true; const NO_RETRY: bool = false; @@ -1339,91 +1342,91 @@ dispatcher // Request handlers that must run on the main thread // because they mutate GlobalState: - .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) + .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) // Request handlers which are related to the user typing // are run on the main thread to reduce latency: - .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) + .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) // 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_request::Formatting>(handlers::handle_formatting) - .on_fmt_thread::<lsp_request::RangeFormatting>(handlers::handle_range_formatting) + .on_fmt_thread::<lsp_types::DocumentFormattingRequest>(handlers::handle_formatting) + .on_fmt_thread::<lsp_types::DocumentRangeFormattingRequest>(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_request::Completion>(handlers::handle_completion) + .on_latency_sensitive::<RETRY, lsp_types::CompletionRequest>(handlers::handle_completion) // FIXME: Retrying can make the result of this stale - .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) + .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) // 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_request::DocumentDiagnosticRequest>(handlers::handle_document_diagnostics, empty_diagnostic_report, || lsp_server::ResponseError { + .on_with_vfs_default::<lsp_types::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_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) + .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) // All other request handlers (lsp extension) - .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::<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::<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::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::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::InternalTestingFetchConfig>(handlers::internal_testing_fetch_config) - .on::<RETRY, lsp_ext::EvaluatePredicate>(handlers::handle_evaluate_predicate) - .on::<RETRY, lsp_ext::GetFailedObligations>(handlers::get_failed_obligations) + .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) .finish(); } @@ -1432,28 +1435,37 @@ 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::<notifs::Cancel>(handlers::handle_cancel) - .on_sync_mut::<notifs::WorkDoneProgressCancel>( + .on_sync_mut::<lsp_types::CancelNotification>(handlers::handle_cancel) + .on_sync_mut::<lsp_types::WorkDoneProgressCancelNotification>( handlers::handle_work_done_progress_cancel, ) - .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>( + .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>( handlers::handle_did_change_configuration, ) - .on_sync_mut::<notifs::DidChangeWorkspaceFolders>( + .on_sync_mut::<lsp_types::DidChangeWorkspaceFoldersNotification>( handlers::handle_did_change_workspace_folders, ) - .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) + .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) .finish(); } }
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 4940def..703af40 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs
@@ -544,8 +544,8 @@ // 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::notification::ShowMessage>( - lsp_types::ShowMessageParams { typ: lsp_types::MessageType::WARNING, message }, + self.send_notification::<lsp_types::ShowMessageNotification>( + lsp_types::ShowMessageParams { kind: lsp_types::MessageType::Warning, message }, ); }); @@ -585,10 +585,10 @@ }) }) .map(|(base, pat)| lsp_types::FileSystemWatcher { - glob_pattern: lsp_types::GlobPattern::Relative( + glob_pattern: lsp_types::GlobPattern::RelativePattern( lsp_types::RelativePattern { - base_uri: lsp_types::OneOf::Right( - lsp_types::Url::from_file_path(base).unwrap(), + base_uri: lsp_types::BaseUri::Uri( + lsp_types::Uri::from_file_path(base).unwrap(), ), pattern: pat.to_owned(), }, @@ -610,7 +610,7 @@ }) }) .map(|glob_pattern| lsp_types::FileSystemWatcher { - glob_pattern: lsp_types::GlobPattern::String(glob_pattern), + glob_pattern: lsp_types::GlobPattern::Pattern(glob_pattern), kind: None, }) .collect() @@ -624,7 +624,7 @@ continue; }; watchers.push(lsp_types::FileSystemWatcher { - glob_pattern: lsp_types::GlobPattern::String( + glob_pattern: lsp_types::GlobPattern::Pattern( build.build_file.to_string(), ), kind: None, @@ -638,7 +638,7 @@ .chain(self.workspaces.iter().map(|ws| ws.manifest().map(ManifestPath::as_ref))) .flatten() .map(|glob_pattern| lsp_types::FileSystemWatcher { - glob_pattern: lsp_types::GlobPattern::String(glob_pattern.to_string()), + glob_pattern: lsp_types::GlobPattern::Pattern(glob_pattern.to_string()), kind: None, }), ); @@ -650,7 +650,7 @@ method: "workspace/didChangeWatchedFiles".to_owned(), register_options: Some(serde_json::to_value(registration_options).unwrap()), }; - self.send_request::<lsp_types::request::RegisterCapability>( + self.send_request::<lsp_types::RegistrationRequest>( 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 b91bde8..9edb1df 100644 --- a/crates/rust-analyzer/tests/slow-tests/main.rs +++ b/crates/rust-analyzer/tests/slow-tests/main.rs
@@ -20,23 +20,19 @@ mod support; mod testdir; -use std::{collections::HashMap, path::PathBuf, time::Instant}; +use std::{path::PathBuf, time::Instant}; use ide_db::FxHashMap; use lsp_types::{ - 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, - }, + 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, }; -use rust_analyzer::lsp::ext::{OnEnter, Runnables, RunnablesParams}; +use rust_analyzer::lsp::ext::{OnEnterRequest, RunnablesParams, RunnablesRequest}; use serde_json::json; use stdx::format_to_acc; @@ -68,8 +64,8 @@ .server() .wait_until_workspace_is_loaded(); - let res = server.send_request::<Completion>(CompletionParams { - text_document_position: TextDocumentPositionParams::new( + let res = server.send_request::<CompletionRequest>(CompletionParams { + text_document_position_params: TextDocumentPositionParams::new( server.doc_id("src/lib.rs"), Position::new(0, 23), ), @@ -112,13 +108,13 @@ let hint = hints.pop().unwrap(); assert!(hint.data.is_some()); assert!( - matches!(&hint.label, InlayHintLabel::LabelParts(parts) if parts[1].location.is_none()) + matches!(&hint.label, Label::InlayHintLabelPartList(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, InlayHintLabel::LabelParts(parts) if parts[1].location.is_some()) + matches!(&hint.label, Label::InlayHintLabelPartList(parts) if parts[1].location.is_some()) ); } @@ -160,8 +156,8 @@ .server() .wait_until_workspace_is_loaded(); - let res = server.send_request::<Completion>(CompletionParams { - text_document_position: TextDocumentPositionParams::new( + let res = server.send_request::<CompletionRequest>(CompletionParams { + text_document_position_params: TextDocumentPositionParams::new( server.doc_id("src/lib.rs"), Position::new(5, 18), ), @@ -171,8 +167,8 @@ }); assert!(res.to_string().contains("SpecialHashMap"), "{}", res.to_string()); - let res = server.send_request::<Completion>(CompletionParams { - text_document_position: TextDocumentPositionParams::new( + let res = server.send_request::<CompletionRequest>(CompletionParams { + text_document_position_params: TextDocumentPositionParams::new( server.doc_id("src/lib.rs"), Position::new(6, 18), ), @@ -199,8 +195,8 @@ std::thread::sleep(std::time::Duration::from_secs(3)); - let res = server.send_request::<Completion>(CompletionParams { - text_document_position: TextDocumentPositionParams::new( + let res = server.send_request::<CompletionRequest>(CompletionParams { + text_document_position_params: TextDocumentPositionParams::new( server.doc_id("src/lib.rs"), Position::new(5, 18), ), @@ -210,8 +206,8 @@ }); assert!(!res.to_string().contains("SpecialHashMap")); - let res = server.send_request::<Completion>(CompletionParams { - text_document_position: TextDocumentPositionParams::new( + let res = server.send_request::<CompletionRequest>(CompletionParams { + text_document_position_params: TextDocumentPositionParams::new( server.doc_id("src/lib.rs"), Position::new(6, 18), ), @@ -256,7 +252,7 @@ .server() .wait_until_workspace_is_loaded(); - server.request::<Runnables>( + server.request::<RunnablesRequest>( RunnablesParams { text_document: server.doc_id("foo/tests/spam.rs"), position: None }, json!([ { @@ -407,7 +403,7 @@ .wait_until_workspace_is_loaded(); for runnable in ["consumer", "dependency", "devdependency"] { - server.request::<Runnables>( + server.request::<RunnablesRequest>( RunnablesParams { text_document: server.doc_id(&format!("{runnable}/src/lib.rs")), position: None, @@ -472,7 +468,7 @@ .server() .wait_until_workspace_is_loaded(); - server.request::<Runnables>( + server.request::<RunnablesRequest>( RunnablesParams { text_document: server.doc_id("foo/mainpkg/src/main.rs"), position: None }, json!([ "{...}", @@ -497,7 +493,7 @@ ]), ); - server.request::<Runnables>( + server.request::<RunnablesRequest>( RunnablesParams { text_document: server.doc_id("foo/otherpkg/src/lib.rs"), position: None }, json!([ "{...}", @@ -547,7 +543,7 @@ ) .wait_until_workspace_is_loaded(); - server.request::<Formatting>( + server.request::<DocumentFormattingRequest>( DocumentFormattingParams { text_document: server.doc_id("src/lib.rs"), options: FormattingOptions { @@ -556,7 +552,6 @@ insert_final_newline: None, trim_final_newlines: None, trim_trailing_whitespace: None, - properties: HashMap::new(), }, work_done_progress_params: WorkDoneProgressParams::default(), }, @@ -600,13 +595,12 @@ ) .wait_until_workspace_is_loaded(); - server.request::<Formatting>( + server.request::<DocumentFormattingRequest>( 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, @@ -651,7 +645,7 @@ ) .wait_until_workspace_is_loaded(); - server.request::<Formatting>( + server.request::<DocumentFormattingRequest>( DocumentFormattingParams { text_document: server.doc_id("src/lib.rs"), options: FormattingOptions { @@ -660,7 +654,6 @@ insert_final_newline: None, trim_final_newlines: None, trim_trailing_whitespace: None, - properties: HashMap::new(), }, work_done_progress_params: WorkDoneProgressParams::default(), }, @@ -707,7 +700,7 @@ .server() .wait_until_workspace_is_loaded(); - server.request::<RangeFormatting>( + server.request::<DocumentRangeFormattingRequest>( DocumentRangeFormattingParams { range: Range { end: Position { line: 1, character: 0 }, @@ -720,7 +713,6 @@ insert_final_newline: None, trim_final_newlines: None, trim_trailing_whitespace: None, - properties: HashMap::new(), }, work_done_progress_params: WorkDoneProgressParams::default(), }, @@ -928,17 +920,17 @@ .wait_until_workspace_is_loaded(); for i in 0..10 { - server.notification::<DidOpenTextDocument>(DidOpenTextDocumentParams { + server.notification::<DidOpenTextDocumentNotification>(DidOpenTextDocumentParams { text_document: TextDocumentItem { uri: server.doc_id(&format!("src/m{i}.rs")).uri, - language_id: "rust".to_owned(), + language_id: LanguageKind::Rust, version: 0, text: "/// Docs\nfn foo() {}".to_owned(), }, }); } let start = Instant::now(); - server.request::<OnEnter>( + server.request::<OnEnterRequest>( TextDocumentPositionParams { text_document: server.doc_id("src/m0.rs"), position: Position { line: 0, character: 5 }, @@ -976,7 +968,7 @@ .server() .wait_until_workspace_is_loaded(); - server.request::<OnEnter>( + server.request::<OnEnterRequest>( TextDocumentPositionParams { text_document: server.doc_id("src/main.rs"), position: Position { line: 0, character: 8 }, @@ -1089,8 +1081,8 @@ }); assert!(res.to_string().contains("&str")); - server.request::<GotoTypeDefinition>( - GotoDefinitionParams { + server.request::<TypeDefinitionRequest>( + TypeDefinitionParams { text_document_position_params: TextDocumentPositionParams::new( server.doc_id("src/main.rs"), Position::new(28, 9), @@ -1115,8 +1107,8 @@ }]), ); - server.request::<GotoTypeDefinition>( - GotoDefinitionParams { + server.request::<TypeDefinitionRequest>( + TypeDefinitionParams { text_document_position_params: TextDocumentPositionParams::new( server.doc_id("src/main.rs"), Position::new(29, 9), @@ -1308,8 +1300,8 @@ let server = Project::with_fixture(code).tmp_dir(tmp_dir).server().wait_until_workspace_is_loaded(); - //rename same level file - server.request::<WillRenameFiles>( + // rename same level file + server.request::<WillRenameFilesRequest>( RenameFilesParams { files: vec![FileRename { old_uri: base_path.join("src/old_file.rs").to_str().unwrap().to_owned(), @@ -1343,8 +1335,8 @@ }), ); - //rename file from mod.rs to foo.rs - server.request::<WillRenameFiles>( + // rename file from mod.rs to foo.rs + server.request::<WillRenameFilesRequest>( RenameFilesParams { files: vec![FileRename { old_uri: base_path.join("src/from_mod/mod.rs").to_str().unwrap().to_owned(), @@ -1354,8 +1346,8 @@ json!(null), ); - //rename file from foo.rs to mod.rs - server.request::<WillRenameFiles>( + // rename file from foo.rs to mod.rs + server.request::<WillRenameFilesRequest>( RenameFilesParams { files: vec![FileRename { old_uri: base_path.join("src/to_mod/foo.rs").to_str().unwrap().to_owned(), @@ -1365,8 +1357,8 @@ json!(null), ); - //rename same level file - server.request::<WillRenameFiles>( + // rename same level file + server.request::<WillRenameFilesRequest>( RenameFilesParams { files: vec![FileRename { old_uri: base_path.join("src/old_folder").to_str().unwrap().to_owned(), @@ -1568,7 +1560,7 @@ .server() .wait_until_workspace_is_loaded(); - let res = server.send_request::<rust_analyzer::lsp::ext::EvaluatePredicate>( + let res = server.send_request::<rust_analyzer::lsp::ext::EvaluatePredicateRequest>( rust_analyzer::lsp::ext::EvaluatePredicateParams { text: "T: Trait".to_owned(), text_document: server.doc_id("src/lib.rs"), @@ -1607,7 +1599,7 @@ .server() .wait_until_workspace_is_loaded(); - let res = server.send_request::<rust_analyzer::lsp::ext::GetFailedObligations>( + let res = server.send_request::<rust_analyzer::lsp::ext::GetFailedObligationsRequest>( 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 dd113ba..7ac3465 100644 --- a/crates/rust-analyzer/tests/slow-tests/ratoml.rs +++ b/crates/rust-analyzer/tests/slow-tests/ratoml.rs
@@ -1,23 +1,24 @@ use crate::support::{Project, Server}; use crate::testdir::TestDir; use lsp_types::{ - DidChangeTextDocumentParams, DidOpenTextDocumentParams, DidSaveTextDocumentParams, - TextDocumentContentChangeEvent, TextDocumentIdentifier, TextDocumentItem, Url, + DidChangeTextDocumentNotification, DidChangeTextDocumentParams, + DidOpenTextDocumentNotification, DidOpenTextDocumentParams, DidSaveTextDocumentNotification, + DidSaveTextDocumentParams, TextDocumentContentChangeEvent, + TextDocumentContentChangeWholeDocument, TextDocumentIdentifier, TextDocumentItem, Uri, VersionedTextDocumentIdentifier, - notification::{DidChangeTextDocument, DidOpenTextDocument, DidSaveTextDocument}, }; use paths::Utf8PathBuf; use rust_analyzer::config::Config; use rust_analyzer::lsp::ext::{ - InternalTestingFetchConfig, InternalTestingFetchConfigOption, InternalTestingFetchConfigParams, - InternalTestingFetchConfigResponse, + InternalTestingFetchConfigOption, InternalTestingFetchConfigParams, + InternalTestingFetchConfigRequest, InternalTestingFetchConfigResponse, }; use serde_json::json; use test_utils::skip_slow_tests; struct RatomlTest { - urls: Vec<Url>, + urls: Vec<Uri>, server: Server, tmp_path: Utf8PathBuf, } @@ -54,7 +55,7 @@ case } - fn fixture_path(&self, fixture: &str) -> Url { + fn fixture_path(&self, fixture: &str) -> Uri { let mut lines = fixture.trim().split('\n'); let mut path = @@ -81,7 +82,7 @@ path = path.join(piece); } - Url::parse( + Uri::parse( format!("file://{}", path.into_string().replace("C:\\", "/c:/").replace('\\', "/")) .as_str(), ) @@ -89,65 +90,75 @@ } fn create(&mut self, fixture_path: &str, text: String) { - let url = self.fixture_path(fixture_path); + let uri = self.fixture_path(fixture_path); - self.server.notification::<DidOpenTextDocument>(DidOpenTextDocumentParams { + self.server.notification::<DidOpenTextDocumentNotification>(DidOpenTextDocumentParams { text_document: TextDocumentItem { - uri: url.clone(), - language_id: "rust".to_owned(), + uri: uri.clone(), + language_id: lsp_types::LanguageKind::Rust, version: 0, text: String::new(), }, }); - self.server.notification::<DidChangeTextDocument>(DidChangeTextDocumentParams { - text_document: VersionedTextDocumentIdentifier { uri: url, version: 0 }, - content_changes: vec![TextDocumentContentChangeEvent { - range: None, - range_length: None, - text, - }], - }); + self.server.notification::<DidChangeTextDocumentNotification>( + DidChangeTextDocumentParams { + text_document: VersionedTextDocumentIdentifier { + text_document_identifier: TextDocumentIdentifier { uri }, + version: 0, + }, + + content_changes: vec![ + TextDocumentContentChangeEvent::TextDocumentContentChangeWholeDocument( + TextDocumentContentChangeWholeDocument { text }, + ), + ], + }, + ); } fn delete(&mut self, file_idx: usize) { - self.server.notification::<DidOpenTextDocument>(DidOpenTextDocumentParams { + self.server.notification::<DidOpenTextDocumentNotification>(DidOpenTextDocumentParams { text_document: TextDocumentItem { uri: self.urls[file_idx].clone(), - language_id: "rust".to_owned(), + language_id: lsp_types::LanguageKind::Rust, 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::<DidSaveTextDocument>(DidSaveTextDocumentParams { + self.server.notification::<DidSaveTextDocumentNotification>(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::<DidOpenTextDocument>(DidOpenTextDocumentParams { + self.server.notification::<DidOpenTextDocumentNotification>(DidOpenTextDocumentParams { text_document: TextDocumentItem { uri: self.urls[file_idx].clone(), - language_id: "rust".to_owned(), + language_id: lsp_types::LanguageKind::Rust, version: 0, text: String::new(), }, }); - self.server.notification::<DidChangeTextDocument>(DidChangeTextDocumentParams { - text_document: VersionedTextDocumentIdentifier { - uri: self.urls[file_idx].clone(), - version: 0, + 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 }, + ), + ], }, - content_changes: vec![TextDocumentContentChangeEvent { - range: None, - range_length: None, - text, - }], - }); + ); } fn query( @@ -156,7 +167,7 @@ source_file_idx: usize, expected: InternalTestingFetchConfigResponse, ) { - let res = self.server.send_request::<InternalTestingFetchConfig>( + let res = self.server.send_request::<InternalTestingFetchConfigRequest>( 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 2c4b978..c3568ce 100644 --- a/crates/rust-analyzer/tests/slow-tests/support.rs +++ b/crates/rust-analyzer/tests/slow-tests/support.rs
@@ -9,7 +9,7 @@ use itertools::Itertools; use lsp_server::{Connection, Message, Notification, Request}; use lsp_types::{ - PublishDiagnosticsParams, TextDocumentIdentifier, Url, notification::Exit, request::Shutdown, + ExitNotification, PublishDiagnosticsParams, ShutdownRequest, TextDocumentIdentifier, Uri, }; use parking_lot::{Mutex, MutexGuard}; use paths::{Utf8Path, Utf8PathBuf}; @@ -229,13 +229,13 @@ ..Default::default() }), text_document: Some(lsp_types::TextDocumentClientCapabilities { - definition: Some(lsp_types::GotoCapability { + definition: Some(lsp_types::DefinitionClientCapabilities { link_support: Some(true), ..Default::default() }), code_action: Some(lsp_types::CodeActionClientCapabilities { code_action_literal_support: Some( - lsp_types::CodeActionLiteralSupport::default(), + lsp_types::ClientCodeActionLiteralOptions::default(), ), ..Default::default() }), @@ -244,7 +244,7 @@ ..Default::default() }), inlay_hint: Some(lsp_types::InlayHintClientCapabilities { - resolve_support: Some(lsp_types::InlayHintResolveClientCapabilities { + resolve_support: Some(lsp_types::ClientInlayHintResolveOptions { properties: vec![ "textEdits".to_owned(), "tooltip".to_owned(), @@ -321,22 +321,22 @@ pub(crate) fn doc_id(&self, rel_path: &str) -> TextDocumentIdentifier { let path = self.dir.path().join(rel_path); - TextDocumentIdentifier { uri: Url::from_file_path(path).unwrap() } + TextDocumentIdentifier { uri: Uri::from_file_path(path).unwrap() } } pub(crate) fn notification<N>(&self, params: N::Params) where - N: lsp_types::notification::Notification, + N: lsp_types::Notification, N::Params: Serialize, { - let r = Notification::new(N::METHOD.to_owned(), params); + let r = Notification::new(N::METHOD.into(), params); self.send_notification(r) } #[track_caller] pub(crate) fn request<R>(&self, params: R::Params, expected_resp: Value) where - R: lsp_types::request::Request, + R: lsp_types::Request, R::Params: Serialize, { let actual = self.send_request::<R>(params); @@ -354,13 +354,13 @@ #[track_caller] pub(crate) fn send_request<R>(&self, params: R::Params) -> Value where - R: lsp_types::request::Request, + R: lsp_types::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.to_owned(), params); + let r = Request::new(id.into(), R::METHOD.into(), params); self.send_request_(r) } #[track_caller] @@ -494,7 +494,7 @@ 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::notification::DidSaveTextDocument>( + self.notification::<lsp_types::DidSaveTextDocumentNotification>( lsp_types::DidSaveTextDocumentParams { text_document: self.doc_id(path), text: Some(text), @@ -505,8 +505,8 @@ impl Drop for Server { fn drop(&mut self) { - self.request::<Shutdown>((), Value::Null); - self.notification::<Exit>(()); + self.request::<ShutdownRequest>((), Value::Null); + self.notification::<ExitNotification>(()); } }
diff --git a/docs/book/src/contributing/lsp-extensions.md b/docs/book/src/contributing/lsp-extensions.md index a318940..6902bce 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: cec81c987f189e83 +lsp/ext.rs hash: ca646d2ad3d38ccd 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,9 +31,10 @@ 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` @@ -131,7 +132,6 @@ **Response:** `Location | Location[] | LocationLink[] | null` - ### Example ```rust @@ -671,7 +671,6 @@ Triggers the flycheck processes. - **Method:** `rust-analyzer/clearFlycheck` **Notification:** @@ -849,6 +848,7 @@ ``` Such actions on the client side are appended to a hover bottom as command links: + ``` +-----------------------------+ | Hover content | @@ -875,7 +875,6 @@ **Response:** `Location | null` - ### Example ```rust @@ -919,6 +918,7 @@ 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,7 +965,6 @@ 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 { /** @@ -1002,7 +1001,6 @@ This extensions allows the client to communicate this info. - ```typescript export interface ClientCommandOptions { /** @@ -1050,6 +1048,7 @@ ``` **Response:** + ```typescript export interface FetchDependencyListResult { crates: { @@ -1059,6 +1058,7 @@ }[]; } ``` + 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 @@ 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 f56a0de..606ee2e 100644 --- a/lib/lsp-server/Cargo.toml +++ b/lib/lsp-server/Cargo.toml
@@ -1,6 +1,6 @@ [package] name = "lsp-server" -version = "0.7.9" +version = "0.8.0" description = "Generic LSP server scaffold." license = "MIT OR Apache-2.0" repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/lsp-server" @@ -14,7 +14,9 @@ crossbeam-channel.workspace = true [dev-dependencies] -lsp-types = "=0.95" +lsp-types = { version = "0.4.0", package = "gen-lsp-types", features = [ + "url", +] } 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 5eef999..b7dcef9 100644 --- a/lib/lsp-server/examples/minimal_lsp.rs +++ b/lib/lsp-server/examples/minimal_lsp.rs
@@ -67,6 +67,15 @@ 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 @@ -74,39 +83,6 @@ #[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 @@ -121,11 +97,11 @@ // advertised capabilities let caps = ServerCapabilities { - text_document_sync: Some(TextDocumentSyncCapability::Kind(TextDocumentSyncKind::FULL)), + text_document_sync: Some(TextDocumentSync::Kind(lsp_types::TextDocumentSyncKind::Full)), completion_provider: Some(CompletionOptions::default()), - definition_provider: Some(OneOf::Left(true)), - hover_provider: Some(HoverProviderCapability::Simple(true)), - document_formatting_provider: Some(OneOf::Left(true)), + definition_provider: Some(lsp_types::DefinitionProvider::Bool(true)), + hover_provider: Some(HoverProvider::Bool(true)), + document_formatting_provider: Some(lsp_types::DocumentFormattingProvider::Bool(true)), ..Default::default() }; let init_value = serde_json::json!({ @@ -149,7 +125,7 @@ params: serde_json::Value, ) -> std::result::Result<(), Box<dyn Error + Sync + Send>> { let _init: InitializeParams = serde_json::from_value(params)?; - let mut docs: FxHashMap<Url, String> = FxHashMap::default(); + let mut docs: FxHashMap<Uri, String> = FxHashMap::default(); for msg in &connection.receiver { match msg { @@ -179,20 +155,25 @@ fn handle_notification( conn: &Connection, note: &lsp_server::Notification, - docs: &mut FxHashMap<Url, String>, + docs: &mut FxHashMap<Uri, String>, ) -> Result<()> { - match note.method.as_str() { - DidOpenTextDocument::METHOD => { + let method: LspNotificationMethod = note.method.clone().into(); + match method { + DidOpenTextDocumentNotification::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)?; } - DidChangeTextDocument::METHOD => { + DidChangeTextDocumentNotification::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.uri; - docs.insert(uri.clone(), change.text); + 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); publish_dummy_diag(conn, &uri)?; } } @@ -208,31 +189,43 @@ fn handle_request( conn: &Connection, req: &ServerRequest, - docs: &mut FxHashMap<Url, String>, + docs: &mut FxHashMap<Uri, String>, ) -> Result<()> { - match req.method.as_str() { - GotoDefinition::METHOD => { - send_ok(conn, req.id.clone(), &lsp_types::GotoDefinitionResponse::Array(Vec::new()))?; + let parsed: LspRequestMethod = req.method.clone().into(); + match parsed { + DefinitionRequest::METHOD => { + send_ok( + conn, + req.id.clone(), + &lsp_types::DefinitionResponse::DefinitionLinkList(Vec::new()), + )?; } - Completion::METHOD => { + CompletionRequest::METHOD => { let item = CompletionItem { label: "HelloFromLSP".into(), - kind: Some(CompletionItemKind::FUNCTION), + kind: Some(CompletionItemKind::Function), detail: Some("dummy completion".into()), ..Default::default() }; - send_ok(conn, req.id.clone(), &CompletionResponse::Array(vec![item]))?; + 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)?; } HoverRequest::METHOD => { let hover = Hover { - contents: HoverContents::Scalar(MarkedString::String( + contents: Contents::MarkedString(MarkedString::String( "Hello from *minimal_lsp*".into(), )), range: None, }; send_ok(conn, req.id.clone(), &hover)?; } - Formatting::METHOD => { + DocumentFormattingRequest::METHOD => { let p: DocumentFormattingParams = serde_json::from_value(req.params.clone())?; let uri = p.text_document.uri; let text = docs @@ -255,10 +248,10 @@ // ===================================================================== // diagnostics // ===================================================================== -fn publish_dummy_diag(conn: &Connection, uri: &Url) -> Result<()> { +fn publish_dummy_diag(conn: &Connection, uri: &Uri) -> 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()), @@ -270,7 +263,7 @@ let params = PublishDiagnosticsParams { uri: uri.clone(), diagnostics: vec![diag], version: None }; conn.sender.send(Message::Notification(lsp_server::Notification::new( - PublishDiagnostics::METHOD.to_owned(), + PublishDiagnosticsNotification::METHOD.into(), params, )))?; Ok(())
diff --git a/lib/lsp-server/src/lib.rs b/lib/lsp-server/src/lib.rs index c8cdb86..3f29c39 100644 --- a/lib/lsp-server/src/lib.rs +++ b/lib/lsp-server/src/lib.rs
@@ -376,9 +376,10 @@ #[cfg(test)] mod tests { use crossbeam_channel::unbounded; - use lsp_types::notification::{Exit, Initialized, Notification}; - use lsp_types::request::{Initialize, Request}; - use lsp_types::{InitializeParams, InitializedParams}; + use lsp_types::{ + ExitNotification, InitializeParams, InitializeRequest, InitializedNotification, + InitializedParams, Notification as _, Request as _, + }; use serde_json::to_value; use crate::{Connection, Message, ProtocolError, RequestId}; @@ -406,7 +407,7 @@ #[test] fn not_exit_notification() { let notification = crate::Notification { - method: Initialized::METHOD.to_owned(), + method: InitializedNotification::METHOD.to_string(), params: to_value(InitializedParams {}).unwrap(), }; @@ -414,7 +415,7 @@ let req_id = RequestId::from(234); let request = crate::Request { id: req_id.clone(), - method: Initialize::METHOD.to_owned(), + method: InitializeRequest::METHOD.to_string(), params: params_as_value.clone(), }; @@ -426,8 +427,10 @@ #[test] fn exit_notification() { - let notification = - crate::Notification { method: Exit::METHOD.to_owned(), params: to_value(()).unwrap() }; + let notification = crate::Notification { + method: ExitNotification::METHOD.to_string(), + params: to_value(()).unwrap(), + }; let notification_msg = Message::from(notification); initialize_start_test(TestCase {
diff --git a/lib/smol_str/src/lib.rs b/lib/smol_str/src/lib.rs index b76c1c7..c592cb2 100644 --- a/lib/smol_str/src/lib.rs +++ b/lib/smol_str/src/lib.rs
@@ -721,7 +721,8 @@ fn to_lowercase_smolstr(&self) -> SmolStr { let len = self.len(); if len <= INLINE_CAP { - let (buf, rest) = inline_convert_while_ascii(self, u8::to_ascii_lowercase); + // SAFETY: `to_ascii_lowercase` always converts ASCII to ASCII + let (buf, rest) = unsafe { inline_convert_while_ascii(self, u8::to_ascii_lowercase) }; from_buf_and_chars(buf, len - rest.len(), rest.chars().flat_map(|c| c.to_lowercase())) } else { self.to_lowercase().into() @@ -732,7 +733,8 @@ fn to_uppercase_smolstr(&self) -> SmolStr { let len = self.len(); if len <= INLINE_CAP { - let (buf, rest) = inline_convert_while_ascii(self, u8::to_ascii_uppercase); + // SAFETY: `to_ascii_uppercase` always converts ASCII to ASCII + let (buf, rest) = unsafe { inline_convert_while_ascii(self, u8::to_ascii_uppercase) }; from_buf_and_chars(buf, len - rest.len(), rest.chars().flat_map(|c| c.to_uppercase())) } else { self.to_uppercase().into() @@ -848,8 +850,13 @@ } /// Inline version of std fn `convert_while_ascii`. `s` must have len <= 23. +/// +/// # Safety +/// +/// If the input to `convert` is valid ASCII (<= 0x7F), +/// then the output must be as well. #[inline] -fn inline_convert_while_ascii(s: &str, convert: fn(&u8) -> u8) -> ([u8; INLINE_CAP], &str) { +unsafe fn inline_convert_while_ascii(s: &str, convert: fn(&u8) -> u8) -> ([u8; INLINE_CAP], &str) { // Process the input in chunks of 16 bytes to enable auto-vectorization. // Previously the chunk size depended on the size of `usize`, // but on 32-bit platforms with sse or neon is also the better choice.
diff --git a/rust-version b/rust-version index 5db47ca..f930573 100644 --- a/rust-version +++ b/rust-version
@@ -1 +1 @@ -942ac9ce4116d4ea784c9882659372b34978b1f8 +7fb284d9037fa54f6a9b24261c82b394472cbfd7