From 4fd5248749202e0578d719bc5480171a85358836 Mon Sep 17 00:00:00 2001 From: Aramis Razzaghipour Date: Sun, 23 May 2021 23:45:26 +1000 Subject: Add highlighting of items from other crates --- crates/hir/src/lib.rs | 17 +++++ crates/ide/src/syntax_highlighting.rs | 3 + crates/ide/src/syntax_highlighting/highlight.rs | 89 +++++++++++++++++++++---- crates/ide/src/syntax_highlighting/tags.rs | 4 ++ crates/rust-analyzer/src/semantic_tokens.rs | 1 + crates/rust-analyzer/src/to_proto.rs | 1 + 6 files changed, 103 insertions(+), 12 deletions(-) (limited to 'crates') diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index a7c42ca1e..6522a924b 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -673,6 +673,11 @@ impl Variant { pub fn module(self, db: &dyn HirDatabase) -> Module { self.parent.module(db) } + + pub fn krate(self, db: &dyn HirDatabase) -> Crate { + self.module(db).krate() + } + pub fn parent_enum(self, _db: &dyn HirDatabase) -> Enum { self.parent } @@ -767,6 +772,10 @@ impl VariantDef { } } + pub fn krate(self, db: &dyn HirDatabase) -> Crate { + self.module(db).krate() + } + pub fn name(&self, db: &dyn HirDatabase) -> Name { match self { VariantDef::Struct(s) => s.name(db), @@ -1074,6 +1083,10 @@ impl Trait { Module { id: self.id.lookup(db.upcast()).container } } + pub fn krate(self, db: &dyn HirDatabase) -> Crate { + self.module(db).krate() + } + pub fn name(self, db: &dyn HirDatabase) -> Name { db.trait_data(self.id).name.clone() } @@ -1178,6 +1191,10 @@ impl MacroDef { Some(Module { id: def_map.module_id(module_id) }) } + pub fn krate(self, db: &dyn HirDatabase) -> Option { + self.module(db).map(Module::krate) + } + /// XXX: this parses the file pub fn name(self, db: &dyn HirDatabase) -> Option { match self.source(db)?.value { diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 9df8d21af..cf1a8bad7 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -80,6 +80,7 @@ pub(crate) fn highlight( &mut hl, &sema, InFile::new(file_id.into(), &root), + sema.scope(&root).krate(), range_to_highlight, syntactic_name_ref_highlighting, ); @@ -90,6 +91,7 @@ fn traverse( hl: &mut Highlights, sema: &Semantics, root: InFile<&SyntaxNode>, + krate: Option, range_to_highlight: TextRange, syntactic_name_ref_highlighting: bool, ) { @@ -209,6 +211,7 @@ fn traverse( if let Some((mut highlight, binding_hash)) = highlight::element( &sema, + krate, &mut bindings_shadow_count, syntactic_name_ref_highlighting, element_to_highlight.clone(), diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 058e37ff0..2d6d8d100 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -19,6 +19,7 @@ use crate::{ pub(super) fn element( sema: &Semantics, + krate: Option, bindings_shadow_count: &mut FxHashMap, syntactic_name_ref_highlighting: bool, element: SyntaxElement, @@ -46,8 +47,10 @@ pub(super) fn element( match name_kind { Some(NameClass::ExternCrate(_)) => SymbolKind::Module.into(), - Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, - Some(NameClass::ConstReference(def)) => highlight_def(db, def), + Some(NameClass::Definition(def)) => { + highlight_def(db, krate, def) | HlMod::Definition + } + Some(NameClass::ConstReference(def)) => highlight_def(db, krate, def), Some(NameClass::PatFieldShorthand { field_ref, .. }) => { let mut h = HlTag::Symbol(SymbolKind::Field).into(); if let Definition::Field(field) = field_ref { @@ -82,7 +85,7 @@ pub(super) fn element( } }; - let mut h = highlight_def(db, def); + let mut h = highlight_def(db, krate, def); if let Definition::Local(local) = &def { if is_consumed_lvalue(name_ref.syntax().clone().into(), local, db) { @@ -136,9 +139,11 @@ pub(super) fn element( let lifetime = element.into_node().and_then(ast::Lifetime::cast).unwrap(); match NameClass::classify_lifetime(sema, &lifetime) { - Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, + Some(NameClass::Definition(def)) => { + highlight_def(db, krate, def) | HlMod::Definition + } None => match NameRefClass::classify_lifetime(sema, &lifetime) { - Some(NameRefClass::Definition(def)) => highlight_def(db, def), + Some(NameRefClass::Definition(def)) => highlight_def(db, krate, def), _ => SymbolKind::LifetimeParam.into(), }, _ => Highlight::from(SymbolKind::LifetimeParam) | HlMod::Definition, @@ -277,10 +282,26 @@ pub(super) fn element( hash((name, shadow_count)) } } -fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { +fn highlight_def(db: &RootDatabase, krate: Option, def: Definition) -> Highlight { match def { - Definition::Macro(_) => HlTag::Symbol(SymbolKind::Macro), - Definition::Field(_) => HlTag::Symbol(SymbolKind::Field), + Definition::Macro(m) => { + let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Macro)); + + if m.krate(db) != krate { + h |= HlMod::Foreign; + } + + return h; + } + Definition::Field(field) => { + let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Field)); + + if Some(field.parent_def(db).krate(db)) != krate { + h |= HlMod::Foreign; + } + + return h; + } Definition::ModuleDef(def) => match def { hir::ModuleDef::Module(_) => HlTag::Symbol(SymbolKind::Module), hir::ModuleDef::Function(func) => { @@ -314,14 +335,37 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { if func.is_async(db) { h |= HlMod::Async; } + if func.krate(db) != krate { + h |= HlMod::Foreign; + } + return h; + } + hir::ModuleDef::Adt(adt) => { + let h = match adt { + hir::Adt::Struct(_) => HlTag::Symbol(SymbolKind::Struct), + hir::Adt::Enum(_) => HlTag::Symbol(SymbolKind::Enum), + hir::Adt::Union(_) => HlTag::Symbol(SymbolKind::Union), + }; + let mut h = Highlight::new(h); + + if Some(adt.krate(db)) != krate { + h |= HlMod::Foreign; + } + + return h; + } + hir::ModuleDef::Variant(variant) => { + let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Variant)); + + if Some(variant.krate(db)) != krate { + h |= HlMod::Foreign; + } + return h; } - hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HlTag::Symbol(SymbolKind::Struct), - hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HlTag::Symbol(SymbolKind::Enum), - hir::ModuleDef::Adt(hir::Adt::Union(_)) => HlTag::Symbol(SymbolKind::Union), - hir::ModuleDef::Variant(_) => HlTag::Symbol(SymbolKind::Variant), hir::ModuleDef::Const(konst) => { let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Const)); + if let Some(item) = konst.as_assoc_item(db) { h |= HlMod::Associated; match item.container(db) { @@ -336,6 +380,10 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { } } + if konst.krate(db) != krate { + h |= HlMod::Foreign; + } + return h; } hir::ModuleDef::Trait(trait_) => { @@ -344,10 +392,16 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { if trait_.is_unsafe(db) { h |= HlMod::Unsafe; } + + if Some(trait_.krate(db)) != krate { + h |= HlMod::Foreign; + } + return h; } hir::ModuleDef::TypeAlias(type_) => { let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias)); + if let Some(item) = type_.as_assoc_item(db) { h |= HlMod::Associated; match item.container(db) { @@ -361,15 +415,26 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { } } } + + if Some(type_.krate(db)) != krate { + h |= HlMod::Foreign; + } + return h; } hir::ModuleDef::BuiltinType(_) => HlTag::BuiltinType, hir::ModuleDef::Static(s) => { let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Static)); + if s.is_mut(db) { h |= HlMod::Mutable; h |= HlMod::Unsafe; } + + if s.krate(db) != krate { + h |= HlMod::Foreign; + } + return h; } }, diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs index 27473a2f9..755599cba 100644 --- a/crates/ide/src/syntax_highlighting/tags.rs +++ b/crates/ide/src/syntax_highlighting/tags.rs @@ -67,6 +67,8 @@ pub enum HlMod { Trait, /// Used with keywords like `async` and `await`. Async, + /// Used for items from other crates. + Foreign, // Keep this last! /// Used for unsafe functions, unsafe traits, mutable statics, union accesses and unsafe operations. Unsafe, @@ -189,6 +191,7 @@ impl HlMod { HlMod::Static, HlMod::Trait, HlMod::Async, + HlMod::Foreign, HlMod::Unsafe, ]; @@ -207,6 +210,7 @@ impl HlMod { HlMod::Static => "static", HlMod::Trait => "trait", HlMod::Async => "async", + HlMod::Foreign => "foreign", HlMod::Unsafe => "unsafe", } } diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs index 4fd576adb..9ebe000b5 100644 --- a/crates/rust-analyzer/src/semantic_tokens.rs +++ b/crates/rust-analyzer/src/semantic_tokens.rs @@ -92,6 +92,7 @@ define_semantic_token_modifiers![ (MUTABLE, "mutable"), (CONSUMING, "consuming"), (ASYNC, "async"), + (FOREIGN, "foreign"), (UNSAFE, "unsafe"), (ATTRIBUTE_MODIFIER, "attribute"), (TRAIT_MODIFIER, "trait"), diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 0a3a56773..6368ba413 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -504,6 +504,7 @@ fn semantic_token_type_and_modifiers( HlMod::Mutable => semantic_tokens::MUTABLE, HlMod::Consuming => semantic_tokens::CONSUMING, HlMod::Async => semantic_tokens::ASYNC, + HlMod::Foreign => semantic_tokens::FOREIGN, HlMod::Unsafe => semantic_tokens::UNSAFE, HlMod::Callable => semantic_tokens::CALLABLE, HlMod::Static => lsp_types::SemanticTokenModifier::STATIC, -- cgit v1.2.3