diff options
Diffstat (limited to 'crates/ra_ide')
-rw-r--r-- | crates/ra_ide/src/syntax_highlighting.rs | 87 |
1 files changed, 43 insertions, 44 deletions
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 1b6eb1174..e8ca7d652 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs | |||
@@ -69,7 +69,7 @@ pub(crate) fn highlight( | |||
69 | let mut bindings_shadow_count: FxHashMap<Name, u32> = FxHashMap::default(); | 69 | let mut bindings_shadow_count: FxHashMap<Name, u32> = FxHashMap::default(); |
70 | let mut res = Vec::new(); | 70 | let mut res = Vec::new(); |
71 | 71 | ||
72 | let mut in_macro_call = None; | 72 | let mut current_macro_call: Option<ast::MacroCall> = None; |
73 | 73 | ||
74 | for event in root.preorder_with_tokens() { | 74 | for event in root.preorder_with_tokens() { |
75 | let event_range = match &event { | 75 | let event_range = match &event { |
@@ -81,58 +81,57 @@ pub(crate) fn highlight( | |||
81 | continue; | 81 | continue; |
82 | } | 82 | } |
83 | 83 | ||
84 | match event { | 84 | match event.clone().map(|it| it.into_node().and_then(ast::MacroCall::cast)) { |
85 | WalkEvent::Enter(node) => match node.kind() { | 85 | WalkEvent::Enter(Some(mc)) => { |
86 | MACRO_CALL => { | 86 | current_macro_call = Some(mc.clone()); |
87 | in_macro_call = Some(node.clone()); | 87 | if let Some(range) = highlight_macro(&mc) { |
88 | if let Some(range) = highlight_macro(node) { | 88 | res.push(HighlightedRange { |
89 | res.push(HighlightedRange { | 89 | range, |
90 | range, | 90 | highlight: HighlightTag::Macro.into(), |
91 | highlight: HighlightTag::Macro.into(), | 91 | binding_hash: None, |
92 | binding_hash: None, | 92 | }); |
93 | }); | ||
94 | } | ||
95 | } | 93 | } |
96 | _ if in_macro_call.is_some() => { | 94 | continue; |
97 | if let Some(token) = node.as_token() { | 95 | } |
98 | if let Some((highlight, binding_hash)) = | 96 | WalkEvent::Leave(Some(mc)) => { |
99 | highlight_token_tree(&sema, &mut bindings_shadow_count, token.clone()) | 97 | assert!(current_macro_call == Some(mc)); |
100 | { | 98 | current_macro_call = None; |
101 | res.push(HighlightedRange { | 99 | continue; |
102 | range: node.text_range(), | 100 | } |
103 | highlight, | 101 | _ => (), |
104 | binding_hash, | 102 | } |
105 | }); | 103 | |
106 | } | 104 | let node = match event { |
107 | } | 105 | WalkEvent::Enter(it) => it, |
108 | } | 106 | WalkEvent::Leave(_) => continue, |
109 | _ => { | 107 | }; |
110 | if let Some((highlight, binding_hash)) = | 108 | |
111 | highlight_node(&sema, &mut bindings_shadow_count, node.clone()) | 109 | if current_macro_call.is_some() { |
112 | { | 110 | if let Some(token) = node.into_token() { |
113 | res.push(HighlightedRange { | 111 | if let Some((highlight, binding_hash)) = |
114 | range: node.text_range(), | 112 | highlight_token_tree(&sema, &mut bindings_shadow_count, token.clone()) |
115 | highlight, | 113 | { |
116 | binding_hash, | 114 | res.push(HighlightedRange { |
117 | }); | 115 | range: token.text_range(), |
118 | } | 116 | highlight, |
119 | } | 117 | binding_hash, |
120 | }, | 118 | }); |
121 | WalkEvent::Leave(node) => { | ||
122 | if let Some(m) = in_macro_call.as_ref() { | ||
123 | if *m == node { | ||
124 | in_macro_call = None; | ||
125 | } | ||
126 | } | 119 | } |
127 | } | 120 | } |
121 | continue; | ||
122 | } | ||
123 | |||
124 | if let Some((highlight, binding_hash)) = | ||
125 | highlight_node(&sema, &mut bindings_shadow_count, node.clone()) | ||
126 | { | ||
127 | res.push(HighlightedRange { range: node.text_range(), highlight, binding_hash }); | ||
128 | } | 128 | } |
129 | } | 129 | } |
130 | 130 | ||
131 | res | 131 | res |
132 | } | 132 | } |
133 | 133 | ||
134 | fn highlight_macro(node: SyntaxElement) -> Option<TextRange> { | 134 | fn highlight_macro(macro_call: &ast::MacroCall) -> Option<TextRange> { |
135 | let macro_call = ast::MacroCall::cast(node.as_node()?.clone())?; | ||
136 | let path = macro_call.path()?; | 135 | let path = macro_call.path()?; |
137 | let name_ref = path.segment()?.name_ref()?; | 136 | let name_ref = path.segment()?.name_ref()?; |
138 | 137 | ||