@@ -13,6 +13,7 @@ use std::{
1313use :: tt:: { TextRange , TextSize } ;
1414use proc_macro:: bridge:: { self , server} ;
1515use span:: { Span , FIXUP_ERASED_FILE_AST_ID_MARKER } ;
16+ use syntax:: ast:: { self , HasModuleItem , IsString } ;
1617
1718use crate :: server:: {
1819 delim_to_external, delim_to_internal, token_stream:: TokenStreamBuilder , LiteralFormatter ,
@@ -70,11 +71,71 @@ impl server::FreeFunctions for RaSpanServer {
7071 & mut self ,
7172 s : & str ,
7273 ) -> Result < bridge:: Literal < Self :: Span , Self :: Symbol > , ( ) > {
73- // FIXME: keep track of LitKind and Suffix
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+ }
98+
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+ } ;
134+
74135 Ok ( bridge:: Literal {
75- kind : bridge :: LitKind :: Err ,
136+ kind,
76137 symbol : Symbol :: intern ( self . interner , s) ,
77- suffix : None ,
138+ suffix,
78139 span : self . call_site ,
79140 } )
80141 }
0 commit comments