From dc3848a6a3e659004ba4f2160503be28ea0f9051 Mon Sep 17 00:00:00 2001 From: Martin Asquino Date: Fri, 1 Nov 2019 23:52:59 -0300 Subject: Set `deprecated` field on `CompletionItem`s --- crates/ra_ide_api/src/completion/complete_dot.rs | 11 +++ .../completion/complete_macro_in_item_position.rs | 4 ++ crates/ra_ide_api/src/completion/complete_path.rs | 17 +++++ .../src/completion/complete_record_literal.rs | 32 +++++++++ .../src/completion/complete_record_pattern.rs | 3 + crates/ra_ide_api/src/completion/complete_scope.rs | 19 +++++ .../ra_ide_api/src/completion/completion_item.rs | 17 +++++ crates/ra_ide_api/src/completion/presentation.rs | 83 +++++++++++++++++++++- 8 files changed, 185 insertions(+), 1 deletion(-) (limited to 'crates/ra_ide_api/src') diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs index b4df6ee2a..9c0abd590 100644 --- a/crates/ra_ide_api/src/completion/complete_dot.rs +++ b/crates/ra_ide_api/src/completion/complete_dot.rs @@ -96,6 +96,7 @@ mod tests { ⋮ insert: "the_field", ⋮ kind: Field, ⋮ detail: "u32", + ⋮ deprecated: false, ⋮ }, ⋮] "### @@ -128,6 +129,7 @@ mod tests { kind: Method, lookup: "foo", detail: "fn foo(self)", + deprecated: false, }, CompletionItem { label: "the_field", @@ -139,6 +141,7 @@ mod tests { documentation: Documentation( "This is the_field", ), + deprecated: false, }, ] "### @@ -168,6 +171,7 @@ mod tests { kind: Method, lookup: "foo", detail: "fn foo(&self)", + deprecated: false, }, CompletionItem { label: "the_field", @@ -176,6 +180,7 @@ mod tests { insert: "the_field", kind: Field, detail: "(u32, i32)", + deprecated: false, }, ] "### @@ -221,6 +226,7 @@ mod tests { kind: Method, lookup: "the_method", detail: "fn the_method(&self)", + deprecated: false, }, ] "### @@ -250,6 +256,7 @@ mod tests { kind: Method, lookup: "the_method", detail: "fn the_method(&self)", + deprecated: false, }, ] "### @@ -279,6 +286,7 @@ mod tests { kind: Method, lookup: "the_method", detail: "fn the_method(&self)", + deprecated: false, }, ] "### @@ -331,6 +339,7 @@ mod tests { kind: Method, lookup: "the_method", detail: "fn the_method(&self)", + deprecated: false, }, ] "### @@ -401,6 +410,7 @@ mod tests { kind: Method, lookup: "blah", detail: "pub fn blah(&self)", + deprecated: false, }, ] "### @@ -427,6 +437,7 @@ mod tests { ⋮ insert: "the_field", ⋮ kind: Field, ⋮ detail: "u32", + ⋮ deprecated: false, ⋮ }, ⋮] "### diff --git a/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs b/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs index 09f743c66..a082a3c7c 100644 --- a/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs +++ b/crates/ra_ide_api/src/completion/complete_macro_in_item_position.rs @@ -45,6 +45,7 @@ mod tests { insert: "foo!($0)", kind: Macro, detail: "macro_rules! foo", + deprecated: false, }, ]"## ); @@ -86,6 +87,7 @@ mod tests { documentation: Documentation( "Creates a [`Vec`] containing the arguments.\n\n- Create a [`Vec`] containing a given list of elements:\n\n```\nlet v = vec![1, 2, 3];\nassert_eq!(v[0], 1);\nassert_eq!(v[1], 2);\nassert_eq!(v[2], 3);\n```", ), + deprecated: false, }, ]"## ); @@ -121,6 +123,7 @@ mod tests { documentation: Documentation( "Foo\n\nNot call `fooo!()` `fooo!()`, or `_foo![]` `_foo![]`.\nCall as `let _=foo! { hello world };`", ), + deprecated: false, }, CompletionItem { label: "main()", @@ -130,6 +133,7 @@ mod tests { kind: Function, lookup: "main", detail: "fn main()", + deprecated: false, }, ] "### diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs index 9ac9768af..2c9c8645b 100644 --- a/crates/ra_ide_api/src/completion/complete_path.rs +++ b/crates/ra_ide_api/src/completion/complete_path.rs @@ -308,6 +308,7 @@ mod tests { documentation: Documentation( "Bar Variant with i32", ), + deprecated: false, }, CompletionItem { label: "Foo", @@ -319,6 +320,7 @@ mod tests { documentation: Documentation( "Foo Variant", ), + deprecated: false, }, ]"### ); @@ -354,6 +356,7 @@ mod tests { documentation: Documentation( "Bar Variant with i32 and u32", ), + deprecated: false, }, CompletionItem { label: "Foo", @@ -365,6 +368,7 @@ mod tests { documentation: Documentation( "Foo Variant (empty)", ), + deprecated: false, }, CompletionItem { label: "S", @@ -376,6 +380,7 @@ mod tests { documentation: Documentation( "", ), + deprecated: false, }, ]"### ); @@ -411,6 +416,7 @@ mod tests { documentation: Documentation( "An associated method", ), + deprecated: false, }, ] "### @@ -445,6 +451,7 @@ mod tests { documentation: Documentation( "An associated const", ), + deprecated: false, }, ]"### ); @@ -478,6 +485,7 @@ mod tests { documentation: Documentation( "An associated type", ), + deprecated: false, }, ]"### ); @@ -513,6 +521,7 @@ mod tests { documentation: Documentation( "An associated method", ), + deprecated: false, }, ] "### @@ -549,6 +558,7 @@ mod tests { documentation: Documentation( "An associated method", ), + deprecated: false, }, ] "### @@ -608,6 +618,7 @@ mod tests { documentation: Documentation( "A trait method", ), + deprecated: false, }, ] "### @@ -644,6 +655,7 @@ mod tests { documentation: Documentation( "A trait method", ), + deprecated: false, }, ] "### @@ -680,6 +692,7 @@ mod tests { documentation: Documentation( "A trait method", ), + deprecated: false, }, ] "### @@ -711,6 +724,7 @@ mod tests { kind: Function, lookup: "bar", detail: "fn bar()", + deprecated: false, }, CompletionItem { label: "foo()", @@ -720,6 +734,7 @@ mod tests { kind: Function, lookup: "foo", detail: "fn foo()", + deprecated: false, }, ] "### @@ -750,6 +765,7 @@ mod tests { insert: "foo!($0)", kind: Macro, detail: "#[macro_export]\nmacro_rules! foo", + deprecated: false, }, CompletionItem { label: "main()", @@ -759,6 +775,7 @@ mod tests { kind: Function, lookup: "main", detail: "fn main()", + deprecated: false, }, ] "### diff --git a/crates/ra_ide_api/src/completion/complete_record_literal.rs b/crates/ra_ide_api/src/completion/complete_record_literal.rs index 4406695d5..33bea411f 100644 --- a/crates/ra_ide_api/src/completion/complete_record_literal.rs +++ b/crates/ra_ide_api/src/completion/complete_record_literal.rs @@ -31,6 +31,34 @@ mod tests { do_completion(code, CompletionKind::Reference) } + #[test] + fn test_record_literal_deprecated_field() { + let completions = complete( + r" + struct A { + #[deprecated] + the_field: u32, + } + fn foo() { + A { the<|> } + } + ", + ); + assert_debug_snapshot!(completions, @r###" + ⋮[ + ⋮ CompletionItem { + ⋮ label: "the_field", + ⋮ source_range: [142; 145), + ⋮ delete: [142; 145), + ⋮ insert: "the_field", + ⋮ kind: Field, + ⋮ detail: "u32", + ⋮ deprecated: true, + ⋮ }, + ⋮] + "###); + } + #[test] fn test_record_literal_field() { let completions = complete( @@ -50,6 +78,7 @@ mod tests { ⋮ insert: "the_field", ⋮ kind: Field, ⋮ detail: "u32", + ⋮ deprecated: false, ⋮ }, ⋮] "###); @@ -76,6 +105,7 @@ mod tests { ⋮ insert: "a", ⋮ kind: Field, ⋮ detail: "u32", + ⋮ deprecated: false, ⋮ }, ⋮] "###); @@ -102,6 +132,7 @@ mod tests { ⋮ insert: "b", ⋮ kind: Field, ⋮ detail: "u32", + ⋮ deprecated: false, ⋮ }, ⋮] "###); @@ -127,6 +158,7 @@ mod tests { ⋮ insert: "a", ⋮ kind: Field, ⋮ detail: "u32", + ⋮ deprecated: false, ⋮ }, ⋮] "###); diff --git a/crates/ra_ide_api/src/completion/complete_record_pattern.rs b/crates/ra_ide_api/src/completion/complete_record_pattern.rs index d20fa796c..93c26f229 100644 --- a/crates/ra_ide_api/src/completion/complete_record_pattern.rs +++ b/crates/ra_ide_api/src/completion/complete_record_pattern.rs @@ -52,6 +52,7 @@ mod tests { ⋮ insert: "foo", ⋮ kind: Field, ⋮ detail: "u32", + ⋮ deprecated: false, ⋮ }, ⋮] "###); @@ -81,6 +82,7 @@ mod tests { ⋮ insert: "bar", ⋮ kind: Field, ⋮ detail: "()", + ⋮ deprecated: false, ⋮ }, ⋮ CompletionItem { ⋮ label: "foo", @@ -89,6 +91,7 @@ mod tests { ⋮ insert: "foo", ⋮ kind: Field, ⋮ detail: "u32", + ⋮ deprecated: false, ⋮ }, ⋮] "###); diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 4e56de3f5..9d2deee75 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs @@ -155,6 +155,7 @@ mod tests { kind: Function, lookup: "quux", detail: "fn quux(x: i32)", + deprecated: false, }, CompletionItem { label: "x", @@ -218,6 +219,7 @@ mod tests { kind: Function, lookup: "quux", detail: "fn quux()", + deprecated: false, }, ] "### @@ -246,6 +248,7 @@ mod tests { kind: Function, lookup: "quux", detail: "fn quux()", + deprecated: false, }, CompletionItem { label: "x", @@ -286,6 +289,7 @@ mod tests { kind: Function, lookup: "quux", detail: "fn quux()", + deprecated: false, }, ] "### @@ -391,6 +395,7 @@ mod tests { kind: Function, lookup: "quux", detail: "fn quux()", + deprecated: false, }, ] "### @@ -450,6 +455,7 @@ mod tests { kind: Function, lookup: "quux", detail: "fn quux()", + deprecated: false, }, ] "### @@ -482,6 +488,7 @@ mod tests { kind: Function, lookup: "x", detail: "fn x()", + deprecated: false, }, ] "### @@ -520,6 +527,7 @@ mod tests { kind: Function, lookup: "foo", detail: "fn foo()", + deprecated: false, }, ] "### @@ -584,6 +592,7 @@ mod tests { kind: Function, lookup: "foo", detail: "fn foo()", + deprecated: false, }, CompletionItem { label: "std", @@ -639,6 +648,7 @@ mod tests { insert: "bar!($0)", kind: Macro, detail: "macro_rules! bar", + deprecated: false, }, CompletionItem { label: "baz!", @@ -647,6 +657,7 @@ mod tests { insert: "baz!($0)", kind: Macro, detail: "#[macro_export]\nmacro_rules! baz", + deprecated: false, }, CompletionItem { label: "foo!", @@ -655,6 +666,7 @@ mod tests { insert: "foo!($0)", kind: Macro, detail: "macro_rules! foo", + deprecated: false, }, CompletionItem { label: "m1", @@ -678,6 +690,7 @@ mod tests { kind: Function, lookup: "main", detail: "fn main()", + deprecated: false, }, ] "### @@ -708,6 +721,7 @@ mod tests { insert: "foo!($0)", kind: Macro, detail: "macro_rules! foo", + deprecated: false, }, CompletionItem { label: "foo()", @@ -717,6 +731,7 @@ mod tests { kind: Function, lookup: "foo", detail: "fn foo()", + deprecated: false, }, ] "### @@ -747,6 +762,7 @@ mod tests { insert: "foo!($0)", kind: Macro, detail: "macro_rules! foo", + deprecated: false, }, CompletionItem { label: "main()", @@ -756,6 +772,7 @@ mod tests { kind: Function, lookup: "main", detail: "fn main()", + deprecated: false, }, ] "### @@ -786,6 +803,7 @@ mod tests { insert: "foo!($0)", kind: Macro, detail: "macro_rules! foo", + deprecated: false, }, CompletionItem { label: "main()", @@ -795,6 +813,7 @@ mod tests { kind: Function, lookup: "main", detail: "fn main()", + deprecated: false, }, ] "### diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs index 5c9c44704..6753672ca 100644 --- a/crates/ra_ide_api/src/completion/completion_item.rs +++ b/crates/ra_ide_api/src/completion/completion_item.rs @@ -44,6 +44,9 @@ pub struct CompletionItem { /// Additional info to show in the UI pop up. detail: Option, documentation: Option, + + /// Whether this item is marked as deprecated + deprecated: Option, } // We use custom debug for CompletionItem to make `insta`'s diffs more readable. @@ -70,6 +73,9 @@ impl fmt::Debug for CompletionItem { if let Some(documentation) = self.documentation() { s.field("documentation", &documentation); } + if let Some(deprecated) = self.deprecated { + s.field("deprecated", &deprecated); + } s.finish() } } @@ -132,6 +138,7 @@ impl CompletionItem { lookup: None, kind: None, text_edit: None, + deprecated: None, } } /// What user sees in pop-up in the UI. @@ -166,6 +173,10 @@ impl CompletionItem { pub fn kind(&self) -> Option { self.kind } + + pub fn deprecated(&self) -> Option { + self.deprecated + } } /// A helper to make `CompletionItem`s. @@ -181,6 +192,7 @@ pub(crate) struct Builder { lookup: Option, kind: Option, text_edit: Option, + deprecated: Option, } impl Builder { @@ -208,6 +220,7 @@ impl Builder { lookup: self.lookup, kind: self.kind, completion_kind: self.completion_kind, + deprecated: self.deprecated, } } pub(crate) fn lookup_by(mut self, lookup: impl Into) -> Builder { @@ -254,6 +267,10 @@ impl Builder { self.documentation = docs.map(Into::into); self } + pub(crate) fn set_deprecated(mut self, deprecated: bool) -> Builder { + self.deprecated = Some(deprecated); + self + } } impl<'a> Into for Builder { diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index 65bb639ed..d98201887 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs @@ -2,7 +2,7 @@ use hir::{db::HirDatabase, Docs, HasSource, HirDisplay, ScopeDef, Ty, TypeWalk}; use join_to_string::join; -use ra_syntax::ast::NameOwner; +use ra_syntax::ast::{AttrsOwner, NameOwner}; use test_utils::tested_by; use crate::completion::{ @@ -18,6 +18,11 @@ impl Completions { field: hir::StructField, substs: &hir::Substs, ) { + let ast_node = field.source(ctx.db).ast; + let is_deprecated = match ast_node { + hir::FieldSource::Named(m) => is_deprecated(m), + hir::FieldSource::Pos(m) => is_deprecated(m), + }; CompletionItem::new( CompletionKind::Reference, ctx.source_range(), @@ -26,6 +31,7 @@ impl Completions { .kind(CompletionItemKind::Field) .detail(field.ty(ctx.db).subst(substs).display(ctx.db).to_string()) .set_documentation(field.docs(ctx.db)) + .set_deprecated(is_deprecated) .add_to(self); } @@ -179,6 +185,7 @@ impl Completions { CompletionItem::new(CompletionKind::Reference, ctx.source_range(), ¯o_declaration) .kind(CompletionItemKind::Macro) .set_documentation(docs.clone()) + .set_deprecated(is_deprecated(ast_node)) .detail(detail); builder = if ctx.use_item_syntax.is_some() { @@ -211,6 +218,7 @@ impl Completions { CompletionItemKind::Function }) .set_documentation(func.docs(ctx.db)) + .set_deprecated(is_deprecated(ast_node)) .detail(detail); // Add `<>` for generic types @@ -242,6 +250,7 @@ impl Completions { CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.text().to_string()) .kind(CompletionItemKind::Const) .set_documentation(constant.docs(ctx.db)) + .set_deprecated(is_deprecated(ast_node)) .detail(detail) .add_to(self); } @@ -257,11 +266,13 @@ impl Completions { CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.text().to_string()) .kind(CompletionItemKind::TypeAlias) .set_documentation(type_alias.docs(ctx.db)) + .set_deprecated(is_deprecated(type_def)) .detail(detail) .add_to(self); } pub(crate) fn add_enum_variant(&mut self, ctx: &CompletionContext, variant: hir::EnumVariant) { + let is_deprecated = is_deprecated(variant.source(ctx.db).ast); let name = match variant.name(ctx.db) { Some(it) => it, None => return, @@ -274,11 +285,16 @@ impl Completions { CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string()) .kind(CompletionItemKind::EnumVariant) .set_documentation(variant.docs(ctx.db)) + .set_deprecated(is_deprecated) .detail(detail) .add_to(self); } } +fn is_deprecated(node: impl AttrsOwner) -> bool { + node.attrs().filter_map(|x| x.simple_name()).any(|x| x == "deprecated") +} + fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool { let subst = db.generic_defaults(def); subst.iter().any(|ty| ty == &Ty::Unknown) @@ -295,6 +311,57 @@ mod tests { do_completion(code, CompletionKind::Reference) } + #[test] + fn sets_deprecated_flag_in_completion_items() { + assert_debug_snapshot!( + do_reference_completion( + r#" + #[deprecated] + fn something_deprecated() {} + + #[deprecated(since = "1.0.0")] + fn something_else_deprecated() {} + + fn main() { som<|> } + "#, + ), + @r###" + [ + CompletionItem { + label: "main()", + source_range: [203; 206), + delete: [203; 206), + insert: "main()$0", + kind: Function, + lookup: "main", + detail: "fn main()", + deprecated: false, + }, + CompletionItem { + label: "something_deprecated()", + source_range: [203; 206), + delete: [203; 206), + insert: "something_deprecated()$0", + kind: Function, + lookup: "something_deprecated", + detail: "fn something_deprecated()", + deprecated: true, + }, + CompletionItem { + label: "something_else_deprecated()", + source_range: [203; 206), + delete: [203; 206), + insert: "something_else_deprecated()$0", + kind: Function, + lookup: "something_else_deprecated", + detail: "fn something_else_deprecated()", + deprecated: true, + }, + ] + "### + ); + } + #[test] fn inserts_parens_for_function_calls() { covers!(inserts_parens_for_function_calls); @@ -315,6 +382,7 @@ mod tests { kind: Function, lookup: "main", detail: "fn main()", + deprecated: false, }, CompletionItem { label: "no_args()", @@ -324,6 +392,7 @@ mod tests { kind: Function, lookup: "no_args", detail: "fn no_args()", + deprecated: false, }, ] "### @@ -345,6 +414,7 @@ mod tests { kind: Function, lookup: "main", detail: "fn main()", + deprecated: false, }, CompletionItem { label: "with_args(…)", @@ -354,6 +424,7 @@ mod tests { kind: Function, lookup: "with_args", detail: "fn with_args(x: i32, y: String)", + deprecated: false, }, ] "### @@ -380,6 +451,7 @@ mod tests { kind: Method, lookup: "foo", detail: "fn foo(&self)", + deprecated: false, }, ] "### @@ -404,6 +476,7 @@ mod tests { insert: "foo", kind: Function, detail: "pub fn foo()", + deprecated: false, }, ]"# ); @@ -429,6 +502,7 @@ mod tests { insert: "frobnicate", kind: Function, detail: "fn frobnicate()", + deprecated: false, }, CompletionItem { label: "main", @@ -437,6 +511,7 @@ mod tests { insert: "main", kind: Function, detail: "fn main()", + deprecated: false, }, ]"# ); @@ -459,6 +534,7 @@ mod tests { insert: "new", kind: Function, detail: "fn new() -> Foo", + deprecated: false, }, ]"# ); @@ -492,6 +568,7 @@ mod tests { kind: Function, lookup: "foo", detail: "fn foo(xs: Ve)", + deprecated: false, }, ] "### @@ -521,6 +598,7 @@ mod tests { kind: Function, lookup: "foo", detail: "fn foo(xs: Ve)", + deprecated: false, }, ] "### @@ -549,6 +627,7 @@ mod tests { kind: Function, lookup: "foo", detail: "fn foo(xs: Ve)", + deprecated: false, }, ] "### @@ -577,6 +656,7 @@ mod tests { kind: Function, lookup: "foo", detail: "fn foo(xs: Ve)", + deprecated: false, }, ] "### @@ -607,6 +687,7 @@ mod tests { insert: "frobnicate", kind: Macro, detail: "#[macro_export]\nmacro_rules! frobnicate", + deprecated: false, }, ] "### -- cgit v1.2.3