aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/syntax_highlighting.rs
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2020-11-21 11:51:05 +0000
committerLukas Wirth <[email protected]>2020-11-21 11:51:05 +0000
commit1f87a4198956fd3a8b57d01c2bce19481fe2c610 (patch)
treeb437647703fc681a77d6aa5d5ff3fe65a7cc5d24 /crates/ide/src/syntax_highlighting.rs
parent66db0d3cadd4fefd70543aba8eae57e8db99935a (diff)
Add attribute highlight modifier to all tokens inside attributes
Diffstat (limited to 'crates/ide/src/syntax_highlighting.rs')
-rw-r--r--crates/ide/src/syntax_highlighting.rs19
1 files changed, 16 insertions, 3 deletions
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index 1ed77b40b..5150a970c 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -76,6 +76,7 @@ pub(crate) fn highlight(
76 let mut current_macro_call: Option<ast::MacroCall> = None; 76 let mut current_macro_call: Option<ast::MacroCall> = None;
77 let mut format_string_highlighter = FormatStringHighlighter::default(); 77 let mut format_string_highlighter = FormatStringHighlighter::default();
78 let mut macro_rules_highlighter = MacroRulesHighlighter::default(); 78 let mut macro_rules_highlighter = MacroRulesHighlighter::default();
79 let mut inside_attribute = false;
79 80
80 // Walk all nodes, keeping track of whether we are inside a macro or not. 81 // Walk all nodes, keeping track of whether we are inside a macro or not.
81 // If in macro, expand it first and highlight the expanded code. 82 // If in macro, expand it first and highlight the expanded code.
@@ -132,9 +133,12 @@ pub(crate) fn highlight(
132 _ => (), 133 _ => (),
133 } 134 }
134 135
135 // Check for Rust code in documentation
136 match &event { 136 match &event {
137 // Check for Rust code in documentation
137 WalkEvent::Leave(NodeOrToken::Node(node)) => { 138 WalkEvent::Leave(NodeOrToken::Node(node)) => {
139 if ast::Attr::can_cast(node.kind()) {
140 inside_attribute = false
141 }
138 if let Some((doctest, range_mapping, new_comments)) = 142 if let Some((doctest, range_mapping, new_comments)) =
139 injection::extract_doc_comments(node) 143 injection::extract_doc_comments(node)
140 { 144 {
@@ -146,6 +150,9 @@ pub(crate) fn highlight(
146 ); 150 );
147 } 151 }
148 } 152 }
153 WalkEvent::Enter(NodeOrToken::Node(node)) if ast::Attr::can_cast(node.kind()) => {
154 inside_attribute = true
155 }
149 _ => (), 156 _ => (),
150 } 157 }
151 158
@@ -188,12 +195,16 @@ pub(crate) fn highlight(
188 } 195 }
189 } 196 }
190 197
191 if let Some((highlight, binding_hash)) = highlight_element( 198 if let Some((mut highlight, binding_hash)) = highlight_element(
192 &sema, 199 &sema,
193 &mut bindings_shadow_count, 200 &mut bindings_shadow_count,
194 syntactic_name_ref_highlighting, 201 syntactic_name_ref_highlighting,
195 element_to_highlight.clone(), 202 element_to_highlight.clone(),
196 ) { 203 ) {
204 if inside_attribute {
205 highlight = highlight | HighlightModifier::Attribute;
206 }
207
197 if macro_rules_highlighter.highlight(element_to_highlight.clone()).is_none() { 208 if macro_rules_highlighter.highlight(element_to_highlight.clone()).is_none() {
198 stack.add(HighlightedRange { range, highlight, binding_hash }); 209 stack.add(HighlightedRange { range, highlight, binding_hash });
199 } 210 }
@@ -474,7 +485,9 @@ fn highlight_element(
474 485
475 // Highlight references like the definitions they resolve to 486 // Highlight references like the definitions they resolve to
476 NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => { 487 NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => {
477 Highlight::from(HighlightTag::Function) | HighlightModifier::Attribute 488 // even though we track whether we are in an attribute or not we still need this special case
489 // as otherwise we would emit unresolved references for name refs inside attributes
490 Highlight::from(HighlightTag::Function)
478 } 491 }
479 NAME_REF => { 492 NAME_REF => {
480 let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); 493 let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap();