From 6fcd38cc81bdcc9921da767872dfce65ee7d2d27 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Mon, 24 Dec 2018 21:00:14 +0100 Subject: Infer result of struct literals, and recurse into their child expressions --- crates/ra_syntax/src/ast/generated.rs | 26 +++++++++++++++++++++++--- crates/ra_syntax/src/grammar.ron | 6 +++--- 2 files changed, 26 insertions(+), 6 deletions(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index c73533861..334da67ef 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -2142,7 +2142,15 @@ impl> NamedFieldNode { } -impl<'a> NamedField<'a> {} +impl<'a> NamedField<'a> { + pub fn name_ref(self) -> Option> { + super::child_opt(self) + } + + pub fn expr(self) -> Option> { + super::child_opt(self) + } +} // NamedFieldDef #[derive(Debug, Clone, Copy,)] @@ -2218,7 +2226,11 @@ impl> NamedFieldListNode { } -impl<'a> NamedFieldList<'a> {} +impl<'a> NamedFieldList<'a> { + pub fn fields(self) -> impl Iterator> + 'a { + super::children(self) + } +} // NeverType #[derive(Debug, Clone, Copy,)] @@ -3467,7 +3479,15 @@ impl> StructLitNode { } -impl<'a> StructLit<'a> {} +impl<'a> StructLit<'a> { + pub fn path(self) -> Option> { + super::child_opt(self) + } + + pub fn named_field_list(self) -> Option> { + super::child_opt(self) + } +} // StructPat #[derive(Debug, Clone, Copy,)] diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index e3b9032a0..0da8b8183 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -392,9 +392,9 @@ Grammar( collections: [ [ "pats", "Pat" ] ] ), "MatchGuard": (), - "StructLit": (), - "NamedFieldList": (), - "NamedField": (), + "StructLit": (options: ["Path", "NamedFieldList"]), + "NamedFieldList": (collections: [ ["fields", "NamedField"] ]), + "NamedField": (options: ["NameRef", "Expr"]), "CallExpr": ( traits: ["ArgListOwner"], options: [ "Expr" ], -- cgit v1.2.3 From 4cb7b0f2af9787abe1c73fc3922e9b426a96e0ef Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 25 Dec 2018 13:01:47 +0100 Subject: Add AST definitions for struct/variant fields etc. Fixes #117 --- crates/ra_syntax/src/ast.rs | 31 +++++ crates/ra_syntax/src/ast/generated.rs | 225 ++++++++++++++++++++++++++++++++-- crates/ra_syntax/src/grammar.ron | 12 +- 3 files changed, 256 insertions(+), 12 deletions(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index f12479fb4..5dbf9b221 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -363,3 +363,34 @@ impl<'a, N: AstNode<'a>> Iterator for AstChildren<'a, N> { } } } + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum StructFlavor<'a> { + Tuple(PosFieldList<'a>), + Named(NamedFieldDefList<'a>), + Unit, +} + +impl<'a> StructFlavor<'a> { + fn from_node>(node: N) -> StructFlavor<'a> { + if let Some(nfdl) = child_opt::<_, NamedFieldDefList>(node) { + StructFlavor::Named(nfdl) + } else if let Some(pfl) = child_opt::<_, PosFieldList>(node) { + StructFlavor::Tuple(pfl) + } else { + StructFlavor::Unit + } + } +} + +impl<'a> StructDef<'a> { + pub fn flavor(self) -> StructFlavor<'a> { + StructFlavor::from_node(self) + } +} + +impl<'a> EnumVariant<'a> { + pub fn flavor(self) -> StructFlavor<'a> { + StructFlavor::from_node(self) + } +} diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 334da67ef..35a9770a6 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -806,7 +806,94 @@ impl<'a> ast::NameOwner<'a> for EnumDef<'a> {} impl<'a> ast::TypeParamsOwner<'a> for EnumDef<'a> {} impl<'a> ast::AttrsOwner<'a> for EnumDef<'a> {} impl<'a> ast::DocCommentsOwner<'a> for EnumDef<'a> {} -impl<'a> EnumDef<'a> {} +impl<'a> EnumDef<'a> { + pub fn variant_list(self) -> Option> { + super::child_opt(self) + } +} + +// EnumVariant +#[derive(Debug, Clone, Copy,)] +pub struct EnumVariantNode = OwnedRoot> { + pub(crate) syntax: SyntaxNode, +} +pub type EnumVariant<'a> = EnumVariantNode>; + +impl, R2: TreeRoot> PartialEq> for EnumVariantNode { + fn eq(&self, other: &EnumVariantNode) -> bool { self.syntax == other.syntax } +} +impl> Eq for EnumVariantNode {} +impl> Hash for EnumVariantNode { + fn hash(&self, state: &mut H) { self.syntax.hash(state) } +} + +impl<'a> AstNode<'a> for EnumVariant<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + ENUM_VARIANT => Some(EnumVariant { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl> EnumVariantNode { + pub fn borrowed(&self) -> EnumVariant { + EnumVariantNode { syntax: self.syntax.borrowed() } + } + pub fn owned(&self) -> EnumVariantNode { + EnumVariantNode { syntax: self.syntax.owned() } + } +} + + +impl<'a> ast::NameOwner<'a> for EnumVariant<'a> {} +impl<'a> EnumVariant<'a> { + pub fn expr(self) -> Option> { + super::child_opt(self) + } +} + +// EnumVariantList +#[derive(Debug, Clone, Copy,)] +pub struct EnumVariantListNode = OwnedRoot> { + pub(crate) syntax: SyntaxNode, +} +pub type EnumVariantList<'a> = EnumVariantListNode>; + +impl, R2: TreeRoot> PartialEq> for EnumVariantListNode { + fn eq(&self, other: &EnumVariantListNode) -> bool { self.syntax == other.syntax } +} +impl> Eq for EnumVariantListNode {} +impl> Hash for EnumVariantListNode { + fn hash(&self, state: &mut H) { self.syntax.hash(state) } +} + +impl<'a> AstNode<'a> for EnumVariantList<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + ENUM_VARIANT_LIST => Some(EnumVariantList { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl> EnumVariantListNode { + pub fn borrowed(&self) -> EnumVariantList { + EnumVariantListNode { syntax: self.syntax.borrowed() } + } + pub fn owned(&self) -> EnumVariantListNode { + EnumVariantListNode { syntax: self.syntax.owned() } + } +} + + +impl<'a> EnumVariantList<'a> { + pub fn variants(self) -> impl Iterator> + 'a { + super::children(self) + } +} // Expr #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -2189,7 +2276,52 @@ impl> NamedFieldDefNode { impl<'a> ast::NameOwner<'a> for NamedFieldDef<'a> {} impl<'a> ast::AttrsOwner<'a> for NamedFieldDef<'a> {} -impl<'a> NamedFieldDef<'a> {} +impl<'a> NamedFieldDef<'a> { + pub fn type_ref(self) -> Option> { + super::child_opt(self) + } +} + +// NamedFieldDefList +#[derive(Debug, Clone, Copy,)] +pub struct NamedFieldDefListNode = OwnedRoot> { + pub(crate) syntax: SyntaxNode, +} +pub type NamedFieldDefList<'a> = NamedFieldDefListNode>; + +impl, R2: TreeRoot> PartialEq> for NamedFieldDefListNode { + fn eq(&self, other: &NamedFieldDefListNode) -> bool { self.syntax == other.syntax } +} +impl> Eq for NamedFieldDefListNode {} +impl> Hash for NamedFieldDefListNode { + fn hash(&self, state: &mut H) { self.syntax.hash(state) } +} + +impl<'a> AstNode<'a> for NamedFieldDefList<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + NAMED_FIELD_DEF_LIST => Some(NamedFieldDefList { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl> NamedFieldDefListNode { + pub fn borrowed(&self) -> NamedFieldDefList { + NamedFieldDefListNode { syntax: self.syntax.borrowed() } + } + pub fn owned(&self) -> NamedFieldDefListNode { + NamedFieldDefListNode { syntax: self.syntax.owned() } + } +} + + +impl<'a> NamedFieldDefList<'a> { + pub fn fields(self) -> impl Iterator> + 'a { + super::children(self) + } +} // NamedFieldList #[derive(Debug, Clone, Copy,)] @@ -2830,6 +2962,89 @@ impl> PointerTypeNode { impl<'a> PointerType<'a> {} +// PosField +#[derive(Debug, Clone, Copy,)] +pub struct PosFieldNode = OwnedRoot> { + pub(crate) syntax: SyntaxNode, +} +pub type PosField<'a> = PosFieldNode>; + +impl, R2: TreeRoot> PartialEq> for PosFieldNode { + fn eq(&self, other: &PosFieldNode) -> bool { self.syntax == other.syntax } +} +impl> Eq for PosFieldNode {} +impl> Hash for PosFieldNode { + fn hash(&self, state: &mut H) { self.syntax.hash(state) } +} + +impl<'a> AstNode<'a> for PosField<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + POS_FIELD => Some(PosField { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl> PosFieldNode { + pub fn borrowed(&self) -> PosField { + PosFieldNode { syntax: self.syntax.borrowed() } + } + pub fn owned(&self) -> PosFieldNode { + PosFieldNode { syntax: self.syntax.owned() } + } +} + + +impl<'a> ast::AttrsOwner<'a> for PosField<'a> {} +impl<'a> PosField<'a> { + pub fn type_ref(self) -> Option> { + super::child_opt(self) + } +} + +// PosFieldList +#[derive(Debug, Clone, Copy,)] +pub struct PosFieldListNode = OwnedRoot> { + pub(crate) syntax: SyntaxNode, +} +pub type PosFieldList<'a> = PosFieldListNode>; + +impl, R2: TreeRoot> PartialEq> for PosFieldListNode { + fn eq(&self, other: &PosFieldListNode) -> bool { self.syntax == other.syntax } +} +impl> Eq for PosFieldListNode {} +impl> Hash for PosFieldListNode { + fn hash(&self, state: &mut H) { self.syntax.hash(state) } +} + +impl<'a> AstNode<'a> for PosFieldList<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + POS_FIELD_LIST => Some(PosFieldList { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl> PosFieldListNode { + pub fn borrowed(&self) -> PosFieldList { + PosFieldListNode { syntax: self.syntax.borrowed() } + } + pub fn owned(&self) -> PosFieldListNode { + PosFieldListNode { syntax: self.syntax.owned() } + } +} + + +impl<'a> PosFieldList<'a> { + pub fn fields(self) -> impl Iterator> + 'a { + super::children(self) + } +} + // PrefixExpr #[derive(Debug, Clone, Copy,)] pub struct PrefixExprNode = OwnedRoot> { @@ -3438,11 +3653,7 @@ impl<'a> ast::NameOwner<'a> for StructDef<'a> {} impl<'a> ast::TypeParamsOwner<'a> for StructDef<'a> {} impl<'a> ast::AttrsOwner<'a> for StructDef<'a> {} impl<'a> ast::DocCommentsOwner<'a> for StructDef<'a> {} -impl<'a> StructDef<'a> { - pub fn fields(self) -> impl Iterator> + 'a { - super::children(self) - } -} +impl<'a> StructDef<'a> {} // StructLit #[derive(Debug, Clone, Copy,)] diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 0da8b8183..e4e41d077 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -261,18 +261,20 @@ Grammar( "TypeParamsOwner", "AttrsOwner", "DocCommentsOwner" - ], - collections: [ - ["fields", "NamedFieldDef"] ] ), - "NamedFieldDef": ( traits: ["NameOwner", "AttrsOwner"] ), + "NamedFieldDefList": (collections: [["fields", "NamedFieldDef"]]), + "NamedFieldDef": ( traits: ["NameOwner", "AttrsOwner"], options: ["TypeRef"] ), + "PosFieldList": (collections: [["fields", "PosField"]]), + "PosField": ( traits: ["AttrsOwner"], options: ["TypeRef"]), "EnumDef": ( traits: [ "NameOwner", "TypeParamsOwner", "AttrsOwner", "DocCommentsOwner" - ] ), + ], options: [["variant_list", "EnumVariantList"]] ), + "EnumVariantList": ( collections: [["variants", "EnumVariant"]] ), + "EnumVariant": ( traits: ["NameOwner"], options: ["Expr"] ), "TraitDef": ( traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner"] ), "Module": ( traits: ["NameOwner", "AttrsOwner", "DocCommentsOwner" ], -- cgit v1.2.3 From 55c941cd9fb90c9340f01981e113aabd058b185b Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 25 Dec 2018 13:54:38 +0100 Subject: Type field accesses --- crates/ra_syntax/src/ast/generated.rs | 10 +++++++++- crates/ra_syntax/src/grammar.ron | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 35a9770a6..4e0550487 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -1123,7 +1123,15 @@ impl> FieldExprNode { } -impl<'a> FieldExpr<'a> {} +impl<'a> FieldExpr<'a> { + pub fn expr(self) -> Option> { + super::child_opt(self) + } + + pub fn name_ref(self) -> Option> { + super::child_opt(self) + } +} // FieldPatList #[derive(Debug, Clone, Copy,)] diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index e4e41d077..923da0324 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -406,7 +406,7 @@ Grammar( options: [ "Expr" ], ), "IndexExpr": (), - "FieldExpr": (), + "FieldExpr": (options: ["Expr", "NameRef"]), "TryExpr": (options: ["Expr"]), "CastExpr": (options: ["Expr", "TypeRef"]), "RefExpr": (options: ["Expr"]), -- cgit v1.2.3 From 0d724ea572a5dd26acbbf2eb4538eabe454fb894 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 25 Dec 2018 14:48:54 +0100 Subject: Improve parsing of incomplete field accesses in preparation for field completion We need to be able to get the receiver even if there is no field name yet, and currently "a." wouldn't get parsed as a field name at all. This seems to help. --- crates/ra_syntax/src/grammar/expressions.rs | 16 +++++----- .../tests/data/parser/err/0029_field_completion.rs | 3 ++ .../data/parser/err/0029_field_completion.txt | 35 ++++++++++++++++++++++ 3 files changed, 45 insertions(+), 9 deletions(-) create mode 100644 crates/ra_syntax/tests/data/parser/err/0029_field_completion.rs create mode 100644 crates/ra_syntax/tests/data/parser/err/0029_field_completion.txt (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/grammar/expressions.rs b/crates/ra_syntax/src/grammar/expressions.rs index da78d85a2..2d1f17491 100644 --- a/crates/ra_syntax/src/grammar/expressions.rs +++ b/crates/ra_syntax/src/grammar/expressions.rs @@ -283,14 +283,10 @@ fn postfix_expr( // } L_PAREN if allow_calls => call_expr(p, lhs), L_BRACK if allow_calls => index_expr(p, lhs), - DOT if p.nth(1) == IDENT => { - if p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON { - method_call_expr(p, lhs) - } else { - field_expr(p, lhs) - } + DOT if p.nth(1) == IDENT && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON) => { + method_call_expr(p, lhs) } - DOT if p.nth(1) == INT_NUMBER => field_expr(p, lhs), + DOT => field_expr(p, lhs), // test postfix_range // fn foo() { let x = 1..; } DOTDOT | DOTDOTEQ if !EXPR_FIRST.contains(p.nth(1)) => { @@ -355,13 +351,15 @@ fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { // x.0.bar; // } fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(DOT) && (p.nth(1) == IDENT || p.nth(1) == INT_NUMBER)); + assert!(p.at(DOT)); let m = lhs.precede(p); p.bump(); if p.at(IDENT) { name_ref(p) - } else { + } else if p.at(INT_NUMBER) { p.bump() + } else { + p.error("expected field name or number") } m.complete(p, FIELD_EXPR) } diff --git a/crates/ra_syntax/tests/data/parser/err/0029_field_completion.rs b/crates/ra_syntax/tests/data/parser/err/0029_field_completion.rs new file mode 100644 index 000000000..a7cdc17bb --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0029_field_completion.rs @@ -0,0 +1,3 @@ +fn foo(a: A) { + a. +} diff --git a/crates/ra_syntax/tests/data/parser/err/0029_field_completion.txt b/crates/ra_syntax/tests/data/parser/err/0029_field_completion.txt new file mode 100644 index 000000000..fd2a3f37b --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/err/0029_field_completion.txt @@ -0,0 +1,35 @@ +SOURCE_FILE@[0; 24) + FN_DEF@[0; 23) + FN_KW@[0; 2) + WHITESPACE@[2; 3) + NAME@[3; 6) + IDENT@[3; 6) "foo" + PARAM_LIST@[6; 12) + L_PAREN@[6; 7) + PARAM@[7; 11) + BIND_PAT@[7; 8) + NAME@[7; 8) + IDENT@[7; 8) "a" + COLON@[8; 9) + WHITESPACE@[9; 10) + PATH_TYPE@[10; 11) + PATH@[10; 11) + PATH_SEGMENT@[10; 11) + NAME_REF@[10; 11) + IDENT@[10; 11) "A" + R_PAREN@[11; 12) + WHITESPACE@[12; 13) + BLOCK@[13; 23) + L_CURLY@[13; 14) + WHITESPACE@[14; 19) + FIELD_EXPR@[19; 21) + PATH_EXPR@[19; 20) + PATH@[19; 20) + PATH_SEGMENT@[19; 20) + NAME_REF@[19; 20) + IDENT@[19; 20) "a" + DOT@[20; 21) + err: `expected field name or number` + WHITESPACE@[21; 22) + R_CURLY@[22; 23) + WHITESPACE@[23; 24) -- cgit v1.2.3 From ab0b63992be0cec4999810096a53b40f63f90349 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 25 Dec 2018 15:15:40 +0100 Subject: Implement basic completion for fields --- crates/ra_syntax/src/ast/generated.rs | 4 ++++ crates/ra_syntax/src/grammar.ron | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 4e0550487..6b2800a0e 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -2030,6 +2030,10 @@ impl<'a> MethodCallExpr<'a> { pub fn expr(self) -> Option> { super::child_opt(self) } + + pub fn name_ref(self) -> Option> { + super::child_opt(self) + } } // Module diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 923da0324..dcde32923 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -403,7 +403,7 @@ Grammar( ), "MethodCallExpr": ( traits: ["ArgListOwner"], - options: [ "Expr" ], + options: [ "Expr", "NameRef" ], ), "IndexExpr": (), "FieldExpr": (options: ["Expr", "NameRef"]), -- cgit v1.2.3 From 2870effd5c69941bbf32a44c0ee6d9d42e0b038d Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 25 Dec 2018 17:17:39 +0100 Subject: Implement reference / pointer types - parse them - infer types of & and * expressions --- crates/ra_syntax/src/ast.rs | 39 +++++++++++++++++++++++++++++++++++ crates/ra_syntax/src/ast/generated.rs | 18 +++++++++++++--- crates/ra_syntax/src/grammar.ron | 6 +++--- 3 files changed, 57 insertions(+), 6 deletions(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 5dbf9b221..8fb6b6408 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -394,3 +394,42 @@ impl<'a> EnumVariant<'a> { StructFlavor::from_node(self) } } + +impl<'a> PointerType<'a> { + pub fn is_mut(&self) -> bool { + self.syntax().children().any(|n| n.kind() == MUT_KW) + } +} + +impl<'a> ReferenceType<'a> { + pub fn is_mut(&self) -> bool { + self.syntax().children().any(|n| n.kind() == MUT_KW) + } +} + +impl<'a> RefExpr<'a> { + pub fn is_mut(&self) -> bool { + self.syntax().children().any(|n| n.kind() == MUT_KW) + } +} + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum PrefixOp { + /// The `*` operator for dereferencing + Deref, + /// The `!` operator for logical inversion + Not, + /// The `-` operator for negation + Neg, +} + +impl<'a> PrefixExpr<'a> { + pub fn op(&self) -> Option { + match self.syntax().first_child()?.kind() { + STAR => Some(PrefixOp::Deref), + EXCL => Some(PrefixOp::Not), + MINUS => Some(PrefixOp::Neg), + _ => None, + } + } +} diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 6b2800a0e..535dcc975 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -2607,7 +2607,11 @@ impl> ParenTypeNode { } -impl<'a> ParenType<'a> {} +impl<'a> ParenType<'a> { + pub fn type_ref(self) -> Option> { + super::child_opt(self) + } +} // Pat #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -2972,7 +2976,11 @@ impl> PointerTypeNode { } -impl<'a> PointerType<'a> {} +impl<'a> PointerType<'a> { + pub fn type_ref(self) -> Option> { + super::child_opt(self) + } +} // PosField #[derive(Debug, Clone, Copy,)] @@ -3285,7 +3293,11 @@ impl> ReferenceTypeNode { } -impl<'a> ReferenceType<'a> {} +impl<'a> ReferenceType<'a> { + pub fn type_ref(self) -> Option> { + super::child_opt(self) + } +} // RetType #[derive(Debug, Clone, Copy,)] diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index dcde32923..8b1bd6d1c 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -303,14 +303,14 @@ Grammar( ] ), "ImplItem": (), - "ParenType": (), + "ParenType": (options: ["TypeRef"]), "TupleType": (), "NeverType": (), "PathType": (options: ["Path"]), - "PointerType": (), + "PointerType": (options: ["TypeRef"]), "ArrayType": (), "SliceType": (), - "ReferenceType": (), + "ReferenceType": (options: ["TypeRef"]), "PlaceholderType": (), "FnPointerType": (), "ForType": (), -- cgit v1.2.3 From cdca39706121b2d1734a94938a2372da881e10c6 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 25 Dec 2018 21:14:13 +0100 Subject: Add a hir::TypeRef as an intermediate between ast::TypeRef and ty::Ty --- crates/ra_syntax/src/ast/generated.rs | 38 ++++++++++++++++++++++++++++++----- crates/ra_syntax/src/grammar.ron | 10 ++++----- 2 files changed, 38 insertions(+), 10 deletions(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 535dcc975..c22e026cf 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -131,7 +131,15 @@ impl> ArrayTypeNode { } -impl<'a> ArrayType<'a> {} +impl<'a> ArrayType<'a> { + pub fn type_ref(self) -> Option> { + super::child_opt(self) + } + + pub fn expr(self) -> Option> { + super::child_opt(self) + } +} // Attr #[derive(Debug, Clone, Copy,)] @@ -1258,7 +1266,15 @@ impl> FnPointerTypeNode { } -impl<'a> FnPointerType<'a> {} +impl<'a> FnPointerType<'a> { + pub fn param_list(self) -> Option> { + super::child_opt(self) + } + + pub fn ret_type(self) -> Option> { + super::child_opt(self) + } +} // ForExpr #[derive(Debug, Clone, Copy,)] @@ -1341,7 +1357,11 @@ impl> ForTypeNode { } -impl<'a> ForType<'a> {} +impl<'a> ForType<'a> { + pub fn type_ref(self) -> Option> { + super::child_opt(self) + } +} // IfExpr #[derive(Debug, Clone, Copy,)] @@ -3490,7 +3510,11 @@ impl> SliceTypeNode { } -impl<'a> SliceType<'a> {} +impl<'a> SliceType<'a> { + pub fn type_ref(self) -> Option> { + super::child_opt(self) + } +} // SourceFile #[derive(Debug, Clone, Copy,)] @@ -4025,7 +4049,11 @@ impl> TupleTypeNode { } -impl<'a> TupleType<'a> {} +impl<'a> TupleType<'a> { + pub fn fields(self) -> impl Iterator> + 'a { + super::children(self) + } +} // TypeDef #[derive(Debug, Clone, Copy,)] diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 8b1bd6d1c..4bcff4e14 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -304,16 +304,16 @@ Grammar( "ImplItem": (), "ParenType": (options: ["TypeRef"]), - "TupleType": (), + "TupleType": ( collections: [["fields", "TypeRef"]] ), "NeverType": (), "PathType": (options: ["Path"]), "PointerType": (options: ["TypeRef"]), - "ArrayType": (), - "SliceType": (), + "ArrayType": ( options: ["TypeRef", "Expr"] ), + "SliceType": ( options: ["TypeRef"] ), "ReferenceType": (options: ["TypeRef"]), "PlaceholderType": (), - "FnPointerType": (), - "ForType": (), + "FnPointerType": (options: ["ParamList", "RetType"]), + "ForType": (options: ["TypeRef"]), "ImplTraitType": (), "DynTraitType": (), -- cgit v1.2.3