diff options
Diffstat (limited to 'crates/ra_parser')
-rw-r--r-- | crates/ra_parser/src/grammar.rs | 10 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/expressions.rs | 11 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/params.rs | 13 | ||||
-rw-r--r-- | crates/ra_parser/src/grammar/type_args.rs | 7 | ||||
-rw-r--r-- | crates/ra_parser/src/parser.rs | 54 |
5 files changed, 69 insertions, 26 deletions
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs index 658034097..beedac457 100644 --- a/crates/ra_parser/src/grammar.rs +++ b/crates/ra_parser/src/grammar.rs | |||
@@ -287,6 +287,16 @@ fn name_ref(p: &mut Parser) { | |||
287 | } | 287 | } |
288 | } | 288 | } |
289 | 289 | ||
290 | fn name_ref_or_index(p: &mut Parser) { | ||
291 | if p.at(IDENT) || p.at(INT_NUMBER) { | ||
292 | let m = p.start(); | ||
293 | p.bump(); | ||
294 | m.complete(p, NAME_REF); | ||
295 | } else { | ||
296 | p.err_and_bump("expected identifier"); | ||
297 | } | ||
298 | } | ||
299 | |||
290 | fn error_block(p: &mut Parser, message: &str) { | 300 | fn error_block(p: &mut Parser, message: &str) { |
291 | assert!(p.at(T!['{'])); | 301 | assert!(p.at(T!['{'])); |
292 | let m = p.start(); | 302 | let m = p.start(); |
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index b60a2f68c..742076c1a 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs | |||
@@ -489,10 +489,8 @@ fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | |||
489 | assert!(p.at(T![.])); | 489 | assert!(p.at(T![.])); |
490 | let m = lhs.precede(p); | 490 | let m = lhs.precede(p); |
491 | p.bump(); | 491 | p.bump(); |
492 | if p.at(IDENT) { | 492 | if p.at(IDENT) || p.at(INT_NUMBER) { |
493 | name_ref(p) | 493 | name_ref_or_index(p) |
494 | } else if p.at(INT_NUMBER) { | ||
495 | p.bump(); | ||
496 | } else if p.at(FLOAT_NUMBER) { | 494 | } else if p.at(FLOAT_NUMBER) { |
497 | // FIXME: How to recover and instead parse INT + T![.]? | 495 | // FIXME: How to recover and instead parse INT + T![.]? |
498 | p.bump(); | 496 | p.bump(); |
@@ -577,6 +575,7 @@ fn path_expr(p: &mut Parser, r: Restrictions) -> (CompletedMarker, BlockLike) { | |||
577 | // S {}; | 575 | // S {}; |
578 | // S { x, y: 32, }; | 576 | // S { x, y: 32, }; |
579 | // S { x, y: 32, ..Default::default() }; | 577 | // S { x, y: 32, ..Default::default() }; |
578 | // TupleStruct { 0: 1 }; | ||
580 | // } | 579 | // } |
581 | pub(crate) fn named_field_list(p: &mut Parser) { | 580 | pub(crate) fn named_field_list(p: &mut Parser) { |
582 | assert!(p.at(T!['{'])); | 581 | assert!(p.at(T!['{'])); |
@@ -588,10 +587,10 @@ pub(crate) fn named_field_list(p: &mut Parser) { | |||
588 | // fn main() { | 587 | // fn main() { |
589 | // S { #[cfg(test)] field: 1 } | 588 | // S { #[cfg(test)] field: 1 } |
590 | // } | 589 | // } |
591 | IDENT | T![#] => { | 590 | IDENT | INT_NUMBER | T![#] => { |
592 | let m = p.start(); | 591 | let m = p.start(); |
593 | attributes::outer_attributes(p); | 592 | attributes::outer_attributes(p); |
594 | name_ref(p); | 593 | name_ref_or_index(p); |
595 | if p.eat(T![:]) { | 594 | if p.eat(T![:]) { |
596 | expr(p); | 595 | expr(p); |
597 | } | 596 | } |
diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs index 723b56343..0b09f1874 100644 --- a/crates/ra_parser/src/grammar/params.rs +++ b/crates/ra_parser/src/grammar/params.rs | |||
@@ -41,9 +41,20 @@ fn list_(p: &mut Parser, flavor: Flavor) { | |||
41 | let m = p.start(); | 41 | let m = p.start(); |
42 | p.bump(); | 42 | p.bump(); |
43 | if flavor.type_required() { | 43 | if flavor.type_required() { |
44 | // test self_param_outer_attr | ||
45 | // fn f(#[must_use] self) {} | ||
46 | attributes::outer_attributes(p); | ||
44 | opt_self_param(p); | 47 | opt_self_param(p); |
45 | } | 48 | } |
46 | while !p.at(EOF) && !p.at(ket) && !(flavor.type_required() && p.at(T![...])) { | 49 | while !p.at(EOF) && !p.at(ket) { |
50 | // test param_outer_arg | ||
51 | // fn f(#[attr1] pat: Type) {} | ||
52 | attributes::outer_attributes(p); | ||
53 | |||
54 | if flavor.type_required() && p.at(T![...]) { | ||
55 | break; | ||
56 | } | ||
57 | |||
47 | if !p.at_ts(VALUE_PARAMETER_FIRST) { | 58 | if !p.at_ts(VALUE_PARAMETER_FIRST) { |
48 | p.error("expected value parameter"); | 59 | p.error("expected value parameter"); |
49 | break; | 60 | break; |
diff --git a/crates/ra_parser/src/grammar/type_args.rs b/crates/ra_parser/src/grammar/type_args.rs index f391b63db..3db08b280 100644 --- a/crates/ra_parser/src/grammar/type_args.rs +++ b/crates/ra_parser/src/grammar/type_args.rs | |||
@@ -35,6 +35,13 @@ fn type_arg(p: &mut Parser) { | |||
35 | p.bump(); | 35 | p.bump(); |
36 | m.complete(p, LIFETIME_ARG); | 36 | m.complete(p, LIFETIME_ARG); |
37 | } | 37 | } |
38 | // test associated_type_bounds | ||
39 | // fn print_all<T: Iterator<Item: Display>>(printables: T) {} | ||
40 | IDENT if p.nth(1) == T![:] => { | ||
41 | name_ref(p); | ||
42 | type_params::bounds(p); | ||
43 | m.complete(p, ASSOC_TYPE_ARG); | ||
44 | } | ||
38 | IDENT if p.nth(1) == T![=] => { | 45 | IDENT if p.nth(1) == T![=] => { |
39 | name_ref(p); | 46 | name_ref(p); |
40 | p.bump(); | 47 | p.bump(); |
diff --git a/crates/ra_parser/src/parser.rs b/crates/ra_parser/src/parser.rs index 159ed50df..393586561 100644 --- a/crates/ra_parser/src/parser.rs +++ b/crates/ra_parser/src/parser.rs | |||
@@ -6,7 +6,7 @@ use crate::{ | |||
6 | event::Event, | 6 | event::Event, |
7 | ParseError, | 7 | ParseError, |
8 | SyntaxKind::{self, EOF, ERROR, TOMBSTONE}, | 8 | SyntaxKind::{self, EOF, ERROR, TOMBSTONE}, |
9 | TokenSet, TokenSource, T, | 9 | Token, TokenSet, TokenSource, T, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | /// `Parser` struct provides the low-level API for | 12 | /// `Parser` struct provides the low-level API for |
@@ -87,8 +87,9 @@ impl<'t> Parser<'t> { | |||
87 | let mut i = 0; | 87 | let mut i = 0; |
88 | 88 | ||
89 | loop { | 89 | loop { |
90 | let mut kind = self.token_source.lookahead_nth(i).kind; | 90 | let token = self.token_source.lookahead_nth(i); |
91 | if let Some((composited, step)) = self.is_composite(kind, i) { | 91 | let mut kind = token.kind; |
92 | if let Some((composited, step)) = self.is_composite(token, i) { | ||
92 | kind = composited; | 93 | kind = composited; |
93 | i += step; | 94 | i += step; |
94 | } else { | 95 | } else { |
@@ -250,32 +251,47 @@ impl<'t> Parser<'t> { | |||
250 | } | 251 | } |
251 | 252 | ||
252 | /// helper function for check if it is composite. | 253 | /// helper function for check if it is composite. |
253 | fn is_composite(&self, kind: SyntaxKind, n: usize) -> Option<(SyntaxKind, usize)> { | 254 | fn is_composite(&self, first: Token, n: usize) -> Option<(SyntaxKind, usize)> { |
254 | // We assume the dollars will not occuried between | 255 | // We assume the dollars will not occuried between |
255 | // mult-byte tokens | 256 | // mult-byte tokens |
256 | 257 | ||
257 | let first = self.token_source.lookahead_nth(n); | 258 | let jn1 = first.is_jointed_to_next; |
259 | if !jn1 && first.kind != T![-] { | ||
260 | return None; | ||
261 | } | ||
262 | |||
258 | let second = self.token_source.lookahead_nth(n + 1); | 263 | let second = self.token_source.lookahead_nth(n + 1); |
264 | if first.kind == T![-] && second.kind == T![>] { | ||
265 | return Some((T![->], 2)); | ||
266 | } | ||
267 | if !jn1 { | ||
268 | return None; | ||
269 | } | ||
270 | |||
271 | match (first.kind, second.kind) { | ||
272 | (T![:], T![:]) => return Some((T![::], 2)), | ||
273 | (T![=], T![=]) => return Some((T![==], 2)), | ||
274 | (T![=], T![>]) => return Some((T![=>], 2)), | ||
275 | (T![!], T![=]) => return Some((T![!=], 2)), | ||
276 | _ => {} | ||
277 | } | ||
278 | |||
279 | if first.kind != T![.] || second.kind != T![.] { | ||
280 | return None; | ||
281 | } | ||
282 | |||
259 | let third = self.token_source.lookahead_nth(n + 2); | 283 | let third = self.token_source.lookahead_nth(n + 2); |
260 | 284 | ||
261 | let jn1 = first.is_jointed_to_next; | ||
262 | let la2 = second.kind; | ||
263 | let jn2 = second.is_jointed_to_next; | 285 | let jn2 = second.is_jointed_to_next; |
264 | let la3 = third.kind; | 286 | let la3 = third.kind; |
265 | 287 | ||
266 | match kind { | 288 | if jn2 && la3 == T![.] { |
267 | T![.] if jn1 && la2 == T![.] && jn2 && la3 == T![.] => Some((T![...], 3)), | 289 | return Some((T![...], 3)); |
268 | T![.] if jn1 && la2 == T![.] && la3 == T![=] => Some((T![..=], 3)), | 290 | } |
269 | T![.] if jn1 && la2 == T![.] => Some((T![..], 2)), | 291 | if la3 == T![=] { |
270 | 292 | return Some((T![..=], 3)); | |
271 | T![:] if jn1 && la2 == T![:] => Some((T![::], 2)), | ||
272 | T![=] if jn1 && la2 == T![=] => Some((T![==], 2)), | ||
273 | T![=] if jn1 && la2 == T![>] => Some((T![=>], 2)), | ||
274 | |||
275 | T![!] if jn1 && la2 == T![=] => Some((T![!=], 2)), | ||
276 | T![-] if la2 == T![>] => Some((T![->], 2)), | ||
277 | _ => None, | ||
278 | } | 293 | } |
294 | return Some((T![..], 2)); | ||
279 | } | 295 | } |
280 | 296 | ||
281 | fn eat_dollars(&mut self) { | 297 | fn eat_dollars(&mut self) { |