diff options
author | Ville Penttinen <[email protected]> | 2019-02-17 17:08:34 +0000 |
---|---|---|
committer | Ville Penttinen <[email protected]> | 2019-02-17 17:26:57 +0000 |
commit | 1c97c1ac11459d45f7bfc57dc72428d2b294520c (patch) | |
tree | 70638cabf61f96a7511f974cc66dae40175bfb22 | |
parent | 982f72c022b45629e6adbaef22884359d3495ecf (diff) |
Enable parsing of attributes inside a match block
We allow invalid inner attributes to be parsed, e.g. inner attributes that are
not directly after the opening brace of the match block.
Instead we run validation on `MatchArmList` to allow better reporting of errors.
16 files changed, 589 insertions, 1 deletions
diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 22105d6c9..350f01f33 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs | |||
@@ -153,6 +153,20 @@ impl FnDef { | |||
153 | } | 153 | } |
154 | 154 | ||
155 | impl Attr { | 155 | impl Attr { |
156 | pub fn is_inner(&self) -> bool { | ||
157 | let tt = match self.value() { | ||
158 | None => return false, | ||
159 | Some(tt) => tt, | ||
160 | }; | ||
161 | |||
162 | let prev = match tt.syntax().prev_sibling() { | ||
163 | None => return false, | ||
164 | Some(prev) => prev, | ||
165 | }; | ||
166 | |||
167 | prev.kind() == EXCL | ||
168 | } | ||
169 | |||
156 | pub fn as_atom(&self) -> Option<SmolStr> { | 170 | pub fn as_atom(&self) -> Option<SmolStr> { |
157 | let tt = self.value()?; | 171 | let tt = self.value()?; |
158 | let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?; | 172 | let (_bra, attr, _ket) = tt.syntax().children().collect_tuple()?; |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index dd91b5063..c7aaccc95 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -1946,6 +1946,7 @@ impl ToOwned for MatchArm { | |||
1946 | } | 1946 | } |
1947 | 1947 | ||
1948 | 1948 | ||
1949 | impl ast::AttrsOwner for MatchArm {} | ||
1949 | impl MatchArm { | 1950 | impl MatchArm { |
1950 | pub fn pats(&self) -> impl Iterator<Item = &Pat> { | 1951 | pub fn pats(&self) -> impl Iterator<Item = &Pat> { |
1951 | super::children(self) | 1952 | super::children(self) |
@@ -1986,6 +1987,7 @@ impl ToOwned for MatchArmList { | |||
1986 | } | 1987 | } |
1987 | 1988 | ||
1988 | 1989 | ||
1990 | impl ast::AttrsOwner for MatchArmList {} | ||
1989 | impl MatchArmList { | 1991 | impl MatchArmList { |
1990 | pub fn arms(&self) -> impl Iterator<Item = &MatchArm> { | 1992 | pub fn arms(&self) -> impl Iterator<Item = &MatchArm> { |
1991 | super::children(self) | 1993 | super::children(self) |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 27a123681..193b563aa 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -413,13 +413,15 @@ Grammar( | |||
413 | ), | 413 | ), |
414 | "MatchArmList": ( | 414 | "MatchArmList": ( |
415 | collections: [ ["arms", "MatchArm"] ], | 415 | collections: [ ["arms", "MatchArm"] ], |
416 | traits: [ "AttrsOwner" ] | ||
416 | ), | 417 | ), |
417 | "MatchArm": ( | 418 | "MatchArm": ( |
418 | options: [ | 419 | options: [ |
419 | [ "guard", "MatchGuard" ], | 420 | [ "guard", "MatchGuard" ], |
420 | "Expr", | 421 | "Expr", |
421 | ], | 422 | ], |
422 | collections: [ [ "pats", "Pat" ] ] | 423 | collections: [ [ "pats", "Pat" ] ], |
424 | traits: [ "AttrsOwner" ] | ||
423 | ), | 425 | ), |
424 | "MatchGuard": (options: ["Expr"]), | 426 | "MatchGuard": (options: ["Expr"]), |
425 | "StructLit": (options: ["Path", "NamedFieldList", ["spread", "Expr"]]), | 427 | "StructLit": (options: ["Path", "NamedFieldList", ["spread", "Expr"]]), |
diff --git a/crates/ra_syntax/src/grammar/attributes.rs b/crates/ra_syntax/src/grammar/attributes.rs index cd30e8a45..2624d2e16 100644 --- a/crates/ra_syntax/src/grammar/attributes.rs +++ b/crates/ra_syntax/src/grammar/attributes.rs | |||
@@ -1,5 +1,15 @@ | |||
1 | use super::*; | 1 | use super::*; |
2 | 2 | ||
3 | /// Parses both inner & outer attributes. | ||
4 | /// | ||
5 | /// Allowing to run validation for reporting errors | ||
6 | /// regarding attributes | ||
7 | pub(super) fn all_attributes(p: &mut Parser) { | ||
8 | while p.at(POUND) { | ||
9 | attribute(p, p.nth(1) == EXCL) | ||
10 | } | ||
11 | } | ||
12 | |||
3 | pub(super) fn inner_attributes(p: &mut Parser) { | 13 | pub(super) fn inner_attributes(p: &mut Parser) { |
4 | while p.current() == POUND && p.nth(1) == EXCL { | 14 | while p.current() == POUND && p.nth(1) == EXCL { |
5 | attribute(p, true) | 15 | attribute(p, true) |
diff --git a/crates/ra_syntax/src/grammar/expressions/atom.rs b/crates/ra_syntax/src/grammar/expressions/atom.rs index 27ba87657..67cd7e6b0 100644 --- a/crates/ra_syntax/src/grammar/expressions/atom.rs +++ b/crates/ra_syntax/src/grammar/expressions/atom.rs | |||
@@ -313,11 +313,44 @@ pub(crate) fn match_arm_list(p: &mut Parser) { | |||
313 | assert!(p.at(L_CURLY)); | 313 | assert!(p.at(L_CURLY)); |
314 | let m = p.start(); | 314 | let m = p.start(); |
315 | p.eat(L_CURLY); | 315 | p.eat(L_CURLY); |
316 | |||
317 | // test match_arms_inner_attribute | ||
318 | // fn foo() { | ||
319 | // match () { | ||
320 | // #![doc("Inner attribute")] | ||
321 | // #![doc("Can be")] | ||
322 | // #![doc("Stacked")] | ||
323 | // _ => (), | ||
324 | // } | ||
325 | // } | ||
326 | attributes::inner_attributes(p); | ||
327 | |||
316 | while !p.at(EOF) && !p.at(R_CURLY) { | 328 | while !p.at(EOF) && !p.at(R_CURLY) { |
317 | if p.at(L_CURLY) { | 329 | if p.at(L_CURLY) { |
318 | error_block(p, "expected match arm"); | 330 | error_block(p, "expected match arm"); |
319 | continue; | 331 | continue; |
320 | } | 332 | } |
333 | |||
334 | // This may result in invalid attributes | ||
335 | // if there are inner attributes mixed in together | ||
336 | // with the outer attributes, but we allow parsing | ||
337 | // those so we can run validation and report better errors | ||
338 | |||
339 | // test match_arms_outer_attributes | ||
340 | // fn foo() { | ||
341 | // match () { | ||
342 | // #[cfg(feature = "some")] | ||
343 | // _ => (), | ||
344 | // #[cfg(feature = "other")] | ||
345 | // _ => (), | ||
346 | // #[cfg(feature = "many")] | ||
347 | // #[cfg(feature = "attributes")] | ||
348 | // #[cfg(feature = "before")] | ||
349 | // _ => (), | ||
350 | // } | ||
351 | // } | ||
352 | attributes::all_attributes(p); | ||
353 | |||
321 | // test match_arms_commas | 354 | // test match_arms_commas |
322 | // fn foo() { | 355 | // fn foo() { |
323 | // match () { | 356 | // match () { |
diff --git a/crates/ra_syntax/src/syntax_node/syntax_error.rs b/crates/ra_syntax/src/syntax_node/syntax_error.rs index 412cf82cc..4ff998090 100644 --- a/crates/ra_syntax/src/syntax_node/syntax_error.rs +++ b/crates/ra_syntax/src/syntax_node/syntax_error.rs | |||
@@ -92,6 +92,7 @@ pub enum SyntaxErrorKind { | |||
92 | UnclosedString, | 92 | UnclosedString, |
93 | InvalidSuffix, | 93 | InvalidSuffix, |
94 | InvalidBlockAttr, | 94 | InvalidBlockAttr, |
95 | InvalidMatchInnerAttr, | ||
95 | } | 96 | } |
96 | 97 | ||
97 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 98 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
@@ -136,6 +137,9 @@ impl fmt::Display for SyntaxErrorKind { | |||
136 | InvalidBlockAttr => { | 137 | InvalidBlockAttr => { |
137 | write!(f, "A block in this position cannot accept inner attributes") | 138 | write!(f, "A block in this position cannot accept inner attributes") |
138 | } | 139 | } |
140 | InvalidMatchInnerAttr => { | ||
141 | write!(f, "Inner attributes are only allowed directly after the opening brace of the match expression") | ||
142 | } | ||
139 | ParseError(msg) => write!(f, "{}", msg.0), | 143 | ParseError(msg) => write!(f, "{}", msg.0), |
140 | } | 144 | } |
141 | } | 145 | } |
diff --git a/crates/ra_syntax/src/validation.rs b/crates/ra_syntax/src/validation.rs index 10672d6bf..27a465a78 100644 --- a/crates/ra_syntax/src/validation.rs +++ b/crates/ra_syntax/src/validation.rs | |||
@@ -3,6 +3,7 @@ mod byte_string; | |||
3 | mod char; | 3 | mod char; |
4 | mod string; | 4 | mod string; |
5 | mod block; | 5 | mod block; |
6 | mod match_armlist; | ||
6 | 7 | ||
7 | use crate::{ | 8 | use crate::{ |
8 | SourceFile, syntax_node::SyntaxError, AstNode, | 9 | SourceFile, syntax_node::SyntaxError, AstNode, |
@@ -19,6 +20,7 @@ pub(crate) fn validate(file: &SourceFile) -> Vec<SyntaxError> { | |||
19 | .visit::<ast::Char, _>(self::char::validate_char_node) | 20 | .visit::<ast::Char, _>(self::char::validate_char_node) |
20 | .visit::<ast::String, _>(self::string::validate_string_node) | 21 | .visit::<ast::String, _>(self::string::validate_string_node) |
21 | .visit::<ast::Block, _>(self::block::validate_block_node) | 22 | .visit::<ast::Block, _>(self::block::validate_block_node) |
23 | .visit::<ast::MatchArmList, _>(self::match_armlist::validate_match_armlist) | ||
22 | .accept(node); | 24 | .accept(node); |
23 | } | 25 | } |
24 | errors | 26 | errors |
diff --git a/crates/ra_syntax/src/validation/match_armlist.rs b/crates/ra_syntax/src/validation/match_armlist.rs new file mode 100644 index 000000000..c43ed7092 --- /dev/null +++ b/crates/ra_syntax/src/validation/match_armlist.rs | |||
@@ -0,0 +1,28 @@ | |||
1 | use crate::{ | ||
2 | ast::{self, AttrsOwner, AstNode}, | ||
3 | syntax_node::{ | ||
4 | SyntaxError, | ||
5 | SyntaxErrorKind::*, | ||
6 | Direction, | ||
7 | }, | ||
8 | }; | ||
9 | |||
10 | pub(crate) fn validate_match_armlist(node: &ast::MatchArmList, errors: &mut Vec<SyntaxError>) { | ||
11 | // Report errors for any inner attribute | ||
12 | // which has a preceding matcharm or an outer attribute | ||
13 | for inner_attr in node.attrs().filter(|s| s.is_inner()) { | ||
14 | let any_errors = inner_attr.syntax().siblings(Direction::Prev).any(|s| { | ||
15 | match (ast::MatchArm::cast(s), ast::Attr::cast(s)) { | ||
16 | (Some(_), _) => true, | ||
17 | // Outer attributes which preceed an inner attribute are not allowed | ||
18 | (_, Some(a)) if !a.is_inner() => true, | ||
19 | (_, Some(_)) => false, | ||
20 | (None, None) => false, | ||
21 | } | ||
22 | }); | ||
23 | |||
24 | if any_errors { | ||
25 | errors.push(SyntaxError::new(InvalidMatchInnerAttr, inner_attr.syntax().range())); | ||
26 | } | ||
27 | } | ||
28 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.rs b/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.rs new file mode 100644 index 000000000..06aa47770 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.rs | |||
@@ -0,0 +1,20 @@ | |||
1 | fn foo() { | ||
2 | match () { | ||
3 | _ => (), | ||
4 | #![doc("Not allowed here")] | ||
5 | _ => (), | ||
6 | } | ||
7 | |||
8 | match () { | ||
9 | _ => (), | ||
10 | _ => (), | ||
11 | #![doc("Nor here")] | ||
12 | } | ||
13 | |||
14 | match () { | ||
15 | #[cfg(test)] | ||
16 | #![doc("Nor here")] | ||
17 | _ => (), | ||
18 | _ => (), | ||
19 | } | ||
20 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt b/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt new file mode 100644 index 000000000..b3ff36364 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0032_match_arms_inner_attrs.txt | |||
@@ -0,0 +1,173 @@ | |||
1 | SOURCE_FILE@[0; 293) | ||
2 | FN_DEF@[0; 292) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 292) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | EXPR_STMT@[15; 101) | ||
15 | MATCH_EXPR@[15; 101) | ||
16 | MATCH_KW@[15; 20) | ||
17 | WHITESPACE@[20; 21) | ||
18 | TUPLE_EXPR@[21; 23) | ||
19 | L_PAREN@[21; 22) | ||
20 | R_PAREN@[22; 23) | ||
21 | WHITESPACE@[23; 24) | ||
22 | MATCH_ARM_LIST@[24; 101) | ||
23 | L_CURLY@[24; 25) | ||
24 | WHITESPACE@[25; 34) | ||
25 | MATCH_ARM@[34; 41) | ||
26 | PLACEHOLDER_PAT@[34; 35) | ||
27 | UNDERSCORE@[34; 35) | ||
28 | WHITESPACE@[35; 36) | ||
29 | FAT_ARROW@[36; 38) | ||
30 | WHITESPACE@[38; 39) | ||
31 | TUPLE_EXPR@[39; 41) | ||
32 | L_PAREN@[39; 40) | ||
33 | R_PAREN@[40; 41) | ||
34 | COMMA@[41; 42) | ||
35 | WHITESPACE@[42; 51) | ||
36 | err: `Inner attributes are only allowed directly after the opening brace of the match expression` | ||
37 | ATTR@[51; 78) | ||
38 | POUND@[51; 52) | ||
39 | EXCL@[52; 53) | ||
40 | TOKEN_TREE@[53; 78) | ||
41 | L_BRACK@[53; 54) | ||
42 | IDENT@[54; 57) "doc" | ||
43 | TOKEN_TREE@[57; 77) | ||
44 | L_PAREN@[57; 58) | ||
45 | STRING@[58; 76) | ||
46 | R_PAREN@[76; 77) | ||
47 | R_BRACK@[77; 78) | ||
48 | WHITESPACE@[78; 87) | ||
49 | MATCH_ARM@[87; 94) | ||
50 | PLACEHOLDER_PAT@[87; 88) | ||
51 | UNDERSCORE@[87; 88) | ||
52 | WHITESPACE@[88; 89) | ||
53 | FAT_ARROW@[89; 91) | ||
54 | WHITESPACE@[91; 92) | ||
55 | TUPLE_EXPR@[92; 94) | ||
56 | L_PAREN@[92; 93) | ||
57 | R_PAREN@[93; 94) | ||
58 | COMMA@[94; 95) | ||
59 | WHITESPACE@[95; 100) | ||
60 | R_CURLY@[100; 101) | ||
61 | WHITESPACE@[101; 107) | ||
62 | EXPR_STMT@[107; 185) | ||
63 | MATCH_EXPR@[107; 185) | ||
64 | MATCH_KW@[107; 112) | ||
65 | WHITESPACE@[112; 113) | ||
66 | TUPLE_EXPR@[113; 115) | ||
67 | L_PAREN@[113; 114) | ||
68 | R_PAREN@[114; 115) | ||
69 | WHITESPACE@[115; 116) | ||
70 | MATCH_ARM_LIST@[116; 185) | ||
71 | L_CURLY@[116; 117) | ||
72 | WHITESPACE@[117; 126) | ||
73 | MATCH_ARM@[126; 133) | ||
74 | PLACEHOLDER_PAT@[126; 127) | ||
75 | UNDERSCORE@[126; 127) | ||
76 | WHITESPACE@[127; 128) | ||
77 | FAT_ARROW@[128; 130) | ||
78 | WHITESPACE@[130; 131) | ||
79 | TUPLE_EXPR@[131; 133) | ||
80 | L_PAREN@[131; 132) | ||
81 | R_PAREN@[132; 133) | ||
82 | COMMA@[133; 134) | ||
83 | WHITESPACE@[134; 143) | ||
84 | MATCH_ARM@[143; 150) | ||
85 | PLACEHOLDER_PAT@[143; 144) | ||
86 | UNDERSCORE@[143; 144) | ||
87 | WHITESPACE@[144; 145) | ||
88 | FAT_ARROW@[145; 147) | ||
89 | WHITESPACE@[147; 148) | ||
90 | TUPLE_EXPR@[148; 150) | ||
91 | L_PAREN@[148; 149) | ||
92 | R_PAREN@[149; 150) | ||
93 | COMMA@[150; 151) | ||
94 | WHITESPACE@[151; 160) | ||
95 | err: `Inner attributes are only allowed directly after the opening brace of the match expression` | ||
96 | ATTR@[160; 179) | ||
97 | POUND@[160; 161) | ||
98 | EXCL@[161; 162) | ||
99 | TOKEN_TREE@[162; 179) | ||
100 | L_BRACK@[162; 163) | ||
101 | IDENT@[163; 166) "doc" | ||
102 | TOKEN_TREE@[166; 178) | ||
103 | L_PAREN@[166; 167) | ||
104 | STRING@[167; 177) | ||
105 | R_PAREN@[177; 178) | ||
106 | R_BRACK@[178; 179) | ||
107 | WHITESPACE@[179; 184) | ||
108 | err: `expected pattern` | ||
109 | err: `expected FAT_ARROW` | ||
110 | err: `expected expression` | ||
111 | MATCH_ARM@[184; 184) | ||
112 | R_CURLY@[184; 185) | ||
113 | WHITESPACE@[185; 191) | ||
114 | MATCH_EXPR@[191; 290) | ||
115 | MATCH_KW@[191; 196) | ||
116 | WHITESPACE@[196; 197) | ||
117 | TUPLE_EXPR@[197; 199) | ||
118 | L_PAREN@[197; 198) | ||
119 | R_PAREN@[198; 199) | ||
120 | WHITESPACE@[199; 200) | ||
121 | MATCH_ARM_LIST@[200; 290) | ||
122 | L_CURLY@[200; 201) | ||
123 | WHITESPACE@[201; 210) | ||
124 | ATTR@[210; 222) | ||
125 | POUND@[210; 211) | ||
126 | TOKEN_TREE@[211; 222) | ||
127 | L_BRACK@[211; 212) | ||
128 | IDENT@[212; 215) "cfg" | ||
129 | TOKEN_TREE@[215; 221) | ||
130 | L_PAREN@[215; 216) | ||
131 | IDENT@[216; 220) "test" | ||
132 | R_PAREN@[220; 221) | ||
133 | R_BRACK@[221; 222) | ||
134 | WHITESPACE@[222; 231) | ||
135 | err: `Inner attributes are only allowed directly after the opening brace of the match expression` | ||
136 | ATTR@[231; 250) | ||
137 | POUND@[231; 232) | ||
138 | EXCL@[232; 233) | ||
139 | TOKEN_TREE@[233; 250) | ||
140 | L_BRACK@[233; 234) | ||
141 | IDENT@[234; 237) "doc" | ||
142 | TOKEN_TREE@[237; 249) | ||
143 | L_PAREN@[237; 238) | ||
144 | STRING@[238; 248) | ||
145 | R_PAREN@[248; 249) | ||
146 | R_BRACK@[249; 250) | ||
147 | WHITESPACE@[250; 259) | ||
148 | MATCH_ARM@[259; 266) | ||
149 | PLACEHOLDER_PAT@[259; 260) | ||
150 | UNDERSCORE@[259; 260) | ||
151 | WHITESPACE@[260; 261) | ||
152 | FAT_ARROW@[261; 263) | ||
153 | WHITESPACE@[263; 264) | ||
154 | TUPLE_EXPR@[264; 266) | ||
155 | L_PAREN@[264; 265) | ||
156 | R_PAREN@[265; 266) | ||
157 | COMMA@[266; 267) | ||
158 | WHITESPACE@[267; 276) | ||
159 | MATCH_ARM@[276; 283) | ||
160 | PLACEHOLDER_PAT@[276; 277) | ||
161 | UNDERSCORE@[276; 277) | ||
162 | WHITESPACE@[277; 278) | ||
163 | FAT_ARROW@[278; 280) | ||
164 | WHITESPACE@[280; 281) | ||
165 | TUPLE_EXPR@[281; 283) | ||
166 | L_PAREN@[281; 282) | ||
167 | R_PAREN@[282; 283) | ||
168 | COMMA@[283; 284) | ||
169 | WHITESPACE@[284; 289) | ||
170 | R_CURLY@[289; 290) | ||
171 | WHITESPACE@[290; 291) | ||
172 | R_CURLY@[291; 292) | ||
173 | WHITESPACE@[292; 293) | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.rs b/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.rs new file mode 100644 index 000000000..4635222da --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.rs | |||
@@ -0,0 +1,7 @@ | |||
1 | fn foo() { | ||
2 | match () { | ||
3 | _ => (), | ||
4 | _ => (), | ||
5 | #[cfg(test)] | ||
6 | } | ||
7 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt b/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt new file mode 100644 index 000000000..7f8767001 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0033_match_arms_outer_attrs.txt | |||
@@ -0,0 +1,64 @@ | |||
1 | SOURCE_FILE@[0; 89) | ||
2 | FN_DEF@[0; 88) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 88) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | MATCH_EXPR@[15; 86) | ||
15 | MATCH_KW@[15; 20) | ||
16 | WHITESPACE@[20; 21) | ||
17 | TUPLE_EXPR@[21; 23) | ||
18 | L_PAREN@[21; 22) | ||
19 | R_PAREN@[22; 23) | ||
20 | WHITESPACE@[23; 24) | ||
21 | MATCH_ARM_LIST@[24; 86) | ||
22 | L_CURLY@[24; 25) | ||
23 | WHITESPACE@[25; 34) | ||
24 | MATCH_ARM@[34; 41) | ||
25 | PLACEHOLDER_PAT@[34; 35) | ||
26 | UNDERSCORE@[34; 35) | ||
27 | WHITESPACE@[35; 36) | ||
28 | FAT_ARROW@[36; 38) | ||
29 | WHITESPACE@[38; 39) | ||
30 | TUPLE_EXPR@[39; 41) | ||
31 | L_PAREN@[39; 40) | ||
32 | R_PAREN@[40; 41) | ||
33 | COMMA@[41; 42) | ||
34 | WHITESPACE@[42; 51) | ||
35 | MATCH_ARM@[51; 58) | ||
36 | PLACEHOLDER_PAT@[51; 52) | ||
37 | UNDERSCORE@[51; 52) | ||
38 | WHITESPACE@[52; 53) | ||
39 | FAT_ARROW@[53; 55) | ||
40 | WHITESPACE@[55; 56) | ||
41 | TUPLE_EXPR@[56; 58) | ||
42 | L_PAREN@[56; 57) | ||
43 | R_PAREN@[57; 58) | ||
44 | COMMA@[58; 59) | ||
45 | WHITESPACE@[59; 68) | ||
46 | ATTR@[68; 80) | ||
47 | POUND@[68; 69) | ||
48 | TOKEN_TREE@[69; 80) | ||
49 | L_BRACK@[69; 70) | ||
50 | IDENT@[70; 73) "cfg" | ||
51 | TOKEN_TREE@[73; 79) | ||
52 | L_PAREN@[73; 74) | ||
53 | IDENT@[74; 78) "test" | ||
54 | R_PAREN@[78; 79) | ||
55 | R_BRACK@[79; 80) | ||
56 | WHITESPACE@[80; 85) | ||
57 | err: `expected pattern` | ||
58 | err: `expected FAT_ARROW` | ||
59 | err: `expected expression` | ||
60 | MATCH_ARM@[85; 85) | ||
61 | R_CURLY@[85; 86) | ||
62 | WHITESPACE@[86; 87) | ||
63 | R_CURLY@[87; 88) | ||
64 | WHITESPACE@[88; 89) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0120_match_arms_inner_attribute.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0120_match_arms_inner_attribute.rs new file mode 100644 index 000000000..54a67c9d7 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0120_match_arms_inner_attribute.rs | |||
@@ -0,0 +1,8 @@ | |||
1 | fn foo() { | ||
2 | match () { | ||
3 | #![doc("Inner attribute")] | ||
4 | #![doc("Can be")] | ||
5 | #![doc("Stacked")] | ||
6 | _ => (), | ||
7 | } | ||
8 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0120_match_arms_inner_attribute.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0120_match_arms_inner_attribute.txt new file mode 100644 index 000000000..b39a217bd --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0120_match_arms_inner_attribute.txt | |||
@@ -0,0 +1,74 @@ | |||
1 | SOURCE_FILE@[0; 139) | ||
2 | FN_DEF@[0; 138) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 138) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | MATCH_EXPR@[15; 136) | ||
15 | MATCH_KW@[15; 20) | ||
16 | WHITESPACE@[20; 21) | ||
17 | TUPLE_EXPR@[21; 23) | ||
18 | L_PAREN@[21; 22) | ||
19 | R_PAREN@[22; 23) | ||
20 | WHITESPACE@[23; 24) | ||
21 | MATCH_ARM_LIST@[24; 136) | ||
22 | L_CURLY@[24; 25) | ||
23 | WHITESPACE@[25; 34) | ||
24 | ATTR@[34; 60) | ||
25 | POUND@[34; 35) | ||
26 | EXCL@[35; 36) | ||
27 | TOKEN_TREE@[36; 60) | ||
28 | L_BRACK@[36; 37) | ||
29 | IDENT@[37; 40) "doc" | ||
30 | TOKEN_TREE@[40; 59) | ||
31 | L_PAREN@[40; 41) | ||
32 | STRING@[41; 58) | ||
33 | R_PAREN@[58; 59) | ||
34 | R_BRACK@[59; 60) | ||
35 | WHITESPACE@[60; 69) | ||
36 | ATTR@[69; 86) | ||
37 | POUND@[69; 70) | ||
38 | EXCL@[70; 71) | ||
39 | TOKEN_TREE@[71; 86) | ||
40 | L_BRACK@[71; 72) | ||
41 | IDENT@[72; 75) "doc" | ||
42 | TOKEN_TREE@[75; 85) | ||
43 | L_PAREN@[75; 76) | ||
44 | STRING@[76; 84) | ||
45 | R_PAREN@[84; 85) | ||
46 | R_BRACK@[85; 86) | ||
47 | WHITESPACE@[86; 95) | ||
48 | ATTR@[95; 113) | ||
49 | POUND@[95; 96) | ||
50 | EXCL@[96; 97) | ||
51 | TOKEN_TREE@[97; 113) | ||
52 | L_BRACK@[97; 98) | ||
53 | IDENT@[98; 101) "doc" | ||
54 | TOKEN_TREE@[101; 112) | ||
55 | L_PAREN@[101; 102) | ||
56 | STRING@[102; 111) | ||
57 | R_PAREN@[111; 112) | ||
58 | R_BRACK@[112; 113) | ||
59 | WHITESPACE@[113; 122) | ||
60 | MATCH_ARM@[122; 129) | ||
61 | PLACEHOLDER_PAT@[122; 123) | ||
62 | UNDERSCORE@[122; 123) | ||
63 | WHITESPACE@[123; 124) | ||
64 | FAT_ARROW@[124; 126) | ||
65 | WHITESPACE@[126; 127) | ||
66 | TUPLE_EXPR@[127; 129) | ||
67 | L_PAREN@[127; 128) | ||
68 | R_PAREN@[128; 129) | ||
69 | COMMA@[129; 130) | ||
70 | WHITESPACE@[130; 135) | ||
71 | R_CURLY@[135; 136) | ||
72 | WHITESPACE@[136; 137) | ||
73 | R_CURLY@[137; 138) | ||
74 | WHITESPACE@[138; 139) | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.rs new file mode 100644 index 000000000..676db42d1 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.rs | |||
@@ -0,0 +1,12 @@ | |||
1 | fn foo() { | ||
2 | match () { | ||
3 | #[cfg(feature = "some")] | ||
4 | _ => (), | ||
5 | #[cfg(feature = "other")] | ||
6 | _ => (), | ||
7 | #[cfg(feature = "many")] | ||
8 | #[cfg(feature = "attributes")] | ||
9 | #[cfg(feature = "before")] | ||
10 | _ => (), | ||
11 | } | ||
12 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.txt new file mode 100644 index 000000000..c888fb8f0 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0121_match_arms_outer_attributes.txt | |||
@@ -0,0 +1,135 @@ | |||
1 | SOURCE_FILE@[0; 259) | ||
2 | FN_DEF@[0; 258) | ||
3 | FN_KW@[0; 2) | ||
4 | WHITESPACE@[2; 3) | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) | ||
9 | R_PAREN@[7; 8) | ||
10 | WHITESPACE@[8; 9) | ||
11 | BLOCK@[9; 258) | ||
12 | L_CURLY@[9; 10) | ||
13 | WHITESPACE@[10; 15) | ||
14 | MATCH_EXPR@[15; 256) | ||
15 | MATCH_KW@[15; 20) | ||
16 | WHITESPACE@[20; 21) | ||
17 | TUPLE_EXPR@[21; 23) | ||
18 | L_PAREN@[21; 22) | ||
19 | R_PAREN@[22; 23) | ||
20 | WHITESPACE@[23; 24) | ||
21 | MATCH_ARM_LIST@[24; 256) | ||
22 | L_CURLY@[24; 25) | ||
23 | WHITESPACE@[25; 34) | ||
24 | ATTR@[34; 58) | ||
25 | POUND@[34; 35) | ||
26 | TOKEN_TREE@[35; 58) | ||
27 | L_BRACK@[35; 36) | ||
28 | IDENT@[36; 39) "cfg" | ||
29 | TOKEN_TREE@[39; 57) | ||
30 | L_PAREN@[39; 40) | ||
31 | IDENT@[40; 47) "feature" | ||
32 | WHITESPACE@[47; 48) | ||
33 | EQ@[48; 49) | ||
34 | WHITESPACE@[49; 50) | ||
35 | STRING@[50; 56) | ||
36 | R_PAREN@[56; 57) | ||
37 | R_BRACK@[57; 58) | ||
38 | WHITESPACE@[58; 67) | ||
39 | MATCH_ARM@[67; 74) | ||
40 | PLACEHOLDER_PAT@[67; 68) | ||
41 | UNDERSCORE@[67; 68) | ||
42 | WHITESPACE@[68; 69) | ||
43 | FAT_ARROW@[69; 71) | ||
44 | WHITESPACE@[71; 72) | ||
45 | TUPLE_EXPR@[72; 74) | ||
46 | L_PAREN@[72; 73) | ||
47 | R_PAREN@[73; 74) | ||
48 | COMMA@[74; 75) | ||
49 | WHITESPACE@[75; 84) | ||
50 | ATTR@[84; 109) | ||
51 | POUND@[84; 85) | ||
52 | TOKEN_TREE@[85; 109) | ||
53 | L_BRACK@[85; 86) | ||
54 | IDENT@[86; 89) "cfg" | ||
55 | TOKEN_TREE@[89; 108) | ||
56 | L_PAREN@[89; 90) | ||
57 | IDENT@[90; 97) "feature" | ||
58 | WHITESPACE@[97; 98) | ||
59 | EQ@[98; 99) | ||
60 | WHITESPACE@[99; 100) | ||
61 | STRING@[100; 107) | ||
62 | R_PAREN@[107; 108) | ||
63 | R_BRACK@[108; 109) | ||
64 | WHITESPACE@[109; 118) | ||
65 | MATCH_ARM@[118; 125) | ||
66 | PLACEHOLDER_PAT@[118; 119) | ||
67 | UNDERSCORE@[118; 119) | ||
68 | WHITESPACE@[119; 120) | ||
69 | FAT_ARROW@[120; 122) | ||
70 | WHITESPACE@[122; 123) | ||
71 | TUPLE_EXPR@[123; 125) | ||
72 | L_PAREN@[123; 124) | ||
73 | R_PAREN@[124; 125) | ||
74 | COMMA@[125; 126) | ||
75 | WHITESPACE@[126; 135) | ||
76 | ATTR@[135; 159) | ||
77 | POUND@[135; 136) | ||
78 | TOKEN_TREE@[136; 159) | ||
79 | L_BRACK@[136; 137) | ||
80 | IDENT@[137; 140) "cfg" | ||
81 | TOKEN_TREE@[140; 158) | ||
82 | L_PAREN@[140; 141) | ||
83 | IDENT@[141; 148) "feature" | ||
84 | WHITESPACE@[148; 149) | ||
85 | EQ@[149; 150) | ||
86 | WHITESPACE@[150; 151) | ||
87 | STRING@[151; 157) | ||
88 | R_PAREN@[157; 158) | ||
89 | R_BRACK@[158; 159) | ||
90 | WHITESPACE@[159; 168) | ||
91 | ATTR@[168; 198) | ||
92 | POUND@[168; 169) | ||
93 | TOKEN_TREE@[169; 198) | ||
94 | L_BRACK@[169; 170) | ||
95 | IDENT@[170; 173) "cfg" | ||
96 | TOKEN_TREE@[173; 197) | ||
97 | L_PAREN@[173; 174) | ||
98 | IDENT@[174; 181) "feature" | ||
99 | WHITESPACE@[181; 182) | ||
100 | EQ@[182; 183) | ||
101 | WHITESPACE@[183; 184) | ||
102 | STRING@[184; 196) | ||
103 | R_PAREN@[196; 197) | ||
104 | R_BRACK@[197; 198) | ||
105 | WHITESPACE@[198; 207) | ||
106 | ATTR@[207; 233) | ||
107 | POUND@[207; 208) | ||
108 | TOKEN_TREE@[208; 233) | ||
109 | L_BRACK@[208; 209) | ||
110 | IDENT@[209; 212) "cfg" | ||
111 | TOKEN_TREE@[212; 232) | ||
112 | L_PAREN@[212; 213) | ||
113 | IDENT@[213; 220) "feature" | ||
114 | WHITESPACE@[220; 221) | ||
115 | EQ@[221; 222) | ||
116 | WHITESPACE@[222; 223) | ||
117 | STRING@[223; 231) | ||
118 | R_PAREN@[231; 232) | ||
119 | R_BRACK@[232; 233) | ||
120 | WHITESPACE@[233; 242) | ||
121 | MATCH_ARM@[242; 249) | ||
122 | PLACEHOLDER_PAT@[242; 243) | ||
123 | UNDERSCORE@[242; 243) | ||
124 | WHITESPACE@[243; 244) | ||
125 | FAT_ARROW@[244; 246) | ||
126 | WHITESPACE@[246; 247) | ||
127 | TUPLE_EXPR@[247; 249) | ||
128 | L_PAREN@[247; 248) | ||
129 | R_PAREN@[248; 249) | ||
130 | COMMA@[249; 250) | ||
131 | WHITESPACE@[250; 255) | ||
132 | R_CURLY@[255; 256) | ||
133 | WHITESPACE@[256; 257) | ||
134 | R_CURLY@[257; 258) | ||
135 | WHITESPACE@[258; 259) | ||