mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-26 20:09:19 +00:00
Move parsing of field pattern lists to the parser (where it belongs)
This commit is contained in:
parent
d2769837f1
commit
f9a6050034
6 changed files with 71 additions and 64 deletions
|
@ -857,11 +857,19 @@ impl ExprCollector {
|
||||||
let fields = p
|
let fields = p
|
||||||
.field_pat_list()
|
.field_pat_list()
|
||||||
.expect("every struct should have a field list")
|
.expect("every struct should have a field list")
|
||||||
.field_pats()
|
.pats()
|
||||||
.into_iter()
|
|
||||||
.map(|f| {
|
.map(|f| {
|
||||||
let name = Name::new(f.ident);
|
let ast_pat = f.pat().expect("field pat always contains a pattern");
|
||||||
let pat = self.collect_pat(&*f.pat);
|
let pat = self.collect_pat(ast_pat);
|
||||||
|
let name = f
|
||||||
|
.name()
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
ast::BindPat::cast(ast_pat.syntax())
|
||||||
|
.expect("field pat without label is a bind pat")
|
||||||
|
.name()
|
||||||
|
.expect("bind pat has a name")
|
||||||
|
})
|
||||||
|
.as_name();
|
||||||
FieldPat { name, pat }
|
FieldPat { name, pat }
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
|
@ -664,55 +664,6 @@ impl LiteralExpr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
|
||||||
pub struct FieldPat {
|
|
||||||
pub ident: SmolStr,
|
|
||||||
// FIXME: could we use a regular reference?
|
|
||||||
pub pat: TreeArc<Pat>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FieldPatList {
|
|
||||||
// TODO: try returning an iterator?
|
|
||||||
// FIXME: shouldnt the parser do this? :o
|
|
||||||
pub fn field_pats(&self) -> Vec<FieldPat> {
|
|
||||||
let mut child_iter = self.syntax().children();
|
|
||||||
let mut pats = Vec::new();
|
|
||||||
|
|
||||||
while let Some(node) = child_iter.next() {
|
|
||||||
let kind = node.kind();
|
|
||||||
if kind != IDENT && kind != BIND_PAT {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let ident = if let Some(text) = node.leaf_text() {
|
|
||||||
text.clone()
|
|
||||||
} else {
|
|
||||||
SmolStr::new(node.text().to_string())
|
|
||||||
};
|
|
||||||
let mut pat = Pat::cast(node).map(AstNode::to_owned);
|
|
||||||
|
|
||||||
// get pat
|
|
||||||
while let Some(node) = child_iter.next() {
|
|
||||||
if node.kind() == COMMA {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(p) = Pat::cast(node) {
|
|
||||||
pat = Some(p.to_owned());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let field_pat = FieldPat {
|
|
||||||
ident: ident,
|
|
||||||
pat: pat.unwrap(),
|
|
||||||
};
|
|
||||||
pats.push(field_pat);
|
|
||||||
}
|
|
||||||
|
|
||||||
pats
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BindPat {
|
impl BindPat {
|
||||||
pub fn is_mutable(&self) -> bool {
|
pub fn is_mutable(&self) -> bool {
|
||||||
self.syntax().children().any(|n| n.kind() == MUT_KW)
|
self.syntax().children().any(|n| n.kind() == MUT_KW)
|
||||||
|
|
|
@ -858,6 +858,35 @@ impl FieldExpr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FieldPat
|
||||||
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct FieldPat {
|
||||||
|
pub(crate) syntax: SyntaxNode,
|
||||||
|
}
|
||||||
|
unsafe impl TransparentNewType for FieldPat {
|
||||||
|
type Repr = rowan::SyntaxNode<RaTypes>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AstNode for FieldPat {
|
||||||
|
fn cast(syntax: &SyntaxNode) -> Option<&Self> {
|
||||||
|
match syntax.kind() {
|
||||||
|
FIELD_PAT => Some(FieldPat::from_repr(syntax.into_repr())),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||||
|
fn to_owned(&self) -> TreeArc<FieldPat> { TreeArc::cast(self.syntax.to_owned()) }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl ast::NameOwner for FieldPat {}
|
||||||
|
impl FieldPat {
|
||||||
|
pub fn pat(&self) -> Option<&Pat> {
|
||||||
|
super::child_opt(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FieldPatList
|
// FieldPatList
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
|
@ -880,7 +909,11 @@ impl AstNode for FieldPatList {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl FieldPatList {}
|
impl FieldPatList {
|
||||||
|
pub fn pats(&self) -> impl Iterator<Item = &FieldPat> {
|
||||||
|
super::children(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// FloatNumber
|
// FloatNumber
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
|
|
|
@ -154,6 +154,7 @@ Grammar(
|
||||||
"PATH_PAT",
|
"PATH_PAT",
|
||||||
"STRUCT_PAT",
|
"STRUCT_PAT",
|
||||||
"FIELD_PAT_LIST",
|
"FIELD_PAT_LIST",
|
||||||
|
"FIELD_PAT",
|
||||||
"TUPLE_STRUCT_PAT",
|
"TUPLE_STRUCT_PAT",
|
||||||
"TUPLE_PAT",
|
"TUPLE_PAT",
|
||||||
"SLICE_PAT",
|
"SLICE_PAT",
|
||||||
|
@ -495,7 +496,11 @@ Grammar(
|
||||||
"PlaceholderPat": (),
|
"PlaceholderPat": (),
|
||||||
"PathPat": ( options: [ "Path" ] ),
|
"PathPat": ( options: [ "Path" ] ),
|
||||||
"StructPat": ( options: ["FieldPatList", "Path"] ),
|
"StructPat": ( options: ["FieldPatList", "Path"] ),
|
||||||
"FieldPatList": (),
|
"FieldPatList": ( collections: [["pats", "FieldPat"]] ),
|
||||||
|
"FieldPat": (
|
||||||
|
traits: ["NameOwner"],
|
||||||
|
options: ["Pat"]
|
||||||
|
),
|
||||||
"TupleStructPat": (
|
"TupleStructPat": (
|
||||||
options: ["Path"],
|
options: ["Path"],
|
||||||
collections: [["args", "Pat"]],
|
collections: [["args", "Pat"]],
|
||||||
|
|
|
@ -128,15 +128,7 @@ fn field_pat_list(p: &mut Parser) {
|
||||||
while !p.at(EOF) && !p.at(R_CURLY) {
|
while !p.at(EOF) && !p.at(R_CURLY) {
|
||||||
match p.current() {
|
match p.current() {
|
||||||
DOTDOT => p.bump(),
|
DOTDOT => p.bump(),
|
||||||
IDENT if p.nth(1) == COLON => {
|
_ => field_pat(p),
|
||||||
p.bump();
|
|
||||||
p.bump();
|
|
||||||
pattern(p);
|
|
||||||
}
|
|
||||||
L_CURLY => error_block(p, "expected ident"),
|
|
||||||
_ => {
|
|
||||||
bind_pat(p, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if !p.at(R_CURLY) {
|
if !p.at(R_CURLY) {
|
||||||
p.expect(COMMA);
|
p.expect(COMMA);
|
||||||
|
@ -146,6 +138,22 @@ fn field_pat_list(p: &mut Parser) {
|
||||||
m.complete(p, FIELD_PAT_LIST);
|
m.complete(p, FIELD_PAT_LIST);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn field_pat(p: &mut Parser) {
|
||||||
|
let m = p.start();
|
||||||
|
match p.current() {
|
||||||
|
IDENT if p.nth(1) == COLON => {
|
||||||
|
name(p);
|
||||||
|
p.bump();
|
||||||
|
pattern(p);
|
||||||
|
}
|
||||||
|
L_CURLY => error_block(p, "expected ident"),
|
||||||
|
_ => {
|
||||||
|
bind_pat(p, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m.complete(p, FIELD_PAT);
|
||||||
|
}
|
||||||
|
|
||||||
// test placeholder_pat
|
// test placeholder_pat
|
||||||
// fn main() { let _ = (); }
|
// fn main() { let _ = (); }
|
||||||
fn placeholder_pat(p: &mut Parser) -> CompletedMarker {
|
fn placeholder_pat(p: &mut Parser) -> CompletedMarker {
|
||||||
|
|
|
@ -152,6 +152,7 @@ pub enum SyntaxKind {
|
||||||
PATH_PAT,
|
PATH_PAT,
|
||||||
STRUCT_PAT,
|
STRUCT_PAT,
|
||||||
FIELD_PAT_LIST,
|
FIELD_PAT_LIST,
|
||||||
|
FIELD_PAT,
|
||||||
TUPLE_STRUCT_PAT,
|
TUPLE_STRUCT_PAT,
|
||||||
TUPLE_PAT,
|
TUPLE_PAT,
|
||||||
SLICE_PAT,
|
SLICE_PAT,
|
||||||
|
@ -414,6 +415,7 @@ impl SyntaxKind {
|
||||||
PATH_PAT => &SyntaxInfo { name: "PATH_PAT" },
|
PATH_PAT => &SyntaxInfo { name: "PATH_PAT" },
|
||||||
STRUCT_PAT => &SyntaxInfo { name: "STRUCT_PAT" },
|
STRUCT_PAT => &SyntaxInfo { name: "STRUCT_PAT" },
|
||||||
FIELD_PAT_LIST => &SyntaxInfo { name: "FIELD_PAT_LIST" },
|
FIELD_PAT_LIST => &SyntaxInfo { name: "FIELD_PAT_LIST" },
|
||||||
|
FIELD_PAT => &SyntaxInfo { name: "FIELD_PAT" },
|
||||||
TUPLE_STRUCT_PAT => &SyntaxInfo { name: "TUPLE_STRUCT_PAT" },
|
TUPLE_STRUCT_PAT => &SyntaxInfo { name: "TUPLE_STRUCT_PAT" },
|
||||||
TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" },
|
TUPLE_PAT => &SyntaxInfo { name: "TUPLE_PAT" },
|
||||||
SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" },
|
SLICE_PAT => &SyntaxInfo { name: "SLICE_PAT" },
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue