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:
Aleksey Kladov 2020-11-06 22:21:56 +01:00
parent 6725dcf847
commit 5ba4f949c2
53 changed files with 142 additions and 165 deletions

View file

@ -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!(),

View file

@ -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 })

View file

@ -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))
}

View file

@ -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] = &[