@@ -13,11 +13,10 @@ use std::{
13
13
use :: tt:: { TextRange , TextSize } ;
14
14
use proc_macro:: bridge:: { self , server} ;
15
15
use span:: { Span , FIXUP_ERASED_FILE_AST_ID_MARKER } ;
16
- use syntax:: ast:: { self , IsString } ;
17
16
18
17
use crate :: server:: {
19
- delim_to_external, delim_to_internal, literal_to_external , token_stream:: TokenStreamBuilder ,
20
- LiteralFormatter , Symbol , SymbolInternerRef , SYMBOL_INTERNER ,
18
+ delim_to_external, delim_to_internal, token_stream:: TokenStreamBuilder , LiteralFormatter ,
19
+ Symbol , SymbolInternerRef , SYMBOL_INTERNER ,
21
20
} ;
22
21
mod tt {
23
22
pub use :: tt:: * ;
@@ -71,32 +70,57 @@ impl server::FreeFunctions for RaSpanServer {
71
70
& mut self ,
72
71
s : & str ,
73
72
) -> Result < bridge:: Literal < Self :: Span , Self :: Symbol > , ( ) > {
74
- let literal = ast:: Literal :: parse ( s) . ok_or ( ( ) ) ?;
75
- let literal = literal. tree ( ) ;
73
+ use proc_macro:: bridge:: LitKind ;
74
+ use rustc_lexer:: { LiteralKind , Token , TokenKind } ;
75
+
76
+ let mut tokens = rustc_lexer:: tokenize ( s) ;
77
+ let minus_or_lit = tokens. next ( ) . unwrap_or ( Token { kind : TokenKind :: Eof , len : 0 } ) ;
78
+
79
+ let lit = if minus_or_lit. kind == TokenKind :: Minus {
80
+ let lit = tokens. next ( ) . ok_or ( ( ) ) ?;
81
+ if !matches ! (
82
+ lit. kind,
83
+ TokenKind :: Literal {
84
+ kind: LiteralKind :: Int { .. } | LiteralKind :: Float { .. } ,
85
+ ..
86
+ }
87
+ ) {
88
+ return Err ( ( ) ) ;
89
+ }
90
+ lit
91
+ } else {
92
+ minus_or_lit
93
+ } ;
76
94
77
- let kind = literal_to_external ( literal. kind ( ) ) . ok_or ( ( ) ) ?;
95
+ if tokens. next ( ) . is_some ( ) {
96
+ return Err ( ( ) ) ;
97
+ }
78
98
79
- // FIXME: handle more than just int and float suffixes
80
- let suffix = match literal. kind ( ) {
81
- ast:: LiteralKind :: FloatNumber ( num) => num. suffix ( ) . map ( ToString :: to_string) ,
82
- ast:: LiteralKind :: IntNumber ( num) => num. suffix ( ) . map ( ToString :: to_string) ,
83
- _ => None ,
99
+ let TokenKind :: Literal { kind, suffix_start } = lit. kind else { return Err ( ( ) ) } ;
100
+ let kind = match kind {
101
+ LiteralKind :: Int { .. } => LitKind :: Integer ,
102
+ LiteralKind :: Float { .. } => LitKind :: Float ,
103
+ LiteralKind :: Char { .. } => LitKind :: Char ,
104
+ LiteralKind :: Byte { .. } => LitKind :: Byte ,
105
+ LiteralKind :: Str { .. } => LitKind :: Str ,
106
+ LiteralKind :: ByteStr { .. } => LitKind :: ByteStr ,
107
+ LiteralKind :: CStr { .. } => LitKind :: CStr ,
108
+ LiteralKind :: RawStr { n_hashes } => LitKind :: StrRaw ( n_hashes. unwrap_or_default ( ) ) ,
109
+ LiteralKind :: RawByteStr { n_hashes } => {
110
+ LitKind :: ByteStrRaw ( n_hashes. unwrap_or_default ( ) )
111
+ }
112
+ LiteralKind :: RawCStr { n_hashes } => LitKind :: CStrRaw ( n_hashes. unwrap_or_default ( ) ) ,
84
113
} ;
85
114
86
- let text = match literal. kind ( ) {
87
- ast:: LiteralKind :: String ( data) => data. text_without_quotes ( ) . to_string ( ) ,
88
- ast:: LiteralKind :: ByteString ( data) => data. text_without_quotes ( ) . to_string ( ) ,
89
- ast:: LiteralKind :: CString ( data) => data. text_without_quotes ( ) . to_string ( ) ,
90
- _ => s. to_string ( ) ,
115
+ let ( lit, suffix) = s. split_at ( suffix_start as usize ) ;
116
+ let suffix = match suffix {
117
+ "" | "_" => None ,
118
+ suffix => Some ( Symbol :: intern ( self . interner , suffix) ) ,
91
119
} ;
92
- let text = if let Some ( ref suffix) = suffix { text. strip_suffix ( suffix) } else { None }
93
- . unwrap_or ( & text) ;
94
-
95
- let suffix = suffix. map ( |suffix| Symbol :: intern ( self . interner , & suffix) ) ;
96
120
97
121
Ok ( bridge:: Literal {
98
122
kind,
99
- symbol : Symbol :: intern ( self . interner , text ) ,
123
+ symbol : Symbol :: intern ( self . interner , lit ) ,
100
124
suffix,
101
125
span : self . call_site ,
102
126
} )
0 commit comments