⬆️ rust-analyzer

This commit is contained in:
Laurențiu Nicola 2022-11-23 17:24:03 +02:00
parent 61c744d4fd
commit a2a1d99545
126 changed files with 2098 additions and 904 deletions

View file

@ -407,6 +407,8 @@ impl Trait {
pub fn auto_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![auto]) }
pub fn trait_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![trait]) }
pub fn assoc_item_list(&self) -> Option<AssocItemList> { support::child(&self.syntax) }
pub fn eq_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![=]) }
pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]

View file

@ -209,17 +209,19 @@ impl ast::String {
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
let mut buf = String::new();
let mut text_iter = text.chars();
let mut prev_end = 0;
let mut has_error = false;
unescape_literal(text, Mode::Str, &mut |char_range, unescaped_char| match (
unescaped_char,
buf.capacity() == 0,
) {
(Ok(c), false) => buf.push(c),
(Ok(c), true) if char_range.len() == 1 && Some(c) == text_iter.next() => (),
(Ok(_), true) if char_range.len() == 1 && char_range.start == prev_end => {
prev_end = char_range.end
}
(Ok(c), true) => {
buf.reserve_exact(text.len());
buf.push_str(&text[..char_range.start]);
buf.push_str(&text[..prev_end]);
buf.push(c);
}
(Err(_), _) => has_error = true,
@ -252,17 +254,19 @@ impl ast::ByteString {
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
let mut buf: Vec<u8> = Vec::new();
let mut text_iter = text.chars();
let mut prev_end = 0;
let mut has_error = false;
unescape_literal(text, Mode::ByteStr, &mut |char_range, unescaped_char| match (
unescaped_char,
buf.capacity() == 0,
) {
(Ok(c), false) => buf.push(c as u8),
(Ok(c), true) if char_range.len() == 1 && Some(c) == text_iter.next() => (),
(Ok(_), true) if char_range.len() == 1 && char_range.start == prev_end => {
prev_end = char_range.end
}
(Ok(c), true) => {
buf.reserve_exact(text.len());
buf.extend_from_slice(text[..char_range.start].as_bytes());
buf.extend_from_slice(text[..prev_end].as_bytes());
buf.push(c as u8);
}
(Err(_), _) => has_error = true,
@ -445,6 +449,36 @@ mod tests {
check_string_value(r"\foobar", None);
check_string_value(r"\nfoobar", "\nfoobar");
check_string_value(r"C:\\Windows\\System32\\", "C:\\Windows\\System32\\");
check_string_value(r"\x61bcde", "abcde");
check_string_value(
r"a\
bcde", "abcde",
);
}
fn check_byte_string_value<'a, const N: usize>(
lit: &str,
expected: impl Into<Option<&'a [u8; N]>>,
) {
assert_eq!(
ast::ByteString { syntax: make::tokens::literal(&format!("b\"{}\"", lit)) }
.value()
.as_deref(),
expected.into().map(|value| &value[..])
);
}
#[test]
fn test_byte_string_escape() {
check_byte_string_value(r"foobar", b"foobar");
check_byte_string_value(r"\foobar", None::<&[u8; 0]>);
check_byte_string_value(r"\nfoobar", b"\nfoobar");
check_byte_string_value(r"C:\\Windows\\System32\\", b"C:\\Windows\\System32\\");
check_byte_string_value(r"\x61bcde", b"abcde");
check_byte_string_value(
r"a\
bcde", b"abcde",
);
}
#[test]

View file

@ -86,7 +86,7 @@ fn generate_nodes(kinds: KindsSrc<'_>, grammar: &AstSrc) -> String {
.traits
.iter()
.filter(|trait_name| {
// Loops have two expressions so this might collide, therefor manual impl it
// Loops have two expressions so this might collide, therefore manual impl it
node.name != "ForExpr" && node.name != "WhileExpr"
|| trait_name.as_str() != "HasLoopBody"
})