diff options
Diffstat (limited to 'crates/ra_syntax/src/grammar/params.rs')
-rw-r--r-- | crates/ra_syntax/src/grammar/params.rs | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/crates/ra_syntax/src/grammar/params.rs b/crates/ra_syntax/src/grammar/params.rs new file mode 100644 index 000000000..903c25939 --- /dev/null +++ b/crates/ra_syntax/src/grammar/params.rs | |||
@@ -0,0 +1,142 @@ | |||
1 | use super::*; | ||
2 | |||
3 | // test param_list | ||
4 | // fn a() {} | ||
5 | // fn b(x: i32) {} | ||
6 | // fn c(x: i32, ) {} | ||
7 | // fn d(x: i32, y: ()) {} | ||
8 | pub(super) fn param_list(p: &mut Parser) { | ||
9 | list_(p, Flavor::Normal) | ||
10 | } | ||
11 | |||
12 | // test param_list_opt_patterns | ||
13 | // fn foo<F: FnMut(&mut Foo<'a>)>(){} | ||
14 | pub(super) fn param_list_opt_patterns(p: &mut Parser) { | ||
15 | list_(p, Flavor::OptionalPattern) | ||
16 | } | ||
17 | |||
18 | pub(super) fn param_list_opt_types(p: &mut Parser) { | ||
19 | list_(p, Flavor::OptionalType) | ||
20 | } | ||
21 | |||
22 | #[derive(Clone, Copy, Eq, PartialEq)] | ||
23 | enum Flavor { | ||
24 | OptionalType, | ||
25 | OptionalPattern, | ||
26 | Normal, | ||
27 | } | ||
28 | |||
29 | impl Flavor { | ||
30 | fn type_required(self) -> bool { | ||
31 | match self { | ||
32 | Flavor::OptionalType => false, | ||
33 | _ => true, | ||
34 | } | ||
35 | } | ||
36 | } | ||
37 | |||
38 | fn list_(p: &mut Parser, flavor: Flavor) { | ||
39 | let (bra, ket) = if flavor.type_required() { | ||
40 | (L_PAREN, R_PAREN) | ||
41 | } else { | ||
42 | (PIPE, PIPE) | ||
43 | }; | ||
44 | assert!(p.at(bra)); | ||
45 | let m = p.start(); | ||
46 | p.bump(); | ||
47 | if flavor.type_required() { | ||
48 | opt_self_param(p); | ||
49 | } | ||
50 | while !p.at(EOF) && !p.at(ket) { | ||
51 | if !p.at_ts(VALUE_PARAMETER_FIRST) { | ||
52 | p.error("expected value parameter"); | ||
53 | break; | ||
54 | } | ||
55 | value_parameter(p, flavor); | ||
56 | if !p.at(ket) { | ||
57 | p.expect(COMMA); | ||
58 | } | ||
59 | } | ||
60 | p.expect(ket); | ||
61 | m.complete(p, PARAM_LIST); | ||
62 | } | ||
63 | |||
64 | |||
65 | const VALUE_PARAMETER_FIRST: TokenSet = | ||
66 | token_set_union![ | ||
67 | patterns::PATTERN_FIRST, | ||
68 | types::TYPE_FIRST, | ||
69 | ]; | ||
70 | |||
71 | fn value_parameter(p: &mut Parser, flavor: Flavor) { | ||
72 | let m = p.start(); | ||
73 | match flavor { | ||
74 | Flavor::OptionalType | Flavor::Normal => { | ||
75 | patterns::pattern(p); | ||
76 | if p.at(COLON) || flavor.type_required() { | ||
77 | types::ascription(p) | ||
78 | } | ||
79 | }, | ||
80 | // test value_parameters_no_patterns | ||
81 | // type F = Box<Fn(a: i32, &b: &i32, &mut c: &i32, ())>; | ||
82 | Flavor::OptionalPattern => { | ||
83 | let la0 = p.current(); | ||
84 | let la1 = p.nth(1); | ||
85 | let la2 = p.nth(2); | ||
86 | let la3 = p.nth(3); | ||
87 | if la0 == IDENT && la1 == COLON | ||
88 | || la0 == AMP && la1 == IDENT && la2 == COLON | ||
89 | || la0 == AMP && la1 == MUT_KW && la2 == IDENT && la3 == COLON { | ||
90 | patterns::pattern(p); | ||
91 | types::ascription(p); | ||
92 | } else { | ||
93 | types::type_(p); | ||
94 | } | ||
95 | }, | ||
96 | } | ||
97 | m.complete(p, PARAM); | ||
98 | } | ||
99 | |||
100 | // test self_param | ||
101 | // impl S { | ||
102 | // fn a(self) {} | ||
103 | // fn b(&self,) {} | ||
104 | // fn c(&'a self,) {} | ||
105 | // fn d(&'a mut self, x: i32) {} | ||
106 | // fn e(mut self) {} | ||
107 | // } | ||
108 | fn opt_self_param(p: &mut Parser) { | ||
109 | let m; | ||
110 | if p.at(SELF_KW) || p.at(MUT_KW) && p.nth(1) == SELF_KW { | ||
111 | m = p.start(); | ||
112 | p.eat(MUT_KW); | ||
113 | p.eat(SELF_KW); | ||
114 | // test arb_self_types | ||
115 | // impl S { | ||
116 | // fn a(self: &Self) {} | ||
117 | // fn b(mut self: Box<Self>) {} | ||
118 | // } | ||
119 | if p.at(COLON) { | ||
120 | types::ascription(p); | ||
121 | } | ||
122 | } else { | ||
123 | let la1 = p.nth(1); | ||
124 | let la2 = p.nth(2); | ||
125 | let la3 = p.nth(3); | ||
126 | let n_toks = match (p.current(), la1, la2, la3) { | ||
127 | (AMP, SELF_KW, _, _) => 2, | ||
128 | (AMP, MUT_KW, SELF_KW, _) => 3, | ||
129 | (AMP, LIFETIME, SELF_KW, _) => 3, | ||
130 | (AMP, LIFETIME, MUT_KW, SELF_KW) => 4, | ||
131 | _ => return, | ||
132 | }; | ||
133 | m = p.start(); | ||
134 | for _ in 0..n_toks { | ||
135 | p.bump(); | ||
136 | } | ||
137 | } | ||
138 | m.complete(p, SELF_PARAM); | ||
139 | if !p.at(R_PAREN) { | ||
140 | p.expect(COMMA); | ||
141 | } | ||
142 | } | ||