From 5db789df9c767985a564a31cc593ce7f5964100e Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Fri, 6 Nov 2020 22:52:22 +0100
Subject: Cleanup API

---
 crates/syntax/src/ast/expr_ext.rs  | 64 +++++++++++---------------------------
 crates/syntax/src/ast/token_ext.rs | 32 ++++++++++++-------
 2 files changed, 39 insertions(+), 57 deletions(-)

(limited to 'crates/syntax/src/ast')

diff --git a/crates/syntax/src/ast/expr_ext.rs b/crates/syntax/src/ast/expr_ext.rs
index eb44bb2ab..9253c97d0 100644
--- a/crates/syntax/src/ast/expr_ext.rs
+++ b/crates/syntax/src/ast/expr_ext.rs
@@ -2,7 +2,7 @@
 
 use crate::{
     ast::{self, support, AstChildren, AstNode},
-    AstToken, SmolStr,
+    AstToken,
     SyntaxKind::*,
     SyntaxToken, T,
 };
@@ -298,12 +298,12 @@ impl ast::ArrayExpr {
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
 pub enum LiteralKind {
-    String,
-    ByteString,
+    String(ast::String),
+    ByteString(ast::ByteString),
+    IntNumber(ast::IntNumber),
+    FloatNumber(ast::FloatNumber),
     Char,
     Byte,
-    IntNumber { suffix: Option<SmolStr> },
-    FloatNumber { suffix: Option<SmolStr> },
     Bool(bool),
 }
 
@@ -315,53 +315,25 @@ impl ast::Literal {
             .and_then(|e| e.into_token())
             .unwrap()
     }
-
-    pub fn as_int_number(&self) -> Option<ast::IntNumber> {
-        ast::IntNumber::cast(self.token())
-    }
-
-    pub fn as_string(&self) -> Option<ast::String> {
-        ast::String::cast(self.token())
-    }
-    pub fn as_byte_string(&self) -> Option<ast::ByteString> {
-        ast::ByteString::cast(self.token())
-    }
-
-    fn find_suffix(text: &str, possible_suffixes: &[&str]) -> Option<SmolStr> {
-        possible_suffixes
-            .iter()
-            .find(|&suffix| text.ends_with(suffix))
-            .map(|&suffix| SmolStr::new(suffix))
-    }
-
     pub fn kind(&self) -> LiteralKind {
         let token = self.token();
 
+        if let Some(t) = ast::IntNumber::cast(token.clone()) {
+            return LiteralKind::IntNumber(t);
+        }
+        if let Some(t) = ast::FloatNumber::cast(token.clone()) {
+            return LiteralKind::FloatNumber(t);
+        }
+        if let Some(t) = ast::String::cast(token.clone()) {
+            return LiteralKind::String(t);
+        }
+        if let Some(t) = ast::ByteString::cast(token.clone()) {
+            return LiteralKind::ByteString(t);
+        }
+
         match token.kind() {
-            INT_NUMBER => {
-                // FYI: there was a bug here previously, thus the if statement below is necessary.
-                // The lexer treats e.g. `1f64` as an integer literal. See
-                // https://github.com/rust-analyzer/rust-analyzer/issues/1592
-                // and the comments on the linked PR.
-                let text = token.text();
-                if let suffix @ Some(_) = Self::find_suffix(&text, &ast::FloatNumber::SUFFIXES) {
-                    LiteralKind::FloatNumber { suffix }
-                } else {
-                    LiteralKind::IntNumber {
-                        suffix: Self::find_suffix(&text, &ast::IntNumber::SUFFIXES),
-                    }
-                }
-            }
-            FLOAT_NUMBER => {
-                let text = token.text();
-                LiteralKind::FloatNumber {
-                    suffix: Self::find_suffix(&text, &ast::FloatNumber::SUFFIXES),
-                }
-            }
-            STRING => LiteralKind::String,
             T![true] => LiteralKind::Bool(true),
             T![false] => LiteralKind::Bool(false),
-            BYTE_STRING => LiteralKind::ByteString,
             CHAR => LiteralKind::Char,
             BYTE => LiteralKind::Byte,
             _ => unreachable!(),
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs
index bf0035986..e4e512f2e 100644
--- a/crates/syntax/src/ast/token_ext.rs
+++ b/crates/syntax/src/ast/token_ext.rs
@@ -517,10 +517,9 @@ impl HasFormatSpecifier for ast::String {
 }
 
 impl ast::IntNumber {
-    #[rustfmt::skip]
-    pub(crate) const SUFFIXES: &'static [&'static str] = &[
-        "u8", "u16", "u32", "u64", "u128", "usize",
-        "i8", "i16", "i32", "i64", "i128", "isize",
+    const SUFFIXES: &'static [&'static str] = &[
+        "u8", "u16", "u32", "u64", "u128", "usize", // Unsigned.
+        "i8", "i16", "i32", "i64", "i128", "isize", // Signed.
     ];
 
     pub fn radix(&self) -> Radix {
@@ -555,9 +554,24 @@ impl ast::IntNumber {
 
     pub fn suffix(&self) -> Option<&str> {
         let text = self.text();
-        // FIXME: don't check a fixed set of suffixes, `1_0_1___lol` is valid
-        // syntax, suffix is `lol`.
-        ast::IntNumber::SUFFIXES.iter().find_map(|suffix| {
+        // FIXME: don't check a fixed set of suffixes, `1_0_1_l_o_l` is valid
+        // syntax, suffix is `l_o_l`.
+        ast::IntNumber::SUFFIXES.iter().chain(ast::FloatNumber::SUFFIXES.iter()).find_map(
+            |suffix| {
+                if text.ends_with(suffix) {
+                    return Some(&text[text.len() - suffix.len()..]);
+                }
+                None
+            },
+        )
+    }
+}
+
+impl ast::FloatNumber {
+    const SUFFIXES: &'static [&'static str] = &["f32", "f64"];
+    pub fn suffix(&self) -> Option<&str> {
+        let text = self.text();
+        ast::FloatNumber::SUFFIXES.iter().find_map(|suffix| {
             if text.ends_with(suffix) {
                 return Some(&text[text.len() - suffix.len()..]);
             }
@@ -566,10 +580,6 @@ impl ast::IntNumber {
     }
 }
 
-impl ast::FloatNumber {
-    pub(crate) const SUFFIXES: &'static [&'static str] = &["f32", "f64"];
-}
-
 #[derive(Debug, PartialEq, Eq, Copy, Clone)]
 pub enum Radix {
     Binary = 2,
-- 
cgit v1.2.3