Skip to content

Commit dbb0237

Browse files
committed
Add semantic token modifier for crate root
1 parent c30a6a2 commit dbb0237

File tree

10 files changed

+141
-14
lines changed

10 files changed

+141
-14
lines changed

crates/ide/src/syntax_highlighting.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ pub struct HlRange {
133133
// constant:: Emitted for consts.
134134
// consuming:: Emitted for locals that are being consumed when use in a function call.
135135
// controlFlow:: Emitted for control-flow related tokens, this includes the `?` operator.
136+
// crateRoot:: Emitted for crate names, like `serde` and `crate`.
136137
// declaration:: Emitted for names of definitions, like `foo` in `fn foo() {}`.
137138
// defaultLibrary:: Emitted for items from built-in crates (std, core, alloc, test and proc_macro).
138139
// documentation:: Emitted for documentation comments.

crates/ide/src/syntax_highlighting/highlight.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,10 @@ fn token(
164164
T![for] if !is_child_of_impl(&token) => h | HlMod::ControlFlow,
165165
T![unsafe] => h | HlMod::Unsafe,
166166
T![true] | T![false] => HlTag::BoolLiteral.into(),
167-
// self is handled as either a Name or NameRef already
168-
T![self] => return None,
167+
// crate is handled just as a token if it's in an `extern crate`
168+
T![crate] if parent_matches::<ast::ExternCrate>(&token) => h,
169+
// self, crate and super are handled as either a Name or NameRef already
170+
T![self] | T![crate] | T![super] => return None,
169171
T![ref] => token
170172
.parent()
171173
.and_then(ast::IdentPat::cast)
@@ -283,7 +285,7 @@ fn highlight_name_ref(
283285
}
284286
}
285287
};
286-
let h = match name_class {
288+
let mut h = match name_class {
287289
NameRefClass::Definition(def) => {
288290
if let Definition::Local(local) = &def {
289291
if let Some(name) = local.name(db) {
@@ -325,11 +327,15 @@ fn highlight_name_ref(
325327
}
326328
NameRefClass::FieldShorthand { .. } => SymbolKind::Field.into(),
327329
};
328-
if h.tag == HlTag::Symbol(SymbolKind::Module) && name_ref.self_token().is_some() {
329-
SymbolKind::SelfParam.into()
330-
} else {
331-
h
330+
if h.tag == HlTag::Symbol(SymbolKind::Module) {
331+
if name_ref.self_token().is_some() {
332+
return SymbolKind::SelfParam.into();
333+
}
334+
if name_ref.crate_token().is_some() || name_ref.super_token().is_some() {
335+
h.tag = HlTag::Keyword;
336+
}
332337
}
338+
h
333339
})
334340
}
335341

@@ -393,7 +399,13 @@ fn highlight_def(
393399
Definition::Macro(_) => Highlight::new(HlTag::Symbol(SymbolKind::Macro)),
394400
Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)),
395401
Definition::ModuleDef(def) => match def {
396-
hir::ModuleDef::Module(_) => Highlight::new(HlTag::Symbol(SymbolKind::Module)),
402+
hir::ModuleDef::Module(module) => {
403+
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module));
404+
if module.parent(db).is_none() {
405+
h |= HlMod::CrateRoot
406+
}
407+
h
408+
}
397409
hir::ModuleDef::Function(func) => {
398410
let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function));
399411
if let Some(item) = func.as_assoc_item(db) {

crates/ide/src/syntax_highlighting/tags.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ pub enum HlMod {
5555
Consuming,
5656
/// Used with keywords like `if` and `break`.
5757
ControlFlow,
58+
/// Used for crate names, like `serde`.
59+
CrateRoot,
5860
/// Used for items from built-in crates (std, core, alloc, test and proc_macro).
5961
DefaultLibrary,
6062
/// `foo` in `fn foo(x: i32)` is a definition, `foo` in `foo(90 + 2)` is
@@ -194,6 +196,7 @@ impl HlMod {
194196
HlMod::Callable,
195197
HlMod::Consuming,
196198
HlMod::ControlFlow,
199+
HlMod::CrateRoot,
197200
HlMod::DefaultLibrary,
198201
HlMod::Definition,
199202
HlMod::Documentation,
@@ -216,6 +219,7 @@ impl HlMod {
216219
HlMod::Callable => "callable",
217220
HlMod::Consuming => "consuming",
218221
HlMod::ControlFlow => "control",
222+
HlMod::CrateRoot => "crate_root",
219223
HlMod::DefaultLibrary => "default_library",
220224
HlMod::Definition => "declaration",
221225
HlMod::Documentation => "documentation",
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
2+
<style>
3+
body { margin: 0; }
4+
pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
5+
6+
.lifetime { color: #DFAF8F; font-style: italic; }
7+
.label { color: #DFAF8F; font-style: italic; }
8+
.comment { color: #7F9F7F; }
9+
.documentation { color: #629755; }
10+
.intra_doc_link { font-style: italic; }
11+
.injected { opacity: 0.65 ; }
12+
.struct, .enum { color: #7CB8BB; }
13+
.enum_variant { color: #BDE0F3; }
14+
.string_literal { color: #CC9393; }
15+
.field { color: #94BFF3; }
16+
.function { color: #93E0E3; }
17+
.function.unsafe { color: #BC8383; }
18+
.trait.unsafe { color: #BC8383; }
19+
.operator.unsafe { color: #BC8383; }
20+
.mutable.unsafe { color: #BC8383; text-decoration: underline; }
21+
.keyword.unsafe { color: #BC8383; font-weight: bold; }
22+
.parameter { color: #94BFF3; }
23+
.text { color: #DCDCCC; }
24+
.type { color: #7CB8BB; }
25+
.builtin_type { color: #8CD0D3; }
26+
.type_param { color: #DFAF8F; }
27+
.attribute { color: #94BFF3; }
28+
.numeric_literal { color: #BFEBBF; }
29+
.bool_literal { color: #BFE6EB; }
30+
.macro { color: #94BFF3; }
31+
.module { color: #AFD8AF; }
32+
.value_param { color: #DCDCCC; }
33+
.variable { color: #DCDCCC; }
34+
.format_specifier { color: #CC696B; }
35+
.mutable { text-decoration: underline; }
36+
.escape_sequence { color: #94BFF3; }
37+
.keyword { color: #F0DFAF; font-weight: bold; }
38+
.control { font-style: italic; }
39+
.reference { font-style: italic; font-weight: bold; }
40+
41+
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
42+
</style>
43+
<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module crate_root library">foo</span><span class="semicolon">;</span>
44+
<span class="keyword">use</span> <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">iter</span><span class="semicolon">;</span>
45+
46+
<span class="keyword">pub</span> <span class="keyword">const</span> <span class="constant declaration public">NINETY_TWO</span><span class="colon">:</span> <span class="builtin_type">u8</span> <span class="operator">=</span> <span class="numeric_literal">92</span><span class="semicolon">;</span>
47+
48+
<span class="keyword">use</span> <span class="module crate_root library">foo</span> <span class="keyword">as</span> <span class="module crate_root declaration library">foooo</span><span class="semicolon">;</span>
49+
50+
<span class="keyword">pub</span><span class="parenthesis">(</span><span class="keyword crate_root">crate</span><span class="parenthesis">)</span> <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
51+
<span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="module default_library library">iter</span><span class="operator">::</span><span class="function default_library library">repeat</span><span class="parenthesis">(</span><span class="numeric_literal">92</span><span class="parenthesis">)</span><span class="semicolon">;</span>
52+
<span class="brace">}</span>
53+
54+
<span class="keyword">mod</span> <span class="module declaration">bar</span> <span class="brace">{</span>
55+
<span class="keyword">pub</span><span class="parenthesis">(</span><span class="keyword control">in</span> <span class="keyword crate_root">super</span><span class="parenthesis">)</span> <span class="keyword">const</span> <span class="constant declaration">FORTY_TWO</span><span class="colon">:</span> <span class="builtin_type">u8</span> <span class="operator">=</span> <span class="numeric_literal">42</span><span class="semicolon">;</span>
56+
57+
<span class="keyword">mod</span> <span class="module declaration">baz</span> <span class="brace">{</span>
58+
<span class="keyword">use</span> <span class="keyword">super</span><span class="operator">::</span><span class="keyword crate_root">super</span><span class="operator">::</span><span class="constant public">NINETY_TWO</span><span class="semicolon">;</span>
59+
<span class="keyword">use</span> <span class="keyword crate_root">crate</span><span class="operator">::</span><span class="module crate_root library">foooo</span><span class="operator">::</span><span class="struct library">Point</span><span class="semicolon">;</span>
60+
61+
<span class="keyword">pub</span><span class="parenthesis">(</span><span class="keyword control">in</span> <span class="keyword">super</span><span class="operator">::</span><span class="keyword crate_root">super</span><span class="parenthesis">)</span> <span class="keyword">const</span> <span class="constant declaration">TWENTY_NINE</span><span class="colon">:</span> <span class="builtin_type">u8</span> <span class="operator">=</span> <span class="numeric_literal">29</span><span class="semicolon">;</span>
62+
<span class="brace">}</span>
63+
<span class="brace">}</span>
64+
</code></pre>

crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040

4141
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4242
</style>
43-
<pre><code><span class="keyword">use</span> <span class="module default_library library">core</span><span class="operator">::</span><span class="module default_library library">iter</span><span class="semicolon">;</span>
43+
<pre><code><span class="keyword">use</span> <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">iter</span><span class="semicolon">;</span>
4444

4545
<span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
4646
<span class="keyword">let</span> <span class="variable declaration">foo</span> <span class="operator">=</span> <span class="enum_variant default_library library">Some</span><span class="parenthesis">(</span><span class="numeric_literal">92</span><span class="parenthesis">)</span><span class="semicolon">;</span>

crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,6 @@
4040

4141
.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
4242
</style>
43-
<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module default_library library">std</span><span class="semicolon">;</span>
44-
<span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module default_library library">alloc</span> <span class="keyword">as</span> <span class="module default_library declaration library">abc</span><span class="semicolon">;</span>
43+
<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module crate_root default_library library">std</span><span class="semicolon">;</span>
44+
<span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module crate_root default_library library">alloc</span> <span class="keyword">as</span> <span class="module crate_root default_library declaration library">abc</span><span class="semicolon">;</span>
4545
</code></pre>

crates/ide/src/syntax_highlighting/test_data/highlighting.html

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,12 +253,12 @@
253253
<span class="brace">}</span>
254254

255255
<span class="keyword">fn</span> <span class="function declaration">use_foo_items</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
256-
<span class="keyword">let</span> <span class="variable declaration">bob</span> <span class="operator">=</span> <span class="module library">foo</span><span class="operator">::</span><span class="struct library">Person</span> <span class="brace">{</span>
256+
<span class="keyword">let</span> <span class="variable declaration">bob</span> <span class="operator">=</span> <span class="module crate_root library">foo</span><span class="operator">::</span><span class="struct library">Person</span> <span class="brace">{</span>
257257
<span class="field library">name</span><span class="colon">:</span> <span class="string_literal">"Bob"</span><span class="comma">,</span>
258-
<span class="field library">age</span><span class="colon">:</span> <span class="module library">foo</span><span class="operator">::</span><span class="module library">consts</span><span class="operator">::</span><span class="constant library">NUMBER</span><span class="comma">,</span>
258+
<span class="field library">age</span><span class="colon">:</span> <span class="module crate_root library">foo</span><span class="operator">::</span><span class="module library">consts</span><span class="operator">::</span><span class="constant library">NUMBER</span><span class="comma">,</span>
259259
<span class="brace">}</span><span class="semicolon">;</span>
260260

261-
<span class="keyword">let</span> <span class="variable declaration">control_flow</span> <span class="operator">=</span> <span class="module library">foo</span><span class="operator">::</span><span class="function library">identity</span><span class="parenthesis">(</span><span class="module library">foo</span><span class="operator">::</span><span class="enum library">ControlFlow</span><span class="operator">::</span><span class="enum_variant library">Continue</span><span class="parenthesis">)</span><span class="semicolon">;</span>
261+
<span class="keyword">let</span> <span class="variable declaration">control_flow</span> <span class="operator">=</span> <span class="module crate_root library">foo</span><span class="operator">::</span><span class="function library">identity</span><span class="parenthesis">(</span><span class="module crate_root library">foo</span><span class="operator">::</span><span class="enum library">ControlFlow</span><span class="operator">::</span><span class="enum_variant library">Continue</span><span class="parenthesis">)</span><span class="semicolon">;</span>
262262

263263
<span class="keyword control">if</span> <span class="variable">control_flow</span><span class="operator">.</span><span class="function associated consuming library">should_die</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
264264
foo::<span class="macro">die!</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>

crates/ide/src/syntax_highlighting/tests.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,50 @@ fn test_extern_crate() {
776776
);
777777
}
778778

779+
#[test]
780+
fn test_crate_root() {
781+
check_highlighting(
782+
r#"
783+
//- minicore: iterators
784+
//- /main.rs crate:main deps:foo
785+
extern crate foo;
786+
use core::iter;
787+
788+
pub const NINETY_TWO: u8 = 92;
789+
790+
use foo as foooo;
791+
792+
pub(crate) fn main() {
793+
let baz = iter::repeat(92);
794+
}
795+
796+
mod bar {
797+
pub(in super) const FORTY_TWO: u8 = 42;
798+
799+
mod baz {
800+
use super::super::NINETY_TWO;
801+
use crate::foooo::Point;
802+
803+
pub(in super::super) const TWENTY_NINE: u8 = 29;
804+
}
805+
}
806+
//- /foo.rs crate:foo
807+
struct Point {
808+
x: u8,
809+
y: u8,
810+
}
811+
812+
mod inner {
813+
pub(super) fn swap(p: crate::Point) -> crate::Point {
814+
crate::Point { x: p.y, y: p.x }
815+
}
816+
}
817+
"#,
818+
expect_file!["./test_data/highlight_crate_root.html"],
819+
false,
820+
);
821+
}
822+
779823
#[test]
780824
fn test_default_library() {
781825
check_highlighting(

crates/rust-analyzer/src/semantic_tokens.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ define_semantic_token_modifiers![
9494
(CONSTANT, "constant"),
9595
(CONSUMING, "consuming"),
9696
(CONTROL_FLOW, "controlFlow"),
97+
(CRATE_ROOT, "crateRoot"),
9798
(INJECTED, "injected"),
9899
(INTRA_DOC_LINK, "intraDocLink"),
99100
(LIBRARY, "library"),

crates/rust-analyzer/src/to_proto.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ fn semantic_token_type_and_modifiers(
535535
HlMod::Callable => semantic_tokens::CALLABLE,
536536
HlMod::Consuming => semantic_tokens::CONSUMING,
537537
HlMod::ControlFlow => semantic_tokens::CONTROL_FLOW,
538+
HlMod::CrateRoot => semantic_tokens::CRATE_ROOT,
538539
HlMod::DefaultLibrary => lsp_types::SemanticTokenModifier::DEFAULT_LIBRARY,
539540
HlMod::Definition => lsp_types::SemanticTokenModifier::DECLARATION,
540541
HlMod::Documentation => lsp_types::SemanticTokenModifier::DOCUMENTATION,

0 commit comments

Comments
 (0)