aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Cumming <[email protected]>2019-06-30 08:59:26 +0100
committerRyan Cumming <[email protected]>2019-06-30 09:36:54 +0100
commitb01496538c938d6a0c904512a38e4325cc960334 (patch)
treea6588dc1af1094aadac540bfe90acced3fb08fea
parent27df89f47d5f0a6e8e62d517d98dda854efabc34 (diff)
Support attributes on array members
Array members are allow to have attributes such as `#[cfg]`. This is a bit tricky as we don't know if the first expression is an initializer or a member until we encounter a `;`. This reuses a trick from `stmt` where we remember if we saw an attribute and then raise an error if the first expression ends up being an initializer. This isn't perfect as the error isn't correctly located on the attribute or initializer; it ends up immediately after the `;`.
-rw-r--r--crates/ra_parser/src/grammar/expressions/atom.rs28
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0015_array_length_attributes.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/err/0015_array_length_attributes.txt60
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0135_first_array_member_attributes.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0135_first_array_member_attributes.txt51
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0136_subsequent_array_member_attributes.rs5
-rw-r--r--crates/ra_syntax/tests/data/parser/inline/ok/0136_subsequent_array_member_attributes.txt51
7 files changed, 205 insertions, 0 deletions
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs
index 41be283d0..5e51d667e 100644
--- a/crates/ra_parser/src/grammar/expressions/atom.rs
+++ b/crates/ra_parser/src/grammar/expressions/atom.rs
@@ -170,8 +170,28 @@ fn array_expr(p: &mut Parser) -> CompletedMarker {
170 if p.eat(T![']']) { 170 if p.eat(T![']']) {
171 return m.complete(p, ARRAY_EXPR); 171 return m.complete(p, ARRAY_EXPR);
172 } 172 }
173
174 // test first_array_member_attributes
175 // pub const A: &[i64] = &[
176 // #[cfg(test)]
177 // 1,
178 // 2,
179 // ];
180 let first_member_has_attrs = p.at(T![#]);
181 attributes::outer_attributes(p);
182
173 expr(p); 183 expr(p);
174 if p.eat(T![;]) { 184 if p.eat(T![;]) {
185 if first_member_has_attrs {
186 // test_err array_length_attributes
187 // pub const A: &[i64] = &[
188 // #[cfg(test)]
189 // 1;
190 // 2,
191 // ];
192 p.error("removing an expression is not supported in this position");
193 }
194
175 expr(p); 195 expr(p);
176 p.expect(T![']']); 196 p.expect(T![']']);
177 return m.complete(p, ARRAY_EXPR); 197 return m.complete(p, ARRAY_EXPR);
@@ -181,6 +201,14 @@ fn array_expr(p: &mut Parser) -> CompletedMarker {
181 if p.at(T![']']) { 201 if p.at(T![']']) {
182 break; 202 break;
183 } 203 }
204
205 // test subsequent_array_member_attributes
206 // pub const A: &[i64] = &[
207 // 1,
208 // #[cfg(test)]
209 // 2,
210 // ];
211 attributes::outer_attributes(p);
184 if !p.at_ts(EXPR_FIRST) { 212 if !p.at_ts(EXPR_FIRST) {
185 p.error("expected expression"); 213 p.error("expected expression");
186 break; 214 break;
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0015_array_length_attributes.rs b/crates/ra_syntax/tests/data/parser/inline/err/0015_array_length_attributes.rs
new file mode 100644
index 000000000..ba630981d
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0015_array_length_attributes.rs
@@ -0,0 +1,5 @@
1pub const A: &[i64] = &[
2 #[cfg(test)]
3 1;
4 2,
5];
diff --git a/crates/ra_syntax/tests/data/parser/inline/err/0015_array_length_attributes.txt b/crates/ra_syntax/tests/data/parser/inline/err/0015_array_length_attributes.txt
new file mode 100644
index 000000000..5f0e3f22c
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/err/0015_array_length_attributes.txt
@@ -0,0 +1,60 @@
1SOURCE_FILE@[0; 53)
2 CONST_DEF@[0; 48)
3 VISIBILITY@[0; 3)
4 PUB_KW@[0; 3) "pub"
5 WHITESPACE@[3; 4) " "
6 CONST_KW@[4; 9) "const"
7 WHITESPACE@[9; 10) " "
8 NAME@[10; 11)
9 IDENT@[10; 11) "A"
10 COLON@[11; 12) ":"
11 WHITESPACE@[12; 13) " "
12 REFERENCE_TYPE@[13; 19)
13 AMP@[13; 14) "&"
14 SLICE_TYPE@[14; 19)
15 L_BRACK@[14; 15) "["
16 PATH_TYPE@[15; 18)
17 PATH@[15; 18)
18 PATH_SEGMENT@[15; 18)
19 NAME_REF@[15; 18)
20 IDENT@[15; 18) "i64"
21 R_BRACK@[18; 19) "]"
22 WHITESPACE@[19; 20) " "
23 EQ@[20; 21) "="
24 WHITESPACE@[21; 22) " "
25 REF_EXPR@[22; 48)
26 AMP@[22; 23) "&"
27 ARRAY_EXPR@[23; 48)
28 L_BRACK@[23; 24) "["
29 WHITESPACE@[24; 27) "\n "
30 ATTR@[27; 39)
31 POUND@[27; 28) "#"
32 TOKEN_TREE@[28; 39)
33 L_BRACK@[28; 29) "["
34 IDENT@[29; 32) "cfg"
35 TOKEN_TREE@[32; 38)
36 L_PAREN@[32; 33) "("
37 IDENT@[33; 37) "test"
38 R_PAREN@[37; 38) ")"
39 R_BRACK@[38; 39) "]"
40 WHITESPACE@[39; 42) "\n "
41 LITERAL@[42; 43)
42 INT_NUMBER@[42; 43) "1"
43 SEMI@[43; 44) ";"
44 WHITESPACE@[44; 47) "\n "
45 LITERAL@[47; 48)
46 INT_NUMBER@[47; 48) "2"
47 ERROR@[48; 49)
48 COMMA@[48; 49) ","
49 WHITESPACE@[49; 50) "\n"
50 ERROR@[50; 51)
51 R_BRACK@[50; 51) "]"
52 ERROR@[51; 52)
53 SEMI@[51; 52) ";"
54 WHITESPACE@[52; 53) "\n"
55error 44: removing an expression is not supported in this position
56error 48: expected R_BRACK
57error 48: expected SEMI
58error 48: expected an item
59error 50: expected an item
60error 51: expected an item
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0135_first_array_member_attributes.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0135_first_array_member_attributes.rs
new file mode 100644
index 000000000..f59e13771
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0135_first_array_member_attributes.rs
@@ -0,0 +1,5 @@
1pub const A: &[i64] = &[
2 #[cfg(test)]
3 1,
4 2,
5];
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0135_first_array_member_attributes.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0135_first_array_member_attributes.txt
new file mode 100644
index 000000000..eac4f6f30
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0135_first_array_member_attributes.txt
@@ -0,0 +1,51 @@
1SOURCE_FILE@[0; 56)
2 CONST_DEF@[0; 55)
3 VISIBILITY@[0; 3)
4 PUB_KW@[0; 3) "pub"
5 WHITESPACE@[3; 4) " "
6 CONST_KW@[4; 9) "const"
7 WHITESPACE@[9; 10) " "
8 NAME@[10; 11)
9 IDENT@[10; 11) "A"
10 COLON@[11; 12) ":"
11 WHITESPACE@[12; 13) " "
12 REFERENCE_TYPE@[13; 19)
13 AMP@[13; 14) "&"
14 SLICE_TYPE@[14; 19)
15 L_BRACK@[14; 15) "["
16 PATH_TYPE@[15; 18)
17 PATH@[15; 18)
18 PATH_SEGMENT@[15; 18)
19 NAME_REF@[15; 18)
20 IDENT@[15; 18) "i64"
21 R_BRACK@[18; 19) "]"
22 WHITESPACE@[19; 20) " "
23 EQ@[20; 21) "="
24 WHITESPACE@[21; 22) " "
25 REF_EXPR@[22; 54)
26 AMP@[22; 23) "&"
27 ARRAY_EXPR@[23; 54)
28 L_BRACK@[23; 24) "["
29 WHITESPACE@[24; 28) "\n "
30 ATTR@[28; 40)
31 POUND@[28; 29) "#"
32 TOKEN_TREE@[29; 40)
33 L_BRACK@[29; 30) "["
34 IDENT@[30; 33) "cfg"
35 TOKEN_TREE@[33; 39)
36 L_PAREN@[33; 34) "("
37 IDENT@[34; 38) "test"
38 R_PAREN@[38; 39) ")"
39 R_BRACK@[39; 40) "]"
40 WHITESPACE@[40; 44) "\n "
41 LITERAL@[44; 45)
42 INT_NUMBER@[44; 45) "1"
43 COMMA@[45; 46) ","
44 WHITESPACE@[46; 50) "\n "
45 LITERAL@[50; 51)
46 INT_NUMBER@[50; 51) "2"
47 COMMA@[51; 52) ","
48 WHITESPACE@[52; 53) "\n"
49 R_BRACK@[53; 54) "]"
50 SEMI@[54; 55) ";"
51 WHITESPACE@[55; 56) "\n"
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0136_subsequent_array_member_attributes.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0136_subsequent_array_member_attributes.rs
new file mode 100644
index 000000000..1324acb3f
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0136_subsequent_array_member_attributes.rs
@@ -0,0 +1,5 @@
1pub const A: &[i64] = &[
2 1,
3 #[cfg(test)]
4 2,
5];
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0136_subsequent_array_member_attributes.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0136_subsequent_array_member_attributes.txt
new file mode 100644
index 000000000..6fa1b42d9
--- /dev/null
+++ b/crates/ra_syntax/tests/data/parser/inline/ok/0136_subsequent_array_member_attributes.txt
@@ -0,0 +1,51 @@
1SOURCE_FILE@[0; 56)
2 CONST_DEF@[0; 55)
3 VISIBILITY@[0; 3)
4 PUB_KW@[0; 3) "pub"
5 WHITESPACE@[3; 4) " "
6 CONST_KW@[4; 9) "const"
7 WHITESPACE@[9; 10) " "
8 NAME@[10; 11)
9 IDENT@[10; 11) "A"
10 COLON@[11; 12) ":"
11 WHITESPACE@[12; 13) " "
12 REFERENCE_TYPE@[13; 19)
13 AMP@[13; 14) "&"
14 SLICE_TYPE@[14; 19)
15 L_BRACK@[14; 15) "["
16 PATH_TYPE@[15; 18)
17 PATH@[15; 18)
18 PATH_SEGMENT@[15; 18)
19 NAME_REF@[15; 18)
20 IDENT@[15; 18) "i64"
21 R_BRACK@[18; 19) "]"
22 WHITESPACE@[19; 20) " "
23 EQ@[20; 21) "="
24 WHITESPACE@[21; 22) " "
25 REF_EXPR@[22; 54)
26 AMP@[22; 23) "&"
27 ARRAY_EXPR@[23; 54)
28 L_BRACK@[23; 24) "["
29 WHITESPACE@[24; 28) "\n "
30 LITERAL@[28; 29)
31 INT_NUMBER@[28; 29) "1"
32 COMMA@[29; 30) ","
33 WHITESPACE@[30; 34) "\n "
34 ATTR@[34; 46)
35 POUND@[34; 35) "#"
36 TOKEN_TREE@[35; 46)
37 L_BRACK@[35; 36) "["
38 IDENT@[36; 39) "cfg"
39 TOKEN_TREE@[39; 45)
40 L_PAREN@[39; 40) "("
41 IDENT@[40; 44) "test"
42 R_PAREN@[44; 45) ")"
43 R_BRACK@[45; 46) "]"
44 WHITESPACE@[46; 50) "\n "
45 LITERAL@[50; 51)
46 INT_NUMBER@[50; 51) "2"
47 COMMA@[51; 52) ","
48 WHITESPACE@[52; 53) "\n"
49 R_BRACK@[53; 54) "]"
50 SEMI@[54; 55) ";"
51 WHITESPACE@[55; 56) "\n"