aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src')
-rw-r--r--crates/ra_parser/src/grammar.rs10
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs11
-rw-r--r--crates/ra_parser/src/grammar/params.rs13
-rw-r--r--crates/ra_parser/src/grammar/type_args.rs7
-rw-r--r--crates/ra_parser/src/parser.rs54
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
290fn 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
290fn error_block(p: &mut Parser, message: &str) { 300fn 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// }
581pub(crate) fn named_field_list(p: &mut Parser) { 580pub(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) {