From 4560fe2abffde05e6ceb084e6d42207e0ce84b68 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Fri, 10 Apr 2020 15:53:09 +0200
Subject: [PATCH] Generate only minimal set of ineresting tokens

---
 crates/ra_syntax/src/ast.rs                  |    6 +-
 crates/ra_syntax/src/ast/edit.rs             |    6 +-
 crates/ra_syntax/src/ast/extensions.rs       |   16 +-
 crates/ra_syntax/src/ast/generated/tokens.rs | 1296 +-----------------
 crates/ra_syntax/src/ast/traits.rs           |    5 +-
 xtask/src/ast_src.rs                         |    2 +
 xtask/src/codegen.rs                         |    1 +
 xtask/src/codegen/gen_syntax.rs              |   35 +
 8 files changed, 61 insertions(+), 1306 deletions(-)

diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs
index 1ee60e74ce7..1437a38c968 100644
--- a/crates/ra_syntax/src/ast.rs
+++ b/crates/ra_syntax/src/ast.rs
@@ -80,7 +80,7 @@ impl<N: AstNode> Iterator for AstChildren<N> {
 }
 
 mod support {
-    use super::{AstChildren, AstNode, AstToken, SyntaxKind, SyntaxNode, SyntaxToken};
+    use super::{AstChildren, AstNode, SyntaxKind, SyntaxNode, SyntaxToken};
 
     pub(super) fn child<N: AstNode>(parent: &SyntaxNode) -> Option<N> {
         parent.children().find_map(N::cast)
@@ -90,10 +90,6 @@ mod support {
         AstChildren::new(parent)
     }
 
-    pub(super) fn token<T: AstToken>(parent: &SyntaxNode) -> Option<T> {
-        parent.children_with_tokens().filter_map(|it| it.into_token()).find_map(T::cast)
-    }
-
     pub(super) fn token2(parent: &SyntaxNode, kind: SyntaxKind) -> Option<SyntaxToken> {
         parent.children_with_tokens().filter_map(|it| it.into_token()).find(|it| it.kind() == kind)
     }
diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs
index 7e14349d2b4..9e5411ee58a 100644
--- a/crates/ra_syntax/src/ast/edit.rs
+++ b/crates/ra_syntax/src/ast/edit.rs
@@ -189,15 +189,15 @@ impl ast::RecordFieldList {
 impl ast::TypeParam {
     #[must_use]
     pub fn remove_bounds(&self) -> ast::TypeParam {
-        let colon = match self.colon() {
+        let colon = match self.colon_token() {
             Some(it) => it,
             None => return self.clone(),
         };
         let end = match self.type_bound_list() {
             Some(it) => it.syntax().clone().into(),
-            None => colon.syntax().clone().into(),
+            None => colon.clone().into(),
         };
-        self.replace_children(colon.syntax().clone().into()..=end, iter::empty())
+        self.replace_children(colon.into()..=end, iter::empty())
     }
 }
 
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs
index 03d94170dab..d91275b531f 100644
--- a/crates/ra_syntax/src/ast/extensions.rs
+++ b/crates/ra_syntax/src/ast/extensions.rs
@@ -5,7 +5,7 @@ use itertools::Itertools;
 use ra_parser::SyntaxKind;
 
 use crate::{
-    ast::{self, support, AstNode, AstToken, AttrInput, NameOwner, SyntaxNode},
+    ast::{self, support, AstNode, AttrInput, NameOwner, SyntaxNode},
     SmolStr, SyntaxElement, SyntaxToken, T,
 };
 
@@ -327,23 +327,23 @@ impl ast::TypeBound {
         }
     }
 
-    pub fn const_question_token(&self) -> Option<ast::Question> {
+    pub fn const_question_token(&self) -> Option<SyntaxToken> {
         self.syntax()
             .children_with_tokens()
             .filter_map(|it| it.into_token())
             .take_while(|it| it.kind() != T![const])
-            .find_map(ast::Question::cast)
+            .find(|it| it.kind() == T![?])
     }
 
-    pub fn question_token(&self) -> Option<ast::Question> {
+    pub fn question_token(&self) -> Option<SyntaxToken> {
         if self.const_token().is_some() {
             self.syntax()
                 .children_with_tokens()
                 .filter_map(|it| it.into_token())
                 .skip_while(|it| it.kind() != T![const])
-                .find_map(ast::Question::cast)
+                .find(|it| it.kind() == T![?])
         } else {
-            support::token(&self.syntax)
+            support::token2(&self.syntax, T![?])
         }
     }
 }
@@ -384,12 +384,12 @@ impl ast::MacroCall {
 }
 
 impl ast::LifetimeParam {
-    pub fn lifetime_bounds(&self) -> impl Iterator<Item = ast::Lifetime> {
+    pub fn lifetime_bounds(&self) -> impl Iterator<Item = SyntaxToken> {
         self.syntax()
             .children_with_tokens()
             .filter_map(|it| it.into_token())
             .skip_while(|x| x.kind() != T![:])
-            .filter_map(ast::Lifetime::cast)
+            .filter(|it| it.kind() == T![lifetime])
     }
 }
 
diff --git a/crates/ra_syntax/src/ast/generated/tokens.rs b/crates/ra_syntax/src/ast/generated/tokens.rs
index 293f91c2e9e..3950e2b7f36 100644
--- a/crates/ra_syntax/src/ast/generated/tokens.rs
+++ b/crates/ra_syntax/src/ast/generated/tokens.rs
@@ -6,16 +6,16 @@ use crate::{
     SyntaxToken,
 };
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Semi {
+pub struct Whitespace {
     pub(crate) syntax: SyntaxToken,
 }
-impl std::fmt::Display for Semi {
+impl std::fmt::Display for Whitespace {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
         std::fmt::Display::fmt(&self.syntax, f)
     }
 }
-impl AstToken for Semi {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == SEMI }
+impl AstToken for Whitespace {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == WHITESPACE }
     fn cast(syntax: SyntaxToken) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -26,1096 +26,16 @@ impl AstToken for Semi {
     fn syntax(&self) -> &SyntaxToken { &self.syntax }
 }
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Comma {
+pub struct Comment {
     pub(crate) syntax: SyntaxToken,
 }
-impl std::fmt::Display for Comma {
+impl std::fmt::Display for Comment {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
         std::fmt::Display::fmt(&self.syntax, f)
     }
 }
-impl AstToken for Comma {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == COMMA }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct LParen {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for LParen {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for LParen {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == L_PAREN }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RParen {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for RParen {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for RParen {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == R_PAREN }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct LCurly {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for LCurly {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for LCurly {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == L_CURLY }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RCurly {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for RCurly {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for RCurly {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == R_CURLY }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct LBrack {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for LBrack {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for LBrack {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == L_BRACK }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RBrack {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for RBrack {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for RBrack {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == R_BRACK }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct LAngle {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for LAngle {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for LAngle {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == L_ANGLE }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RAngle {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for RAngle {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for RAngle {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == R_ANGLE }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct At {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for At {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for At {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == AT }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Pound {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Pound {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Pound {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == POUND }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Tilde {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Tilde {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Tilde {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == TILDE }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Question {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Question {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Question {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == QUESTION }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Dollar {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Dollar {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Dollar {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == DOLLAR }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Amp {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Amp {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Amp {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == AMP }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Pipe {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Pipe {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Pipe {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == PIPE }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Plus {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Plus {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Plus {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == PLUS }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Star {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Star {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Star {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == STAR }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Slash {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Slash {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Slash {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == SLASH }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Caret {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Caret {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Caret {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == CARET }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Percent {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Percent {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Percent {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == PERCENT }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Underscore {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Underscore {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Underscore {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == UNDERSCORE }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Dot {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Dot {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Dot {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == DOT }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Dotdot {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Dotdot {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Dotdot {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == DOTDOT }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Dotdotdot {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Dotdotdot {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Dotdotdot {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == DOTDOTDOT }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Dotdoteq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Dotdoteq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Dotdoteq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == DOTDOTEQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Colon {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Colon {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Colon {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == COLON }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Coloncolon {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Coloncolon {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Coloncolon {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == COLONCOLON }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Eq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Eq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Eq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == EQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Eqeq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Eqeq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Eqeq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == EQEQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct FatArrow {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for FatArrow {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for FatArrow {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == FAT_ARROW }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Excl {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Excl {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Excl {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == EXCL }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Neq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Neq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Neq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == NEQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Minus {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Minus {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Minus {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == MINUS }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ThinArrow {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for ThinArrow {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for ThinArrow {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == THIN_ARROW }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Lteq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Lteq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Lteq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == LTEQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Gteq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Gteq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Gteq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == GTEQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Pluseq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Pluseq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Pluseq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == PLUSEQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Minuseq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Minuseq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Minuseq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == MINUSEQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Pipeeq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Pipeeq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Pipeeq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == PIPEEQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Ampeq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Ampeq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Ampeq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == AMPEQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Careteq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Careteq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Careteq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == CARETEQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Slasheq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Slasheq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Slasheq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == SLASHEQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Stareq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Stareq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Stareq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == STAREQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Percenteq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Percenteq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Percenteq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == PERCENTEQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Ampamp {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Ampamp {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Ampamp {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == AMPAMP }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Pipepipe {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Pipepipe {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Pipepipe {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == PIPEPIPE }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Shl {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Shl {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Shl {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == SHL }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Shr {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Shr {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Shr {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == SHR }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Shleq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Shleq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Shleq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == SHLEQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Shreq {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Shreq {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Shreq {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == SHREQ }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct IntNumber {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for IntNumber {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for IntNumber {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == INT_NUMBER }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct FloatNumber {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for FloatNumber {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for FloatNumber {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == FLOAT_NUMBER }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Char {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Char {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Char {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == CHAR }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Byte {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Byte {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Byte {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == BYTE }
+impl AstToken for Comment {
+    fn can_cast(kind: SyntaxKind) -> bool { kind == COMMENT }
     fn cast(syntax: SyntaxToken) -> Option<Self> {
         if Self::can_cast(syntax.kind()) {
             Some(Self { syntax })
@@ -1165,203 +85,3 @@ impl AstToken for RawString {
     }
     fn syntax(&self) -> &SyntaxToken { &self.syntax }
 }
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct ByteString {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for ByteString {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for ByteString {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == BYTE_STRING }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RawByteString {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for RawByteString {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for RawByteString {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == RAW_BYTE_STRING }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Error {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Error {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Error {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == ERROR }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Ident {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Ident {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Ident {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == IDENT }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Whitespace {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Whitespace {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Whitespace {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == WHITESPACE }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Lifetime {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Lifetime {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Lifetime {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == LIFETIME }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Comment {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Comment {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Comment {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == COMMENT }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct Shebang {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for Shebang {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for Shebang {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == SHEBANG }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct LDollar {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for LDollar {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for LDollar {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == L_DOLLAR }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
-pub struct RDollar {
-    pub(crate) syntax: SyntaxToken,
-}
-impl std::fmt::Display for RDollar {
-    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
-        std::fmt::Display::fmt(&self.syntax, f)
-    }
-}
-impl AstToken for RDollar {
-    fn can_cast(kind: SyntaxKind) -> bool { kind == R_DOLLAR }
-    fn cast(syntax: SyntaxToken) -> Option<Self> {
-        if Self::can_cast(syntax.kind()) {
-            Some(Self { syntax })
-        } else {
-            None
-        }
-    }
-    fn syntax(&self) -> &SyntaxToken { &self.syntax }
-}
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs
index 4ed7cf73b6b..4d1a290c285 100644
--- a/crates/ra_syntax/src/ast/traits.rs
+++ b/crates/ra_syntax/src/ast/traits.rs
@@ -6,6 +6,7 @@ use stdx::SepBy;
 use crate::{
     ast::{self, support, AstChildren, AstNode, AstToken},
     syntax_node::SyntaxElementChildren,
+    SyntaxToken, T,
 };
 
 pub trait TypeAscriptionOwner: AstNode {
@@ -63,8 +64,8 @@ pub trait TypeBoundsOwner: AstNode {
         support::child(self.syntax())
     }
 
-    fn colon(&self) -> Option<ast::Colon> {
-        support::token(self.syntax())
+    fn colon_token(&self) -> Option<SyntaxToken> {
+        support::token2(self.syntax(), T![:])
     }
 }
 
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs
index 554afc76aa7..7a20d9991b8 100644
--- a/xtask/src/ast_src.rs
+++ b/xtask/src/ast_src.rs
@@ -225,6 +225,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc {
 };
 
 pub(crate) struct AstSrc<'a> {
+    pub(crate) tokens: &'a [&'a str],
     pub(crate) nodes: &'a [AstNodeSrc<'a>],
     pub(crate) enums: &'a [AstEnumSrc<'a>],
 }
@@ -303,6 +304,7 @@ macro_rules! ast_enums {
 }
 
 pub(crate) const AST_SRC: AstSrc = AstSrc {
+    tokens: &["Whitespace", "Comment", "String", "RawString"],
     nodes: &ast_nodes! {
         struct SourceFile: ModuleItemOwner, AttrsOwner {
             modules: [Module],
diff --git a/xtask/src/codegen.rs b/xtask/src/codegen.rs
index e6ba2009c1f..678b40133b0 100644
--- a/xtask/src/codegen.rs
+++ b/xtask/src/codegen.rs
@@ -24,6 +24,7 @@ const ERR_INLINE_TESTS_DIR: &str = "crates/ra_syntax/test_data/parser/inline/err
 
 const SYNTAX_KINDS: &str = "crates/ra_parser/src/syntax_kind/generated.rs";
 const AST_NODES: &str = "crates/ra_syntax/src/ast/generated/nodes.rs";
+const AST_TOKENS: &str = "crates/ra_syntax/src/ast/generated/tokens.rs";
 
 const ASSISTS_DIR: &str = "crates/ra_assists/src/handlers";
 const ASSISTS_TESTS: &str = "crates/ra_assists/src/doc_tests/generated.rs";
diff --git a/xtask/src/codegen/gen_syntax.rs b/xtask/src/codegen/gen_syntax.rs
index ce18f2b8f94..fa48853d20b 100644
--- a/xtask/src/codegen/gen_syntax.rs
+++ b/xtask/src/codegen/gen_syntax.rs
@@ -19,6 +19,10 @@ pub fn generate_syntax(mode: Mode) -> Result<()> {
     let syntax_kinds = generate_syntax_kinds(KINDS_SRC)?;
     update(syntax_kinds_file.as_path(), &syntax_kinds, mode)?;
 
+    let ast_tokens_file = project_root().join(codegen::AST_TOKENS);
+    let contents = generate_tokens(KINDS_SRC, AST_SRC)?;
+    update(ast_tokens_file.as_path(), &contents, mode)?;
+
     let ast_nodes_file = project_root().join(codegen::AST_NODES);
     let contents = generate_nodes(KINDS_SRC, AST_SRC)?;
     update(ast_nodes_file.as_path(), &contents, mode)?;
@@ -33,6 +37,37 @@ struct ElementKinds {
     has_tokens: bool,
 }
 
+fn generate_tokens(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
+    let tokens = grammar.tokens.iter().map(|token| {
+        let name = format_ident!("{}", token);
+        let kind = format_ident!("{}", to_upper_snake_case(token));
+        quote! {
+            #[derive(Debug, Clone, PartialEq, Eq, Hash)]
+            pub struct #name {
+                pub(crate) syntax: SyntaxToken,
+            }
+            impl std::fmt::Display for #name {
+                fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+                    std::fmt::Display::fmt(&self.syntax, f)
+                }
+            }
+            impl AstToken for #name {
+                fn can_cast(kind: SyntaxKind) -> bool { kind == #kind }
+                fn cast(syntax: SyntaxToken) -> Option<Self> {
+                    if Self::can_cast(syntax.kind()) { Some(Self { syntax }) } else { None }
+                }
+                fn syntax(&self) -> &SyntaxToken { &self.syntax }
+            }
+        }
+    });
+
+    let pretty = crate::reformat(quote! {
+        use crate::{SyntaxKind::{self, *}, SyntaxToken, ast::AstToken};
+        #(#tokens)*
+    })?;
+    Ok(pretty)
+}
+
 fn generate_nodes(kinds: KindsSrc<'_>, grammar: AstSrc<'_>) -> Result<String> {
     let nodes = grammar.nodes.iter().map(|node| {
         let name = format_ident!("{}", node.name);