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.rs55
1 files changed, 51 insertions, 4 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 8a9d52a37a..c6a0a66655 100644
--- a/crates/proc-macro-srv/src/server/rust_analyzer_span.rs
+++ b/crates/proc-macro-srv/src/server/rust_analyzer_span.rs
@@ -70,11 +70,58 @@ impl server::FreeFunctions for RaSpanServer {
&mut self,
s: &str,
) -> Result<bridge::Literal<Self::Span, Self::Symbol>, ()> {
- // FIXME: keep track of LitKind and Suffix
+ 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
+ };
+
+ if tokens.next().is_some() {
+ return Err(());
+ }
+
+ 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 (lit, suffix) = s.split_at(suffix_start as usize);
+ let suffix = match suffix {
+ "" | "_" => None,
+ suffix => Some(Symbol::intern(self.interner, suffix)),
+ };
+
Ok(bridge::Literal {
- kind: bridge::LitKind::Integer, // dummy
- symbol: Symbol::intern(self.interner, s),
- suffix: None,
+ kind,
+ symbol: Symbol::intern(self.interner, lit),
+ suffix,
span: self.call_site,
})
}