From ca6548827634155f28e75bc6cb2e734d2d5d1e95 Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Tue, 19 Jan 2021 01:08:59 +0200 Subject: [PATCH] Show deprecated completions for deprecated traits --- crates/assists/src/handlers/qualify_path.rs | 2 +- .../completion/src/completions/flyimport.rs | 12 +++-- crates/completion/src/render.rs | 47 +++++++++++++++---- crates/completion/src/render/const_.rs | 5 +- crates/completion/src/render/function.rs | 4 +- crates/completion/src/render/type_alias.rs | 5 +- crates/completion/src/test_utils.rs | 3 ++ crates/hir/src/code_model.rs | 19 ++++---- 8 files changed, 69 insertions(+), 28 deletions(-) diff --git a/crates/assists/src/handlers/qualify_path.rs b/crates/assists/src/handlers/qualify_path.rs index af8a11d035..b0b0d31b44 100644 --- a/crates/assists/src/handlers/qualify_path.rs +++ b/crates/assists/src/handlers/qualify_path.rs @@ -1,6 +1,6 @@ use std::iter; -use hir::AsName; +use hir::{AsAssocItem, AsName}; use ide_db::helpers::{import_assets::ImportCandidate, mod_path_to_ast}; use ide_db::RootDatabase; use syntax::{ diff --git a/crates/completion/src/completions/flyimport.rs b/crates/completion/src/completions/flyimport.rs index 47e797ac8b..dc0b38a165 100644 --- a/crates/completion/src/completions/flyimport.rs +++ b/crates/completion/src/completions/flyimport.rs @@ -48,7 +48,7 @@ //! Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corredponding //! capability enabled. -use hir::{ModPath, ScopeDef}; +use hir::{AsAssocItem, ModPath, ScopeDef}; use ide_db::helpers::{ import_assets::{ImportAssets, ImportCandidate}, insert_use::ImportScope, @@ -601,11 +601,12 @@ fn main() { } #[test] - fn zero_input_assoc_item_completion() { + fn zero_input_deprecated_assoc_item_completion() { check( r#" //- /lib.rs crate:dep pub mod test_mod { + #[deprecated] pub trait TestTrait { const SPECIAL_CONST: u8; type HumbleType; @@ -628,7 +629,7 @@ fn main() { } "#, expect![[r#" - me random_method() (dep::test_mod::TestTrait) fn random_method(&self) + me random_method() (dep::test_mod::TestTrait) fn random_method(&self) DEPRECATED "#]], ); @@ -636,6 +637,7 @@ fn main() { r#" //- /lib.rs crate:dep pub mod test_mod { + #[deprecated] pub trait TestTrait { const SPECIAL_CONST: u8; type HumbleType; @@ -657,8 +659,8 @@ fn main() { } "#, expect![[r#" - ct SPECIAL_CONST (dep::test_mod::TestTrait) - fn weird_function() (dep::test_mod::TestTrait) fn weird_function() + ct SPECIAL_CONST (dep::test_mod::TestTrait) DEPRECATED + fn weird_function() (dep::test_mod::TestTrait) fn weird_function() DEPRECATED "#]], ); } diff --git a/crates/completion/src/render.rs b/crates/completion/src/render.rs index dbb30d2334..4f622d28ae 100644 --- a/crates/completion/src/render.rs +++ b/crates/completion/src/render.rs @@ -10,7 +10,9 @@ pub(crate) mod type_alias; mod builder_ext; -use hir::{Documentation, HasAttrs, HirDisplay, ModuleDef, Mutability, ScopeDef, Type}; +use hir::{ + AsAssocItem, Documentation, HasAttrs, HirDisplay, ModuleDef, Mutability, ScopeDef, Type, +}; use ide_db::{helpers::SnippetCap, RootDatabase}; use syntax::TextRange; use test_utils::mark; @@ -91,6 +93,22 @@ impl<'a> RenderContext<'a> { attrs.by_key("deprecated").exists() || attrs.by_key("rustc_deprecated").exists() } + fn is_deprecated_assoc_item(&self, as_assoc_item: impl AsAssocItem) -> bool { + let db = self.db(); + let assoc = match as_assoc_item.as_assoc_item(db) { + Some(assoc) => assoc, + None => return false, + }; + + let is_assoc_deprecated = match assoc { + hir::AssocItem::Function(it) => self.is_deprecated(it), + hir::AssocItem::Const(it) => self.is_deprecated(it), + hir::AssocItem::TypeAlias(it) => self.is_deprecated(it), + }; + is_assoc_deprecated + || assoc.containing_trait(db).map(|trait_| self.is_deprecated(trait_)).unwrap_or(false) + } + fn docs(&self, node: impl HasAttrs) -> Option { node.docs(self.db()) } @@ -207,8 +225,6 @@ impl<'a> Render<'a> { } }; - let docs = self.docs(resolution); - let mut item = CompletionItem::new(completion_kind, self.ctx.source_range(), local_name.clone()); if let ScopeDef::Local(local) = resolution { @@ -254,13 +270,14 @@ impl<'a> Render<'a> { } } - let item = item - .kind(kind) - .add_import(import_to_add) - .set_documentation(docs) - .set_ref_match(ref_match) - .build(); - Some(item) + Some( + item.kind(kind) + .add_import(import_to_add) + .set_ref_match(ref_match) + .set_documentation(self.docs(resolution)) + .set_deprecated(self.is_deprecated(resolution)) + .build(), + ) } fn docs(&self, resolution: &ScopeDef) -> Option { @@ -276,6 +293,16 @@ impl<'a> Render<'a> { _ => None, } } + + fn is_deprecated(&self, resolution: &ScopeDef) -> bool { + match resolution { + ScopeDef::ModuleDef(it) => self.ctx.is_deprecated_assoc_item(*it), + ScopeDef::MacroDef(it) => self.ctx.is_deprecated(*it), + ScopeDef::GenericParam(it) => self.ctx.is_deprecated(*it), + ScopeDef::AdtSelfType(it) => self.ctx.is_deprecated(*it), + _ => false, + } + } } fn compute_score_from_active( diff --git a/crates/completion/src/render/const_.rs b/crates/completion/src/render/const_.rs index ce924f3095..e46452d4e4 100644 --- a/crates/completion/src/render/const_.rs +++ b/crates/completion/src/render/const_.rs @@ -38,7 +38,10 @@ impl<'a> ConstRender<'a> { let item = CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), name) .kind(CompletionItemKind::Const) .set_documentation(self.ctx.docs(self.const_)) - .set_deprecated(self.ctx.is_deprecated(self.const_)) + .set_deprecated( + self.ctx.is_deprecated(self.const_) + || self.ctx.is_deprecated_assoc_item(self.const_), + ) .detail(detail) .build(); diff --git a/crates/completion/src/render/function.rs b/crates/completion/src/render/function.rs index f5b0ce3e31..8f4c662114 100644 --- a/crates/completion/src/render/function.rs +++ b/crates/completion/src/render/function.rs @@ -44,7 +44,9 @@ impl<'a> FunctionRender<'a> { CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), self.name.clone()) .kind(self.kind()) .set_documentation(self.ctx.docs(self.func)) - .set_deprecated(self.ctx.is_deprecated(self.func)) + .set_deprecated( + self.ctx.is_deprecated(self.func) || self.ctx.is_deprecated_assoc_item(self.func), + ) .detail(self.detail()) .add_call_parens(self.ctx.completion, self.name, params) .add_import(import_to_add) diff --git a/crates/completion/src/render/type_alias.rs b/crates/completion/src/render/type_alias.rs index 69b445b9c6..29287143a5 100644 --- a/crates/completion/src/render/type_alias.rs +++ b/crates/completion/src/render/type_alias.rs @@ -38,7 +38,10 @@ impl<'a> TypeAliasRender<'a> { let item = CompletionItem::new(CompletionKind::Reference, self.ctx.source_range(), name) .kind(CompletionItemKind::TypeAlias) .set_documentation(self.ctx.docs(self.type_alias)) - .set_deprecated(self.ctx.is_deprecated(self.type_alias)) + .set_deprecated( + self.ctx.is_deprecated(self.type_alias) + || self.ctx.is_deprecated_assoc_item(self.type_alias), + ) .detail(detail) .build(); diff --git a/crates/completion/src/test_utils.rs b/crates/completion/src/test_utils.rs index 3faf861b9a..baff833051 100644 --- a/crates/completion/src/test_utils.rs +++ b/crates/completion/src/test_utils.rs @@ -83,6 +83,9 @@ pub(crate) fn completion_list_with_config( let width = label_width.saturating_sub(monospace_width(it.label())); format_to!(buf, "{:width$} {}", "", detail, width = width); } + if it.deprecated() { + format_to!(buf, " DEPRECATED"); + } format_to!(buf, "\n"); buf }) diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 2950f08b8f..5a4c279061 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs @@ -272,15 +272,6 @@ impl ModuleDef { hir_ty::diagnostics::validate_module_item(db, module.id.krate, id, sink) } - - pub fn as_assoc_item(self, db: &dyn HirDatabase) -> Option { - match self { - ModuleDef::Function(f) => f.as_assoc_item(db), - ModuleDef::Const(c) => c.as_assoc_item(db), - ModuleDef::TypeAlias(t) => t.as_assoc_item(db), - _ => None, - } - } } impl Module { @@ -1060,6 +1051,16 @@ impl AsAssocItem for TypeAlias { as_assoc_item(db, AssocItem::TypeAlias, self.id) } } +impl AsAssocItem for ModuleDef { + fn as_assoc_item(self, db: &dyn HirDatabase) -> Option { + match self { + ModuleDef::Function(it) => it.as_assoc_item(db), + ModuleDef::Const(it) => it.as_assoc_item(db), + ModuleDef::TypeAlias(it) => it.as_assoc_item(db), + _ => None, + } + } +} fn as_assoc_item(db: &dyn HirDatabase, ctor: CTOR, id: ID) -> Option where ID: Lookup>,