diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index cb23fec3c7..03d513fe4d 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs @@ -133,6 +133,7 @@ pub struct HlRange { // constant:: Emitted for consts. // consuming:: Emitted for locals that are being consumed when use in a function call. // controlFlow:: Emitted for control-flow related tokens, this includes the `?` operator. +// crateRoot:: Emitted for crate names, like `serde` and `crate`. // declaration:: Emitted for names of definitions, like `foo` in `fn foo() {}`. // defaultLibrary:: Emitted for items from built-in crates (std, core, alloc, test and proc_macro). // documentation:: Emitted for documentation comments. diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index 65705d303c..d2ec3ca939 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs @@ -164,8 +164,10 @@ fn token( T![for] if !is_child_of_impl(&token) => h | HlMod::ControlFlow, T![unsafe] => h | HlMod::Unsafe, T![true] | T![false] => HlTag::BoolLiteral.into(), - // self is handled as either a Name or NameRef already - T![self] => return None, + // crate is handled just as a token if it's in an `extern crate` + T![crate] if parent_matches::(&token) => h, + // self, crate and super are handled as either a Name or NameRef already + T![self] | T![crate] | T![super] => return None, T![ref] => token .parent() .and_then(ast::IdentPat::cast) @@ -283,7 +285,7 @@ fn highlight_name_ref( } } }; - let h = match name_class { + let mut h = match name_class { NameRefClass::Definition(def) => { if let Definition::Local(local) = &def { if let Some(name) = local.name(db) { @@ -325,11 +327,15 @@ fn highlight_name_ref( } NameRefClass::FieldShorthand { .. } => SymbolKind::Field.into(), }; - if h.tag == HlTag::Symbol(SymbolKind::Module) && name_ref.self_token().is_some() { - SymbolKind::SelfParam.into() - } else { - h + if h.tag == HlTag::Symbol(SymbolKind::Module) { + if name_ref.self_token().is_some() { + return SymbolKind::SelfParam.into(); + } + if name_ref.crate_token().is_some() || name_ref.super_token().is_some() { + h.tag = HlTag::Keyword; + } } + h }) } @@ -393,7 +399,13 @@ fn highlight_def( Definition::Macro(_) => Highlight::new(HlTag::Symbol(SymbolKind::Macro)), Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)), Definition::ModuleDef(def) => match def { - hir::ModuleDef::Module(_) => Highlight::new(HlTag::Symbol(SymbolKind::Module)), + hir::ModuleDef::Module(module) => { + let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module)); + if module.parent(db).is_none() { + h |= HlMod::CrateRoot + } + h + } hir::ModuleDef::Function(func) => { let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function)); if let Some(item) = func.as_assoc_item(db) { diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs index 0f9a99efac..92c7fcab76 100644 --- a/crates/ide/src/syntax_highlighting/tags.rs +++ b/crates/ide/src/syntax_highlighting/tags.rs @@ -55,6 +55,8 @@ pub enum HlMod { Consuming, /// Used with keywords like `if` and `break`. ControlFlow, + /// Used for crate names, like `serde`. + CrateRoot, /// Used for items from built-in crates (std, core, alloc, test and proc_macro). DefaultLibrary, /// `foo` in `fn foo(x: i32)` is a definition, `foo` in `foo(90 + 2)` is @@ -194,6 +196,7 @@ impl HlMod { HlMod::Callable, HlMod::Consuming, HlMod::ControlFlow, + HlMod::CrateRoot, HlMod::DefaultLibrary, HlMod::Definition, HlMod::Documentation, @@ -216,6 +219,7 @@ impl HlMod { HlMod::Callable => "callable", HlMod::Consuming => "consuming", HlMod::ControlFlow => "control", + HlMod::CrateRoot => "crate_root", HlMod::DefaultLibrary => "default_library", HlMod::Definition => "declaration", HlMod::Documentation => "documentation", diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html b/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html new file mode 100644 index 0000000000..8b4a76453b --- /dev/null +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html @@ -0,0 +1,64 @@ + + +
extern crate foo;
+use core::iter;
+
+pub const NINETY_TWO: u8 = 92;
+
+use foo as foooo;
+
+pub(crate) fn main() {
+    let baz = iter::repeat(92);
+}
+
+mod bar {
+    pub(in super) const FORTY_TWO: u8 = 42;
+
+    mod baz {
+        use super::super::NINETY_TWO;
+        use crate::foooo::Point;
+
+        pub(in super::super) const TWENTY_NINE: u8 = 29;
+    }
+}
+
\ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html b/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html index 33d3196cdb..ea68f5f14a 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html @@ -40,7 +40,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } -
use core::iter;
+
use core::iter;
 
 fn main() {
     let foo = Some(92);
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html b/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
index 92cfa0d0a8..ca869c78be 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
@@ -40,6 +40,6 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
 .unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
 
-
extern crate std;
-extern crate alloc as abc;
+
extern crate std;
+extern crate alloc as abc;
 
\ No newline at end of file diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index 7918a96275..05e6739830 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html @@ -253,12 +253,12 @@ proc_macros::mirror! { } fn use_foo_items() { - let bob = foo::Person { + let bob = foo::Person { name: "Bob", - age: foo::consts::NUMBER, + age: foo::consts::NUMBER, }; - let control_flow = foo::identity(foo::ControlFlow::Continue); + let control_flow = foo::identity(foo::ControlFlow::Continue); if control_flow.should_die() { foo::die!(); diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index fd8e1a0e21..6972d431d2 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs @@ -779,6 +779,50 @@ fn test_extern_crate() { ); } +#[test] +fn test_crate_root() { + check_highlighting( + r#" + //- minicore: iterators + //- /main.rs crate:main deps:foo + extern crate foo; + use core::iter; + + pub const NINETY_TWO: u8 = 92; + + use foo as foooo; + + pub(crate) fn main() { + let baz = iter::repeat(92); + } + + mod bar { + pub(in super) const FORTY_TWO: u8 = 42; + + mod baz { + use super::super::NINETY_TWO; + use crate::foooo::Point; + + pub(in super::super) const TWENTY_NINE: u8 = 29; + } + } + //- /foo.rs crate:foo + struct Point { + x: u8, + y: u8, + } + + mod inner { + pub(super) fn swap(p: crate::Point) -> crate::Point { + crate::Point { x: p.y, y: p.x } + } + } + "#, + expect_file!["./test_data/highlight_crate_root.html"], + false, + ); +} + #[test] fn test_default_library() { check_highlighting( diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs index d5f579f11d..3117b75728 100644 --- a/crates/rust-analyzer/src/semantic_tokens.rs +++ b/crates/rust-analyzer/src/semantic_tokens.rs @@ -94,6 +94,7 @@ define_semantic_token_modifiers![ (CONSTANT, "constant"), (CONSUMING, "consuming"), (CONTROL_FLOW, "controlFlow"), + (CRATE_ROOT, "crateRoot"), (INJECTED, "injected"), (INTRA_DOC_LINK, "intraDocLink"), (LIBRARY, "library"), diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 3508fcc189..e18298fade 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -535,6 +535,7 @@ fn semantic_token_type_and_modifiers( HlMod::Callable => semantic_tokens::CALLABLE, HlMod::Consuming => semantic_tokens::CONSUMING, HlMod::ControlFlow => semantic_tokens::CONTROL_FLOW, + HlMod::CrateRoot => semantic_tokens::CRATE_ROOT, HlMod::DefaultLibrary => lsp_types::SemanticTokenModifier::DEFAULT_LIBRARY, HlMod::Definition => lsp_types::SemanticTokenModifier::DECLARATION, HlMod::Documentation => lsp_types::SemanticTokenModifier::DOCUMENTATION,