From 7e66785859fc4a31fc3faf4848174699d3a2c020 Mon Sep 17 00:00:00 2001 From: Toby Dimmick Date: Thu, 6 Feb 2020 11:44:00 +0000 Subject: Rework value parameter parsing - `Fn__(...)` parameters with idents/patterns no longer parse - Trait function parameters with arbitrary patterns parse - Trait function parameters without idents/patterns no longer parse - `fn(...)` parameters no longer parse with patterns other than a single ident --- crates/ra_parser/src/grammar/params.rs | 111 ++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 45 deletions(-) (limited to 'crates/ra_parser/src/grammar/params.rs') diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs index c10b53316..897092a67 100644 --- a/crates/ra_parser/src/grammar/params.rs +++ b/crates/ra_parser/src/grammar/params.rs @@ -7,54 +7,59 @@ use super::*; // fn b(x: i32) {} // fn c(x: i32, ) {} // fn d(x: i32, y: ()) {} -pub(super) fn param_list(p: &mut Parser) { - list_(p, Flavor::Normal) +pub(super) fn param_list_fn(p: &mut Parser) { + list_(p, Flavor::Function) } // test param_list_opt_patterns // fn foo)>(){} -pub(super) fn param_list_opt_patterns(p: &mut Parser) { - list_(p, Flavor::OptionalPattern) +pub(super) fn param_list_impl_fn(p: &mut Parser) { + list_(p, Flavor::ImplFn) } -pub(super) fn param_list_opt_types(p: &mut Parser) { - list_(p, Flavor::OptionalType) +pub(super) fn param_list_fn_ptr(p: &mut Parser) { + list_(p, Flavor::FnPointer) } -#[derive(Clone, Copy, Eq, PartialEq)] -enum Flavor { - OptionalType, - OptionalPattern, - Normal, +pub(super) fn param_list_closure(p: &mut Parser) { + list_(p, Flavor::Closure) } -impl Flavor { - fn type_required(self) -> bool { - match self { - Flavor::OptionalType => false, - _ => true, - } - } +#[derive(Debug, Clone, Copy)] +enum Flavor { + Function, // Includes trait fn params; omitted param idents are not supported + ImplFn, + FnPointer, + Closure } fn list_(p: &mut Parser, flavor: Flavor) { - let (bra, ket) = if flavor.type_required() { (T!['('], T![')']) } else { (T![|], T![|]) }; - assert!(p.at(bra)); + use Flavor::*; + + let (bra, ket) = match flavor { + Closure => (T![|], T![|]), + Function | ImplFn | FnPointer => (T!['('], T![')']) + }; + let m = p.start(); p.bump(bra); - if flavor.type_required() { + + if let Function = flavor { // test self_param_outer_attr // fn f(#[must_use] self) {} attributes::outer_attributes(p); opt_self_param(p); } + while !p.at(EOF) && !p.at(ket) { // test param_outer_arg // fn f(#[attr1] pat: Type) {} attributes::outer_attributes(p); - if flavor.type_required() && p.at(T![...]) { - break; + if let Function | FnPointer = flavor { + if p.at(T![...]) { + break; + } } if !p.at_ts(VALUE_PARAMETER_FIRST) { @@ -68,7 +73,7 @@ fn list_(p: &mut Parser, flavor: Flavor) { } // test param_list_vararg // extern "C" { fn printf(format: *const i8, ...) -> i32; } - if flavor.type_required() { + if let Function | FnPointer = flavor { p.eat(T![...]); } p.expect(ket); @@ -80,36 +85,52 @@ const VALUE_PARAMETER_FIRST: TokenSet = patterns::PATTERN_FIRST.union(types::TYP fn value_parameter(p: &mut Parser, flavor: Flavor) { let m = p.start(); match flavor { - Flavor::OptionalType | Flavor::Normal => { + // test trait_fn_placeholder_parameter + // trait Foo { + // fn bar(_: u64, mut x: i32); + // } + + // test trait_fn_patterns + // trait T { + // fn f1((a, b): (usize, usize)) {} + // fn f2(S { a, b }: S) {} + // fn f3(NewType(a): NewType) {} + // fn f4(&&a: &&usize) {} + // } + + // test fn_patterns + // impl U { + // fn f1((a, b): (usize, usize)) {} + // fn f2(S { a, b }: S) {} + // fn f3(NewType(a): NewType) {} + // fn f4(&&a: &&usize) {} + // } + Flavor::Function => { patterns::pattern(p); - if p.at(T![:]) && !p.at(T![::]) || flavor.type_required() { - types::ascription(p) - } + types::ascription(p); } // test value_parameters_no_patterns - // type F = Box; - 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); - // } - if (la0 == IDENT || la0 == T![_]) && la1 == T![:] && !p.nth_at(1, T![::]) - || la0 == T![mut] && la1 == IDENT && la2 == T![:] - || la0 == T![&] - && (la1 == IDENT && la2 == T![:] && !p.nth_at(2, T![::]) - || la1 == T![mut] && la2 == IDENT && la3 == T![:] && !p.nth_at(3, T![::])) - { + // type F = Box; + Flavor::ImplFn => { + types::type_(p); + } + // test fn_pointer_param_ident_path + // type Foo = fn(Bar::Baz); + // type Qux = fn(baz: Bar::Baz); + Flavor::FnPointer => { + if p.at(IDENT) && p.nth(1) == T![:] && !p.nth_at(1, T![::]) { patterns::pattern(p); types::ascription(p); } else { types::type_(p); } } + Flavor::Closure => { + patterns::pattern(p); + if p.at(T![:]) && !p.at(T![::]) { + types::ascription(p); + } + } } m.complete(p, PARAM); } -- cgit v1.2.3 From e1921ea59c04a21725caea53777c739e0a954f78 Mon Sep 17 00:00:00 2001 From: Toby Dimmick Date: Thu, 6 Feb 2020 20:04:35 +0000 Subject: rustfmt --- crates/ra_parser/src/grammar/params.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/ra_parser/src/grammar/params.rs') diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs index 897092a67..2445f71f7 100644 --- a/crates/ra_parser/src/grammar/params.rs +++ b/crates/ra_parser/src/grammar/params.rs @@ -30,7 +30,7 @@ enum Flavor { Function, // Includes trait fn params; omitted param idents are not supported ImplFn, FnPointer, - Closure + Closure, } fn list_(p: &mut Parser, flavor: Flavor) { @@ -38,7 +38,7 @@ fn list_(p: &mut Parser, flavor: Flavor) { let (bra, ket) = match flavor { Closure => (T![|], T![|]), - Function | ImplFn | FnPointer => (T!['('], T![')']) + Function | ImplFn | FnPointer => (T!['('], T![')']), }; let m = p.start(); -- cgit v1.2.3 From 0183952d2e1252a030aca3dafd8d7abe093be3a2 Mon Sep 17 00:00:00 2001 From: Toby Dimmick Date: Thu, 6 Feb 2020 20:39:27 +0000 Subject: Closure params test --- crates/ra_parser/src/grammar/params.rs | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'crates/ra_parser/src/grammar/params.rs') diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs index 2445f71f7..d9fbc7c94 100644 --- a/crates/ra_parser/src/grammar/params.rs +++ b/crates/ra_parser/src/grammar/params.rs @@ -125,6 +125,10 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) { types::type_(p); } } + // test closure_params + // fn main() { + // let foo = |bar, baz: Baz, qux: Qux::Quux| (); + // } Flavor::Closure => { patterns::pattern(p); if p.at(T![:]) && !p.at(T![::]) { -- cgit v1.2.3 From 90ff2be4e820601a1d16ba5716916f7424dfa10d Mon Sep 17 00:00:00 2001 From: Toby Dimmick Date: Fri, 7 Feb 2020 12:36:33 +0000 Subject: PR tweaks --- crates/ra_parser/src/grammar/params.rs | 35 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 19 deletions(-) (limited to 'crates/ra_parser/src/grammar/params.rs') diff --git a/crates/ra_parser/src/grammar/params.rs b/crates/ra_parser/src/grammar/params.rs index d9fbc7c94..94edc7f35 100644 --- a/crates/ra_parser/src/grammar/params.rs +++ b/crates/ra_parser/src/grammar/params.rs @@ -7,14 +7,14 @@ use super::*; // fn b(x: i32) {} // fn c(x: i32, ) {} // fn d(x: i32, y: ()) {} -pub(super) fn param_list_fn(p: &mut Parser) { - list_(p, Flavor::Function) +pub(super) fn param_list_fn_def(p: &mut Parser) { + list_(p, Flavor::FnDef) } // test param_list_opt_patterns // fn foo)>(){} -pub(super) fn param_list_impl_fn(p: &mut Parser) { - list_(p, Flavor::ImplFn) +pub(super) fn param_list_fn_trait(p: &mut Parser) { + list_(p, Flavor::FnTrait) } pub(super) fn param_list_fn_ptr(p: &mut Parser) { @@ -27,8 +27,8 @@ pub(super) fn param_list_closure(p: &mut Parser) { #[derive(Debug, Clone, Copy)] enum Flavor { - Function, // Includes trait fn params; omitted param idents are not supported - ImplFn, + FnDef, // Includes trait fn params; omitted param idents are not supported + FnTrait, // Params for `Fn(...)`/`FnMut(...)`/`FnOnce(...)` annotations FnPointer, Closure, } @@ -38,13 +38,13 @@ fn list_(p: &mut Parser, flavor: Flavor) { let (bra, ket) = match flavor { Closure => (T![|], T![|]), - Function | ImplFn | FnPointer => (T!['('], T![')']), + FnDef | FnTrait | FnPointer => (T!['('], T![')']), }; let m = p.start(); p.bump(bra); - if let Function = flavor { + if let FnDef = flavor { // test self_param_outer_attr // fn f(#[must_use] self) {} attributes::outer_attributes(p); @@ -56,10 +56,11 @@ fn list_(p: &mut Parser, flavor: Flavor) { // fn f(#[attr1] pat: Type) {} attributes::outer_attributes(p); - if let Function | FnPointer = flavor { - if p.at(T![...]) { - break; - } + // test param_list_vararg + // extern "C" { fn printf(format: *const i8, ...) -> i32; } + match flavor { + FnDef | FnPointer if p.eat(T![...]) => break, + _ => (), } if !p.at_ts(VALUE_PARAMETER_FIRST) { @@ -71,11 +72,7 @@ fn list_(p: &mut Parser, flavor: Flavor) { p.expect(T![,]); } } - // test param_list_vararg - // extern "C" { fn printf(format: *const i8, ...) -> i32; } - if let Function | FnPointer = flavor { - p.eat(T![...]); - } + p.expect(ket); m.complete(p, PARAM_LIST); } @@ -105,13 +102,13 @@ fn value_parameter(p: &mut Parser, flavor: Flavor) { // fn f3(NewType(a): NewType) {} // fn f4(&&a: &&usize) {} // } - Flavor::Function => { + Flavor::FnDef => { patterns::pattern(p); types::ascription(p); } // test value_parameters_no_patterns // type F = Box; - Flavor::ImplFn => { + Flavor::FnTrait => { types::type_(p); } // test fn_pointer_param_ident_path -- cgit v1.2.3