aboutsummaryrefslogtreecommitdiff
path: root/crates/ide/src/syntax_highlighting.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide/src/syntax_highlighting.rs')
-rw-r--r--crates/ide/src/syntax_highlighting.rs52
1 files changed, 29 insertions, 23 deletions
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index f5c6eabef..990b0f7d9 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -74,6 +74,7 @@ pub(crate) fn highlight(
74 let mut stack = HighlightedRangeStack::new(); 74 let mut stack = HighlightedRangeStack::new();
75 75
76 let mut current_macro_call: Option<ast::MacroCall> = None; 76 let mut current_macro_call: Option<ast::MacroCall> = None;
77 let mut current_macro_rules: Option<ast::MacroRules> = None;
77 let mut format_string_highlighter = FormatStringHighlighter::default(); 78 let mut format_string_highlighter = FormatStringHighlighter::default();
78 let mut macro_rules_highlighter = MacroRulesHighlighter::default(); 79 let mut macro_rules_highlighter = MacroRulesHighlighter::default();
79 let mut inside_attribute = false; 80 let mut inside_attribute = false;
@@ -106,28 +107,26 @@ pub(crate) fn highlight(
106 binding_hash: None, 107 binding_hash: None,
107 }); 108 });
108 } 109 }
109 if let Some(name) = mc.is_macro_rules() {
110 macro_rules_highlighter.init();
111 if let Some((highlight, binding_hash)) = highlight_element(
112 &sema,
113 &mut bindings_shadow_count,
114 syntactic_name_ref_highlighting,
115 name.syntax().clone().into(),
116 ) {
117 stack.add(HighlightedRange {
118 range: name.syntax().text_range(),
119 highlight,
120 binding_hash,
121 });
122 }
123 }
124 current_macro_call = Some(mc.clone()); 110 current_macro_call = Some(mc.clone());
125 continue; 111 continue;
126 } 112 }
127 WalkEvent::Leave(Some(mc)) => { 113 WalkEvent::Leave(Some(mc)) => {
128 assert!(current_macro_call == Some(mc)); 114 assert_eq!(current_macro_call, Some(mc));
129 current_macro_call = None; 115 current_macro_call = None;
130 format_string_highlighter = FormatStringHighlighter::default(); 116 format_string_highlighter = FormatStringHighlighter::default();
117 }
118 _ => (),
119 }
120
121 match event.clone().map(|it| it.into_node().and_then(ast::MacroRules::cast)) {
122 WalkEvent::Enter(Some(mac)) => {
123 macro_rules_highlighter.init();
124 current_macro_rules = Some(mac);
125 continue;
126 }
127 WalkEvent::Leave(Some(mac)) => {
128 assert_eq!(current_macro_rules, Some(mac));
129 current_macro_rules = None;
131 macro_rules_highlighter = MacroRulesHighlighter::default(); 130 macro_rules_highlighter = MacroRulesHighlighter::default();
132 } 131 }
133 _ => (), 132 _ => (),
@@ -163,6 +162,12 @@ pub(crate) fn highlight(
163 162
164 let range = element.text_range(); 163 let range = element.text_range();
165 164
165 if current_macro_rules.is_some() {
166 if let Some(tok) = element.as_token() {
167 macro_rules_highlighter.advance(tok);
168 }
169 }
170
166 let element_to_highlight = if current_macro_call.is_some() && element.kind() != COMMENT { 171 let element_to_highlight = if current_macro_call.is_some() && element.kind() != COMMENT {
167 // Inside a macro -- expand it first 172 // Inside a macro -- expand it first
168 let token = match element.clone().into_token() { 173 let token = match element.clone().into_token() {
@@ -173,9 +178,6 @@ pub(crate) fn highlight(
173 let parent = token.parent(); 178 let parent = token.parent();
174 179
175 format_string_highlighter.check_for_format_string(&parent); 180 format_string_highlighter.check_for_format_string(&parent);
176 if let Some(tok) = element.as_token() {
177 macro_rules_highlighter.advance(tok);
178 }
179 181
180 // We only care Name and Name_ref 182 // We only care Name and Name_ref
181 match (token.kind(), parent.kind()) { 183 match (token.kind(), parent.kind()) {
@@ -386,10 +388,14 @@ impl HighlightedRangeStack {
386 let mut res = self.stack.pop().unwrap(); 388 let mut res = self.stack.pop().unwrap();
387 res.sort_by_key(|range| range.range.start()); 389 res.sort_by_key(|range| range.range.start());
388 // Check that ranges are sorted and disjoint 390 // Check that ranges are sorted and disjoint
389 assert!(res 391 for (left, right) in res.iter().zip(res.iter().skip(1)) {
390 .iter() 392 assert!(
391 .zip(res.iter().skip(1)) 393 left.range.end() <= right.range.start(),
392 .all(|(left, right)| left.range.end() <= right.range.start())); 394 "left: {:#?}, right: {:#?}",
395 left,
396 right
397 );
398 }
393 res 399 res
394 } 400 }
395} 401}