rust-analyzer/crates/ra_parser/src/grammar/params.rs

166 lines
4.5 KiB
Rust
Raw Normal View History

2018-07-31 20:13:08 +00:00
use super::*;
// test param_list
// fn a() {}
// fn b(x: i32) {}
// fn c(x: i32, ) {}
// fn d(x: i32, y: ()) {}
2019-08-07 16:42:28 +00:00
// fn g1(#[attr1] #[attr2] pat: Type) {}
// fn g2(#[attr1] x: u8) {}
2018-07-31 20:16:07 +00:00
pub(super) fn param_list(p: &mut Parser) {
2018-08-08 15:13:30 +00:00
list_(p, Flavor::Normal)
}
// test param_list_opt_patterns
// fn foo<F: FnMut(&mut Foo<'a>)>(){}
2019-08-07 16:42:28 +00:00
// fn foo<F: FnMut(#[attr] &mut Foo<'a>)>(){}
2018-08-08 15:13:30 +00:00
pub(super) fn param_list_opt_patterns(p: &mut Parser) {
list_(p, Flavor::OptionalPattern)
2018-07-31 20:13:08 +00:00
}
2018-07-31 20:16:07 +00:00
pub(super) fn param_list_opt_types(p: &mut Parser) {
2018-08-08 15:13:30 +00:00
list_(p, Flavor::OptionalType)
}
#[derive(Clone, Copy, Eq, PartialEq)]
enum Flavor {
OptionalType,
OptionalPattern,
Normal,
2018-07-31 20:13:08 +00:00
}
2018-08-08 15:13:30 +00:00
impl Flavor {
fn type_required(self) -> bool {
match self {
Flavor::OptionalType => false,
_ => true,
}
}
}
fn list_(p: &mut Parser, flavor: Flavor) {
2019-05-15 12:35:47 +00:00
let (bra, ket) = if flavor.type_required() { (T!['('], T![')']) } else { (T![|], T![|]) };
2018-08-08 15:13:30 +00:00
assert!(p.at(bra));
2018-07-31 20:13:08 +00:00
let m = p.start();
p.bump();
2018-08-08 15:13:30 +00:00
if flavor.type_required() {
2019-08-07 16:42:28 +00:00
attributes::outer_attributes(p);
2018-08-23 23:14:10 +00:00
opt_self_param(p);
2018-07-31 20:13:08 +00:00
}
2019-08-08 01:58:28 +00:00
while !p.at(EOF) && !p.at(ket) {
2019-08-07 16:42:28 +00:00
attributes::outer_attributes(p);
2019-08-08 01:58:28 +00:00
if flavor.type_required() && p.at(T![...]) {
break;
}
2018-09-08 07:38:53 +00:00
if !p.at_ts(VALUE_PARAMETER_FIRST) {
p.error("expected value parameter");
break;
}
2018-08-08 15:13:30 +00:00
value_parameter(p, flavor);
if !p.at(ket) {
2019-05-15 12:35:47 +00:00
p.expect(T![,]);
2018-07-31 20:13:08 +00:00
}
}
2019-03-04 11:34:59 +00:00
// test param_list_vararg
// extern "C" { fn printf(format: *const i8, ...) -> i32; }
2019-08-07 16:48:21 +00:00
// extern "C" { fn printf(format: *const i8, #[attr] ...) -> i32; }
2019-04-23 03:10:41 +00:00
if flavor.type_required() {
2019-05-15 12:35:47 +00:00
p.eat(T![...]);
2019-03-04 11:34:59 +00:00
}
2018-08-08 15:13:30 +00:00
p.expect(ket);
2018-07-31 20:13:08 +00:00
m.complete(p, PARAM_LIST);
}
2019-01-18 08:02:30 +00:00
const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYPE_FIRST);
2018-08-08 15:13:30 +00:00
fn value_parameter(p: &mut Parser, flavor: Flavor) {
2018-07-31 20:13:08 +00:00
let m = p.start();
2018-08-08 15:34:26 +00:00
match flavor {
Flavor::OptionalType | Flavor::Normal => {
patterns::pattern(p);
2019-05-15 12:35:47 +00:00
if p.at(T![:]) || flavor.type_required() {
2018-08-08 15:34:26 +00:00
types::ascription(p)
}
}
2018-08-08 15:34:26 +00:00
// test value_parameters_no_patterns
// type F = Box<Fn(a: i32, &b: &i32, &mut c: &i32, ())>;
Flavor::OptionalPattern => {
let la0 = p.current();
let la1 = p.nth(1);
let la2 = p.nth(2);
let la3 = p.nth(3);
// test trait_fn_placeholder_parameter
// trait Foo {
// fn bar(_: u64, mut x: i32);
2019-08-07 16:42:28 +00:00
// fn bar(#[attr] _: u64, #[attr] mut x: i32);
// }
2019-05-15 12:35:47 +00:00
if (la0 == IDENT || la0 == T![_]) && la1 == T![:]
|| la0 == T![mut] && la1 == IDENT && la2 == T![:]
|| la0 == T![&] && la1 == IDENT && la2 == T![:]
|| la0 == T![&] && la1 == T![mut] && la2 == IDENT && la3 == T![:]
{
2018-08-08 15:34:26 +00:00
patterns::pattern(p);
types::ascription(p);
} else {
types::type_(p);
}
}
2018-07-31 20:13:08 +00:00
}
2018-07-31 20:13:55 +00:00
m.complete(p, PARAM);
2018-07-31 20:13:08 +00:00
}
// test self_param
// impl S {
// fn a(self) {}
// fn b(&self,) {}
// fn c(&'a self,) {}
// fn d(&'a mut self, x: i32) {}
2018-08-23 22:19:38 +00:00
// fn e(mut self) {}
2019-08-07 16:42:28 +00:00
// fn f(#[must_use] self) {}
// fn g1(#[attr] self) {}
// fn g2(#[attr] &self) {}
// fn g3<'a>(#[attr] &mut self) {}
// fn g4<'a>(#[attr] &'a self) {}
// fn g5<'a>(#[attr] &'a mut self) {}
2018-07-31 20:13:08 +00:00
// }
2018-08-23 23:14:10 +00:00
fn opt_self_param(p: &mut Parser) {
2018-08-23 16:07:33 +00:00
let m;
2019-05-15 12:35:47 +00:00
if p.at(T![self]) || p.at(T![mut]) && p.nth(1) == T![self] {
2018-08-23 16:07:33 +00:00
m = p.start();
2019-05-15 12:35:47 +00:00
p.eat(T![mut]);
p.eat(T![self]);
2018-08-23 16:07:33 +00:00
// test arb_self_types
// impl S {
// fn a(self: &Self) {}
2018-08-23 22:19:38 +00:00
// fn b(mut self: Box<Self>) {}
2019-08-07 16:42:28 +00:00
// fn c(#[attr] self: Self) {}
// fn d(#[attr] self: Rc<Self>) {}
2018-08-23 16:07:33 +00:00
// }
2019-05-15 12:35:47 +00:00
if p.at(T![:]) {
2018-08-23 16:07:33 +00:00
types::ascription(p);
}
} else {
let la1 = p.nth(1);
let la2 = p.nth(2);
let la3 = p.nth(3);
let n_toks = match (p.current(), la1, la2, la3) {
2019-05-15 12:35:47 +00:00
(T![&], T![self], _, _) => 2,
(T![&], T![mut], T![self], _) => 3,
(T![&], LIFETIME, T![self], _) => 3,
(T![&], LIFETIME, T![mut], T![self]) => 4,
2018-08-23 16:07:33 +00:00
_ => return,
};
m = p.start();
for _ in 0..n_toks {
p.bump();
}
2018-07-31 20:13:08 +00:00
}
m.complete(p, SELF_PARAM);
2019-05-15 12:35:47 +00:00
if !p.at(T![')']) {
p.expect(T![,]);
2018-07-31 20:13:08 +00:00
}
}