Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/proc-macro-srv/src/server/rust_analyzer_span.rs')
| -rw-r--r-- | crates/proc-macro-srv/src/server/rust_analyzer_span.rs | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/crates/proc-macro-srv/src/server/rust_analyzer_span.rs b/crates/proc-macro-srv/src/server/rust_analyzer_span.rs index cf6e816d59..17159ffbb8 100644 --- a/crates/proc-macro-srv/src/server/rust_analyzer_span.rs +++ b/crates/proc-macro-srv/src/server/rust_analyzer_span.rs @@ -13,11 +13,10 @@ use std::{ use ::tt::{TextRange, TextSize}; use proc_macro::bridge::{self, server}; use span::{Span, FIXUP_ERASED_FILE_AST_ID_MARKER}; -use syntax::ast::{self, IsString}; use crate::server::{ - delim_to_external, delim_to_internal, literal_to_external, token_stream::TokenStreamBuilder, - LiteralFormatter, Symbol, SymbolInternerRef, SYMBOL_INTERNER, + delim_to_external, delim_to_internal, token_stream::TokenStreamBuilder, LiteralFormatter, + Symbol, SymbolInternerRef, SYMBOL_INTERNER, }; mod tt { pub use ::tt::*; @@ -71,32 +70,57 @@ impl server::FreeFunctions for RaSpanServer { &mut self, s: &str, ) -> Result<bridge::Literal<Self::Span, Self::Symbol>, ()> { - let literal = ast::Literal::parse(s).ok_or(())?; - let literal = literal.tree(); + use proc_macro::bridge::LitKind; + use rustc_lexer::{LiteralKind, Token, TokenKind}; + + let mut tokens = rustc_lexer::tokenize(s); + let minus_or_lit = tokens.next().unwrap_or(Token { kind: TokenKind::Eof, len: 0 }); + + let lit = if minus_or_lit.kind == TokenKind::Minus { + let lit = tokens.next().ok_or(())?; + if !matches!( + lit.kind, + TokenKind::Literal { + kind: LiteralKind::Int { .. } | LiteralKind::Float { .. }, + .. + } + ) { + return Err(()); + } + lit + } else { + minus_or_lit + }; - let kind = literal_to_external(literal.kind()).ok_or(())?; + if tokens.next().is_some() { + return Err(()); + } - // FIXME: handle more than just int and float suffixes - let suffix = match literal.kind() { - ast::LiteralKind::FloatNumber(num) => num.suffix().map(ToString::to_string), - ast::LiteralKind::IntNumber(num) => num.suffix().map(ToString::to_string), - _ => None, + let TokenKind::Literal { kind, suffix_start } = lit.kind else { return Err(()) }; + let kind = match kind { + LiteralKind::Int { .. } => LitKind::Integer, + LiteralKind::Float { .. } => LitKind::Float, + LiteralKind::Char { .. } => LitKind::Char, + LiteralKind::Byte { .. } => LitKind::Byte, + LiteralKind::Str { .. } => LitKind::Str, + LiteralKind::ByteStr { .. } => LitKind::ByteStr, + LiteralKind::CStr { .. } => LitKind::CStr, + LiteralKind::RawStr { n_hashes } => LitKind::StrRaw(n_hashes.unwrap_or_default()), + LiteralKind::RawByteStr { n_hashes } => { + LitKind::ByteStrRaw(n_hashes.unwrap_or_default()) + } + LiteralKind::RawCStr { n_hashes } => LitKind::CStrRaw(n_hashes.unwrap_or_default()), }; - let text = match literal.kind() { - ast::LiteralKind::String(data) => data.text_without_quotes().to_string(), - ast::LiteralKind::ByteString(data) => data.text_without_quotes().to_string(), - ast::LiteralKind::CString(data) => data.text_without_quotes().to_string(), - _ => s.to_string(), + let (lit, suffix) = s.split_at(suffix_start as usize); + let suffix = match suffix { + "" | "_" => None, + suffix => Some(Symbol::intern(self.interner, suffix)), }; - let text = if let Some(ref suffix) = suffix { text.strip_suffix(suffix) } else { None } - .unwrap_or(&text); - - let suffix = suffix.map(|suffix| Symbol::intern(self.interner, &suffix)); Ok(bridge::Literal { kind, - symbol: Symbol::intern(self.interner, text), + symbol: Symbol::intern(self.interner, lit), suffix, span: self.call_site, }) |