From 57bb618fd3f11d9ac817f76a965316723aa69ee9 Mon Sep 17 00:00:00 2001
From: Sergey Parilin <Sergey.Parilin@fxdd.com>
Date: Wed, 8 May 2019 18:35:32 +0300
Subject: [PATCH] Implemented T! macro for syntax kinds

---
 crates/ra_ide_api/src/extend_selection.rs     |  3 +-
 crates/ra_parser/src/lib.rs                   |  1 +
 crates/ra_parser/src/syntax_kind.rs           |  1 +
 crates/ra_parser/src/syntax_kind/generated.rs | 95 +++++++++++++++++++
 .../src/syntax_kind/generated.rs.tera         | 14 +++
 crates/ra_syntax/src/lib.rs                   |  1 +
 6 files changed, 114 insertions(+), 1 deletion(-)

diff --git a/crates/ra_ide_api/src/extend_selection.rs b/crates/ra_ide_api/src/extend_selection.rs
index 7293ba3590c..163fa8c3c79 100644
--- a/crates/ra_ide_api/src/extend_selection.rs
+++ b/crates/ra_ide_api/src/extend_selection.rs
@@ -4,6 +4,7 @@ use ra_syntax::{
     algo::{find_covering_element, find_token_at_offset, TokenAtOffset},
     SyntaxKind::*, SyntaxToken,
     ast::{self, AstNode, AstToken},
+    T
 };
 
 use crate::{FileRange, db::RootDatabase};
@@ -135,7 +136,7 @@ fn pick_best<'a>(l: SyntaxToken<'a>, r: SyntaxToken<'a>) -> SyntaxToken<'a> {
     fn priority(n: SyntaxToken) -> usize {
         match n.kind() {
             WHITESPACE => 0,
-            IDENT | SELF_KW | SUPER_KW | CRATE_KW | LIFETIME => 2,
+            IDENT | T![self] | T![super] | T![crate] | LIFETIME => 2,
             _ => 1,
         }
     }
diff --git a/crates/ra_parser/src/lib.rs b/crates/ra_parser/src/lib.rs
index 970d699c01b..697d1b79498 100644
--- a/crates/ra_parser/src/lib.rs
+++ b/crates/ra_parser/src/lib.rs
@@ -14,6 +14,7 @@
 
 #[macro_use]
 mod token_set;
+#[macro_use]
 mod syntax_kind;
 mod event;
 mod parser;
diff --git a/crates/ra_parser/src/syntax_kind.rs b/crates/ra_parser/src/syntax_kind.rs
index a2353317f87..00faa779924 100644
--- a/crates/ra_parser/src/syntax_kind.rs
+++ b/crates/ra_parser/src/syntax_kind.rs
@@ -1,3 +1,4 @@
+#[macro_use]
 mod generated;
 
 use std::fmt;
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index 6f984aea16f..1a08cc6eb12 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs
+++ b/crates/ra_parser/src/syntax_kind/generated.rs
@@ -241,6 +241,101 @@ pub enum SyntaxKind {
 }
 use self::SyntaxKind::*;
 
+#[macro_export]
+macro_rules! T {
+    (;) => { $crate::SyntaxKind::SEMI };
+    (,) => { $crate::SyntaxKind::COMMA };
+    (() => { $crate::SyntaxKind::L_PAREN };
+    ()) => { $crate::SyntaxKind::R_PAREN };
+    ('{') => { $crate::SyntaxKind::L_CURLY };
+    ('}') => { $crate::SyntaxKind::R_CURLY };
+    ('[') => { $crate::SyntaxKind::L_BRACK };
+    (']') => { $crate::SyntaxKind::R_BRACK };
+    (<) => { $crate::SyntaxKind::L_ANGLE };
+    (>) => { $crate::SyntaxKind::R_ANGLE };
+    (@) => { $crate::SyntaxKind::AT };
+    (#) => { $crate::SyntaxKind::POUND };
+    (~) => { $crate::SyntaxKind::TILDE };
+    (?) => { $crate::SyntaxKind::QUESTION };
+    ($) => { $crate::SyntaxKind::DOLLAR };
+    (&) => { $crate::SyntaxKind::AMP };
+    (|) => { $crate::SyntaxKind::PIPE };
+    (+) => { $crate::SyntaxKind::PLUS };
+    (*) => { $crate::SyntaxKind::STAR };
+    (/) => { $crate::SyntaxKind::SLASH };
+    (^) => { $crate::SyntaxKind::CARET };
+    (%) => { $crate::SyntaxKind::PERCENT };
+    (_) => { $crate::SyntaxKind::UNDERSCORE };
+    (.) => { $crate::SyntaxKind::DOT };
+    (..) => { $crate::SyntaxKind::DOTDOT };
+    (...) => { $crate::SyntaxKind::DOTDOTDOT };
+    (..=) => { $crate::SyntaxKind::DOTDOTEQ };
+    (:) => { $crate::SyntaxKind::COLON };
+    (::) => { $crate::SyntaxKind::COLONCOLON };
+    (=) => { $crate::SyntaxKind::EQ };
+    (==) => { $crate::SyntaxKind::EQEQ };
+    (=>) => { $crate::SyntaxKind::FAT_ARROW };
+    (!) => { $crate::SyntaxKind::EXCL };
+    (!=) => { $crate::SyntaxKind::NEQ };
+    (-) => { $crate::SyntaxKind::MINUS };
+    (->) => { $crate::SyntaxKind::THIN_ARROW };
+    (<=) => { $crate::SyntaxKind::LTEQ };
+    (>=) => { $crate::SyntaxKind::GTEQ };
+    (+=) => { $crate::SyntaxKind::PLUSEQ };
+    (-=) => { $crate::SyntaxKind::MINUSEQ };
+    (|=) => { $crate::SyntaxKind::PIPEEQ };
+    (&=) => { $crate::SyntaxKind::AMPEQ };
+    (^=) => { $crate::SyntaxKind::CARETEQ };
+    (/=) => { $crate::SyntaxKind::SLASHEQ };
+    (*=) => { $crate::SyntaxKind::STAREQ };
+    (%=) => { $crate::SyntaxKind::PERCENTEQ };
+    (&&) => { $crate::SyntaxKind::AMPAMP };
+    (||) => { $crate::SyntaxKind::PIPEPIPE };
+    (<<) => { $crate::SyntaxKind::SHL };
+    (>>) => { $crate::SyntaxKind::SHR };
+    (<<=) => { $crate::SyntaxKind::SHLEQ };
+    (>>=) => { $crate::SyntaxKind::SHREQ };
+    (async) => { $crate::SyntaxKind::ASYNC_KW };
+    (use) => { $crate::SyntaxKind::USE_KW };
+    (fn) => { $crate::SyntaxKind::FN_KW };
+    (struct) => { $crate::SyntaxKind::STRUCT_KW };
+    (enum) => { $crate::SyntaxKind::ENUM_KW };
+    (trait) => { $crate::SyntaxKind::TRAIT_KW };
+    (impl) => { $crate::SyntaxKind::IMPL_KW };
+    (dyn) => { $crate::SyntaxKind::DYN_KW };
+    (true) => { $crate::SyntaxKind::TRUE_KW };
+    (false) => { $crate::SyntaxKind::FALSE_KW };
+    (as) => { $crate::SyntaxKind::AS_KW };
+    (extern) => { $crate::SyntaxKind::EXTERN_KW };
+    (crate) => { $crate::SyntaxKind::CRATE_KW };
+    (mod) => { $crate::SyntaxKind::MOD_KW };
+    (pub) => { $crate::SyntaxKind::PUB_KW };
+    (self) => { $crate::SyntaxKind::SELF_KW };
+    (super) => { $crate::SyntaxKind::SUPER_KW };
+    (in) => { $crate::SyntaxKind::IN_KW };
+    (where) => { $crate::SyntaxKind::WHERE_KW };
+    (for) => { $crate::SyntaxKind::FOR_KW };
+    (loop) => { $crate::SyntaxKind::LOOP_KW };
+    (while) => { $crate::SyntaxKind::WHILE_KW };
+    (continue) => { $crate::SyntaxKind::CONTINUE_KW };
+    (break) => { $crate::SyntaxKind::BREAK_KW };
+    (if) => { $crate::SyntaxKind::IF_KW };
+    (else) => { $crate::SyntaxKind::ELSE_KW };
+    (match) => { $crate::SyntaxKind::MATCH_KW };
+    (const) => { $crate::SyntaxKind::CONST_KW };
+    (static) => { $crate::SyntaxKind::STATIC_KW };
+    (mut) => { $crate::SyntaxKind::MUT_KW };
+    (unsafe) => { $crate::SyntaxKind::UNSAFE_KW };
+    (type) => { $crate::SyntaxKind::TYPE_KW };
+    (ref) => { $crate::SyntaxKind::REF_KW };
+    (let) => { $crate::SyntaxKind::LET_KW };
+    (move) => { $crate::SyntaxKind::MOVE_KW };
+    (return) => { $crate::SyntaxKind::RETURN_KW };
+    (auto) => { $crate::SyntaxKind::AUTO_KW };
+    (default) => { $crate::SyntaxKind::DEFAULT_KW };
+    (union) => { $crate::SyntaxKind::UNION_KW };
+}
+
 impl From<u16> for SyntaxKind {
     fn from(d: u16) -> SyntaxKind {
         assert!(d <= (__LAST as u16));
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs.tera b/crates/ra_parser/src/syntax_kind/generated.rs.tera
index 5b9ff21af46..ccb8ca4bae3 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs.tera
+++ b/crates/ra_parser/src/syntax_kind/generated.rs.tera
@@ -33,6 +33,20 @@ pub enum SyntaxKind {
 }
 use self::SyntaxKind::*;
 
+#[macro_export]
+macro_rules! T {
+{%- for t in concat(a=single_byte_tokens, b=multi_byte_tokens) %}
+    {%- if t.0 == '{' or t.0 == '}' or t.0 == '[' or t.0 == ']' %}
+    ('{{t.0}}') => { $crate::SyntaxKind::{{t.1}} };
+    {%- else %}
+    ({{t.0}}) => { $crate::SyntaxKind::{{t.1}} };
+    {%- endif %}
+{%- endfor -%}
+{% for kw in concat(a=keywords, b=contextual_keywords) %}
+    ({{kw}}) => { $crate::SyntaxKind::{{kw | upper}}_KW };
+{%- endfor %}
+}
+
 impl From<u16> for SyntaxKind {
     fn from(d: u16) -> SyntaxKind {
         assert!(d <= (__LAST as u16));
diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs
index 9cb66b76b3b..4f51654524e 100644
--- a/crates/ra_syntax/src/lib.rs
+++ b/crates/ra_syntax/src/lib.rs
@@ -34,6 +34,7 @@ pub mod fuzz;
 
 pub use rowan::{SmolStr, TextRange, TextUnit};
 pub use ra_parser::SyntaxKind;
+pub use ra_parser::T;
 pub use crate::{
     ast::AstNode,
     syntax_error::{SyntaxError, SyntaxErrorKind, Location},