diff options
Diffstat (limited to 'crates/ide/src')
-rw-r--r-- | crates/ide/src/annotations.rs | 66 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting.rs | 24 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/highlight.rs | 23 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/tags.rs | 2 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/test_data/highlighting.html | 2 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/tests.rs | 8 |
6 files changed, 82 insertions, 43 deletions
diff --git a/crates/ide/src/annotations.rs b/crates/ide/src/annotations.rs index 5ebe7fd0e..b0c4ed60a 100644 --- a/crates/ide/src/annotations.rs +++ b/crates/ide/src/annotations.rs | |||
@@ -5,7 +5,7 @@ use ide_db::{ | |||
5 | helpers::visit_file_defs, | 5 | helpers::visit_file_defs, |
6 | RootDatabase, | 6 | RootDatabase, |
7 | }; | 7 | }; |
8 | use syntax::{ast::NameOwner, AstNode, TextRange, TextSize}; | 8 | use syntax::{ast::NameOwner, AstNode, TextRange}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | fn_references::find_all_methods, | 11 | fn_references::find_all_methods, |
@@ -80,26 +80,26 @@ pub(crate) fn annotations( | |||
80 | 80 | ||
81 | visit_file_defs(&Semantics::new(db), file_id, &mut |def| match def { | 81 | visit_file_defs(&Semantics::new(db), file_id, &mut |def| match def { |
82 | Either::Left(def) => { | 82 | Either::Left(def) => { |
83 | let node = match def { | 83 | let range = match def { |
84 | hir::ModuleDef::Const(konst) => { | 84 | hir::ModuleDef::Const(konst) => { |
85 | konst.source(db).and_then(|node| range_and_position_of(&node, file_id)) | 85 | konst.source(db).and_then(|node| name_range(&node, file_id)) |
86 | } | 86 | } |
87 | hir::ModuleDef::Trait(trait_) => { | 87 | hir::ModuleDef::Trait(trait_) => { |
88 | trait_.source(db).and_then(|node| range_and_position_of(&node, file_id)) | 88 | trait_.source(db).and_then(|node| name_range(&node, file_id)) |
89 | } | 89 | } |
90 | hir::ModuleDef::Adt(hir::Adt::Struct(strukt)) => { | 90 | hir::ModuleDef::Adt(hir::Adt::Struct(strukt)) => { |
91 | strukt.source(db).and_then(|node| range_and_position_of(&node, file_id)) | 91 | strukt.source(db).and_then(|node| name_range(&node, file_id)) |
92 | } | 92 | } |
93 | hir::ModuleDef::Adt(hir::Adt::Enum(enum_)) => { | 93 | hir::ModuleDef::Adt(hir::Adt::Enum(enum_)) => { |
94 | enum_.source(db).and_then(|node| range_and_position_of(&node, file_id)) | 94 | enum_.source(db).and_then(|node| name_range(&node, file_id)) |
95 | } | 95 | } |
96 | hir::ModuleDef::Adt(hir::Adt::Union(union)) => { | 96 | hir::ModuleDef::Adt(hir::Adt::Union(union)) => { |
97 | union.source(db).and_then(|node| range_and_position_of(&node, file_id)) | 97 | union.source(db).and_then(|node| name_range(&node, file_id)) |
98 | } | 98 | } |
99 | _ => None, | 99 | _ => None, |
100 | }; | 100 | }; |
101 | let (offset, range) = match node { | 101 | let (range, offset) = match range { |
102 | Some(node) => node, | 102 | Some(range) => (range, range.start()), |
103 | None => return, | 103 | None => return, |
104 | }; | 104 | }; |
105 | 105 | ||
@@ -122,18 +122,12 @@ pub(crate) fn annotations( | |||
122 | }); | 122 | }); |
123 | } | 123 | } |
124 | 124 | ||
125 | fn range_and_position_of<T: NameOwner>( | 125 | fn name_range<T: NameOwner>(node: &InFile<T>, file_id: FileId) -> Option<TextRange> { |
126 | node: &InFile<T>, | 126 | if node.file_id == file_id.into() { |
127 | file_id: FileId, | 127 | node.value.name().map(|it| it.syntax().text_range()) |
128 | ) -> Option<(TextSize, TextRange)> { | 128 | } else { |
129 | if node.file_id != file_id.into() { | ||
130 | // Node is outside the file we are adding annotations to (e.g. macros). | 129 | // Node is outside the file we are adding annotations to (e.g. macros). |
131 | None | 130 | None |
132 | } else { | ||
133 | Some(( | ||
134 | node.value.name()?.syntax().text_range().start(), | ||
135 | node.value.syntax().text_range(), | ||
136 | )) | ||
137 | } | 131 | } |
138 | } | 132 | } |
139 | } | 133 | } |
@@ -141,13 +135,15 @@ pub(crate) fn annotations( | |||
141 | }); | 135 | }); |
142 | 136 | ||
143 | if config.annotate_method_references { | 137 | if config.annotate_method_references { |
144 | annotations.extend(find_all_methods(db, file_id).into_iter().map(|method| Annotation { | 138 | annotations.extend(find_all_methods(db, file_id).into_iter().map( |
145 | range: method.range, | 139 | |FileRange { file_id, range }| Annotation { |
146 | kind: AnnotationKind::HasReferences { | 140 | range, |
147 | position: FilePosition { file_id, offset: method.range.start() }, | 141 | kind: AnnotationKind::HasReferences { |
148 | data: None, | 142 | position: FilePosition { file_id, offset: range.start() }, |
143 | data: None, | ||
144 | }, | ||
149 | }, | 145 | }, |
150 | })); | 146 | )); |
151 | } | 147 | } |
152 | 148 | ||
153 | annotations | 149 | annotations |
@@ -266,7 +262,7 @@ fn main() { | |||
266 | }, | 262 | }, |
267 | }, | 263 | }, |
268 | Annotation { | 264 | Annotation { |
269 | range: 0..22, | 265 | range: 6..10, |
270 | kind: HasReferences { | 266 | kind: HasReferences { |
271 | position: FilePosition { | 267 | position: FilePosition { |
272 | file_id: FileId( | 268 | file_id: FileId( |
@@ -287,7 +283,7 @@ fn main() { | |||
287 | }, | 283 | }, |
288 | }, | 284 | }, |
289 | Annotation { | 285 | Annotation { |
290 | range: 24..48, | 286 | range: 30..36, |
291 | kind: HasReferences { | 287 | kind: HasReferences { |
292 | position: FilePosition { | 288 | position: FilePosition { |
293 | file_id: FileId( | 289 | file_id: FileId( |
@@ -370,7 +366,7 @@ fn main() { | |||
370 | }, | 366 | }, |
371 | }, | 367 | }, |
372 | Annotation { | 368 | Annotation { |
373 | range: 0..12, | 369 | range: 7..11, |
374 | kind: HasImpls { | 370 | kind: HasImpls { |
375 | position: FilePosition { | 371 | position: FilePosition { |
376 | file_id: FileId( | 372 | file_id: FileId( |
@@ -384,7 +380,7 @@ fn main() { | |||
384 | }, | 380 | }, |
385 | }, | 381 | }, |
386 | Annotation { | 382 | Annotation { |
387 | range: 0..12, | 383 | range: 7..11, |
388 | kind: HasReferences { | 384 | kind: HasReferences { |
389 | position: FilePosition { | 385 | position: FilePosition { |
390 | file_id: FileId( | 386 | file_id: FileId( |
@@ -478,7 +474,7 @@ fn main() { | |||
478 | }, | 474 | }, |
479 | }, | 475 | }, |
480 | Annotation { | 476 | Annotation { |
481 | range: 0..12, | 477 | range: 7..11, |
482 | kind: HasImpls { | 478 | kind: HasImpls { |
483 | position: FilePosition { | 479 | position: FilePosition { |
484 | file_id: FileId( | 480 | file_id: FileId( |
@@ -502,7 +498,7 @@ fn main() { | |||
502 | }, | 498 | }, |
503 | }, | 499 | }, |
504 | Annotation { | 500 | Annotation { |
505 | range: 0..12, | 501 | range: 7..11, |
506 | kind: HasReferences { | 502 | kind: HasReferences { |
507 | position: FilePosition { | 503 | position: FilePosition { |
508 | file_id: FileId( | 504 | file_id: FileId( |
@@ -529,7 +525,7 @@ fn main() { | |||
529 | }, | 525 | }, |
530 | }, | 526 | }, |
531 | Annotation { | 527 | Annotation { |
532 | range: 14..34, | 528 | range: 20..31, |
533 | kind: HasImpls { | 529 | kind: HasImpls { |
534 | position: FilePosition { | 530 | position: FilePosition { |
535 | file_id: FileId( | 531 | file_id: FileId( |
@@ -553,7 +549,7 @@ fn main() { | |||
553 | }, | 549 | }, |
554 | }, | 550 | }, |
555 | Annotation { | 551 | Annotation { |
556 | range: 14..34, | 552 | range: 20..31, |
557 | kind: HasReferences { | 553 | kind: HasReferences { |
558 | position: FilePosition { | 554 | position: FilePosition { |
559 | file_id: FileId( | 555 | file_id: FileId( |
@@ -712,7 +708,7 @@ fn main() { | |||
712 | }, | 708 | }, |
713 | }, | 709 | }, |
714 | Annotation { | 710 | Annotation { |
715 | range: 0..12, | 711 | range: 7..11, |
716 | kind: HasImpls { | 712 | kind: HasImpls { |
717 | position: FilePosition { | 713 | position: FilePosition { |
718 | file_id: FileId( | 714 | file_id: FileId( |
@@ -736,7 +732,7 @@ fn main() { | |||
736 | }, | 732 | }, |
737 | }, | 733 | }, |
738 | Annotation { | 734 | Annotation { |
739 | range: 0..12, | 735 | range: 7..11, |
740 | kind: HasReferences { | 736 | kind: HasReferences { |
741 | position: FilePosition { | 737 | position: FilePosition { |
742 | file_id: FileId( | 738 | file_id: FileId( |
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index cf1a8bad7..7f7f4d38a 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs | |||
@@ -49,6 +49,30 @@ pub struct HlRange { | |||
49 | // The general rule is that a reference to an entity gets colored the same way as the entity itself. | 49 | // The general rule is that a reference to an entity gets colored the same way as the entity itself. |
50 | // We also give special modifier for `mut` and `&mut` local variables. | 50 | // We also give special modifier for `mut` and `&mut` local variables. |
51 | // | 51 | // |
52 | // .Token Modifiers | ||
53 | // | ||
54 | // Token modifiers allow to style some elements in the source code more precisely. | ||
55 | // | ||
56 | // Rust-analyzer currently emits the following token modifiers: | ||
57 | // | ||
58 | // [horizontal] | ||
59 | // associated:: Emitted for associated items. | ||
60 | // async:: Emitted for async functions and the `async` and `await` keywords. | ||
61 | // attribute:: Emitted for tokens inside attributes. | ||
62 | // callable:: Emitted for locals whose types implements one of the `Fn*` traits. | ||
63 | // consuming:: Emitted for locals that are being consumed when use in a function call. | ||
64 | // controlFlow:: Emitted for control-flow related tokens, this includes the `?` operator. | ||
65 | // declaration:: Emitted for names of definitions, like `foo` in `fn foo() {}`. | ||
66 | // documentation:: Emitted for documentation comments. | ||
67 | // injected:: Emitted for doc-string injected highlighting like rust source blocks in documentation. | ||
68 | // intraDocLink:: Emitted for intra doc links in doc-strings. | ||
69 | // library:: Emitted for items that are defined outside of the current crate. | ||
70 | // mutable:: Emitted for mutable locals and statics. | ||
71 | // static:: Emitted for "static" functions, also known as functions that do not take a `self` param. | ||
72 | // trait:: Emitted for associated trait items. | ||
73 | // unsafe:: Emitted for unsafe operations, like unsafe function calls, as well as the `unsafe` token. | ||
74 | // | ||
75 | // | ||
52 | // image::https://user-images.githubusercontent.com/48062697/113164457-06cfb980-9239-11eb-819b-0f93e646acf8.png[] | 76 | // image::https://user-images.githubusercontent.com/48062697/113164457-06cfb980-9239-11eb-819b-0f93e646acf8.png[] |
53 | // image::https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png[] | 77 | // image::https://user-images.githubusercontent.com/48062697/113187625-f7f50100-9250-11eb-825e-91c58f236071.png[] |
54 | pub(crate) fn highlight( | 78 | pub(crate) fn highlight( |
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs index b4a3d39c9..9503c936d 100644 --- a/crates/ide/src/syntax_highlighting/highlight.rs +++ b/crates/ide/src/syntax_highlighting/highlight.rs | |||
@@ -71,7 +71,7 @@ pub(super) fn element( | |||
71 | } | 71 | } |
72 | NAME_REF => { | 72 | NAME_REF => { |
73 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); | 73 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); |
74 | highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| { | 74 | highlight_func_by_name_ref(sema, krate, &name_ref).unwrap_or_else(|| { |
75 | let is_self = name_ref.self_token().is_some(); | 75 | let is_self = name_ref.self_token().is_some(); |
76 | let h = match NameRefClass::classify(sema, &name_ref) { | 76 | let h = match NameRefClass::classify(sema, &name_ref) { |
77 | Some(name_kind) => match name_kind { | 77 | Some(name_kind) => match name_kind { |
@@ -108,7 +108,7 @@ pub(super) fn element( | |||
108 | NameRefClass::FieldShorthand { .. } => SymbolKind::Field.into(), | 108 | NameRefClass::FieldShorthand { .. } => SymbolKind::Field.into(), |
109 | }, | 109 | }, |
110 | None if syntactic_name_ref_highlighting => { | 110 | None if syntactic_name_ref_highlighting => { |
111 | highlight_name_ref_by_syntax(name_ref, sema) | 111 | highlight_name_ref_by_syntax(name_ref, sema, krate) |
112 | } | 112 | } |
113 | None => HlTag::UnresolvedReference.into(), | 113 | None => HlTag::UnresolvedReference.into(), |
114 | }; | 114 | }; |
@@ -434,19 +434,23 @@ fn highlight_def(db: &RootDatabase, krate: Option<hir::Crate>, def: Definition) | |||
434 | 434 | ||
435 | fn highlight_func_by_name_ref( | 435 | fn highlight_func_by_name_ref( |
436 | sema: &Semantics<RootDatabase>, | 436 | sema: &Semantics<RootDatabase>, |
437 | krate: Option<hir::Crate>, | ||
437 | name_ref: &ast::NameRef, | 438 | name_ref: &ast::NameRef, |
438 | ) -> Option<Highlight> { | 439 | ) -> Option<Highlight> { |
439 | let mc = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast)?; | 440 | let mc = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast)?; |
440 | highlight_method_call(sema, &mc) | 441 | highlight_method_call(sema, krate, &mc) |
441 | } | 442 | } |
442 | 443 | ||
443 | fn highlight_method_call( | 444 | fn highlight_method_call( |
444 | sema: &Semantics<RootDatabase>, | 445 | sema: &Semantics<RootDatabase>, |
446 | krate: Option<hir::Crate>, | ||
445 | method_call: &ast::MethodCallExpr, | 447 | method_call: &ast::MethodCallExpr, |
446 | ) -> Option<Highlight> { | 448 | ) -> Option<Highlight> { |
447 | let func = sema.resolve_method_call(&method_call)?; | 449 | let func = sema.resolve_method_call(&method_call)?; |
450 | |||
448 | let mut h = SymbolKind::Function.into(); | 451 | let mut h = SymbolKind::Function.into(); |
449 | h |= HlMod::Associated; | 452 | h |= HlMod::Associated; |
453 | |||
450 | if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { | 454 | if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { |
451 | h |= HlMod::Unsafe; | 455 | h |= HlMod::Unsafe; |
452 | } | 456 | } |
@@ -454,7 +458,10 @@ fn highlight_method_call( | |||
454 | h |= HlMod::Async; | 458 | h |= HlMod::Async; |
455 | } | 459 | } |
456 | if func.as_assoc_item(sema.db).and_then(|it| it.containing_trait(sema.db)).is_some() { | 460 | if func.as_assoc_item(sema.db).and_then(|it| it.containing_trait(sema.db)).is_some() { |
457 | h |= HlMod::Trait | 461 | h |= HlMod::Trait; |
462 | } | ||
463 | if Some(func.module(sema.db).krate()) != krate { | ||
464 | h |= HlMod::Library; | ||
458 | } | 465 | } |
459 | 466 | ||
460 | if let Some(self_param) = func.self_param(sema.db) { | 467 | if let Some(self_param) = func.self_param(sema.db) { |
@@ -503,7 +510,11 @@ fn highlight_name_by_syntax(name: ast::Name) -> Highlight { | |||
503 | tag.into() | 510 | tag.into() |
504 | } | 511 | } |
505 | 512 | ||
506 | fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabase>) -> Highlight { | 513 | fn highlight_name_ref_by_syntax( |
514 | name: ast::NameRef, | ||
515 | sema: &Semantics<RootDatabase>, | ||
516 | krate: Option<hir::Crate>, | ||
517 | ) -> Highlight { | ||
507 | let default = HlTag::UnresolvedReference; | 518 | let default = HlTag::UnresolvedReference; |
508 | 519 | ||
509 | let parent = match name.syntax().parent() { | 520 | let parent = match name.syntax().parent() { |
@@ -514,7 +525,7 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas | |||
514 | match parent.kind() { | 525 | match parent.kind() { |
515 | METHOD_CALL_EXPR => { | 526 | METHOD_CALL_EXPR => { |
516 | return ast::MethodCallExpr::cast(parent) | 527 | return ast::MethodCallExpr::cast(parent) |
517 | .and_then(|it| highlight_method_call(sema, &it)) | 528 | .and_then(|it| highlight_method_call(sema, krate, &it)) |
518 | .unwrap_or_else(|| SymbolKind::Function.into()); | 529 | .unwrap_or_else(|| SymbolKind::Function.into()); |
519 | } | 530 | } |
520 | FIELD_EXPR => { | 531 | FIELD_EXPR => { |
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs index e94f17cd9..9d481deae 100644 --- a/crates/ide/src/syntax_highlighting/tags.rs +++ b/crates/ide/src/syntax_highlighting/tags.rs | |||
@@ -37,6 +37,8 @@ pub enum HlTag { | |||
37 | None, | 37 | None, |
38 | } | 38 | } |
39 | 39 | ||
40 | // Don't forget to adjust the feature description in crates/ide/src/syntax_highlighting.rs. | ||
41 | // And make sure to use the lsp strings used when converting to the protocol in crates\rust-analyzer\src\semantic_tokens.rs, not the names of the variants here. | ||
40 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | 42 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] |
41 | #[repr(u8)] | 43 | #[repr(u8)] |
42 | pub enum HlMod { | 44 | pub enum HlMod { |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index 055d21109..0264e39a3 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html | |||
@@ -258,7 +258,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
258 | 258 | ||
259 | <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> | 259 | <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> |
260 | 260 | ||
261 | <span class="keyword control">if</span> <span class="keyword">let</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">Die</span> <span class="operator">=</span> <span class="variable">control_flow</span> <span class="brace">{</span> | 261 | <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> |
262 | foo::<span class="macro">die!</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> | 262 | foo::<span class="macro">die!</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
263 | <span class="brace">}</span> | 263 | <span class="brace">}</span> |
264 | <span class="brace">}</span> | 264 | <span class="brace">}</span> |
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index be4447ebb..662b53481 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs | |||
@@ -232,7 +232,7 @@ fn use_foo_items() { | |||
232 | 232 | ||
233 | let control_flow = foo::identity(foo::ControlFlow::Continue); | 233 | let control_flow = foo::identity(foo::ControlFlow::Continue); |
234 | 234 | ||
235 | if let foo::ControlFlow::Die = control_flow { | 235 | if control_flow.should_die() { |
236 | foo::die!(); | 236 | foo::die!(); |
237 | } | 237 | } |
238 | } | 238 | } |
@@ -249,6 +249,12 @@ pub enum ControlFlow { | |||
249 | Die, | 249 | Die, |
250 | } | 250 | } |
251 | 251 | ||
252 | impl ControlFlow { | ||
253 | pub fn should_die(self) -> bool { | ||
254 | matches!(self, ControlFlow::Die) | ||
255 | } | ||
256 | } | ||
257 | |||
252 | pub fn identity<T>(x: T) -> T { x } | 258 | pub fn identity<T>(x: T) -> T { x } |
253 | 259 | ||
254 | pub mod consts { | 260 | pub mod consts { |