internal: parser cleanup

This commit is contained in:
Aleksey Kladov 2021-09-18 15:46:28 +03:00
parent af9fd37cd9
commit 3dc2aeea0f
12 changed files with 175 additions and 116 deletions

View File

@ -19,7 +19,7 @@
// struct S; // struct S;
pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) { pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) {
attributes::inner_attrs(p); attributes::inner_attrs(p);
while !(stop_on_r_curly && p.at(T!['}']) || p.at(EOF)) { while !p.at(EOF) && !(p.at(T!['}']) && stop_on_r_curly) {
item_or_macro(p, stop_on_r_curly) item_or_macro(p, stop_on_r_curly)
} }
} }

View File

@ -1,12 +1,13 @@
use super::*; use super::*;
pub(super) fn opt_generic_param_list(p: &mut Parser) { pub(super) fn opt_generic_param_list(p: &mut Parser) {
if !p.at(T![<]) { if p.at(T![<]) {
return; generic_param_list(p);
} }
generic_param_list(p);
} }
// test generic_param_list
// fn f<T: Clone>() {}
fn generic_param_list(p: &mut Parser) { fn generic_param_list(p: &mut Parser) {
assert!(p.at(T![<])); assert!(p.at(T![<]));
let m = p.start(); let m = p.start();
@ -15,9 +16,8 @@ fn generic_param_list(p: &mut Parser) {
while !p.at(EOF) && !p.at(T![>]) { while !p.at(EOF) && !p.at(T![>]) {
let m = p.start(); let m = p.start();
// test generic_lifetime_type_attribute // test generic_param_list_param_attribute
// fn foo<#[derive(Lifetime)] 'a, #[derive(Type)] T>(_: &'a T) { // fn foo<#[lt_attr] 'a, #[t_attr] T>() {}
// }
attributes::outer_attrs(p); attributes::outer_attrs(p);
match p.current() { match p.current() {
@ -37,6 +37,8 @@ fn generic_param_list(p: &mut Parser) {
m.complete(p, GENERIC_PARAM_LIST); m.complete(p, GENERIC_PARAM_LIST);
} }
// test lifetime_param
// fn f<'a: 'b>() {}
fn lifetime_param(p: &mut Parser, m: Marker) { fn lifetime_param(p: &mut Parser, m: Marker) {
assert!(p.at(LIFETIME_IDENT)); assert!(p.at(LIFETIME_IDENT));
lifetime(p); lifetime(p);
@ -46,15 +48,17 @@ fn lifetime_param(p: &mut Parser, m: Marker) {
m.complete(p, LIFETIME_PARAM); m.complete(p, LIFETIME_PARAM);
} }
// test type_param
// fn f<T: Clone>() {}
fn type_param(p: &mut Parser, m: Marker) { fn type_param(p: &mut Parser, m: Marker) {
assert!(p.at(IDENT)); assert!(p.at(IDENT));
name(p); name(p);
if p.at(T![:]) { if p.at(T![:]) {
bounds(p); bounds(p);
} }
// test type_param_default
// struct S<T = i32>;
if p.at(T![=]) { if p.at(T![=]) {
// test type_param_default
// struct S<T = i32>;
p.bump(T![=]); p.bump(T![=]);
types::type_(p) types::type_(p)
} }
@ -64,7 +68,6 @@ fn type_param(p: &mut Parser, m: Marker) {
// test const_param // test const_param
// struct S<const N: u32>; // struct S<const N: u32>;
fn const_param(p: &mut Parser, m: Marker) { fn const_param(p: &mut Parser, m: Marker) {
assert!(p.at(T![const]));
p.bump(T![const]); p.bump(T![const]);
name(p); name(p);
if p.at(T![:]) { if p.at(T![:]) {
@ -73,11 +76,11 @@ fn const_param(p: &mut Parser, m: Marker) {
p.error("missing type for const parameter"); p.error("missing type for const parameter");
} }
// test const_param_defaults
// struct A<const N: i32 = -1>;
// struct B<const N: i32 = {}>;
// struct C<const N: i32 = some::CONST>;
if p.at(T![=]) { if p.at(T![=]) {
// test const_param_defaults
// struct A<const N: i32 = -1>;
// struct B<const N: i32 = {}>;
// struct C<const N: i32 = some::CONST>;
p.bump(T![=]); p.bump(T![=]);
type_args::const_arg(p); type_args::const_arg(p);
} }
@ -85,14 +88,6 @@ fn const_param(p: &mut Parser, m: Marker) {
m.complete(p, CONST_PARAM); m.complete(p, CONST_PARAM);
} }
// test type_param_bounds
// struct S<T: 'a + ?Sized + (Copy)>;
pub(super) fn bounds(p: &mut Parser) {
assert!(p.at(T![:]));
p.bump(T![:]);
bounds_without_colon(p);
}
fn lifetime_bounds(p: &mut Parser) { fn lifetime_bounds(p: &mut Parser) {
assert!(p.at(T![:])); assert!(p.at(T![:]));
p.bump(T![:]); p.bump(T![:]);
@ -104,21 +99,28 @@ fn lifetime_bounds(p: &mut Parser) {
} }
} }
// test type_param_bounds
// struct S<T: 'a + ?Sized + (Copy)>;
pub(super) fn bounds(p: &mut Parser) {
assert!(p.at(T![:]));
p.bump(T![:]);
bounds_without_colon(p);
}
pub(super) fn bounds_without_colon(p: &mut Parser) {
let m = p.start();
bounds_without_colon_m(p, m);
}
pub(super) fn bounds_without_colon_m(p: &mut Parser, marker: Marker) -> CompletedMarker { pub(super) fn bounds_without_colon_m(p: &mut Parser, marker: Marker) -> CompletedMarker {
while type_bound(p) { while type_bound(p) {
if !p.eat(T![+]) { if !p.eat(T![+]) {
break; break;
} }
} }
marker.complete(p, TYPE_BOUND_LIST) marker.complete(p, TYPE_BOUND_LIST)
} }
pub(super) fn bounds_without_colon(p: &mut Parser) {
let m = p.start();
bounds_without_colon_m(p, m);
}
fn type_bound(p: &mut Parser) -> bool { fn type_bound(p: &mut Parser) -> bool {
let m = p.start(); let m = p.start();
let has_paren = p.eat(T!['(']); let has_paren = p.eat(T!['(']);
@ -160,8 +162,9 @@ pub(super) fn opt_where_clause(p: &mut Parser) {
let comma = p.eat(T![,]); let comma = p.eat(T![,]);
if is_where_clause_end(p) { match p.current() {
break; T!['{'] | T![;] | T![=] => break,
_ => (),
} }
if !comma { if !comma {
@ -170,20 +173,16 @@ pub(super) fn opt_where_clause(p: &mut Parser) {
} }
m.complete(p, WHERE_CLAUSE); m.complete(p, WHERE_CLAUSE);
}
fn is_where_predicate(p: &mut Parser) -> bool { fn is_where_predicate(p: &mut Parser) -> bool {
match p.current() { match p.current() {
LIFETIME_IDENT => true, LIFETIME_IDENT => true,
T![impl] => false, T![impl] => false,
token => types::TYPE_FIRST.contains(token), token => types::TYPE_FIRST.contains(token),
}
} }
} }
fn is_where_clause_end(p: &mut Parser) -> bool {
matches!(p.current(), T!['{'] | T![;] | T![=])
}
fn where_predicate(p: &mut Parser) { fn where_predicate(p: &mut Parser) {
let m = p.start(); let m = p.start();
match p.current() { match p.current() {
@ -199,12 +198,12 @@ fn where_predicate(p: &mut Parser) {
p.error("expected lifetime or type"); p.error("expected lifetime or type");
} }
_ => { _ => {
// test where_pred_for
// fn for_trait<F>()
// where
// for<'a> F: Fn(&'a str)
// { }
if p.at(T![for]) { if p.at(T![for]) {
// test where_pred_for
// fn for_trait<F>()
// where
// for<'a> F: Fn(&'a str)
// { }
types::for_binder(p); types::for_binder(p);
} }

View File

@ -1,69 +0,0 @@
SOURCE_FILE@0..64
FN@0..63
FN_KW@0..2 "fn"
WHITESPACE@2..3 " "
NAME@3..6
IDENT@3..6 "foo"
GENERIC_PARAM_LIST@6..49
L_ANGLE@6..7 "<"
LIFETIME_PARAM@7..29
ATTR@7..26
POUND@7..8 "#"
L_BRACK@8..9 "["
META@9..25
PATH@9..15
PATH_SEGMENT@9..15
NAME_REF@9..15
IDENT@9..15 "derive"
TOKEN_TREE@15..25
L_PAREN@15..16 "("
IDENT@16..24 "Lifetime"
R_PAREN@24..25 ")"
R_BRACK@25..26 "]"
WHITESPACE@26..27 " "
LIFETIME@27..29
LIFETIME_IDENT@27..29 "'a"
COMMA@29..30 ","
WHITESPACE@30..31 " "
TYPE_PARAM@31..48
ATTR@31..46
POUND@31..32 "#"
L_BRACK@32..33 "["
META@33..45
PATH@33..39
PATH_SEGMENT@33..39
NAME_REF@33..39
IDENT@33..39 "derive"
TOKEN_TREE@39..45
L_PAREN@39..40 "("
IDENT@40..44 "Type"
R_PAREN@44..45 ")"
R_BRACK@45..46 "]"
WHITESPACE@46..47 " "
NAME@47..48
IDENT@47..48 "T"
R_ANGLE@48..49 ">"
PARAM_LIST@49..59
L_PAREN@49..50 "("
PARAM@50..58
WILDCARD_PAT@50..51
UNDERSCORE@50..51 "_"
COLON@51..52 ":"
WHITESPACE@52..53 " "
REF_TYPE@53..58
AMP@53..54 "&"
LIFETIME@54..56
LIFETIME_IDENT@54..56 "'a"
WHITESPACE@56..57 " "
PATH_TYPE@57..58
PATH@57..58
PATH_SEGMENT@57..58
NAME_REF@57..58
IDENT@57..58 "T"
R_PAREN@58..59 ")"
WHITESPACE@59..60 " "
BLOCK_EXPR@60..63
L_CURLY@60..61 "{"
WHITESPACE@61..62 "\n"
R_CURLY@62..63 "}"
WHITESPACE@63..64 "\n"

View File

@ -1,2 +0,0 @@
fn foo<#[derive(Lifetime)] 'a, #[derive(Type)] T>(_: &'a T) {
}

View File

@ -0,0 +1,45 @@
SOURCE_FILE@0..40
FN@0..39
FN_KW@0..2 "fn"
WHITESPACE@2..3 " "
NAME@3..6
IDENT@3..6 "foo"
GENERIC_PARAM_LIST@6..34
L_ANGLE@6..7 "<"
LIFETIME_PARAM@7..20
ATTR@7..17
POUND@7..8 "#"
L_BRACK@8..9 "["
META@9..16
PATH@9..16
PATH_SEGMENT@9..16
NAME_REF@9..16
IDENT@9..16 "lt_attr"
R_BRACK@16..17 "]"
WHITESPACE@17..18 " "
LIFETIME@18..20
LIFETIME_IDENT@18..20 "'a"
COMMA@20..21 ","
WHITESPACE@21..22 " "
TYPE_PARAM@22..33
ATTR@22..31
POUND@22..23 "#"
L_BRACK@23..24 "["
META@24..30
PATH@24..30
PATH_SEGMENT@24..30
NAME_REF@24..30
IDENT@24..30 "t_attr"
R_BRACK@30..31 "]"
WHITESPACE@31..32 " "
NAME@32..33
IDENT@32..33 "T"
R_ANGLE@33..34 ">"
PARAM_LIST@34..36
L_PAREN@34..35 "("
R_PAREN@35..36 ")"
WHITESPACE@36..37 " "
BLOCK_EXPR@37..39
L_CURLY@37..38 "{"
R_CURLY@38..39 "}"
WHITESPACE@39..40 "\n"

View File

@ -0,0 +1 @@
fn foo<#[lt_attr] 'a, #[t_attr] T>() {}

View File

@ -0,0 +1,24 @@
SOURCE_FILE@0..18
FN@0..17
FN_KW@0..2 "fn"
WHITESPACE@2..3 " "
NAME@3..4
IDENT@3..4 "f"
GENERIC_PARAM_LIST@4..12
L_ANGLE@4..5 "<"
LIFETIME_PARAM@5..11
LIFETIME@5..7
LIFETIME_IDENT@5..7 "'a"
COLON@7..8 ":"
WHITESPACE@8..9 " "
LIFETIME@9..11
LIFETIME_IDENT@9..11 "'b"
R_ANGLE@11..12 ">"
PARAM_LIST@12..14
L_PAREN@12..13 "("
R_PAREN@13..14 ")"
WHITESPACE@14..15 " "
BLOCK_EXPR@15..17
L_CURLY@15..16 "{"
R_CURLY@16..17 "}"
WHITESPACE@17..18 "\n"

View File

@ -0,0 +1 @@
fn f<'a: 'b>() {}

View File

@ -0,0 +1,29 @@
SOURCE_FILE@0..20
FN@0..19
FN_KW@0..2 "fn"
WHITESPACE@2..3 " "
NAME@3..4
IDENT@3..4 "f"
GENERIC_PARAM_LIST@4..14
L_ANGLE@4..5 "<"
TYPE_PARAM@5..13
NAME@5..6
IDENT@5..6 "T"
COLON@6..7 ":"
WHITESPACE@7..8 " "
TYPE_BOUND_LIST@8..13
TYPE_BOUND@8..13
PATH_TYPE@8..13
PATH@8..13
PATH_SEGMENT@8..13
NAME_REF@8..13
IDENT@8..13 "Clone"
R_ANGLE@13..14 ">"
PARAM_LIST@14..16
L_PAREN@14..15 "("
R_PAREN@15..16 ")"
WHITESPACE@16..17 " "
BLOCK_EXPR@17..19
L_CURLY@17..18 "{"
R_CURLY@18..19 "}"
WHITESPACE@19..20 "\n"

View File

@ -0,0 +1 @@
fn f<T: Clone>() {}

View File

@ -0,0 +1,29 @@
SOURCE_FILE@0..20
FN@0..19
FN_KW@0..2 "fn"
WHITESPACE@2..3 " "
NAME@3..4
IDENT@3..4 "f"
GENERIC_PARAM_LIST@4..14
L_ANGLE@4..5 "<"
TYPE_PARAM@5..13
NAME@5..6
IDENT@5..6 "T"
COLON@6..7 ":"
WHITESPACE@7..8 " "
TYPE_BOUND_LIST@8..13
TYPE_BOUND@8..13
PATH_TYPE@8..13
PATH@8..13
PATH_SEGMENT@8..13
NAME_REF@8..13
IDENT@8..13 "Clone"
R_ANGLE@13..14 ">"
PARAM_LIST@14..16
L_PAREN@14..15 "("
R_PAREN@15..16 ")"
WHITESPACE@16..17 " "
BLOCK_EXPR@17..19
L_CURLY@17..18 "{"
R_CURLY@18..19 "}"
WHITESPACE@19..20 "\n"

View File

@ -0,0 +1 @@
fn f<T: Clone>() {}