mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-27 04:15:08 +00:00
Labeled expressions
This commit is contained in:
parent
719710a132
commit
89e56c364f
6 changed files with 123 additions and 23 deletions
|
@ -161,11 +161,12 @@ Grammar(
|
||||||
"PATH_EXPR",
|
"PATH_EXPR",
|
||||||
"LAMBDA_EXPR",
|
"LAMBDA_EXPR",
|
||||||
"IF_EXPR",
|
"IF_EXPR",
|
||||||
"WHILE_EXPR",
|
|
||||||
"LOOP_EXPR",
|
"LOOP_EXPR",
|
||||||
|
"FOR_EXPR",
|
||||||
|
"WHILE_EXPR",
|
||||||
"CONTINUE_EXPR",
|
"CONTINUE_EXPR",
|
||||||
"BREAK_EXPR",
|
"BREAK_EXPR",
|
||||||
"FOR_EXPR",
|
"LABEL",
|
||||||
"BLOCK_EXPR",
|
"BLOCK_EXPR",
|
||||||
"RETURN_EXPR",
|
"RETURN_EXPR",
|
||||||
"MATCH_EXPR",
|
"MATCH_EXPR",
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet =
|
||||||
token_set_union![
|
token_set_union![
|
||||||
LITERAL_FIRST,
|
LITERAL_FIRST,
|
||||||
token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, WHILE_KW, MATCH_KW, UNSAFE_KW, L_CURLY, RETURN_KW,
|
token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, WHILE_KW, MATCH_KW, UNSAFE_KW, L_CURLY, RETURN_KW,
|
||||||
IDENT, SELF_KW, SUPER_KW, COLONCOLON, BREAK_KW, CONTINUE_KW ],
|
IDENT, SELF_KW, SUPER_KW, COLONCOLON, BREAK_KW, CONTINUE_KW, LIFETIME ],
|
||||||
];
|
];
|
||||||
|
|
||||||
pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> {
|
pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMarker> {
|
||||||
|
@ -48,9 +48,24 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<CompletedMark
|
||||||
PIPE => lambda_expr(p),
|
PIPE => lambda_expr(p),
|
||||||
MOVE_KW if la == PIPE => lambda_expr(p),
|
MOVE_KW if la == PIPE => lambda_expr(p),
|
||||||
IF_KW => if_expr(p),
|
IF_KW => if_expr(p),
|
||||||
WHILE_KW => while_expr(p),
|
|
||||||
LOOP_KW => loop_expr(p),
|
LOOP_KW => loop_expr(p, None),
|
||||||
FOR_KW => for_expr(p),
|
FOR_KW => for_expr(p, None),
|
||||||
|
WHILE_KW => while_expr(p, None),
|
||||||
|
LIFETIME if la == COLON => {
|
||||||
|
let m = p.start();
|
||||||
|
label(p);
|
||||||
|
match p.current() {
|
||||||
|
LOOP_KW => loop_expr(p, Some(m)),
|
||||||
|
FOR_KW => for_expr(p, Some(m)),
|
||||||
|
WHILE_KW => while_expr(p, Some(m)),
|
||||||
|
_ => {
|
||||||
|
p.error("expected a loop");
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MATCH_KW => match_expr(p),
|
MATCH_KW => match_expr(p),
|
||||||
UNSAFE_KW if la == L_CURLY => block_expr(p),
|
UNSAFE_KW if la == L_CURLY => block_expr(p),
|
||||||
L_CURLY => block_expr(p),
|
L_CURLY => block_expr(p),
|
||||||
|
@ -164,39 +179,53 @@ fn if_expr(p: &mut Parser) -> CompletedMarker {
|
||||||
m.complete(p, IF_EXPR)
|
m.complete(p, IF_EXPR)
|
||||||
}
|
}
|
||||||
|
|
||||||
// test while_expr
|
// test label
|
||||||
// fn foo() {
|
// fn foo() {
|
||||||
// while true {};
|
// 'a: loop {}
|
||||||
// while let Some(x) = it.next() {};
|
// 'b: while true {}
|
||||||
|
// 'c: for x in () {}
|
||||||
// }
|
// }
|
||||||
fn while_expr(p: &mut Parser) -> CompletedMarker {
|
fn label(p: &mut Parser) {
|
||||||
assert!(p.at(WHILE_KW));
|
assert!(p.at(LIFETIME) && p.nth(1) == COLON);
|
||||||
let m = p.start();
|
let m = p.start();
|
||||||
p.bump();
|
p.bump();
|
||||||
cond(p);
|
p.bump();
|
||||||
block(p);
|
m.complete(p, LABEL);
|
||||||
m.complete(p, WHILE_EXPR)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// test loop_expr
|
// test loop_expr
|
||||||
// fn foo() {
|
// fn foo() {
|
||||||
// loop {};
|
// loop {};
|
||||||
// }
|
// }
|
||||||
fn loop_expr(p: &mut Parser) -> CompletedMarker {
|
fn loop_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
|
||||||
assert!(p.at(LOOP_KW));
|
assert!(p.at(LOOP_KW));
|
||||||
let m = p.start();
|
let m = m.unwrap_or_else(|| p.start());
|
||||||
p.bump();
|
p.bump();
|
||||||
block(p);
|
block(p);
|
||||||
m.complete(p, LOOP_EXPR)
|
m.complete(p, LOOP_EXPR)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test while_expr
|
||||||
|
// fn foo() {
|
||||||
|
// while true {};
|
||||||
|
// while let Some(x) = it.next() {};
|
||||||
|
// }
|
||||||
|
fn while_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
|
||||||
|
assert!(p.at(WHILE_KW));
|
||||||
|
let m = m.unwrap_or_else(|| p.start());
|
||||||
|
p.bump();
|
||||||
|
cond(p);
|
||||||
|
block(p);
|
||||||
|
m.complete(p, WHILE_EXPR)
|
||||||
|
}
|
||||||
|
|
||||||
// test for_expr
|
// test for_expr
|
||||||
// fn foo() {
|
// fn foo() {
|
||||||
// for x in [] {};
|
// for x in [] {};
|
||||||
// }
|
// }
|
||||||
fn for_expr(p: &mut Parser) -> CompletedMarker {
|
fn for_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker {
|
||||||
assert!(p.at(FOR_KW));
|
assert!(p.at(FOR_KW));
|
||||||
let m = p.start();
|
let m = m.unwrap_or_else(|| p.start());
|
||||||
p.bump();
|
p.bump();
|
||||||
patterns::pattern(p);
|
patterns::pattern(p);
|
||||||
p.expect(IN_KW);
|
p.expect(IN_KW);
|
||||||
|
|
|
@ -32,7 +32,7 @@ mod type_params;
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
use {
|
use {
|
||||||
parser_api::{CompletedMarker, Parser, TokenSet},
|
parser_api::{Marker, CompletedMarker, Parser, TokenSet},
|
||||||
SyntaxKind::{self, *},
|
SyntaxKind::{self, *},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -157,11 +157,12 @@ pub enum SyntaxKind {
|
||||||
PATH_EXPR,
|
PATH_EXPR,
|
||||||
LAMBDA_EXPR,
|
LAMBDA_EXPR,
|
||||||
IF_EXPR,
|
IF_EXPR,
|
||||||
WHILE_EXPR,
|
|
||||||
LOOP_EXPR,
|
LOOP_EXPR,
|
||||||
|
FOR_EXPR,
|
||||||
|
WHILE_EXPR,
|
||||||
CONTINUE_EXPR,
|
CONTINUE_EXPR,
|
||||||
BREAK_EXPR,
|
BREAK_EXPR,
|
||||||
FOR_EXPR,
|
LABEL,
|
||||||
BLOCK_EXPR,
|
BLOCK_EXPR,
|
||||||
RETURN_EXPR,
|
RETURN_EXPR,
|
||||||
MATCH_EXPR,
|
MATCH_EXPR,
|
||||||
|
@ -406,11 +407,12 @@ impl SyntaxKind {
|
||||||
PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" },
|
PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" },
|
||||||
LAMBDA_EXPR => &SyntaxInfo { name: "LAMBDA_EXPR" },
|
LAMBDA_EXPR => &SyntaxInfo { name: "LAMBDA_EXPR" },
|
||||||
IF_EXPR => &SyntaxInfo { name: "IF_EXPR" },
|
IF_EXPR => &SyntaxInfo { name: "IF_EXPR" },
|
||||||
WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" },
|
|
||||||
LOOP_EXPR => &SyntaxInfo { name: "LOOP_EXPR" },
|
LOOP_EXPR => &SyntaxInfo { name: "LOOP_EXPR" },
|
||||||
|
FOR_EXPR => &SyntaxInfo { name: "FOR_EXPR" },
|
||||||
|
WHILE_EXPR => &SyntaxInfo { name: "WHILE_EXPR" },
|
||||||
CONTINUE_EXPR => &SyntaxInfo { name: "CONTINUE_EXPR" },
|
CONTINUE_EXPR => &SyntaxInfo { name: "CONTINUE_EXPR" },
|
||||||
BREAK_EXPR => &SyntaxInfo { name: "BREAK_EXPR" },
|
BREAK_EXPR => &SyntaxInfo { name: "BREAK_EXPR" },
|
||||||
FOR_EXPR => &SyntaxInfo { name: "FOR_EXPR" },
|
LABEL => &SyntaxInfo { name: "LABEL" },
|
||||||
BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" },
|
BLOCK_EXPR => &SyntaxInfo { name: "BLOCK_EXPR" },
|
||||||
RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" },
|
RETURN_EXPR => &SyntaxInfo { name: "RETURN_EXPR" },
|
||||||
MATCH_EXPR => &SyntaxInfo { name: "MATCH_EXPR" },
|
MATCH_EXPR => &SyntaxInfo { name: "MATCH_EXPR" },
|
||||||
|
|
5
crates/libsyntax2/tests/data/parser/inline/0107_label.rs
Normal file
5
crates/libsyntax2/tests/data/parser/inline/0107_label.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
fn foo() {
|
||||||
|
'a: loop {}
|
||||||
|
'b: while true {}
|
||||||
|
'c: for x in () {}
|
||||||
|
}
|
63
crates/libsyntax2/tests/data/parser/inline/0107_label.txt
Normal file
63
crates/libsyntax2/tests/data/parser/inline/0107_label.txt
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
FILE@[0; 74)
|
||||||
|
FN_DEF@[0; 73)
|
||||||
|
FN_KW@[0; 2)
|
||||||
|
WHITESPACE@[2; 3)
|
||||||
|
NAME@[3; 6)
|
||||||
|
IDENT@[3; 6) "foo"
|
||||||
|
PARAM_LIST@[6; 8)
|
||||||
|
L_PAREN@[6; 7)
|
||||||
|
R_PAREN@[7; 8)
|
||||||
|
WHITESPACE@[8; 9)
|
||||||
|
BLOCK_EXPR@[9; 73)
|
||||||
|
L_CURLY@[9; 10)
|
||||||
|
WHITESPACE@[10; 15)
|
||||||
|
EXPR_STMT@[15; 26)
|
||||||
|
LOOP_EXPR@[15; 26)
|
||||||
|
LABEL@[15; 18)
|
||||||
|
LIFETIME@[15; 17) "'a"
|
||||||
|
COLON@[17; 18)
|
||||||
|
WHITESPACE@[18; 19)
|
||||||
|
LOOP_KW@[19; 23)
|
||||||
|
WHITESPACE@[23; 24)
|
||||||
|
BLOCK_EXPR@[24; 26)
|
||||||
|
L_CURLY@[24; 25)
|
||||||
|
R_CURLY@[25; 26)
|
||||||
|
WHITESPACE@[26; 31)
|
||||||
|
EXPR_STMT@[31; 48)
|
||||||
|
WHILE_EXPR@[31; 48)
|
||||||
|
LABEL@[31; 34)
|
||||||
|
LIFETIME@[31; 33) "'b"
|
||||||
|
COLON@[33; 34)
|
||||||
|
WHITESPACE@[34; 35)
|
||||||
|
WHILE_KW@[35; 40)
|
||||||
|
WHITESPACE@[40; 41)
|
||||||
|
LITERAL@[41; 45)
|
||||||
|
TRUE_KW@[41; 45)
|
||||||
|
WHITESPACE@[45; 46)
|
||||||
|
BLOCK_EXPR@[46; 48)
|
||||||
|
L_CURLY@[46; 47)
|
||||||
|
R_CURLY@[47; 48)
|
||||||
|
WHITESPACE@[48; 53)
|
||||||
|
FOR_EXPR@[53; 71)
|
||||||
|
LABEL@[53; 56)
|
||||||
|
LIFETIME@[53; 55) "'c"
|
||||||
|
COLON@[55; 56)
|
||||||
|
WHITESPACE@[56; 57)
|
||||||
|
FOR_KW@[57; 60)
|
||||||
|
WHITESPACE@[60; 61)
|
||||||
|
BIND_PAT@[61; 62)
|
||||||
|
NAME@[61; 62)
|
||||||
|
IDENT@[61; 62) "x"
|
||||||
|
WHITESPACE@[62; 63)
|
||||||
|
IN_KW@[63; 65)
|
||||||
|
WHITESPACE@[65; 66)
|
||||||
|
TUPLE_EXPR@[66; 68)
|
||||||
|
L_PAREN@[66; 67)
|
||||||
|
R_PAREN@[67; 68)
|
||||||
|
WHITESPACE@[68; 69)
|
||||||
|
BLOCK_EXPR@[69; 71)
|
||||||
|
L_CURLY@[69; 70)
|
||||||
|
R_CURLY@[70; 71)
|
||||||
|
WHITESPACE@[71; 72)
|
||||||
|
R_CURLY@[72; 73)
|
||||||
|
WHITESPACE@[73; 74)
|
Loading…
Reference in a new issue