aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_parser/src/grammar/attributes.rs22
-rw-r--r--crates/ra_parser/src/grammar/expressions.rs4
-rw-r--r--crates/ra_parser/src/grammar/expressions/atom.rs14
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0135_first_array_member_attributes.txt28
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0136_subsequent_array_member_attributes.txt28
5 files changed, 60 insertions, 36 deletions
diff --git a/crates/ra_parser/src/grammar/attributes.rs b/crates/ra_parser/src/grammar/attributes.rs
index f3158ade3..eeae37aef 100644
--- a/crates/ra_parser/src/grammar/attributes.rs
+++ b/crates/ra_parser/src/grammar/attributes.rs
@@ -8,6 +8,28 @@ 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
11pub(super) fn outer_attributes(p: &mut Parser) { 33pub(super) fn outer_attributes(p: &mut Parser) {
12 while p.at(T![#]) { 34 while p.at(T![#]) {
13 attribute(p, false) 35 attribute(p, false)
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs
index 81d4f75f9..d733499d1 100644
--- a/crates/ra_parser/src/grammar/expressions.rs
+++ b/crates/ra_parser/src/grammar/expressions.rs
@@ -14,9 +14,9 @@ pub(super) enum StmtWithSemi {
14 14
15const EXPR_FIRST: TokenSet = LHS_FIRST; 15const EXPR_FIRST: TokenSet = LHS_FIRST;
16 16
17pub(super) fn expr(p: &mut Parser) -> BlockLike { 17pub(super) fn expr(p: &mut Parser) -> (Option<CompletedMarker>, BlockLike) {
18 let r = Restrictions { forbid_structs: false, prefer_stmt: false }; 18 let r = Restrictions { forbid_structs: false, prefer_stmt: false };
19 expr_bp(p, r, 1).1 19 expr_bp(p, r, 1)
20} 20}
21 21
22pub(super) fn expr_stmt(p: &mut Parser) -> (Option<CompletedMarker>, BlockLike) { 22pub(super) fn expr_stmt(p: &mut Parser) -> (Option<CompletedMarker>, BlockLike) {
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs
index 4ac1d6334..700994e80 100644
--- a/crates/ra_parser/src/grammar/expressions/atom.rs
+++ b/crates/ra_parser/src/grammar/expressions/atom.rs
@@ -192,9 +192,8 @@ fn array_expr(p: &mut Parser) -> CompletedMarker {
192 // 1, 192 // 1,
193 // 2, 193 // 2,
194 // ]; 194 // ];
195 attributes::outer_attributes(p); 195 attributes::with_outer_attributes(p, |p| expr(p).0);
196 196
197 expr(p);
198 if p.eat(T![;]) { 197 if p.eat(T![;]) {
199 expr(p); 198 expr(p);
200 p.expect(T![']']); 199 p.expect(T![']']);
@@ -212,12 +211,15 @@ fn array_expr(p: &mut Parser) -> CompletedMarker {
212 // #[cfg(test)] 211 // #[cfg(test)]
213 // 2, 212 // 2,
214 // ]; 213 // ];
215 attributes::outer_attributes(p); 214 if !attributes::with_outer_attributes(p, |p| {
216 if !p.at_ts(EXPR_FIRST) { 215 if !p.at_ts(EXPR_FIRST) {
217 p.error("expected expression"); 216 p.error("expected expression");
217 return None;
218 }
219 expr(p).0
220 }) {
218 break; 221 break;
219 } 222 }
220 expr(p);
221 } 223 }
222 p.expect(T![']']); 224 p.expect(T![']']);
223 m.complete(p, ARRAY_EXPR) 225 m.complete(p, ARRAY_EXPR)
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0135_first_array_member_attributes.txt b/crates/ra_syntax/test_data/parser/inline/ok/0135_first_array_member_attributes.txt
index 8f2e91bdf..2e3a13005 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0135_first_array_member_attributes.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0135_first_array_member_attributes.txt
@@ -27,20 +27,20 @@ SOURCE_FILE@[0; 56)
27 ARRAY_EXPR@[23; 54) 27 ARRAY_EXPR@[23; 54)
28 L_BRACK@[23; 24) "[" 28 L_BRACK@[23; 24) "["
29 WHITESPACE@[24; 28) "\n " 29 WHITESPACE@[24; 28) "\n "
30 ATTR@[28; 40) 30 LITERAL@[28; 45)
31 POUND@[28; 29) "#" 31 ATTR@[28; 40)
32 L_BRACK@[29; 30) "[" 32 POUND@[28; 29) "#"
33 PATH@[30; 33) 33 L_BRACK@[29; 30) "["
34 PATH_SEGMENT@[30; 33) 34 PATH@[30; 33)
35 NAME_REF@[30; 33) 35 PATH_SEGMENT@[30; 33)
36 IDENT@[30; 33) "cfg" 36 NAME_REF@[30; 33)
37 TOKEN_TREE@[33; 39) 37 IDENT@[30; 33) "cfg"
38 L_PAREN@[33; 34) "(" 38 TOKEN_TREE@[33; 39)
39 IDENT@[34; 38) "test" 39 L_PAREN@[33; 34) "("
40 R_PAREN@[38; 39) ")" 40 IDENT@[34; 38) "test"
41 R_BRACK@[39; 40) "]" 41 R_PAREN@[38; 39) ")"
42 WHITESPACE@[40; 44) "\n " 42 R_BRACK@[39; 40) "]"
43 LITERAL@[44; 45) 43 WHITESPACE@[40; 44) "\n "
44 INT_NUMBER@[44; 45) "1" 44 INT_NUMBER@[44; 45) "1"
45 COMMA@[45; 46) "," 45 COMMA@[45; 46) ","
46 WHITESPACE@[46; 50) "\n " 46 WHITESPACE@[46; 50) "\n "
diff --git a/crates/ra_syntax/test_data/parser/inline/ok/0136_subsequent_array_member_attributes.txt b/crates/ra_syntax/test_data/parser/inline/ok/0136_subsequent_array_member_attributes.txt
index 41914eb8e..1bb8a0afc 100644
--- a/crates/ra_syntax/test_data/parser/inline/ok/0136_subsequent_array_member_attributes.txt
+++ b/crates/ra_syntax/test_data/parser/inline/ok/0136_subsequent_array_member_attributes.txt
@@ -31,20 +31,20 @@ SOURCE_FILE@[0; 56)
31 INT_NUMBER@[28; 29) "1" 31 INT_NUMBER@[28; 29) "1"
32 COMMA@[29; 30) "," 32 COMMA@[29; 30) ","
33 WHITESPACE@[30; 34) "\n " 33 WHITESPACE@[30; 34) "\n "
34 ATTR@[34; 46) 34 LITERAL@[34; 51)
35 POUND@[34; 35) "#" 35 ATTR@[34; 46)
36 L_BRACK@[35; 36) "[" 36 POUND@[34; 35) "#"
37 PATH@[36; 39) 37 L_BRACK@[35; 36) "["
38 PATH_SEGMENT@[36; 39) 38 PATH@[36; 39)
39 NAME_REF@[36; 39) 39 PATH_SEGMENT@[36; 39)
40 IDENT@[36; 39) "cfg" 40 NAME_REF@[36; 39)
41 TOKEN_TREE@[39; 45) 41 IDENT@[36; 39) "cfg"
42 L_PAREN@[39; 40) "(" 42 TOKEN_TREE@[39; 45)
43 IDENT@[40; 44) "test" 43 L_PAREN@[39; 40) "("
44 R_PAREN@[44; 45) ")" 44 IDENT@[40; 44) "test"
45 R_BRACK@[45; 46) "]" 45 R_PAREN@[44; 45) ")"
46 WHITESPACE@[46; 50) "\n " 46 R_BRACK@[45; 46) "]"
47 LITERAL@[50; 51) 47 WHITESPACE@[46; 50) "\n "
48 INT_NUMBER@[50; 51) "2" 48 INT_NUMBER@[50; 51) "2"
49 COMMA@[51; 52) "," 49 COMMA@[51; 52) ","
50 WHITESPACE@[52; 53) "\n" 50 WHITESPACE@[52; 53) "\n"