mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-14 22:24:14 +00:00
Stringify literals create client-side properly
This commit is contained in:
parent
36d825fd5d
commit
9cf99a9c71
2 changed files with 51 additions and 11 deletions
|
@ -132,17 +132,11 @@ impl server::TokenStream for RustAnalyzer {
|
||||||
}
|
}
|
||||||
|
|
||||||
bridge::TokenTree::Literal(literal) => {
|
bridge::TokenTree::Literal(literal) => {
|
||||||
// FIXME: remove unnecessary clones here
|
let literal = LiteralFormatter(literal);
|
||||||
let symbol = ThreadLocalSymbolInterner::get_cloned(&literal.symbol);
|
let text = literal
|
||||||
|
.with_stringify_parts(|parts| tt::SmolStr::from_iter(parts.iter().copied()));
|
||||||
|
|
||||||
let text: tt::SmolStr = if let Some(suffix) = literal.suffix {
|
let literal = tt::Literal { text, id: literal.0.span };
|
||||||
let suffix = ThreadLocalSymbolInterner::get_cloned(&suffix);
|
|
||||||
format!("{symbol}{suffix}").into()
|
|
||||||
} else {
|
|
||||||
symbol
|
|
||||||
};
|
|
||||||
|
|
||||||
let literal = tt::Literal { text, id: literal.span };
|
|
||||||
let leaf = tt::Leaf::from(literal);
|
let leaf = tt::Leaf::from(literal);
|
||||||
let tree = TokenTree::from(leaf);
|
let tree = TokenTree::from(leaf);
|
||||||
Self::TokenStream::from_iter(vec![tree])
|
Self::TokenStream::from_iter(vec![tree])
|
||||||
|
@ -416,6 +410,53 @@ impl server::Server for RustAnalyzer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct LiteralFormatter(bridge::Literal<tt::TokenId, Symbol>);
|
||||||
|
|
||||||
|
impl LiteralFormatter {
|
||||||
|
/// Invokes the callback with a `&[&str]` consisting of each part of the
|
||||||
|
/// literal's representation. This is done to allow the `ToString` and
|
||||||
|
/// `Display` implementations to borrow references to symbol values, and
|
||||||
|
/// both be optimized to reduce overhead.
|
||||||
|
fn with_stringify_parts<R>(&self, f: impl FnOnce(&[&str]) -> R) -> R {
|
||||||
|
/// Returns a string containing exactly `num` '#' characters.
|
||||||
|
/// Uses a 256-character source string literal which is always safe to
|
||||||
|
/// index with a `u8` index.
|
||||||
|
fn get_hashes_str(num: u8) -> &'static str {
|
||||||
|
const HASHES: &str = "\
|
||||||
|
################################################################\
|
||||||
|
################################################################\
|
||||||
|
################################################################\
|
||||||
|
################################################################\
|
||||||
|
";
|
||||||
|
const _: () = assert!(HASHES.len() == 256);
|
||||||
|
&HASHES[..num as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
self.with_symbol_and_suffix(|symbol, suffix| match self.0.kind {
|
||||||
|
bridge::LitKind::Byte => f(&["b'", symbol, "'", suffix]),
|
||||||
|
bridge::LitKind::Char => f(&["'", symbol, "'", suffix]),
|
||||||
|
bridge::LitKind::Str => f(&["\"", symbol, "\"", suffix]),
|
||||||
|
bridge::LitKind::StrRaw(n) => {
|
||||||
|
let hashes = get_hashes_str(n);
|
||||||
|
f(&["r", hashes, "\"", symbol, "\"", hashes, suffix])
|
||||||
|
}
|
||||||
|
bridge::LitKind::ByteStr => f(&["b\"", symbol, "\"", suffix]),
|
||||||
|
bridge::LitKind::ByteStrRaw(n) => {
|
||||||
|
let hashes = get_hashes_str(n);
|
||||||
|
f(&["br", hashes, "\"", symbol, "\"", hashes, suffix])
|
||||||
|
}
|
||||||
|
_ => f(&[symbol, suffix]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_symbol_and_suffix<R>(&self, f: impl FnOnce(&str, &str) -> R) -> R {
|
||||||
|
ThreadLocalSymbolInterner::with(&self.0.symbol, |symbol| match self.0.suffix.as_ref() {
|
||||||
|
Some(suffix) => ThreadLocalSymbolInterner::with(suffix, |suffix| f(symbol, suffix)),
|
||||||
|
None => f(symbol, ""),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
|
@ -77,7 +77,6 @@ fn test_fn_like_mk_literals() {
|
||||||
LITERAL b"byte_string" 4294967295
|
LITERAL b"byte_string" 4294967295
|
||||||
LITERAL 'c' 4294967295
|
LITERAL 'c' 4294967295
|
||||||
LITERAL "string" 4294967295
|
LITERAL "string" 4294967295
|
||||||
LITERAL "maybe \"raw\"?" 4294967295
|
|
||||||
LITERAL 3.14f64 4294967295
|
LITERAL 3.14f64 4294967295
|
||||||
LITERAL 3.14 4294967295
|
LITERAL 3.14 4294967295
|
||||||
LITERAL 123i64 4294967295
|
LITERAL 123i64 4294967295
|
||||||
|
|
Loading…
Reference in a new issue