From 8e3bec11ebd1fce78701670cf9189b5a9d0d68f8 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Wed, 22 Aug 2018 16:46:42 +0300
Subject: TypeParamList Owner

---
 crates/libsyntax2/src/ast/generated.rs             | 35 ++++++++++++---
 crates/libsyntax2/src/ast/mod.rs                   | 16 +++++++
 crates/libsyntax2/src/grammar.ron                  | 50 ++++++++++++++++------
 .../tests/data/parser/ok/0001_struct_item.rs       |  6 +--
 .../tests/data/parser/ok/0001_struct_item.txt      | 37 +++++++++++++---
 5 files changed, 118 insertions(+), 26 deletions(-)

(limited to 'crates/libsyntax2')

diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs
index 0651da26d..d0e07fddc 100644
--- a/crates/libsyntax2/src/ast/generated.rs
+++ b/crates/libsyntax2/src/ast/generated.rs
@@ -64,6 +64,7 @@ impl<'a> AstNode<'a> for ConstDef<'a> {
 }
 
 impl<'a> ast::NameOwner<'a> for ConstDef<'a> {}
+impl<'a> ast::TypeParamsOwner<'a> for ConstDef<'a> {}
 impl<'a> ast::AttrsOwner<'a> for ConstDef<'a> {}
 impl<'a> ConstDef<'a> {}
 
@@ -102,6 +103,7 @@ impl<'a> AstNode<'a> for EnumDef<'a> {
 }
 
 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> EnumDef<'a> {}
 
@@ -152,6 +154,7 @@ impl<'a> AstNode<'a> for FnDef<'a> {
 }
 
 impl<'a> ast::NameOwner<'a> for FnDef<'a> {}
+impl<'a> ast::TypeParamsOwner<'a> for FnDef<'a> {}
 impl<'a> ast::AttrsOwner<'a> for FnDef<'a> {}
 impl<'a> FnDef<'a> {}
 
@@ -351,6 +354,7 @@ impl<'a> AstNode<'a> for NominalDef<'a> {
 }
 
 impl<'a> ast::AttrsOwner<'a> for NominalDef<'a> {}
+impl<'a> ast::TypeParamsOwner<'a> for NominalDef<'a> {}
 impl<'a> NominalDef<'a> {}
 
 // ParenType
@@ -478,6 +482,7 @@ impl<'a> AstNode<'a> for StaticDef<'a> {
 }
 
 impl<'a> ast::NameOwner<'a> for StaticDef<'a> {}
+impl<'a> ast::TypeParamsOwner<'a> for StaticDef<'a> {}
 impl<'a> ast::AttrsOwner<'a> for StaticDef<'a> {}
 impl<'a> StaticDef<'a> {}
 
@@ -498,6 +503,7 @@ impl<'a> AstNode<'a> for StructDef<'a> {
 }
 
 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> StructDef<'a> {
     pub fn fields(self) -> impl Iterator<Item = NamedField<'a>> + 'a {
@@ -580,9 +586,28 @@ impl<'a> AstNode<'a> for TypeDef<'a> {
 }
 
 impl<'a> ast::NameOwner<'a> for TypeDef<'a> {}
+impl<'a> ast::TypeParamsOwner<'a> for TypeDef<'a> {}
 impl<'a> ast::AttrsOwner<'a> for TypeDef<'a> {}
 impl<'a> TypeDef<'a> {}
 
+// TypeParamList
+#[derive(Debug, Clone, Copy)]
+pub struct TypeParamList<'a> {
+    syntax: SyntaxNodeRef<'a>,
+}
+
+impl<'a> AstNode<'a> for TypeParamList<'a> {
+    fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
+        match syntax.kind() {
+            TYPE_PARAM_LIST => Some(TypeParamList { syntax }),
+            _ => None,
+        }
+    }
+    fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
+}
+
+impl<'a> TypeParamList<'a> {}
+
 // TypeRef
 #[derive(Debug, Clone, Copy)]
 pub enum TypeRef<'a> {
@@ -641,21 +666,21 @@ impl<'a> AstNode<'a> for TypeRef<'a> {
 
 impl<'a> TypeRef<'a> {}
 
-// Whitespace
+// WhereClause
 #[derive(Debug, Clone, Copy)]
-pub struct Whitespace<'a> {
+pub struct WhereClause<'a> {
     syntax: SyntaxNodeRef<'a>,
 }
 
-impl<'a> AstNode<'a> for Whitespace<'a> {
+impl<'a> AstNode<'a> for WhereClause<'a> {
     fn cast(syntax: SyntaxNodeRef<'a>) -> Option<Self> {
         match syntax.kind() {
-            WHITESPACE => Some(Whitespace { syntax }),
+            WHERE_CLAUSE => Some(WhereClause { syntax }),
             _ => None,
         }
     }
     fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax }
 }
 
-impl<'a> Whitespace<'a> {}
+impl<'a> WhereClause<'a> {}
 
diff --git a/crates/libsyntax2/src/ast/mod.rs b/crates/libsyntax2/src/ast/mod.rs
index 5b9a07db4..1784b871e 100644
--- a/crates/libsyntax2/src/ast/mod.rs
+++ b/crates/libsyntax2/src/ast/mod.rs
@@ -24,6 +24,22 @@ pub trait NameOwner<'a>: AstNode<'a> {
     }
 }
 
+pub trait TypeParamsOwner<'a>: AstNode<'a> {
+    fn type_param_list(self) -> Option<TypeParamList<'a>> {
+        self.syntax()
+            .children()
+            .filter_map(TypeParamList::cast)
+            .next()
+    }
+
+    fn where_clause(self) -> Option<WhereClause<'a>> {
+        self.syntax()
+            .children()
+            .filter_map(WhereClause::cast)
+            .next()
+    }
+}
+
 pub trait AttrsOwner<'a>: AstNode<'a> {
     fn attrs(&self) -> Box<Iterator<Item=Attr<'a>> + 'a> {
         let it = self.syntax().children()
diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron
index 8e644d3c4..83b56c349 100644
--- a/crates/libsyntax2/src/grammar.ron
+++ b/crates/libsyntax2/src/grammar.ron
@@ -222,15 +222,27 @@ Grammar(
                 ["modules", "Module"],
             ]
         ),
-        "FnDef": ( traits: ["NameOwner", "AttrsOwner"] ),
+        "FnDef": ( traits: [
+            "NameOwner",
+            "TypeParamsOwner",
+            "AttrsOwner",
+        ] ),
         "StructDef": (
-            traits: ["NameOwner", "AttrsOwner"],
+            traits: [
+                "NameOwner",
+                "TypeParamsOwner",
+                "AttrsOwner",
+            ],
             collections: [
                 ["fields", "NamedField"]
             ]
         ),
         "NamedField": ( traits: ["NameOwner", "AttrsOwner"] ),
-        "EnumDef": ( traits: ["NameOwner", "AttrsOwner"] ),
+        "EnumDef": ( traits: [
+            "NameOwner",
+            "TypeParamsOwner",
+            "AttrsOwner",
+        ] ),
         "TraitDef": ( traits: ["NameOwner", "AttrsOwner"] ),
         "Module": (
             traits: ["NameOwner", "AttrsOwner"],
@@ -238,16 +250,23 @@ Grammar(
                 ["modules", "Module"]
             ]
         ),
-        "ConstDef": ( traits: ["NameOwner", "AttrsOwner"] ),
-        "StaticDef": ( traits: ["NameOwner", "AttrsOwner"] ),
-        "TypeDef": ( traits: ["NameOwner", "AttrsOwner"] ),
+        "ConstDef": ( traits: [
+            "NameOwner",
+            "TypeParamsOwner",
+            "AttrsOwner",
+        ] ),
+        "StaticDef": ( traits: [
+            "NameOwner",
+            "TypeParamsOwner",
+            "AttrsOwner",
+        ] ),
+        "TypeDef": ( traits: [
+            "NameOwner",
+            "TypeParamsOwner",
+            "AttrsOwner",
+        ] ),
         "ImplItem": (),
 
-        "Name": (),
-        "NameRef": (),
-        "Attr": ( options: [ ["value", "TokenTree"] ] ),
-        "TokenTree": (),
-
         "ParenType": (),
         "TupleType": (),
         "NeverType": (),
@@ -280,7 +299,14 @@ Grammar(
 
         "NominalDef": (
             enum: ["StructDef", "EnumDef"],
-            traits: [ "AttrsOwner" ],
+            traits: [ "AttrsOwner", "TypeParamsOwner" ],
         ),
+
+        "Name": (),
+        "NameRef": (),
+        "Attr": ( options: [ ["value", "TokenTree"] ] ),
+        "TokenTree": (),
+        "TypeParamList": (),
+        "WhereClause": (),
     },
 )
diff --git a/crates/libsyntax2/tests/data/parser/ok/0001_struct_item.rs b/crates/libsyntax2/tests/data/parser/ok/0001_struct_item.rs
index d3a8c1d23..512aeb3e7 100644
--- a/crates/libsyntax2/tests/data/parser/ok/0001_struct_item.rs
+++ b/crates/libsyntax2/tests/data/parser/ok/0001_struct_item.rs
@@ -1,3 +1,3 @@
-struct S {
-
-}
\ No newline at end of file
+struct S<T: Copy> {
+    f: T,
+}
diff --git a/crates/libsyntax2/tests/data/parser/ok/0001_struct_item.txt b/crates/libsyntax2/tests/data/parser/ok/0001_struct_item.txt
index 798c8fd37..cfe128971 100644
--- a/crates/libsyntax2/tests/data/parser/ok/0001_struct_item.txt
+++ b/crates/libsyntax2/tests/data/parser/ok/0001_struct_item.txt
@@ -1,10 +1,35 @@
-FILE@[0; 13)
-  STRUCT_DEF@[0; 13)
+FILE@[0; 32)
+  STRUCT_DEF@[0; 31)
     STRUCT_KW@[0; 6)
     WHITESPACE@[6; 7)
     NAME@[7; 8)
       IDENT@[7; 8) "S"
-    WHITESPACE@[8; 9)
-    L_CURLY@[9; 10)
-    WHITESPACE@[10; 12)
-    R_CURLY@[12; 13)
+    TYPE_PARAM_LIST@[8; 17)
+      L_ANGLE@[8; 9)
+      TYPE_PARAM@[9; 16)
+        NAME@[9; 10)
+          IDENT@[9; 10) "T"
+        COLON@[10; 11)
+        WHITESPACE@[11; 12)
+        PATH@[12; 16)
+          PATH_SEGMENT@[12; 16)
+            NAME_REF@[12; 16)
+              IDENT@[12; 16) "Copy"
+      R_ANGLE@[16; 17)
+    WHITESPACE@[17; 18)
+    L_CURLY@[18; 19)
+    WHITESPACE@[19; 24)
+    NAMED_FIELD@[24; 28)
+      NAME@[24; 25)
+        IDENT@[24; 25) "f"
+      COLON@[25; 26)
+      WHITESPACE@[26; 27)
+      PATH_TYPE@[27; 28)
+        PATH@[27; 28)
+          PATH_SEGMENT@[27; 28)
+            NAME_REF@[27; 28)
+              IDENT@[27; 28) "T"
+    COMMA@[28; 29)
+    WHITESPACE@[29; 30)
+    R_CURLY@[30; 31)
+  WHITESPACE@[31; 32)
-- 
cgit v1.2.3