aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_parser/src/grammar
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_parser/src/grammar')
-rw-r--r--crates/ra_parser/src/grammar/params.rs44
1 files changed, 33 insertions, 11 deletions
diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs
index 3ca32185c..f0da173cc 100644
--- a/crates/ra_parser/src/grammar/params.rs
+++ b/crates/ra_parser/src/grammar/params.rs
@@ -56,21 +56,17 @@ fn list_(p: &mut Parser, flavor: Flavor) {
56 // fn f(#[attr1] pat: Type) {} 56 // fn f(#[attr1] pat: Type) {}
57 attributes::outer_attributes(p); 57 attributes::outer_attributes(p);
58 58
59 // test param_list_vararg
60 // extern "C" { fn printf(format: *const i8, ...) -> i32; }
61 match flavor {
62 FnDef | FnPointer if p.eat(T![...]) => break,
63 _ => (),
64 }
65
66 if !p.at_ts(VALUE_PARAMETER_FIRST) { 59 if !p.at_ts(VALUE_PARAMETER_FIRST) {
67 p.error("expected value parameter"); 60 p.error("expected value parameter");
68 break; 61 break;
69 } 62 }
70 value_parameter(p, flavor); 63 let param = value_parameter(p, flavor);
71 if !p.at(ket) { 64 if !p.at(ket) {
72 p.expect(T![,]); 65 p.expect(T![,]);
73 } 66 }
67 if let Variadic(true) = param {
68 break;
69 }
74 } 70 }
75 71
76 p.expect(ket); 72 p.expect(ket);
@@ -79,14 +75,25 @@ fn list_(p: &mut Parser, flavor: Flavor) {
79 75
80const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST); 76const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST);
81 77
82fn value_parameter(p: &mut Parser, flavor: Flavor) { 78struct Variadic(bool);
79
80fn value_parameter(p: &mut Parser, flavor: Flavor) -> Variadic {
81 let mut res = Variadic(false);
83 let m = p.start(); 82 let m = p.start();
84 match flavor { 83 match flavor {
84 // test param_list_vararg
85 // extern "C" { fn printf(format: *const i8, ...) -> i32; }
86 Flavor::FnDef | Flavor::FnPointer if p.eat(T![...]) => res = Variadic(true),
87
85 // test fn_def_param 88 // test fn_def_param
86 // fn foo((x, y): (i32, i32)) {} 89 // fn foo((x, y): (i32, i32)) {}
87 Flavor::FnDef => { 90 Flavor::FnDef => {
88 patterns::pattern(p); 91 patterns::pattern(p);
89 types::ascription(p); 92 if variadic_param(p) {
93 res = Variadic(true)
94 } else {
95 types::ascription(p);
96 }
90 } 97 }
91 // test value_parameters_no_patterns 98 // test value_parameters_no_patterns
92 // type F = Box<Fn(i32, &i32, &i32, ())>; 99 // type F = Box<Fn(i32, &i32, &i32, ())>;
@@ -102,7 +109,11 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) {
102 Flavor::FnPointer => { 109 Flavor::FnPointer => {
103 if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) { 110 if (p.at(IDENT) || p.at(UNDERSCORE)) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) {
104 patterns::pattern_single(p); 111 patterns::pattern_single(p);
105 types::ascription(p); 112 if variadic_param(p) {
113 res = Variadic(true)
114 } else {
115 types::ascription(p);
116 }
106 } else { 117 } else {
107 types::type_(p); 118 types::type_(p);
108 } 119 }
@@ -119,6 +130,17 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) {
119 } 130 }
120 } 131 }
121 m.complete(p, PARAM); 132 m.complete(p, PARAM);
133 res
134}
135
136fn variadic_param(p: &mut Parser) -> bool {
137 if p.at(T![:]) && p.nth_at(1, T![...]) {
138 p.bump(T![:]);
139 p.bump(T![...]);
140 true
141 } else {
142 false
143 }
122} 144}
123 145
124// test self_param 146// test self_param