44//! It is an unfortunate result of how the proc-macro API works that we need to look into the
55//! concrete representation of the spans, and as such, RustRover cannot make use of this unless they
66//! change their representation to be compatible with rust-analyzer's.
7+ use core:: num;
78use std:: {
89 collections:: { HashMap , HashSet } ,
910 iter,
@@ -13,11 +14,11 @@ use std::{
1314use :: tt:: { TextRange , TextSize } ;
1415use proc_macro:: bridge:: { self , server} ;
1516use span:: { Span , FIXUP_ERASED_FILE_AST_ID_MARKER } ;
16- use syntax:: ast:: { self , HasModuleItem , IsString } ;
17+ use syntax:: ast;
1718
1819use crate :: server:: {
19- delim_to_external, delim_to_internal, token_stream :: TokenStreamBuilder , LiteralFormatter ,
20- Symbol , SymbolInternerRef , SYMBOL_INTERNER ,
20+ delim_to_external, delim_to_internal, literal_to_external , str_to_lit_node ,
21+ token_stream :: TokenStreamBuilder , LiteralFormatter , Symbol , SymbolInternerRef , SYMBOL_INTERNER ,
2122} ;
2223mod tt {
2324 pub use :: tt:: * ;
@@ -71,66 +72,15 @@ impl server::FreeFunctions for RaSpanServer {
7172 & mut self ,
7273 s : & str ,
7374 ) -> Result < bridge:: Literal < Self :: Span , Self :: Symbol > , ( ) > {
74- let input = s. trim ( ) ;
75- let source_code = format ! ( "fn f() {{ let _ = {input}; }}" ) ;
76-
77- let parse = ast:: SourceFile :: parse ( & source_code) ;
78- let file = parse. tree ( ) ;
79-
80- let Some ( ast:: Item :: Fn ( func) ) = file. items ( ) . next ( ) else { return Err ( ( ) ) } ;
81- let Some ( ast:: Stmt :: LetStmt ( stmt) ) =
82- func. body ( ) . ok_or ( Err ( ( ) ) ) ?. stmt_list ( ) . ok_or ( Err ( ( ) ) ) ?. statements ( ) . next ( )
83- else {
84- return Err ( ( ) ) ;
85- } ;
86- let Some ( ast:: Expr :: Literal ( lit) ) = stmt. initializer ( ) else { return Err ( ( ) ) } ;
87-
88- fn raw_delimiter_count < S : IsString > ( s : S ) -> Option < u8 > {
89- let text = s. text ( ) ;
90- let quote_range = s. text_range_between_quotes ( ) ?;
91- let range_start = s. syntax ( ) . text_range ( ) . start ( ) ;
92- text[ TextRange :: up_to ( ( quote_range - range_start) . start ( ) ) ]
93- . matches ( '#' )
94- . count ( )
95- . try_into ( )
96- . ok ( )
97- }
75+ let literal = str_to_lit_node ( s) . ok_or ( Err ( ( ) ) ) ?;
9876
99- let mut suffix = None ;
100- let kind = match lit. kind ( ) {
101- ast:: LiteralKind :: String ( data) => {
102- if data. is_raw ( ) {
103- bridge:: LitKind :: StrRaw ( raw_delimiter_count ( data) . ok_or ( Err ( ( ) ) ) ?)
104- } else {
105- bridge:: LitKind :: Str
106- }
107- }
108- ast:: LiteralKind :: ByteString ( data) => {
109- if data. is_raw ( ) {
110- bridge:: LitKind :: ByteStrRaw ( raw_delimiter_count ( data) . ok_or ( Err ( ( ) ) ) ?)
111- } else {
112- bridge:: LitKind :: ByteStr
113- }
114- }
115- ast:: LiteralKind :: CString ( data) => {
116- if data. is_raw ( ) {
117- bridge:: LitKind :: CStrRaw ( raw_delimiter_count ( data) . ok_or ( Err ( ( ) ) ) ?)
118- } else {
119- bridge:: LitKind :: CStr
120- }
121- }
122- ast:: LiteralKind :: IntNumber ( num) => {
123- suffix = num. suffix ( ) ;
124- bridge:: LitKind :: Integer
125- }
126- ast:: LiteralKind :: FloatNumber ( num) => {
127- suffix = num. suffix ( ) ;
128- bridge:: LitKind :: Float
129- }
130- ast:: LiteralKind :: Char ( _) => bridge:: LitKind :: Char ,
131- ast:: LiteralKind :: Byte ( _) => bridge:: LitKind :: Byte ,
132- ast:: LiteralKind :: Bool ( _) => unreachable ! ( ) ,
133- } ;
77+ let kind = literal_to_external ( literal. kind ( ) ) . ok_or ( Err ( ( ) ) ) ?;
78+
79+ let suffix = match literal. kind ( ) {
80+ ast:: LiteralKind :: FloatNumber ( num) | ast:: LiteralKind :: IntNumber ( num) => num. suffix ( ) ,
81+ _ => None ,
82+ }
83+ . map ( |suffix| Symbol :: intern ( self . interner , suffix) ) ;
13484
13585 Ok ( bridge:: Literal {
13686 kind,
0 commit comments