diff options
author | Benjamin Coenen <[email protected]> | 2020-04-11 21:54:22 +0100 |
---|---|---|
committer | Benjamin Coenen <[email protected]> | 2020-04-11 22:45:09 +0100 |
commit | 93bfc2d05d36a47dc05a1799210327473d702dbc (patch) | |
tree | dee25e78b24b5d1b23d73ae1009bddbd060927cf /crates/ra_mbe/src | |
parent | d42346fed61f706d68fe888631a41ea5f2752d7f (diff) | |
parent | fd06fe7b13045185ab4e630b0044aa9d8bbcdf8a (diff) |
Improve autocompletion by looking on the type and name
Signed-off-by: Benjamin Coenen <[email protected]>
Diffstat (limited to 'crates/ra_mbe/src')
-rw-r--r-- | crates/ra_mbe/src/syntax_bridge.rs | 36 | ||||
-rw-r--r-- | crates/ra_mbe/src/tests.rs | 99 |
2 files changed, 108 insertions, 27 deletions
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs index 8e8ae2b29..9fb5cb058 100644 --- a/crates/ra_mbe/src/syntax_bridge.rs +++ b/crates/ra_mbe/src/syntax_bridge.rs | |||
@@ -137,21 +137,23 @@ impl TokenMap { | |||
137 | token_id: tt::TokenId, | 137 | token_id: tt::TokenId, |
138 | open_relative_range: TextRange, | 138 | open_relative_range: TextRange, |
139 | close_relative_range: TextRange, | 139 | close_relative_range: TextRange, |
140 | ) { | 140 | ) -> usize { |
141 | let res = self.entries.len(); | ||
141 | self.entries | 142 | self.entries |
142 | .push((token_id, TokenTextRange::Delimiter(open_relative_range, close_relative_range))); | 143 | .push((token_id, TokenTextRange::Delimiter(open_relative_range, close_relative_range))); |
144 | res | ||
143 | } | 145 | } |
144 | 146 | ||
145 | fn update_close_delim(&mut self, token_id: tt::TokenId, close_relative_range: TextRange) { | 147 | fn update_close_delim(&mut self, idx: usize, close_relative_range: TextRange) { |
146 | if let Some(entry) = self.entries.iter_mut().find(|(tid, _)| *tid == token_id) { | 148 | let (_, token_text_range) = &mut self.entries[idx]; |
147 | if let TokenTextRange::Delimiter(dim, _) = entry.1 { | 149 | if let TokenTextRange::Delimiter(dim, _) = token_text_range { |
148 | entry.1 = TokenTextRange::Delimiter(dim, close_relative_range); | 150 | *token_text_range = TokenTextRange::Delimiter(*dim, close_relative_range); |
149 | } | ||
150 | } | 151 | } |
151 | } | 152 | } |
152 | 153 | ||
153 | fn remove_delim(&mut self, token_id: tt::TokenId) { | 154 | fn remove_delim(&mut self, idx: usize) { |
154 | self.entries.retain(|(tid, _)| *tid != token_id); | 155 | // FIXME: This could be accidently quadratic |
156 | self.entries.remove(idx); | ||
155 | } | 157 | } |
156 | } | 158 | } |
157 | 159 | ||
@@ -238,24 +240,24 @@ impl TokenIdAlloc { | |||
238 | token_id | 240 | token_id |
239 | } | 241 | } |
240 | 242 | ||
241 | fn open_delim(&mut self, open_abs_range: TextRange) -> tt::TokenId { | 243 | fn open_delim(&mut self, open_abs_range: TextRange) -> (tt::TokenId, usize) { |
242 | let token_id = tt::TokenId(self.next_id); | 244 | let token_id = tt::TokenId(self.next_id); |
243 | self.next_id += 1; | 245 | self.next_id += 1; |
244 | self.map.insert_delim( | 246 | let idx = self.map.insert_delim( |
245 | token_id, | 247 | token_id, |
246 | open_abs_range - self.global_offset, | 248 | open_abs_range - self.global_offset, |
247 | open_abs_range - self.global_offset, | 249 | open_abs_range - self.global_offset, |
248 | ); | 250 | ); |
249 | token_id | 251 | (token_id, idx) |
250 | } | 252 | } |
251 | 253 | ||
252 | fn close_delim(&mut self, id: tt::TokenId, close_abs_range: Option<TextRange>) { | 254 | fn close_delim(&mut self, idx: usize, close_abs_range: Option<TextRange>) { |
253 | match close_abs_range { | 255 | match close_abs_range { |
254 | None => { | 256 | None => { |
255 | self.map.remove_delim(id); | 257 | self.map.remove_delim(idx); |
256 | } | 258 | } |
257 | Some(close) => { | 259 | Some(close) => { |
258 | self.map.update_close_delim(id, close - self.global_offset); | 260 | self.map.update_close_delim(idx, close - self.global_offset); |
259 | } | 261 | } |
260 | } | 262 | } |
261 | } | 263 | } |
@@ -322,7 +324,7 @@ trait TokenConvertor { | |||
322 | 324 | ||
323 | if let Some((kind, closed)) = delim { | 325 | if let Some((kind, closed)) = delim { |
324 | let mut subtree = tt::Subtree::default(); | 326 | let mut subtree = tt::Subtree::default(); |
325 | let id = self.id_alloc().open_delim(range); | 327 | let (id, idx) = self.id_alloc().open_delim(range); |
326 | subtree.delimiter = Some(tt::Delimiter { kind, id }); | 328 | subtree.delimiter = Some(tt::Delimiter { kind, id }); |
327 | 329 | ||
328 | while self.peek().map(|it| it.kind() != closed).unwrap_or(false) { | 330 | while self.peek().map(|it| it.kind() != closed).unwrap_or(false) { |
@@ -331,7 +333,7 @@ trait TokenConvertor { | |||
331 | let last_range = match self.bump() { | 333 | let last_range = match self.bump() { |
332 | None => { | 334 | None => { |
333 | // For error resilience, we insert an char punct for the opening delim here | 335 | // For error resilience, we insert an char punct for the opening delim here |
334 | self.id_alloc().close_delim(id, None); | 336 | self.id_alloc().close_delim(idx, None); |
335 | let leaf: tt::Leaf = tt::Punct { | 337 | let leaf: tt::Leaf = tt::Punct { |
336 | id: self.id_alloc().alloc(range), | 338 | id: self.id_alloc().alloc(range), |
337 | char: token.to_char().unwrap(), | 339 | char: token.to_char().unwrap(), |
@@ -344,7 +346,7 @@ trait TokenConvertor { | |||
344 | } | 346 | } |
345 | Some(it) => it.1, | 347 | Some(it) => it.1, |
346 | }; | 348 | }; |
347 | self.id_alloc().close_delim(id, Some(last_range)); | 349 | self.id_alloc().close_delim(idx, Some(last_range)); |
348 | subtree.into() | 350 | subtree.into() |
349 | } else { | 351 | } else { |
350 | let spacing = match self.peek() { | 352 | let spacing = match self.peek() { |
diff --git a/crates/ra_mbe/src/tests.rs b/crates/ra_mbe/src/tests.rs index 254318e23..5d1274d21 100644 --- a/crates/ra_mbe/src/tests.rs +++ b/crates/ra_mbe/src/tests.rs | |||
@@ -142,6 +142,79 @@ macro_rules! impl_froms { | |||
142 | } | 142 | } |
143 | 143 | ||
144 | #[test] | 144 | #[test] |
145 | fn test_convert_tt2() { | ||
146 | parse_macro( | ||
147 | r#" | ||
148 | macro_rules! impl_froms { | ||
149 | ($e:ident: $($v:ident),*) => { | ||
150 | $( | ||
151 | impl From<$v> for $e { | ||
152 | fn from(it: $v) -> $e { | ||
153 | $e::$v(it) | ||
154 | } | ||
155 | } | ||
156 | )* | ||
157 | } | ||
158 | } | ||
159 | "#, | ||
160 | ) | ||
161 | .assert_expand( | ||
162 | "impl_froms!(TokenTree: Leaf, Subtree);", | ||
163 | r#" | ||
164 | SUBTREE $ | ||
165 | IDENT impl 20 | ||
166 | IDENT From 21 | ||
167 | PUNCH < [joint] 22 | ||
168 | IDENT Leaf 53 | ||
169 | PUNCH > [alone] 25 | ||
170 | IDENT for 26 | ||
171 | IDENT TokenTree 51 | ||
172 | SUBTREE {} 29 | ||
173 | IDENT fn 30 | ||
174 | IDENT from 31 | ||
175 | SUBTREE () 32 | ||
176 | IDENT it 33 | ||
177 | PUNCH : [alone] 34 | ||
178 | IDENT Leaf 53 | ||
179 | PUNCH - [joint] 37 | ||
180 | PUNCH > [alone] 38 | ||
181 | IDENT TokenTree 51 | ||
182 | SUBTREE {} 41 | ||
183 | IDENT TokenTree 51 | ||
184 | PUNCH : [joint] 44 | ||
185 | PUNCH : [joint] 45 | ||
186 | IDENT Leaf 53 | ||
187 | SUBTREE () 48 | ||
188 | IDENT it 49 | ||
189 | IDENT impl 20 | ||
190 | IDENT From 21 | ||
191 | PUNCH < [joint] 22 | ||
192 | IDENT Subtree 55 | ||
193 | PUNCH > [alone] 25 | ||
194 | IDENT for 26 | ||
195 | IDENT TokenTree 51 | ||
196 | SUBTREE {} 29 | ||
197 | IDENT fn 30 | ||
198 | IDENT from 31 | ||
199 | SUBTREE () 32 | ||
200 | IDENT it 33 | ||
201 | PUNCH : [alone] 34 | ||
202 | IDENT Subtree 55 | ||
203 | PUNCH - [joint] 37 | ||
204 | PUNCH > [alone] 38 | ||
205 | IDENT TokenTree 51 | ||
206 | SUBTREE {} 41 | ||
207 | IDENT TokenTree 51 | ||
208 | PUNCH : [joint] 44 | ||
209 | PUNCH : [joint] 45 | ||
210 | IDENT Subtree 55 | ||
211 | SUBTREE () 48 | ||
212 | IDENT it 49 | ||
213 | "#, | ||
214 | ); | ||
215 | } | ||
216 | |||
217 | #[test] | ||
145 | fn test_expr_order() { | 218 | fn test_expr_order() { |
146 | let expanded = parse_macro( | 219 | let expanded = parse_macro( |
147 | r#" | 220 | r#" |
@@ -179,7 +252,7 @@ fn test_expr_order() { | |||
179 | STAR@[11; 12) "*" | 252 | STAR@[11; 12) "*" |
180 | LITERAL@[12; 13) | 253 | LITERAL@[12; 13) |
181 | INT_NUMBER@[12; 13) "2" | 254 | INT_NUMBER@[12; 13) "2" |
182 | SEMI@[13; 14) ";" | 255 | SEMICOLON@[13; 14) ";" |
183 | R_CURLY@[14; 15) "}""#, | 256 | R_CURLY@[14; 15) "}""#, |
184 | ); | 257 | ); |
185 | } | 258 | } |
@@ -532,7 +605,7 @@ fn test_tt_to_stmts() { | |||
532 | EQ@[4; 5) "=" | 605 | EQ@[4; 5) "=" |
533 | LITERAL@[5; 6) | 606 | LITERAL@[5; 6) |
534 | INT_NUMBER@[5; 6) "0" | 607 | INT_NUMBER@[5; 6) "0" |
535 | SEMI@[6; 7) ";" | 608 | SEMICOLON@[6; 7) ";" |
536 | EXPR_STMT@[7; 14) | 609 | EXPR_STMT@[7; 14) |
537 | BIN_EXPR@[7; 13) | 610 | BIN_EXPR@[7; 13) |
538 | PATH_EXPR@[7; 8) | 611 | PATH_EXPR@[7; 8) |
@@ -547,7 +620,7 @@ fn test_tt_to_stmts() { | |||
547 | PLUS@[11; 12) "+" | 620 | PLUS@[11; 12) "+" |
548 | LITERAL@[12; 13) | 621 | LITERAL@[12; 13) |
549 | INT_NUMBER@[12; 13) "1" | 622 | INT_NUMBER@[12; 13) "1" |
550 | SEMI@[13; 14) ";" | 623 | SEMICOLON@[13; 14) ";" |
551 | EXPR_STMT@[14; 15) | 624 | EXPR_STMT@[14; 15) |
552 | PATH_EXPR@[14; 15) | 625 | PATH_EXPR@[14; 15) |
553 | PATH@[14; 15) | 626 | PATH@[14; 15) |
@@ -880,7 +953,7 @@ fn test_tt_composite2() { | |||
880 | PATH_SEGMENT@[0; 3) | 953 | PATH_SEGMENT@[0; 3) |
881 | NAME_REF@[0; 3) | 954 | NAME_REF@[0; 3) |
882 | IDENT@[0; 3) "abs" | 955 | IDENT@[0; 3) "abs" |
883 | EXCL@[3; 4) "!" | 956 | BANG@[3; 4) "!" |
884 | TOKEN_TREE@[4; 10) | 957 | TOKEN_TREE@[4; 10) |
885 | L_PAREN@[4; 5) "(" | 958 | L_PAREN@[4; 5) "(" |
886 | EQ@[5; 6) "=" | 959 | EQ@[5; 6) "=" |
@@ -1000,14 +1073,14 @@ fn test_vec() { | |||
1000 | PATH_SEGMENT@[9; 12) | 1073 | PATH_SEGMENT@[9; 12) |
1001 | NAME_REF@[9; 12) | 1074 | NAME_REF@[9; 12) |
1002 | IDENT@[9; 12) "Vec" | 1075 | IDENT@[9; 12) "Vec" |
1003 | COLONCOLON@[12; 14) "::" | 1076 | COLON2@[12; 14) "::" |
1004 | PATH_SEGMENT@[14; 17) | 1077 | PATH_SEGMENT@[14; 17) |
1005 | NAME_REF@[14; 17) | 1078 | NAME_REF@[14; 17) |
1006 | IDENT@[14; 17) "new" | 1079 | IDENT@[14; 17) "new" |
1007 | ARG_LIST@[17; 19) | 1080 | ARG_LIST@[17; 19) |
1008 | L_PAREN@[17; 18) "(" | 1081 | L_PAREN@[17; 18) "(" |
1009 | R_PAREN@[18; 19) ")" | 1082 | R_PAREN@[18; 19) ")" |
1010 | SEMI@[19; 20) ";" | 1083 | SEMICOLON@[19; 20) ";" |
1011 | EXPR_STMT@[20; 33) | 1084 | EXPR_STMT@[20; 33) |
1012 | METHOD_CALL_EXPR@[20; 32) | 1085 | METHOD_CALL_EXPR@[20; 32) |
1013 | PATH_EXPR@[20; 21) | 1086 | PATH_EXPR@[20; 21) |
@@ -1023,7 +1096,7 @@ fn test_vec() { | |||
1023 | LITERAL@[27; 31) | 1096 | LITERAL@[27; 31) |
1024 | INT_NUMBER@[27; 31) "1u32" | 1097 | INT_NUMBER@[27; 31) "1u32" |
1025 | R_PAREN@[31; 32) ")" | 1098 | R_PAREN@[31; 32) ")" |
1026 | SEMI@[32; 33) ";" | 1099 | SEMICOLON@[32; 33) ";" |
1027 | EXPR_STMT@[33; 43) | 1100 | EXPR_STMT@[33; 43) |
1028 | METHOD_CALL_EXPR@[33; 42) | 1101 | METHOD_CALL_EXPR@[33; 42) |
1029 | PATH_EXPR@[33; 34) | 1102 | PATH_EXPR@[33; 34) |
@@ -1039,7 +1112,7 @@ fn test_vec() { | |||
1039 | LITERAL@[40; 41) | 1112 | LITERAL@[40; 41) |
1040 | INT_NUMBER@[40; 41) "2" | 1113 | INT_NUMBER@[40; 41) "2" |
1041 | R_PAREN@[41; 42) ")" | 1114 | R_PAREN@[41; 42) ")" |
1042 | SEMI@[42; 43) ";" | 1115 | SEMICOLON@[42; 43) ";" |
1043 | PATH_EXPR@[43; 44) | 1116 | PATH_EXPR@[43; 44) |
1044 | PATH@[43; 44) | 1117 | PATH@[43; 44) |
1045 | PATH_SEGMENT@[43; 44) | 1118 | PATH_SEGMENT@[43; 44) |
@@ -1479,6 +1552,12 @@ impl MacroFixture { | |||
1479 | assert_eq!(expansion.to_string(), expected); | 1552 | assert_eq!(expansion.to_string(), expected); |
1480 | } | 1553 | } |
1481 | 1554 | ||
1555 | fn assert_expand(&self, invocation: &str, expected: &str) { | ||
1556 | let expansion = self.expand_tt(invocation); | ||
1557 | let actual = format!("{:?}", expansion); | ||
1558 | test_utils::assert_eq_text!(&actual.trim(), &expected.trim()); | ||
1559 | } | ||
1560 | |||
1482 | fn assert_expand_items(&self, invocation: &str, expected: &str) -> &MacroFixture { | 1561 | fn assert_expand_items(&self, invocation: &str, expected: &str) -> &MacroFixture { |
1483 | self.assert_expansion(FragmentKind::Items, invocation, expected); | 1562 | self.assert_expansion(FragmentKind::Items, invocation, expected); |
1484 | self | 1563 | self |
@@ -1681,7 +1760,7 @@ fn test_no_space_after_semi_colon() { | |||
1681 | MOD_KW@[21; 24) "mod" | 1760 | MOD_KW@[21; 24) "mod" |
1682 | NAME@[24; 25) | 1761 | NAME@[24; 25) |
1683 | IDENT@[24; 25) "m" | 1762 | IDENT@[24; 25) "m" |
1684 | SEMI@[25; 26) ";" | 1763 | SEMICOLON@[25; 26) ";" |
1685 | MODULE@[26; 52) | 1764 | MODULE@[26; 52) |
1686 | ATTR@[26; 47) | 1765 | ATTR@[26; 47) |
1687 | POUND@[26; 27) "#" | 1766 | POUND@[26; 27) "#" |
@@ -1700,7 +1779,7 @@ fn test_no_space_after_semi_colon() { | |||
1700 | MOD_KW@[47; 50) "mod" | 1779 | MOD_KW@[47; 50) "mod" |
1701 | NAME@[50; 51) | 1780 | NAME@[50; 51) |
1702 | IDENT@[50; 51) "f" | 1781 | IDENT@[50; 51) "f" |
1703 | SEMI@[51; 52) ";""###, | 1782 | SEMICOLON@[51; 52) ";""###, |
1704 | ); | 1783 | ); |
1705 | } | 1784 | } |
1706 | 1785 | ||