mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Path expressions
This commit is contained in:
parent
69c385e810
commit
d436694097
10 changed files with 320 additions and 17 deletions
|
@ -120,6 +120,7 @@ Grammar(
|
|||
"PLACEHOLDER_PAT",
|
||||
|
||||
"TUPLE_EXPR",
|
||||
"PATH_EXPR",
|
||||
|
||||
"EXTERN_BLOCK",
|
||||
"ENUM_VARIANT",
|
||||
|
@ -133,15 +134,18 @@ Grammar(
|
|||
"LITERAL",
|
||||
"ALIAS",
|
||||
"VISIBILITY",
|
||||
"TYPE_PARAM_LIST",
|
||||
"WHERE_CLAUSE",
|
||||
"LIFETIME_PARAM",
|
||||
"TYPE_PARAM",
|
||||
"ABI",
|
||||
"NAME",
|
||||
"NAME_REF",
|
||||
"VALUE_PARAMETER",
|
||||
"BLOCK",
|
||||
"LET_STMT",
|
||||
|
||||
"TYPE_PARAM",
|
||||
"LIFETIME_PARAM",
|
||||
"TYPE_PARAM_LIST",
|
||||
"TYPE_ARG_LIST",
|
||||
|
||||
]
|
||||
)
|
||||
|
|
|
@ -2,7 +2,16 @@ use super::*;
|
|||
|
||||
// test expr_literals
|
||||
// fn foo() {
|
||||
// let _ = 92;
|
||||
// let _ = true;
|
||||
// let _ = false;
|
||||
// let _ = 1;
|
||||
// let _ = 2.0;
|
||||
// let _ = b'a';
|
||||
// let _ = 'b';
|
||||
// let _ = "c";
|
||||
// let _ = r"d";
|
||||
// let _ = b"e";
|
||||
// let _ = br"f";
|
||||
// }
|
||||
pub(super) fn literal(p: &mut Parser) -> bool {
|
||||
match p.current() {
|
||||
|
@ -21,6 +30,9 @@ pub(super) fn expr(p: &mut Parser) {
|
|||
if literal(p) {
|
||||
return;
|
||||
}
|
||||
if paths::is_path_start(p) {
|
||||
return path_expr(p);
|
||||
}
|
||||
|
||||
match p.current() {
|
||||
L_PAREN => tuple_expr(p),
|
||||
|
@ -35,3 +47,16 @@ fn tuple_expr(p: &mut Parser) {
|
|||
p.expect(R_PAREN);
|
||||
m.complete(p, TUPLE_EXPR);
|
||||
}
|
||||
|
||||
// test path_expr
|
||||
// fn foo() {
|
||||
// let _ = a;
|
||||
// let _ = a::b;
|
||||
// let _ = ::a::<b>;
|
||||
// }
|
||||
fn path_expr(p: &mut Parser) {
|
||||
assert!(paths::is_path_start(p));
|
||||
let m = p.start();
|
||||
paths::expr_path(p);
|
||||
m.complete(p, PATH_EXPR);
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ mod items;
|
|||
mod paths;
|
||||
mod patterns;
|
||||
mod type_params;
|
||||
mod type_args;
|
||||
mod types;
|
||||
|
||||
use {
|
||||
|
|
|
@ -8,19 +8,26 @@ pub(super) fn is_path_start(p: &Parser) -> bool {
|
|||
}
|
||||
|
||||
pub(super) fn use_path(p: &mut Parser) {
|
||||
path(p)
|
||||
path(p, Mode::Use)
|
||||
}
|
||||
|
||||
pub(super) fn type_path(p: &mut Parser) {
|
||||
path(p)
|
||||
path(p, Mode::Type)
|
||||
}
|
||||
|
||||
fn path(p: &mut Parser) {
|
||||
pub(super) fn expr_path(p: &mut Parser) {
|
||||
path(p, Mode::Expr)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
enum Mode { Use, Type, Expr }
|
||||
|
||||
fn path(p: &mut Parser, mode: Mode) {
|
||||
if !is_path_start(p) {
|
||||
return;
|
||||
}
|
||||
let path = p.start();
|
||||
path_segment(p, true);
|
||||
path_segment(p, mode, true);
|
||||
let mut qual = path.complete(p, PATH);
|
||||
loop {
|
||||
let use_tree = match p.nth(1) {
|
||||
|
@ -30,7 +37,7 @@ fn path(p: &mut Parser) {
|
|||
if p.at(COLONCOLON) && !use_tree {
|
||||
let path = qual.precede(p);
|
||||
p.bump();
|
||||
path_segment(p, false);
|
||||
path_segment(p, mode, false);
|
||||
let path = path.complete(p, PATH);
|
||||
qual = path;
|
||||
} else {
|
||||
|
@ -39,13 +46,16 @@ fn path(p: &mut Parser) {
|
|||
}
|
||||
}
|
||||
|
||||
fn path_segment(p: &mut Parser, first: bool) {
|
||||
fn path_segment(p: &mut Parser, mode: Mode, first: bool) {
|
||||
let segment = p.start();
|
||||
if first {
|
||||
p.eat(COLONCOLON);
|
||||
}
|
||||
match p.current() {
|
||||
IDENT => name_ref(p),
|
||||
IDENT => {
|
||||
name_ref(p);
|
||||
path_generic_args(p, mode);
|
||||
},
|
||||
SELF_KW | SUPER_KW => p.bump(),
|
||||
_ => {
|
||||
p.error("expected identifier");
|
||||
|
@ -53,3 +63,11 @@ fn path_segment(p: &mut Parser, first: bool) {
|
|||
};
|
||||
segment.complete(p, PATH_SEGMENT);
|
||||
}
|
||||
|
||||
fn path_generic_args(p: &mut Parser, mode: Mode) {
|
||||
match mode {
|
||||
Mode::Use => return,
|
||||
Mode::Type => type_args::list(p, false),
|
||||
Mode::Expr => type_args::list(p, true),
|
||||
}
|
||||
}
|
||||
|
|
26
src/parser/grammar/type_args.rs
Normal file
26
src/parser/grammar/type_args.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use super::*;
|
||||
|
||||
pub(super) fn list(p: &mut Parser, colon_colon_required: bool) {
|
||||
let m;
|
||||
match (colon_colon_required, p.nth(0), p.nth(1)) {
|
||||
(_, COLONCOLON, L_ANGLE) => {
|
||||
m = p.start();
|
||||
p.bump();
|
||||
p.bump();
|
||||
}
|
||||
(false, L_ANGLE, _) => {
|
||||
m = p.start();
|
||||
p.bump();
|
||||
}
|
||||
_ => return
|
||||
};
|
||||
|
||||
while !p.at(EOF) && !p.at(R_ANGLE) {
|
||||
types::type_(p);
|
||||
if !p.at(R_ANGLE) && !p.expect(COMMA) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
p.expect(R_ANGLE);
|
||||
m.complete(p, TYPE_ARG_LIST);
|
||||
}
|
|
@ -115,6 +115,7 @@ pub enum SyntaxKind {
|
|||
BIND_PAT,
|
||||
PLACEHOLDER_PAT,
|
||||
TUPLE_EXPR,
|
||||
PATH_EXPR,
|
||||
EXTERN_BLOCK,
|
||||
ENUM_VARIANT,
|
||||
NAMED_FIELD,
|
||||
|
@ -127,16 +128,17 @@ pub enum SyntaxKind {
|
|||
LITERAL,
|
||||
ALIAS,
|
||||
VISIBILITY,
|
||||
TYPE_PARAM_LIST,
|
||||
WHERE_CLAUSE,
|
||||
LIFETIME_PARAM,
|
||||
TYPE_PARAM,
|
||||
ABI,
|
||||
NAME,
|
||||
NAME_REF,
|
||||
VALUE_PARAMETER,
|
||||
BLOCK,
|
||||
LET_STMT,
|
||||
TYPE_PARAM,
|
||||
LIFETIME_PARAM,
|
||||
TYPE_PARAM_LIST,
|
||||
TYPE_ARG_LIST,
|
||||
// Technical SyntaxKinds: they appear temporally during parsing,
|
||||
// but never end up in the final tree
|
||||
#[doc(hidden)]
|
||||
|
@ -259,6 +261,7 @@ impl SyntaxKind {
|
|||
BIND_PAT => &SyntaxInfo { name: "BIND_PAT" },
|
||||
PLACEHOLDER_PAT => &SyntaxInfo { name: "PLACEHOLDER_PAT" },
|
||||
TUPLE_EXPR => &SyntaxInfo { name: "TUPLE_EXPR" },
|
||||
PATH_EXPR => &SyntaxInfo { name: "PATH_EXPR" },
|
||||
EXTERN_BLOCK => &SyntaxInfo { name: "EXTERN_BLOCK" },
|
||||
ENUM_VARIANT => &SyntaxInfo { name: "ENUM_VARIANT" },
|
||||
NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" },
|
||||
|
@ -271,16 +274,17 @@ impl SyntaxKind {
|
|||
LITERAL => &SyntaxInfo { name: "LITERAL" },
|
||||
ALIAS => &SyntaxInfo { name: "ALIAS" },
|
||||
VISIBILITY => &SyntaxInfo { name: "VISIBILITY" },
|
||||
TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" },
|
||||
WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" },
|
||||
LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" },
|
||||
TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" },
|
||||
ABI => &SyntaxInfo { name: "ABI" },
|
||||
NAME => &SyntaxInfo { name: "NAME" },
|
||||
NAME_REF => &SyntaxInfo { name: "NAME_REF" },
|
||||
VALUE_PARAMETER => &SyntaxInfo { name: "VALUE_PARAMETER" },
|
||||
BLOCK => &SyntaxInfo { name: "BLOCK" },
|
||||
LET_STMT => &SyntaxInfo { name: "LET_STMT" },
|
||||
TYPE_PARAM => &SyntaxInfo { name: "TYPE_PARAM" },
|
||||
LIFETIME_PARAM => &SyntaxInfo { name: "LIFETIME_PARAM" },
|
||||
TYPE_PARAM_LIST => &SyntaxInfo { name: "TYPE_PARAM_LIST" },
|
||||
TYPE_ARG_LIST => &SyntaxInfo { name: "TYPE_ARG_LIST" },
|
||||
|
||||
TOMBSTONE => &SyntaxInfo { name: "TOMBSTONE" },
|
||||
EOF => &SyntaxInfo { name: "EOF" },
|
||||
|
|
5
tests/data/parser/inline/0039_path_expr.rs
Normal file
5
tests/data/parser/inline/0039_path_expr.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
fn foo() {
|
||||
let _ = a;
|
||||
let _ = a::b;
|
||||
let _ = ::a::<b>;
|
||||
}
|
74
tests/data/parser/inline/0039_path_expr.txt
Normal file
74
tests/data/parser/inline/0039_path_expr.txt
Normal file
|
@ -0,0 +1,74 @@
|
|||
FILE@[0; 68)
|
||||
FN_ITEM@[0; 68)
|
||||
FN_KW@[0; 2)
|
||||
NAME@[2; 6)
|
||||
WHITESPACE@[2; 3)
|
||||
IDENT@[3; 6) "foo"
|
||||
L_PAREN@[6; 7)
|
||||
R_PAREN@[7; 8)
|
||||
BLOCK@[8; 68)
|
||||
WHITESPACE@[8; 9)
|
||||
L_CURLY@[9; 10)
|
||||
LET_STMT@[10; 30)
|
||||
WHITESPACE@[10; 15)
|
||||
LET_KW@[15; 18)
|
||||
PLACEHOLDER_PAT@[18; 21)
|
||||
WHITESPACE@[18; 19)
|
||||
UNDERSCORE@[19; 20)
|
||||
WHITESPACE@[20; 21)
|
||||
EQ@[21; 22)
|
||||
PATH_EXPR@[22; 24)
|
||||
PATH@[22; 24)
|
||||
PATH_SEGMENT@[22; 24)
|
||||
NAME_REF@[22; 24)
|
||||
WHITESPACE@[22; 23)
|
||||
IDENT@[23; 24) "a"
|
||||
SEMI@[24; 25)
|
||||
WHITESPACE@[25; 30)
|
||||
LET_STMT@[30; 48)
|
||||
LET_KW@[30; 33)
|
||||
PLACEHOLDER_PAT@[33; 36)
|
||||
WHITESPACE@[33; 34)
|
||||
UNDERSCORE@[34; 35)
|
||||
WHITESPACE@[35; 36)
|
||||
EQ@[36; 37)
|
||||
PATH_EXPR@[37; 42)
|
||||
PATH@[37; 42)
|
||||
PATH@[37; 39)
|
||||
PATH_SEGMENT@[37; 39)
|
||||
NAME_REF@[37; 39)
|
||||
WHITESPACE@[37; 38)
|
||||
IDENT@[38; 39) "a"
|
||||
COLONCOLON@[39; 41)
|
||||
PATH_SEGMENT@[41; 42)
|
||||
NAME_REF@[41; 42)
|
||||
IDENT@[41; 42) "b"
|
||||
SEMI@[42; 43)
|
||||
WHITESPACE@[43; 48)
|
||||
LET_STMT@[48; 66)
|
||||
LET_KW@[48; 51)
|
||||
PLACEHOLDER_PAT@[51; 54)
|
||||
WHITESPACE@[51; 52)
|
||||
UNDERSCORE@[52; 53)
|
||||
WHITESPACE@[53; 54)
|
||||
EQ@[54; 55)
|
||||
PATH_EXPR@[55; 64)
|
||||
PATH@[55; 64)
|
||||
PATH_SEGMENT@[55; 64)
|
||||
WHITESPACE@[55; 56)
|
||||
COLONCOLON@[56; 58)
|
||||
NAME_REF@[58; 59)
|
||||
IDENT@[58; 59) "a"
|
||||
TYPE_ARG_LIST@[59; 64)
|
||||
COLONCOLON@[59; 61)
|
||||
L_ANGLE@[61; 62)
|
||||
PATH_TYPE@[62; 63)
|
||||
PATH@[62; 63)
|
||||
PATH_SEGMENT@[62; 63)
|
||||
NAME_REF@[62; 63)
|
||||
IDENT@[62; 63) "b"
|
||||
R_ANGLE@[63; 64)
|
||||
SEMI@[64; 65)
|
||||
WHITESPACE@[65; 66)
|
||||
R_CURLY@[66; 67)
|
||||
WHITESPACE@[67; 68)
|
12
tests/data/parser/inline/0040_expr_literals.rs
Normal file
12
tests/data/parser/inline/0040_expr_literals.rs
Normal file
|
@ -0,0 +1,12 @@
|
|||
fn foo() {
|
||||
let _ = true;
|
||||
let _ = false;
|
||||
let _ = 1;
|
||||
let _ = 2.0;
|
||||
let _ = b'a';
|
||||
let _ = 'b';
|
||||
let _ = "c";
|
||||
let _ = r"d";
|
||||
let _ = b"e";
|
||||
let _ = br"f";
|
||||
}
|
134
tests/data/parser/inline/0040_expr_literals.txt
Normal file
134
tests/data/parser/inline/0040_expr_literals.txt
Normal file
|
@ -0,0 +1,134 @@
|
|||
FILE@[0; 189)
|
||||
FN_ITEM@[0; 189)
|
||||
FN_KW@[0; 2)
|
||||
NAME@[2; 6)
|
||||
WHITESPACE@[2; 3)
|
||||
IDENT@[3; 6) "foo"
|
||||
L_PAREN@[6; 7)
|
||||
R_PAREN@[7; 8)
|
||||
BLOCK@[8; 189)
|
||||
WHITESPACE@[8; 9)
|
||||
L_CURLY@[9; 10)
|
||||
LET_STMT@[10; 33)
|
||||
WHITESPACE@[10; 15)
|
||||
LET_KW@[15; 18)
|
||||
PLACEHOLDER_PAT@[18; 21)
|
||||
WHITESPACE@[18; 19)
|
||||
UNDERSCORE@[19; 20)
|
||||
WHITESPACE@[20; 21)
|
||||
EQ@[21; 22)
|
||||
LITERAL@[22; 27)
|
||||
WHITESPACE@[22; 23)
|
||||
TRUE_KW@[23; 27)
|
||||
SEMI@[27; 28)
|
||||
WHITESPACE@[28; 33)
|
||||
LET_STMT@[33; 52)
|
||||
LET_KW@[33; 36)
|
||||
PLACEHOLDER_PAT@[36; 39)
|
||||
WHITESPACE@[36; 37)
|
||||
UNDERSCORE@[37; 38)
|
||||
WHITESPACE@[38; 39)
|
||||
EQ@[39; 40)
|
||||
LITERAL@[40; 46)
|
||||
WHITESPACE@[40; 41)
|
||||
FALSE_KW@[41; 46)
|
||||
SEMI@[46; 47)
|
||||
WHITESPACE@[47; 52)
|
||||
LET_STMT@[52; 67)
|
||||
LET_KW@[52; 55)
|
||||
PLACEHOLDER_PAT@[55; 58)
|
||||
WHITESPACE@[55; 56)
|
||||
UNDERSCORE@[56; 57)
|
||||
WHITESPACE@[57; 58)
|
||||
EQ@[58; 59)
|
||||
LITERAL@[59; 61)
|
||||
WHITESPACE@[59; 60)
|
||||
INT_NUMBER@[60; 61)
|
||||
SEMI@[61; 62)
|
||||
WHITESPACE@[62; 67)
|
||||
LET_STMT@[67; 84)
|
||||
LET_KW@[67; 70)
|
||||
PLACEHOLDER_PAT@[70; 73)
|
||||
WHITESPACE@[70; 71)
|
||||
UNDERSCORE@[71; 72)
|
||||
WHITESPACE@[72; 73)
|
||||
EQ@[73; 74)
|
||||
LITERAL@[74; 78)
|
||||
WHITESPACE@[74; 75)
|
||||
FLOAT_NUMBER@[75; 78)
|
||||
SEMI@[78; 79)
|
||||
WHITESPACE@[79; 84)
|
||||
LET_STMT@[84; 102)
|
||||
LET_KW@[84; 87)
|
||||
PLACEHOLDER_PAT@[87; 90)
|
||||
WHITESPACE@[87; 88)
|
||||
UNDERSCORE@[88; 89)
|
||||
WHITESPACE@[89; 90)
|
||||
EQ@[90; 91)
|
||||
LITERAL@[91; 96)
|
||||
WHITESPACE@[91; 92)
|
||||
BYTE@[92; 96)
|
||||
SEMI@[96; 97)
|
||||
WHITESPACE@[97; 102)
|
||||
LET_STMT@[102; 119)
|
||||
LET_KW@[102; 105)
|
||||
PLACEHOLDER_PAT@[105; 108)
|
||||
WHITESPACE@[105; 106)
|
||||
UNDERSCORE@[106; 107)
|
||||
WHITESPACE@[107; 108)
|
||||
EQ@[108; 109)
|
||||
LITERAL@[109; 113)
|
||||
WHITESPACE@[109; 110)
|
||||
CHAR@[110; 113)
|
||||
SEMI@[113; 114)
|
||||
WHITESPACE@[114; 119)
|
||||
LET_STMT@[119; 136)
|
||||
LET_KW@[119; 122)
|
||||
PLACEHOLDER_PAT@[122; 125)
|
||||
WHITESPACE@[122; 123)
|
||||
UNDERSCORE@[123; 124)
|
||||
WHITESPACE@[124; 125)
|
||||
EQ@[125; 126)
|
||||
LITERAL@[126; 130)
|
||||
WHITESPACE@[126; 127)
|
||||
STRING@[127; 130)
|
||||
SEMI@[130; 131)
|
||||
WHITESPACE@[131; 136)
|
||||
LET_STMT@[136; 154)
|
||||
LET_KW@[136; 139)
|
||||
PLACEHOLDER_PAT@[139; 142)
|
||||
WHITESPACE@[139; 140)
|
||||
UNDERSCORE@[140; 141)
|
||||
WHITESPACE@[141; 142)
|
||||
EQ@[142; 143)
|
||||
LITERAL@[143; 148)
|
||||
WHITESPACE@[143; 144)
|
||||
RAW_STRING@[144; 148)
|
||||
SEMI@[148; 149)
|
||||
WHITESPACE@[149; 154)
|
||||
LET_STMT@[154; 172)
|
||||
LET_KW@[154; 157)
|
||||
PLACEHOLDER_PAT@[157; 160)
|
||||
WHITESPACE@[157; 158)
|
||||
UNDERSCORE@[158; 159)
|
||||
WHITESPACE@[159; 160)
|
||||
EQ@[160; 161)
|
||||
LITERAL@[161; 166)
|
||||
WHITESPACE@[161; 162)
|
||||
BYTE_STRING@[162; 166)
|
||||
SEMI@[166; 167)
|
||||
WHITESPACE@[167; 172)
|
||||
LET_STMT@[172; 187)
|
||||
LET_KW@[172; 175)
|
||||
PLACEHOLDER_PAT@[175; 178)
|
||||
WHITESPACE@[175; 176)
|
||||
UNDERSCORE@[176; 177)
|
||||
WHITESPACE@[177; 178)
|
||||
EQ@[178; 179)
|
||||
LITERAL@[179; 185)
|
||||
WHITESPACE@[179; 180)
|
||||
RAW_BYTE_STRING@[180; 185)
|
||||
SEMI@[185; 186)
|
||||
WHITESPACE@[186; 187)
|
||||
R_CURLY@[187; 188)
|
||||
WHITESPACE@[188; 189)
|
Loading…
Reference in a new issue