aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-01-16 17:35:03 +0000
committerAleksey Kladov <[email protected]>2020-01-16 17:35:03 +0000
commitab0a11b1de3237a476639fee39fcf6ef506bdf34 (patch)
treed02418aa8a96b7df2703ed379f96310f7f4441b9 /crates/ra_parser/src/grammar
parentd3c4fbbbc45afc7d480185493b5ce77b5daa1747 (diff)
Simplify array parsing
Diffstat (limited to 'crates/ra_parser/src/grammar')
-rw-r--r--crates/ra_parser/src/grammar/attributes.rs22
-rw-r--r--crates/ra_parser/src/grammar/expressions/atom.rs57
2 files changed, 31 insertions, 48 deletions
diff --git a/crates/ra_parser/src/grammar/attributes.rs b/crates/ra_parser/src/grammar/attributes.rs
index eeae37aef..f3158ade3 100644
--- a/crates/ra_parser/src/grammar/attributes.rs
+++ b/crates/ra_parser/src/grammar/attributes.rs
@@ -8,28 +8,6 @@ pub(super) fn inner_attributes(p: &mut Parser) {
8 } 8 }
9} 9}
10 10
11pub(super) fn with_outer_attributes(
12 p: &mut Parser,
13 f: impl Fn(&mut Parser) -> Option<CompletedMarker>,
14) -> bool {
15 let am = p.start();
16 let has_attrs = p.at(T![#]);
17 attributes::outer_attributes(p);
18 let cm = f(p);
19 let success = cm.is_some();
20
21 match (has_attrs, cm) {
22 (true, Some(cm)) => {
23 let kind = cm.kind();
24 cm.undo_completion(p).abandon(p);
25 am.complete(p, kind);
26 }
27 _ => am.abandon(p),
28 }
29
30 success
31}
32
33pub(super) fn outer_attributes(p: &mut Parser) { 11pub(super) fn outer_attributes(p: &mut Parser) {
34 while p.at(T![#]) { 12 while p.at(T![#]) {
35 attribute(p, false) 13 attribute(p, false)
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs
index 700994e80..5c413317e 100644
--- a/crates/ra_parser/src/grammar/expressions/atom.rs
+++ b/crates/ra_parser/src/grammar/expressions/atom.rs
@@ -181,29 +181,19 @@ fn tuple_expr(p: &mut Parser) -> CompletedMarker {
181fn array_expr(p: &mut Parser) -> CompletedMarker { 181fn array_expr(p: &mut Parser) -> CompletedMarker {
182 assert!(p.at(T!['['])); 182 assert!(p.at(T!['[']));
183 let m = p.start(); 183 let m = p.start();
184 p.bump(T!['[']);
185 if p.eat(T![']']) {
186 return m.complete(p, ARRAY_EXPR);
187 }
188 184
189 // test first_array_member_attributes 185 let mut n_exprs = 0u32;
190 // pub const A: &[i64] = &[ 186 let mut has_semi = false;
191 // #[cfg(test)]
192 // 1,
193 // 2,
194 // ];
195 attributes::with_outer_attributes(p, |p| expr(p).0);
196 187
197 if p.eat(T![;]) { 188 p.bump(T!['[']);
198 expr(p);
199 p.expect(T![']']);
200 return m.complete(p, ARRAY_EXPR);
201 }
202 while !p.at(EOF) && !p.at(T![']']) { 189 while !p.at(EOF) && !p.at(T![']']) {
203 p.expect(T![,]); 190 n_exprs += 1;
204 if p.at(T![']']) { 191 // test first_array_member_attributes
205 break; 192 // pub const A: &[i64] = &[
206 } 193 // #[cfg(test)]
194 // 1,
195 // 2,
196 // ];
207 197
208 // test subsequent_array_member_attributes 198 // test subsequent_array_member_attributes
209 // pub const A: &[i64] = &[ 199 // pub const A: &[i64] = &[
@@ -211,17 +201,32 @@ fn array_expr(p: &mut Parser) -> CompletedMarker {
211 // #[cfg(test)] 201 // #[cfg(test)]
212 // 2, 202 // 2,
213 // ]; 203 // ];
214 if !attributes::with_outer_attributes(p, |p| { 204 let m = p.start();
215 if !p.at_ts(EXPR_FIRST) { 205 let has_attrs = p.at(T![#]);
216 p.error("expected expression"); 206 attributes::outer_attributes(p);
217 return None; 207
208 let cm = expr(p).0;
209
210 match (has_attrs, cm) {
211 (true, Some(cm)) => {
212 let kind = cm.kind();
213 cm.undo_completion(p).abandon(p);
214 m.complete(p, kind);
218 } 215 }
219 expr(p).0 216 _ => m.abandon(p),
220 }) { 217 }
218
219 if n_exprs == 1 && p.eat(T![;]) {
220 has_semi = true;
221 continue;
222 }
223
224 if has_semi || !p.at(T![']']) && !p.expect(T![,]) {
221 break; 225 break;
222 } 226 }
223 } 227 }
224 p.expect(T![']']); 228 p.expect(T![']']);
229
225 m.complete(p, ARRAY_EXPR) 230 m.complete(p, ARRAY_EXPR)
226} 231}
227 232