]> git.lizzy.rs Git - rust.git/commitdiff
Add AST definitions for struct/variant fields etc.
authorFlorian Diebold <flodiebold@gmail.com>
Tue, 25 Dec 2018 12:01:47 +0000 (13:01 +0100)
committerFlorian Diebold <flodiebold@gmail.com>
Tue, 25 Dec 2018 14:16:42 +0000 (15:16 +0100)
Fixes #117

crates/ra_syntax/src/ast.rs
crates/ra_syntax/src/ast/generated.rs
crates/ra_syntax/src/grammar.ron

index f12479fb46e19658d96ad6984e1df2fae0dbc574..5dbf9b221aad80fa7ba270494291128b7903fc76 100644 (file)
@@ -363,3 +363,34 @@ fn next(&mut self) -> Option<N> {
         }
     }
 }
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum StructFlavor<'a> {
+    Tuple(PosFieldList<'a>),
+    Named(NamedFieldDefList<'a>),
+    Unit,
+}
+
+impl<'a> StructFlavor<'a> {
+    fn from_node<N: AstNode<'a>>(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)
+    }
+}
index 334da67ef038dcc34d3188be2b31eda648fe8914..35a9770a6f9420a853b27ceff41522f12a1a84e4 100644 (file)
@@ -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<EnumVariantList<'a>> {
+        super::child_opt(self)
+    }
+}
+
+// EnumVariant
+#[derive(Debug, Clone, Copy,)]
+pub struct EnumVariantNode<R: TreeRoot<RaTypes> = OwnedRoot> {
+    pub(crate) syntax: SyntaxNode<R>,
+}
+pub type EnumVariant<'a> = EnumVariantNode<RefRoot<'a>>;
+
+impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<EnumVariantNode<R1>> for EnumVariantNode<R2> {
+    fn eq(&self, other: &EnumVariantNode<R1>) -> bool { self.syntax == other.syntax }
+}
+impl<R: TreeRoot<RaTypes>> Eq for EnumVariantNode<R> {}
+impl<R: TreeRoot<RaTypes>> Hash for EnumVariantNode<R> {
+    fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
+}
+
+impl<'a> AstNode<'a> for EnumVariant<'a> {
+    fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
+        match syntax.kind() {
+            ENUM_VARIANT => Some(EnumVariant { syntax }),
+            _ => None,
+        }
+    }
+    fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
+}
+
+impl<R: TreeRoot<RaTypes>> EnumVariantNode<R> {
+    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<Expr<'a>> {
+        super::child_opt(self)
+    }
+}
+
+// EnumVariantList
+#[derive(Debug, Clone, Copy,)]
+pub struct EnumVariantListNode<R: TreeRoot<RaTypes> = OwnedRoot> {
+    pub(crate) syntax: SyntaxNode<R>,
+}
+pub type EnumVariantList<'a> = EnumVariantListNode<RefRoot<'a>>;
+
+impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<EnumVariantListNode<R1>> for EnumVariantListNode<R2> {
+    fn eq(&self, other: &EnumVariantListNode<R1>) -> bool { self.syntax == other.syntax }
+}
+impl<R: TreeRoot<RaTypes>> Eq for EnumVariantListNode<R> {}
+impl<R: TreeRoot<RaTypes>> Hash for EnumVariantListNode<R> {
+    fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
+}
+
+impl<'a> AstNode<'a> for EnumVariantList<'a> {
+    fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
+        match syntax.kind() {
+            ENUM_VARIANT_LIST => Some(EnumVariantList { syntax }),
+            _ => None,
+        }
+    }
+    fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
+}
+
+impl<R: TreeRoot<RaTypes>> EnumVariantListNode<R> {
+    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<Item = EnumVariant<'a>> + 'a {
+        super::children(self)
+    }
+}
 
 // Expr
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@@ -2189,7 +2276,52 @@ pub fn owned(&self) -> 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<TypeRef<'a>> {
+        super::child_opt(self)
+    }
+}
+
+// NamedFieldDefList
+#[derive(Debug, Clone, Copy,)]
+pub struct NamedFieldDefListNode<R: TreeRoot<RaTypes> = OwnedRoot> {
+    pub(crate) syntax: SyntaxNode<R>,
+}
+pub type NamedFieldDefList<'a> = NamedFieldDefListNode<RefRoot<'a>>;
+
+impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<NamedFieldDefListNode<R1>> for NamedFieldDefListNode<R2> {
+    fn eq(&self, other: &NamedFieldDefListNode<R1>) -> bool { self.syntax == other.syntax }
+}
+impl<R: TreeRoot<RaTypes>> Eq for NamedFieldDefListNode<R> {}
+impl<R: TreeRoot<RaTypes>> Hash for NamedFieldDefListNode<R> {
+    fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
+}
+
+impl<'a> AstNode<'a> for NamedFieldDefList<'a> {
+    fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
+        match syntax.kind() {
+            NAMED_FIELD_DEF_LIST => Some(NamedFieldDefList { syntax }),
+            _ => None,
+        }
+    }
+    fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
+}
+
+impl<R: TreeRoot<RaTypes>> NamedFieldDefListNode<R> {
+    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<Item = NamedFieldDef<'a>> + 'a {
+        super::children(self)
+    }
+}
 
 // NamedFieldList
 #[derive(Debug, Clone, Copy,)]
@@ -2830,6 +2962,89 @@ pub fn owned(&self) -> PointerTypeNode {
 
 impl<'a> PointerType<'a> {}
 
+// PosField
+#[derive(Debug, Clone, Copy,)]
+pub struct PosFieldNode<R: TreeRoot<RaTypes> = OwnedRoot> {
+    pub(crate) syntax: SyntaxNode<R>,
+}
+pub type PosField<'a> = PosFieldNode<RefRoot<'a>>;
+
+impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<PosFieldNode<R1>> for PosFieldNode<R2> {
+    fn eq(&self, other: &PosFieldNode<R1>) -> bool { self.syntax == other.syntax }
+}
+impl<R: TreeRoot<RaTypes>> Eq for PosFieldNode<R> {}
+impl<R: TreeRoot<RaTypes>> Hash for PosFieldNode<R> {
+    fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
+}
+
+impl<'a> AstNode<'a> for PosField<'a> {
+    fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
+        match syntax.kind() {
+            POS_FIELD => Some(PosField { syntax }),
+            _ => None,
+        }
+    }
+    fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
+}
+
+impl<R: TreeRoot<RaTypes>> PosFieldNode<R> {
+    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<TypeRef<'a>> {
+        super::child_opt(self)
+    }
+}
+
+// PosFieldList
+#[derive(Debug, Clone, Copy,)]
+pub struct PosFieldListNode<R: TreeRoot<RaTypes> = OwnedRoot> {
+    pub(crate) syntax: SyntaxNode<R>,
+}
+pub type PosFieldList<'a> = PosFieldListNode<RefRoot<'a>>;
+
+impl<R1: TreeRoot<RaTypes>, R2: TreeRoot<RaTypes>> PartialEq<PosFieldListNode<R1>> for PosFieldListNode<R2> {
+    fn eq(&self, other: &PosFieldListNode<R1>) -> bool { self.syntax == other.syntax }
+}
+impl<R: TreeRoot<RaTypes>> Eq for PosFieldListNode<R> {}
+impl<R: TreeRoot<RaTypes>> Hash for PosFieldListNode<R> {
+    fn hash<H: Hasher>(&self, state: &mut H) { self.syntax.hash(state) }
+}
+
+impl<'a> AstNode<'a> for PosFieldList<'a> {
+    fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
+        match syntax.kind() {
+            POS_FIELD_LIST => Some(PosFieldList { syntax }),
+            _ => None,
+        }
+    }
+    fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
+}
+
+impl<R: TreeRoot<RaTypes>> PosFieldListNode<R> {
+    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<Item = PosField<'a>> + 'a {
+        super::children(self)
+    }
+}
+
 // PrefixExpr
 #[derive(Debug, Clone, Copy,)]
 pub struct PrefixExprNode<R: TreeRoot<RaTypes> = 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<Item = NamedFieldDef<'a>> + 'a {
-        super::children(self)
-    }
-}
+impl<'a> StructDef<'a> {}
 
 // StructLit
 #[derive(Debug, Clone, Copy,)]
index 0da8b8183d98f514046dc508c16dd440974e5b9c..e4e41d0776e208d61fc4e87d5aeaf516f52fd70e 100644 (file)
@@ -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" ],