mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 21:43:37 +00:00
Auto merge of #16786 - pksunkara:improve-readability, r=lnicola
internal: Improve readability of the parser code The code is basically equivalent to the previous version, but it improves the readability by making it much more simpler and concise.
This commit is contained in:
commit
2b7b44bf27
10 changed files with 38 additions and 63 deletions
|
@ -416,14 +416,12 @@ fn delimited(
|
|||
if !parser(p) {
|
||||
break;
|
||||
}
|
||||
if !p.at(delim) {
|
||||
if !p.eat(delim) {
|
||||
if p.at_ts(first_set) {
|
||||
p.error(format!("expected {:?}", delim));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
p.bump(delim);
|
||||
}
|
||||
}
|
||||
p.expect(ket);
|
||||
|
|
|
@ -211,9 +211,8 @@ fn current_op(p: &Parser<'_>) -> (u8, SyntaxKind, Associativity) {
|
|||
T![>] if p.at(T![>>]) => (9, T![>>], Left),
|
||||
T![>] if p.at(T![>=]) => (5, T![>=], Left),
|
||||
T![>] => (5, T![>], Left),
|
||||
T![=] if p.at(T![=>]) => NOT_AN_OP,
|
||||
T![=] if p.at(T![==]) => (5, T![==], Left),
|
||||
T![=] => (1, T![=], Right),
|
||||
T![=] if !p.at(T![=>]) => (1, T![=], Right),
|
||||
T![<] if p.at(T![<=]) => (5, T![<=], Left),
|
||||
T![<] if p.at(T![<<=]) => (1, T![<<=], Right),
|
||||
T![<] if p.at(T![<<]) => (9, T![<<], Left),
|
||||
|
@ -247,7 +246,7 @@ fn current_op(p: &Parser<'_>) -> (u8, SyntaxKind, Associativity) {
|
|||
fn expr_bp(
|
||||
p: &mut Parser<'_>,
|
||||
m: Option<Marker>,
|
||||
mut r: Restrictions,
|
||||
r: Restrictions,
|
||||
bp: u8,
|
||||
) -> Option<(CompletedMarker, BlockLike)> {
|
||||
let m = m.unwrap_or_else(|| {
|
||||
|
@ -295,10 +294,6 @@ fn expr_bp(
|
|||
let m = lhs.precede(p);
|
||||
p.bump(op);
|
||||
|
||||
// test binop_resets_statementness
|
||||
// fn f() { v = {1}&2; }
|
||||
r = Restrictions { prefer_stmt: false, ..r };
|
||||
|
||||
if is_range {
|
||||
// test postfix_range
|
||||
// fn foo() {
|
||||
|
@ -319,6 +314,9 @@ fn expr_bp(
|
|||
Associativity::Left => op_bp + 1,
|
||||
Associativity::Right => op_bp,
|
||||
};
|
||||
|
||||
// test binop_resets_statementness
|
||||
// fn f() { v = {1}&2; }
|
||||
expr_bp(p, None, Restrictions { prefer_stmt: false, ..r }, op_bp);
|
||||
lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR });
|
||||
}
|
||||
|
@ -345,7 +343,7 @@ fn lhs(p: &mut Parser<'_>, r: Restrictions) -> Option<(CompletedMarker, BlockLik
|
|||
T![&] => {
|
||||
m = p.start();
|
||||
p.bump(T![&]);
|
||||
if p.at_contextual_kw(T![raw]) && (p.nth_at(1, T![mut]) || p.nth_at(1, T![const])) {
|
||||
if p.at_contextual_kw(T![raw]) && [T![mut], T![const]].contains(&p.nth(1)) {
|
||||
p.bump_remap(T![raw]);
|
||||
p.bump_any();
|
||||
} else {
|
||||
|
|
|
@ -147,7 +147,7 @@ pub(super) fn atom_expr(
|
|||
T![async] if la == T![move] && p.nth(2) == T!['{'] => {
|
||||
let m = p.start();
|
||||
p.bump(T![async]);
|
||||
p.eat(T![move]);
|
||||
p.bump(T![move]);
|
||||
stmt_list(p);
|
||||
m.complete(p, BLOCK_EXPR)
|
||||
}
|
||||
|
@ -390,8 +390,7 @@ fn if_expr(p: &mut Parser<'_>) -> CompletedMarker {
|
|||
p.bump(T![if]);
|
||||
expr_no_struct(p);
|
||||
block_expr(p);
|
||||
if p.at(T![else]) {
|
||||
p.bump(T![else]);
|
||||
if p.eat(T![else]) {
|
||||
if p.at(T![if]) {
|
||||
if_expr(p);
|
||||
} else {
|
||||
|
|
|
@ -170,7 +170,7 @@ fn type_bound(p: &mut Parser<'_>) -> bool {
|
|||
_ => (),
|
||||
}
|
||||
if paths::is_use_path_start(p) {
|
||||
types::path_type_(p, false);
|
||||
types::path_type_bounds(p, false);
|
||||
} else {
|
||||
m.abandon(p);
|
||||
return false;
|
||||
|
|
|
@ -156,27 +156,19 @@ pub(super) fn opt_item(p: &mut Parser<'_>, m: Marker) -> Result<(), Marker> {
|
|||
// impl T for Foo {
|
||||
// default async fn foo() {}
|
||||
// }
|
||||
T![async] => {
|
||||
let mut maybe_fn = p.nth(2);
|
||||
let is_unsafe = if matches!(maybe_fn, T![unsafe]) {
|
||||
// test default_async_unsafe_fn
|
||||
// impl T for Foo {
|
||||
// default async unsafe fn foo() {}
|
||||
// }
|
||||
maybe_fn = p.nth(3);
|
||||
true
|
||||
} else {
|
||||
false
|
||||
};
|
||||
T![async]
|
||||
if p.nth_at(2, T![fn]) || (p.nth_at(2, T![unsafe]) && p.nth_at(3, T![fn])) =>
|
||||
{
|
||||
p.bump_remap(T![default]);
|
||||
p.bump(T![async]);
|
||||
|
||||
if matches!(maybe_fn, T![fn]) {
|
||||
p.bump_remap(T![default]);
|
||||
p.bump(T![async]);
|
||||
if is_unsafe {
|
||||
p.bump(T![unsafe]);
|
||||
}
|
||||
has_mods = true;
|
||||
}
|
||||
// test default_async_unsafe_fn
|
||||
// impl T for Foo {
|
||||
// default async unsafe fn foo() {}
|
||||
// }
|
||||
p.eat(T![unsafe]);
|
||||
|
||||
has_mods = true;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
|
@ -419,11 +411,9 @@ fn fn_(p: &mut Parser<'_>, m: Marker) {
|
|||
// fn foo<T>() where T: Copy {}
|
||||
generic_params::opt_where_clause(p);
|
||||
|
||||
if p.at(T![;]) {
|
||||
// test fn_decl
|
||||
// trait T { fn foo(); }
|
||||
p.bump(T![;]);
|
||||
} else {
|
||||
// test fn_decl
|
||||
// trait T { fn foo(); }
|
||||
if !p.eat(T![;]) {
|
||||
expressions::block_expr(p);
|
||||
}
|
||||
m.complete(p, FN);
|
||||
|
|
|
@ -119,11 +119,11 @@ fn not_a_qualified_path(p: &Parser<'_>) -> bool {
|
|||
// we disambiguate it in favor of generics (`impl<T> ::absolute::Path<T> { ... }`)
|
||||
// because this is what almost always expected in practice, qualified paths in impls
|
||||
// (`impl <Type>::AssocTy { ... }`) aren't even allowed by type checker at the moment.
|
||||
if p.nth(1) == T![#] || p.nth(1) == T![>] || p.nth(1) == T![const] {
|
||||
if [T![#], T![>], T![const]].contains(&p.nth(1)) {
|
||||
return true;
|
||||
}
|
||||
(p.nth(1) == LIFETIME_IDENT || p.nth(1) == IDENT)
|
||||
&& (p.nth(2) == T![>] || p.nth(2) == T![,] || p.nth(2) == T![:] || p.nth(2) == T![=])
|
||||
([LIFETIME_IDENT, IDENT].contains(&p.nth(1)))
|
||||
&& ([T![>], T![,], T![:], T![=]].contains(&p.nth(2)))
|
||||
}
|
||||
|
||||
// test_err impl_type
|
||||
|
|
|
@ -76,19 +76,16 @@ fn list_(p: &mut Parser<'_>, flavor: Flavor) {
|
|||
m.abandon(p);
|
||||
if p.eat(T![,]) {
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
param(p, m, flavor);
|
||||
if !p.at(T![,]) {
|
||||
if !p.eat(T![,]) {
|
||||
if p.at_ts(PARAM_FIRST.union(ATTRIBUTE_FIRST)) {
|
||||
p.error("expected `,`");
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
p.bump(T![,]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -255,9 +255,7 @@ fn is_literal_pat_start(p: &Parser<'_>) -> bool {
|
|||
fn literal_pat(p: &mut Parser<'_>) -> CompletedMarker {
|
||||
assert!(is_literal_pat_start(p));
|
||||
let m = p.start();
|
||||
if p.at(T![-]) {
|
||||
p.bump(T![-]);
|
||||
}
|
||||
p.eat(T![-]);
|
||||
expressions::literal(p);
|
||||
m.complete(p, LITERAL_PAT)
|
||||
}
|
||||
|
@ -468,14 +466,12 @@ fn slice_pat(p: &mut Parser<'_>) -> CompletedMarker {
|
|||
fn pat_list(p: &mut Parser<'_>, ket: SyntaxKind) {
|
||||
while !p.at(EOF) && !p.at(ket) {
|
||||
pattern_top(p);
|
||||
if !p.at(T![,]) {
|
||||
if !p.eat(T![,]) {
|
||||
if p.at_ts(PAT_TOP_FIRST) {
|
||||
p.error(format!("expected {:?}, got {:?}", T![,], p.current()));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
p.bump(T![,]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ fn type_with_bounds_cond(p: &mut Parser<'_>, allow_bounds: bool) {
|
|||
T![impl] => impl_trait_type(p),
|
||||
T![dyn] => dyn_trait_type(p),
|
||||
// Some path types are not allowed to have bounds (no plus)
|
||||
T![<] => path_type_(p, allow_bounds),
|
||||
T![<] => path_type_bounds(p, allow_bounds),
|
||||
_ if paths::is_path_start(p) => path_or_macro_type_(p, allow_bounds),
|
||||
LIFETIME_IDENT if p.nth_at(1, T![+]) => bare_dyn_trait_type(p),
|
||||
_ => {
|
||||
|
@ -294,7 +294,7 @@ fn bare_dyn_trait_type(p: &mut Parser<'_>) {
|
|||
// type C = self::Foo;
|
||||
// type D = super::Foo;
|
||||
pub(super) fn path_type(p: &mut Parser<'_>) {
|
||||
path_type_(p, true);
|
||||
path_type_bounds(p, true);
|
||||
}
|
||||
|
||||
// test macro_call_type
|
||||
|
@ -323,7 +323,7 @@ fn path_or_macro_type_(p: &mut Parser<'_>, allow_bounds: bool) {
|
|||
}
|
||||
}
|
||||
|
||||
pub(super) fn path_type_(p: &mut Parser<'_>, allow_bounds: bool) {
|
||||
pub(super) fn path_type_bounds(p: &mut Parser<'_>, allow_bounds: bool) {
|
||||
assert!(paths::is_path_start(p));
|
||||
let m = p.start();
|
||||
paths::type_path(p);
|
||||
|
|
|
@ -250,12 +250,9 @@ impl<'t> Parser<'t> {
|
|||
|
||||
/// Create an error node and consume the next token.
|
||||
pub(crate) fn err_recover(&mut self, message: &str, recovery: TokenSet) {
|
||||
match self.current() {
|
||||
T!['{'] | T!['}'] => {
|
||||
self.error(message);
|
||||
return;
|
||||
}
|
||||
_ => (),
|
||||
if matches!(self.current(), T!['{'] | T!['}']) {
|
||||
self.error(message);
|
||||
return;
|
||||
}
|
||||
|
||||
if self.at_ts(recovery) {
|
||||
|
|
Loading…
Reference in a new issue