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') 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