aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-02-27 10:56:42 +0000
committerAleksey Kladov <[email protected]>2020-02-27 10:56:42 +0000
commita2dbdbba00376305a0cbcd98cd36cd53d5139d96 (patch)
tree32bad598576fb4e8d7be50c4fba152ae0c3da96f /crates/ra_ide
parent9bb17186396b1bdad7b443135165575e81810be3 (diff)
Split loop into orthogonal phases
Diffstat (limited to 'crates/ra_ide')
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs87
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
134fn highlight_macro(node: SyntaxElement) -> Option<TextRange> { 134fn 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