diff options
Diffstat (limited to 'crates/ide/src')
-rw-r--r-- | crates/ide/src/inlay_hints.rs | 77 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting.rs | 118 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/test_data/highlight_strings.html | 2 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/test_data/highlighting.html | 6 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/tests.rs | 4 |
5 files changed, 173 insertions, 34 deletions
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 7d716577e..2ed84095d 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs | |||
@@ -231,12 +231,17 @@ fn hint_iterator( | |||
231 | const LABEL_START: &str = "impl Iterator<Item = "; | 231 | const LABEL_START: &str = "impl Iterator<Item = "; |
232 | const LABEL_END: &str = ">"; | 232 | const LABEL_END: &str = ">"; |
233 | 233 | ||
234 | let ty_display = ty.display_truncated( | 234 | let ty_display = hint_iterator(sema, config, &ty) |
235 | db, | 235 | .map(|assoc_type_impl| assoc_type_impl.to_string()) |
236 | config | 236 | .unwrap_or_else(|| { |
237 | .max_length | 237 | ty.display_truncated( |
238 | .map(|len| len.saturating_sub(LABEL_START.len() + LABEL_END.len())), | 238 | db, |
239 | ); | 239 | config |
240 | .max_length | ||
241 | .map(|len| len.saturating_sub(LABEL_START.len() + LABEL_END.len())), | ||
242 | ) | ||
243 | .to_string() | ||
244 | }); | ||
240 | return Some(format!("{}{}{}", LABEL_START, ty_display, LABEL_END).into()); | 245 | return Some(format!("{}{}{}", LABEL_START, ty_display, LABEL_END).into()); |
241 | } | 246 | } |
242 | } | 247 | } |
@@ -1002,18 +1007,6 @@ fn main() { | |||
1002 | 1007 | ||
1003 | println!("Unit expr"); | 1008 | println!("Unit expr"); |
1004 | } | 1009 | } |
1005 | |||
1006 | //- /alloc.rs crate:alloc deps:core | ||
1007 | mod collections { | ||
1008 | struct Vec<T> {} | ||
1009 | impl<T> Vec<T> { | ||
1010 | fn new() -> Self { Vec {} } | ||
1011 | fn push(&mut self, t: T) { } | ||
1012 | } | ||
1013 | impl<T> IntoIterator for Vec<T> { | ||
1014 | type Item=T; | ||
1015 | } | ||
1016 | } | ||
1017 | "#, | 1010 | "#, |
1018 | ); | 1011 | ); |
1019 | } | 1012 | } |
@@ -1043,17 +1036,6 @@ fn main() { | |||
1043 | //^ &str | 1036 | //^ &str |
1044 | } | 1037 | } |
1045 | } | 1038 | } |
1046 | //- /alloc.rs crate:alloc deps:core | ||
1047 | mod collections { | ||
1048 | struct Vec<T> {} | ||
1049 | impl<T> Vec<T> { | ||
1050 | fn new() -> Self { Vec {} } | ||
1051 | fn push(&mut self, t: T) { } | ||
1052 | } | ||
1053 | impl<T> IntoIterator for Vec<T> { | ||
1054 | type Item=T; | ||
1055 | } | ||
1056 | } | ||
1057 | "#, | 1039 | "#, |
1058 | ); | 1040 | ); |
1059 | } | 1041 | } |
@@ -1183,4 +1165,41 @@ fn main() { | |||
1183 | "#]], | 1165 | "#]], |
1184 | ); | 1166 | ); |
1185 | } | 1167 | } |
1168 | |||
1169 | #[test] | ||
1170 | fn shorten_iterators_in_associated_params() { | ||
1171 | check_with_config( | ||
1172 | InlayHintsConfig { | ||
1173 | parameter_hints: false, | ||
1174 | type_hints: true, | ||
1175 | chaining_hints: false, | ||
1176 | max_length: None, | ||
1177 | }, | ||
1178 | r#" | ||
1179 | use core::iter; | ||
1180 | |||
1181 | pub struct SomeIter<T> {} | ||
1182 | |||
1183 | impl<T> SomeIter<T> { | ||
1184 | pub fn new() -> Self { SomeIter {} } | ||
1185 | pub fn push(&mut self, t: T) {} | ||
1186 | } | ||
1187 | |||
1188 | impl<T> Iterator for SomeIter<T> { | ||
1189 | type Item = T; | ||
1190 | fn next(&mut self) -> Option<Self::Item> { | ||
1191 | None | ||
1192 | } | ||
1193 | } | ||
1194 | |||
1195 | fn main() { | ||
1196 | let mut some_iter = SomeIter::new(); | ||
1197 | //^^^^^^^^^^^^^ SomeIter<Take<Repeat<i32>>> | ||
1198 | some_iter.push(iter::repeat(2).take(2)); | ||
1199 | let iter_of_iters = some_iter.take(2); | ||
1200 | //^^^^^^^^^^^^^ impl Iterator<Item = impl Iterator<Item = i32>> | ||
1201 | } | ||
1202 | "#, | ||
1203 | ); | ||
1204 | } | ||
1186 | } | 1205 | } |
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index d9fc25d88..6aafd6fd5 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs | |||
@@ -68,7 +68,7 @@ pub(crate) fn highlight( | |||
68 | // When we leave a node, the we use it to flatten the highlighted ranges. | 68 | // When we leave a node, the we use it to flatten the highlighted ranges. |
69 | let mut stack = HighlightedRangeStack::new(); | 69 | let mut stack = HighlightedRangeStack::new(); |
70 | 70 | ||
71 | let mut current_macro_call: Option<ast::MacroCall> = None; | 71 | let mut current_macro_call: Option<(ast::MacroCall, Option<MacroMatcherParseState>)> = None; |
72 | let mut format_string: Option<SyntaxElement> = None; | 72 | let mut format_string: Option<SyntaxElement> = None; |
73 | 73 | ||
74 | // Walk all nodes, keeping track of whether we are inside a macro or not. | 74 | // Walk all nodes, keeping track of whether we are inside a macro or not. |
@@ -92,7 +92,6 @@ pub(crate) fn highlight( | |||
92 | // Track "inside macro" state | 92 | // Track "inside macro" state |
93 | match event.clone().map(|it| it.into_node().and_then(ast::MacroCall::cast)) { | 93 | match event.clone().map(|it| it.into_node().and_then(ast::MacroCall::cast)) { |
94 | WalkEvent::Enter(Some(mc)) => { | 94 | WalkEvent::Enter(Some(mc)) => { |
95 | current_macro_call = Some(mc.clone()); | ||
96 | if let Some(range) = macro_call_range(&mc) { | 95 | if let Some(range) = macro_call_range(&mc) { |
97 | stack.add(HighlightedRange { | 96 | stack.add(HighlightedRange { |
98 | range, | 97 | range, |
@@ -100,7 +99,9 @@ pub(crate) fn highlight( | |||
100 | binding_hash: None, | 99 | binding_hash: None, |
101 | }); | 100 | }); |
102 | } | 101 | } |
102 | let mut is_macro_rules = None; | ||
103 | if let Some(name) = mc.is_macro_rules() { | 103 | if let Some(name) = mc.is_macro_rules() { |
104 | is_macro_rules = Some(MacroMatcherParseState::new()); | ||
104 | if let Some((highlight, binding_hash)) = highlight_element( | 105 | if let Some((highlight, binding_hash)) = highlight_element( |
105 | &sema, | 106 | &sema, |
106 | &mut bindings_shadow_count, | 107 | &mut bindings_shadow_count, |
@@ -114,10 +115,11 @@ pub(crate) fn highlight( | |||
114 | }); | 115 | }); |
115 | } | 116 | } |
116 | } | 117 | } |
118 | current_macro_call = Some((mc.clone(), is_macro_rules)); | ||
117 | continue; | 119 | continue; |
118 | } | 120 | } |
119 | WalkEvent::Leave(Some(mc)) => { | 121 | WalkEvent::Leave(Some(mc)) => { |
120 | assert!(current_macro_call == Some(mc)); | 122 | assert!(current_macro_call.map(|it| it.0) == Some(mc)); |
121 | current_macro_call = None; | 123 | current_macro_call = None; |
122 | format_string = None; | 124 | format_string = None; |
123 | } | 125 | } |
@@ -146,6 +148,20 @@ pub(crate) fn highlight( | |||
146 | WalkEvent::Leave(_) => continue, | 148 | WalkEvent::Leave(_) => continue, |
147 | }; | 149 | }; |
148 | 150 | ||
151 | // check if in matcher part of a macro_rules rule | ||
152 | if let Some((_, Some(ref mut state))) = current_macro_call { | ||
153 | if let Some(tok) = element.as_token() { | ||
154 | if matches!( | ||
155 | update_macro_rules_state(tok, state), | ||
156 | RuleState::Matcher | RuleState::Expander | ||
157 | ) { | ||
158 | if skip_metavariables(element.clone()) { | ||
159 | continue; | ||
160 | } | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | |||
149 | let range = element.text_range(); | 165 | let range = element.text_range(); |
150 | 166 | ||
151 | let element_to_highlight = if current_macro_call.is_some() && element.kind() != COMMENT { | 167 | let element_to_highlight = if current_macro_call.is_some() && element.kind() != COMMENT { |
@@ -918,3 +934,99 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas | |||
918 | _ => default.into(), | 934 | _ => default.into(), |
919 | } | 935 | } |
920 | } | 936 | } |
937 | |||
938 | struct MacroMatcherParseState { | ||
939 | /// Opening and corresponding closing bracket of the matcher or expander of the current rule | ||
940 | paren_ty: Option<(SyntaxKind, SyntaxKind)>, | ||
941 | paren_level: usize, | ||
942 | rule_state: RuleState, | ||
943 | /// Whether we are inside the outer `{` `}` macro block that holds the rules | ||
944 | in_invoc_body: bool, | ||
945 | } | ||
946 | |||
947 | impl MacroMatcherParseState { | ||
948 | fn new() -> Self { | ||
949 | MacroMatcherParseState { | ||
950 | paren_ty: None, | ||
951 | paren_level: 0, | ||
952 | in_invoc_body: false, | ||
953 | rule_state: RuleState::None, | ||
954 | } | ||
955 | } | ||
956 | } | ||
957 | |||
958 | #[derive(Copy, Clone, PartialEq)] | ||
959 | enum RuleState { | ||
960 | Matcher, | ||
961 | Expander, | ||
962 | Between, | ||
963 | None, | ||
964 | } | ||
965 | |||
966 | impl RuleState { | ||
967 | fn transition(&mut self) { | ||
968 | *self = match self { | ||
969 | RuleState::Matcher => RuleState::Between, | ||
970 | RuleState::Expander => RuleState::None, | ||
971 | RuleState::Between => RuleState::Expander, | ||
972 | RuleState::None => RuleState::Matcher, | ||
973 | }; | ||
974 | } | ||
975 | } | ||
976 | |||
977 | fn update_macro_rules_state(tok: &SyntaxToken, state: &mut MacroMatcherParseState) -> RuleState { | ||
978 | if !state.in_invoc_body { | ||
979 | if tok.kind() == T!['{'] { | ||
980 | state.in_invoc_body = true; | ||
981 | } | ||
982 | return state.rule_state; | ||
983 | } | ||
984 | |||
985 | match state.paren_ty { | ||
986 | Some((open, close)) => { | ||
987 | if tok.kind() == open { | ||
988 | state.paren_level += 1; | ||
989 | } else if tok.kind() == close { | ||
990 | state.paren_level -= 1; | ||
991 | if state.paren_level == 0 { | ||
992 | let res = state.rule_state; | ||
993 | state.rule_state.transition(); | ||
994 | state.paren_ty = None; | ||
995 | return res; | ||
996 | } | ||
997 | } | ||
998 | } | ||
999 | None => { | ||
1000 | match tok.kind() { | ||
1001 | T!['('] => { | ||
1002 | state.paren_ty = Some((T!['('], T![')'])); | ||
1003 | } | ||
1004 | T!['{'] => { | ||
1005 | state.paren_ty = Some((T!['{'], T!['}'])); | ||
1006 | } | ||
1007 | T!['['] => { | ||
1008 | state.paren_ty = Some((T!['['], T![']'])); | ||
1009 | } | ||
1010 | _ => (), | ||
1011 | } | ||
1012 | if state.paren_ty.is_some() { | ||
1013 | state.paren_level = 1; | ||
1014 | state.rule_state.transition(); | ||
1015 | } | ||
1016 | } | ||
1017 | } | ||
1018 | state.rule_state | ||
1019 | } | ||
1020 | |||
1021 | fn skip_metavariables(element: SyntaxElement) -> bool { | ||
1022 | let tok = match element.as_token() { | ||
1023 | Some(tok) => tok, | ||
1024 | None => return false, | ||
1025 | }; | ||
1026 | let is_fragment = || tok.prev_token().map(|tok| tok.kind()) == Some(T![$]); | ||
1027 | match tok.kind() { | ||
1028 | IDENT if is_fragment() => true, | ||
1029 | kind if kind.is_keyword() && is_fragment() => true, | ||
1030 | _ => false, | ||
1031 | } | ||
1032 | } | ||
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html index 1b681b2c6..43f1b32fd 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html | |||
@@ -37,7 +37,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
37 | </style> | 37 | </style> |
38 | <pre><code><span class="macro">macro_rules!</span> <span class="macro declaration">println</span> <span class="punctuation">{</span> | 38 | <pre><code><span class="macro">macro_rules!</span> <span class="macro declaration">println</span> <span class="punctuation">{</span> |
39 | <span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>arg<span class="punctuation">:</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">(</span><span class="punctuation">{</span> | 39 | <span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>arg<span class="punctuation">:</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">(</span><span class="punctuation">{</span> |
40 | <span class="punctuation">$</span><span class="keyword">crate</span><span class="punctuation">:</span><span class="punctuation">:</span>io<span class="punctuation">:</span><span class="punctuation">:</span>_print<span class="punctuation">(</span><span class="punctuation">$</span><span class="keyword">crate</span><span class="punctuation">:</span><span class="punctuation">:</span>format_args_nl<span class="punctuation">!</span><span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>arg<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span> | 40 | <span class="punctuation">$</span>crate<span class="punctuation">:</span><span class="punctuation">:</span>io<span class="punctuation">:</span><span class="punctuation">:</span>_print<span class="punctuation">(</span><span class="punctuation">$</span>crate<span class="punctuation">:</span><span class="punctuation">:</span>format_args_nl<span class="punctuation">!</span><span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>arg<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span> |
41 | <span class="punctuation">}</span><span class="punctuation">)</span> | 41 | <span class="punctuation">}</span><span class="punctuation">)</span> |
42 | <span class="punctuation">}</span> | 42 | <span class="punctuation">}</span> |
43 | #[rustc_builtin_macro] | 43 | #[rustc_builtin_macro] |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index 1d8a3c404..0bb0928e4 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html | |||
@@ -62,7 +62,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
62 | 62 | ||
63 | <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span> | 63 | <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span> |
64 | <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">Foo</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> | 64 | <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">Foo</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> |
65 | <span class="value_param">f</span><span class="punctuation">.</span><span class="function consuming">baz</span><span class="punctuation">(</span><span class="self_keyword consuming">self</span><span class="punctuation">)</span> | 65 | <span class="value_param">f</span><span class="punctuation">.</span><span class="function consuming">baz</span><span class="punctuation">(</span><span class="self_keyword mutable consuming">self</span><span class="punctuation">)</span> |
66 | <span class="punctuation">}</span> | 66 | <span class="punctuation">}</span> |
67 | 67 | ||
68 | <span class="keyword">fn</span> <span class="function declaration">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 68 | <span class="keyword">fn</span> <span class="function declaration">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span> |
@@ -115,6 +115,10 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
115 | <span class="punctuation">}</span> | 115 | <span class="punctuation">}</span> |
116 | <span class="punctuation">}</span> | 116 | <span class="punctuation">}</span> |
117 | 117 | ||
118 | <span class="macro">macro_rules!</span> <span class="macro declaration">keyword_frag</span> <span class="punctuation">{</span> | ||
119 | <span class="punctuation">(</span><span class="punctuation">$</span>type<span class="punctuation">:</span>ty<span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">(</span><span class="punctuation">$</span>type<span class="punctuation">)</span> | ||
120 | <span class="punctuation">}</span> | ||
121 | |||
118 | <span class="comment">// comment</span> | 122 | <span class="comment">// comment</span> |
119 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 123 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> |
120 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello, {}!"</span><span class="punctuation">,</span> <span class="numeric_literal">92</span><span class="punctuation">)</span><span class="punctuation">;</span> | 124 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello, {}!"</span><span class="punctuation">,</span> <span class="numeric_literal">92</span><span class="punctuation">)</span><span class="punctuation">;</span> |
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index 694c4b7fa..126363b8b 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs | |||
@@ -89,6 +89,10 @@ macro_rules! noop { | |||
89 | } | 89 | } |
90 | } | 90 | } |
91 | 91 | ||
92 | macro_rules! keyword_frag { | ||
93 | ($type:ty) => ($type) | ||
94 | } | ||
95 | |||
92 | // comment | 96 | // comment |
93 | fn main() { | 97 | fn main() { |
94 | println!("Hello, {}!", 92); | 98 | println!("Hello, {}!", 92); |