mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-28 12:54:58 +00:00
Kill RAW_ literals
Syntactically, they are indistinguishable from non-raw versions, so it doesn't make sense to separate then *at the syntax* level.
This commit is contained in:
parent
6725dcf847
commit
5ba4f949c2
53 changed files with 142 additions and 165 deletions
|
@ -320,6 +320,13 @@ impl ast::Literal {
|
|||
ast::IntNumber::cast(self.token())
|
||||
}
|
||||
|
||||
pub fn as_string(&self) -> Option<ast::String> {
|
||||
ast::String::cast(self.token())
|
||||
}
|
||||
pub fn as_byte_string(&self) -> Option<ast::ByteString> {
|
||||
ast::ByteString::cast(self.token())
|
||||
}
|
||||
|
||||
fn find_suffix(text: &str, possible_suffixes: &[&str]) -> Option<SmolStr> {
|
||||
possible_suffixes
|
||||
.iter()
|
||||
|
@ -351,10 +358,10 @@ impl ast::Literal {
|
|||
suffix: Self::find_suffix(&text, &ast::FloatNumber::SUFFIXES),
|
||||
}
|
||||
}
|
||||
STRING | RAW_STRING => LiteralKind::String,
|
||||
STRING => LiteralKind::String,
|
||||
T![true] => LiteralKind::Bool(true),
|
||||
T![false] => LiteralKind::Bool(false),
|
||||
BYTE_STRING | RAW_BYTE_STRING => LiteralKind::ByteString,
|
||||
BYTE_STRING => LiteralKind::ByteString,
|
||||
CHAR => LiteralKind::Char,
|
||||
BYTE => LiteralKind::Byte,
|
||||
_ => unreachable!(),
|
||||
|
|
|
@ -70,16 +70,16 @@ impl AstToken for String {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct RawString {
|
||||
pub struct ByteString {
|
||||
pub(crate) syntax: SyntaxToken,
|
||||
}
|
||||
impl std::fmt::Display for RawString {
|
||||
impl std::fmt::Display for ByteString {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(&self.syntax, f)
|
||||
}
|
||||
}
|
||||
impl AstToken for RawString {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == RAW_STRING }
|
||||
impl AstToken for ByteString {
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == BYTE_STRING }
|
||||
fn cast(syntax: SyntaxToken) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
|
|
|
@ -55,13 +55,7 @@ impl ast::Attr {
|
|||
let key = self.simple_name()?;
|
||||
let value_token = lit.syntax().first_token()?;
|
||||
|
||||
let value: SmolStr = if let Some(s) = ast::String::cast(value_token.clone()) {
|
||||
s.value()?.into()
|
||||
} else if let Some(s) = ast::RawString::cast(value_token) {
|
||||
s.value()?.into()
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
let value: SmolStr = ast::String::cast(value_token.clone())?.value()?.into();
|
||||
|
||||
Some((key, value))
|
||||
}
|
||||
|
|
|
@ -139,14 +139,31 @@ pub trait HasQuotes: AstToken {
|
|||
}
|
||||
|
||||
impl HasQuotes for ast::String {}
|
||||
impl HasQuotes for ast::RawString {}
|
||||
|
||||
pub trait HasStringValue: HasQuotes {
|
||||
fn value(&self) -> Option<Cow<'_, str>>;
|
||||
}
|
||||
|
||||
impl ast::String {
|
||||
pub fn is_raw(&self) -> bool {
|
||||
self.text().starts_with('r')
|
||||
}
|
||||
pub fn map_range_up(&self, range: TextRange) -> Option<TextRange> {
|
||||
let contents_range = self.text_range_between_quotes()?;
|
||||
assert!(TextRange::up_to(contents_range.len()).contains_range(range));
|
||||
Some(range + contents_range.start())
|
||||
}
|
||||
}
|
||||
|
||||
impl HasStringValue for ast::String {
|
||||
fn value(&self) -> Option<Cow<'_, str>> {
|
||||
if self.is_raw() {
|
||||
let text = self.text().as_str();
|
||||
let text =
|
||||
&text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
|
||||
return Some(Cow::Borrowed(text));
|
||||
}
|
||||
|
||||
let text = self.text().as_str();
|
||||
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
|
||||
|
||||
|
@ -166,20 +183,9 @@ impl HasStringValue for ast::String {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: merge `ast::RawString` and `ast::String`.
|
||||
impl HasStringValue for ast::RawString {
|
||||
fn value(&self) -> Option<Cow<'_, str>> {
|
||||
let text = self.text().as_str();
|
||||
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
|
||||
Some(Cow::Borrowed(text))
|
||||
}
|
||||
}
|
||||
|
||||
impl ast::RawString {
|
||||
pub fn map_range_up(&self, range: TextRange) -> Option<TextRange> {
|
||||
let contents_range = self.text_range_between_quotes()?;
|
||||
assert!(TextRange::up_to(contents_range.len()).contains_range(range));
|
||||
Some(range + contents_range.start())
|
||||
impl ast::ByteString {
|
||||
pub fn is_raw(&self) -> bool {
|
||||
self.text().starts_with("br")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -522,22 +528,6 @@ impl HasFormatSpecifier for ast::String {
|
|||
}
|
||||
}
|
||||
|
||||
impl HasFormatSpecifier for ast::RawString {
|
||||
fn char_ranges(
|
||||
&self,
|
||||
) -> Option<Vec<(TextRange, Result<char, rustc_lexer::unescape::EscapeError>)>> {
|
||||
let text = self.text().as_str();
|
||||
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
|
||||
let offset = self.text_range_between_quotes()?.start() - self.syntax().text_range().start();
|
||||
|
||||
let mut res = Vec::with_capacity(text.len());
|
||||
for (idx, c) in text.char_indices() {
|
||||
res.push((TextRange::at(idx.try_into().unwrap(), TextSize::of(c)) + offset, Ok(c)));
|
||||
}
|
||||
Some(res)
|
||||
}
|
||||
}
|
||||
|
||||
impl ast::IntNumber {
|
||||
#[rustfmt::skip]
|
||||
pub(crate) const SUFFIXES: &'static [&'static str] = &[
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue