aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar/params.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src/grammar/params.rs')
-rw-r--r--crates/ra_parser/src/grammar/params.rs120
1 files changed, 71 insertions, 49 deletions
diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs
index c10b53316..94edc7f35 100644
--- a/crates/ra_parser/src/grammar/params.rs
+++ b/crates/ra_parser/src/grammar/params.rs
@@ -7,54 +7,60 @@ use super::*;
7// fn b(x: i32) {} 7// fn b(x: i32) {}
8// fn c(x: i32, ) {} 8// fn c(x: i32, ) {}
9// fn d(x: i32, y: ()) {} 9// fn d(x: i32, y: ()) {}
10pub(super) fn param_list(p: &mut Parser) { 10pub(super) fn param_list_fn_def(p: &mut Parser) {
11 list_(p, Flavor::Normal) 11 list_(p, Flavor::FnDef)
12} 12}
13 13
14// test param_list_opt_patterns 14// test param_list_opt_patterns
15// fn foo<F: FnMut(&mut Foo<'a>)>(){} 15// fn foo<F: FnMut(&mut Foo<'a>)>(){}
16pub(super) fn param_list_opt_patterns(p: &mut Parser) { 16pub(super) fn param_list_fn_trait(p: &mut Parser) {
17 list_(p, Flavor::OptionalPattern) 17 list_(p, Flavor::FnTrait)
18} 18}
19 19
20pub(super) fn param_list_opt_types(p: &mut Parser) { 20pub(super) fn param_list_fn_ptr(p: &mut Parser) {
21 list_(p, Flavor::OptionalType) 21 list_(p, Flavor::FnPointer)
22} 22}
23 23
24#[derive(Clone, Copy, Eq, PartialEq)] 24pub(super) fn param_list_closure(p: &mut Parser) {
25enum Flavor { 25 list_(p, Flavor::Closure)
26 OptionalType,
27 OptionalPattern,
28 Normal,
29} 26}
30 27
31impl Flavor { 28#[derive(Debug, Clone, Copy)]
32 fn type_required(self) -> bool { 29enum Flavor {
33 match self { 30 FnDef, // Includes trait fn params; omitted param idents are not supported
34 Flavor::OptionalType => false, 31 FnTrait, // Params for `Fn(...)`/`FnMut(...)`/`FnOnce(...)` annotations
35 _ => true, 32 FnPointer,
36 } 33 Closure,
37 }
38} 34}
39 35
40fn list_(p: &mut Parser, flavor: Flavor) { 36fn list_(p: &mut Parser, flavor: Flavor) {
41 let (bra, ket) = if flavor.type_required() { (T!['('], T![')']) } else { (T![|], T![|]) }; 37 use Flavor::*;
42 assert!(p.at(bra)); 38
39 let (bra, ket) = match flavor {
40 Closure => (T![|], T![|]),
41 FnDef | FnTrait | FnPointer => (T!['('], T![')']),
42 };
43
43 let m = p.start(); 44 let m = p.start();
44 p.bump(bra); 45 p.bump(bra);
45 if flavor.type_required() { 46
47 if let FnDef = flavor {
46 // test self_param_outer_attr 48 // test self_param_outer_attr
47 // fn f(#[must_use] self) {} 49 // fn f(#[must_use] self) {}
48 attributes::outer_attributes(p); 50 attributes::outer_attributes(p);
49 opt_self_param(p); 51 opt_self_param(p);
50 } 52 }
53
51 while !p.at(EOF) && !p.at(ket) { 54 while !p.at(EOF) && !p.at(ket) {
52 // test param_outer_arg 55 // test param_outer_arg
53 // fn f(#[attr1] pat: Type) {} 56 // fn f(#[attr1] pat: Type) {}
54 attributes::outer_attributes(p); 57 attributes::outer_attributes(p);
55 58
56 if flavor.type_required() && p.at(T![...]) { 59 // test param_list_vararg
57 break; 60 // extern "C" { fn printf(format: *const i8, ...) -> i32; }
61 match flavor {
62 FnDef | FnPointer if p.eat(T![...]) => break,
63 _ => (),
58 } 64 }
59 65
60 if !p.at_ts(VALUE_PARAMETER_FIRST) { 66 if !p.at_ts(VALUE_PARAMETER_FIRST) {
@@ -66,11 +72,7 @@ fn list_(p: &mut Parser, flavor: Flavor) {
66 p.expect(T![,]); 72 p.expect(T![,]);
67 } 73 }
68 } 74 }
69 // test param_list_vararg 75
70 // extern "C" { fn printf(format: *const i8, ...) -> i32; }
71 if flavor.type_required() {
72 p.eat(T![...]);
73 }
74 p.expect(ket); 76 p.expect(ket);
75 m.complete(p, PARAM_LIST); 77 m.complete(p, PARAM_LIST);
76} 78}
@@ -80,36 +82,56 @@ const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYP
80fn value_parameter(p: &mut Parser, flavor: Flavor) { 82fn value_parameter(p: &mut Parser, flavor: Flavor) {
81 let m = p.start(); 83 let m = p.start();
82 match flavor { 84 match flavor {
83 Flavor::OptionalType | Flavor::Normal => { 85 // test trait_fn_placeholder_parameter
86 // trait Foo {
87 // fn bar(_: u64, mut x: i32);
88 // }
89
90 // test trait_fn_patterns
91 // trait T {
92 // fn f1((a, b): (usize, usize)) {}
93 // fn f2(S { a, b }: S) {}
94 // fn f3(NewType(a): NewType) {}
95 // fn f4(&&a: &&usize) {}
96 // }
97
98 // test fn_patterns
99 // impl U {
100 // fn f1((a, b): (usize, usize)) {}
101 // fn f2(S { a, b }: S) {}
102 // fn f3(NewType(a): NewType) {}
103 // fn f4(&&a: &&usize) {}
104 // }
105 Flavor::FnDef => {
84 patterns::pattern(p); 106 patterns::pattern(p);
85 if p.at(T![:]) && !p.at(T![::]) || flavor.type_required() { 107 types::ascription(p);
86 types::ascription(p)
87 }
88 } 108 }
89 // test value_parameters_no_patterns 109 // test value_parameters_no_patterns
90 // type F = Box<Fn(a: i32, &b: &i32, &mut c: &i32, ())>; 110 // type F = Box<Fn(i32, &i32, &i32, ())>;
91 Flavor::OptionalPattern => { 111 Flavor::FnTrait => {
92 let la0 = p.current(); 112 types::type_(p);
93 let la1 = p.nth(1); 113 }
94 let la2 = p.nth(2); 114 // test fn_pointer_param_ident_path
95 let la3 = p.nth(3); 115 // type Foo = fn(Bar::Baz);
96 116 // type Qux = fn(baz: Bar::Baz);
97 // test trait_fn_placeholder_parameter 117 Flavor::FnPointer => {
98 // trait Foo { 118 if p.at(IDENT) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) {
99 // fn bar(_: u64, mut x: i32);
100 // }
101 if (la0 == IDENT || la0 == T![_]) && la1 == T![:] && !p.nth_at(1, T![::])
102 || la0 == T![mut] && la1 == IDENT && la2 == T![:]
103 || la0 == T![&]
104 && (la1 == IDENT && la2 == T![:] && !p.nth_at(2, T![::])
105 || la1 == T![mut] && la2 == IDENT && la3 == T![:] && !p.nth_at(3, T![::]))
106 {
107 patterns::pattern(p); 119 patterns::pattern(p);
108 types::ascription(p); 120 types::ascription(p);
109 } else { 121 } else {
110 types::type_(p); 122 types::type_(p);
111 } 123 }
112 } 124 }
125 // test closure_params
126 // fn main() {
127 // let foo = |bar, baz: Baz, qux: Qux::Quux| ();
128 // }
129 Flavor::Closure => {
130 patterns::pattern(p);
131 if p.at(T![:]) && !p.at(T![::]) {
132 types::ascription(p);
133 }
134 }
113 } 135 }
114 m.complete(p, PARAM); 136 m.complete(p, PARAM);
115} 137}