mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-28 05:53:45 +00:00
fix: replace unescape fn with the one in ra-ap-rustc_lexer
This commit is contained in:
parent
a543516ea4
commit
3e232bb78a
2 changed files with 31 additions and 34 deletions
|
@ -8,6 +8,7 @@ use intern::Interned;
|
||||||
use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct};
|
use mbe::{syntax_node_to_token_tree, DelimiterKind, Punct};
|
||||||
use smallvec::{smallvec, SmallVec};
|
use smallvec::{smallvec, SmallVec};
|
||||||
use span::{Span, SyntaxContextId};
|
use span::{Span, SyntaxContextId};
|
||||||
|
use syntax::unescape;
|
||||||
use syntax::{ast, format_smolstr, match_ast, AstNode, AstToken, SmolStr, SyntaxNode};
|
use syntax::{ast, format_smolstr, match_ast, AstNode, AstToken, SmolStr, SyntaxNode};
|
||||||
use triomphe::ThinArc;
|
use triomphe::ThinArc;
|
||||||
|
|
||||||
|
@ -54,8 +55,7 @@ impl RawAttrs {
|
||||||
Attr {
|
Attr {
|
||||||
id,
|
id,
|
||||||
input: Some(Interned::new(AttrInput::Literal(tt::Literal {
|
input: Some(Interned::new(AttrInput::Literal(tt::Literal {
|
||||||
// FIXME: Escape quotes from comment content
|
text: SmolStr::new(format_smolstr!("\"{}\"", Self::escape_chars(doc))),
|
||||||
text: SmolStr::new(format_smolstr!("\"{doc}\"",)),
|
|
||||||
span,
|
span,
|
||||||
}))),
|
}))),
|
||||||
path: Interned::new(ModPath::from(crate::name!(doc))),
|
path: Interned::new(ModPath::from(crate::name!(doc))),
|
||||||
|
@ -74,6 +74,10 @@ impl RawAttrs {
|
||||||
RawAttrs { entries }
|
RawAttrs { entries }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn escape_chars(s: &str) -> String {
|
||||||
|
s.replace('\\', r#"\\"#).replace('"', r#"\""#)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from_attrs_owner(
|
pub fn from_attrs_owner(
|
||||||
db: &dyn ExpandDatabase,
|
db: &dyn ExpandDatabase,
|
||||||
owner: InFile<&dyn ast::HasAttrs>,
|
owner: InFile<&dyn ast::HasAttrs>,
|
||||||
|
@ -303,9 +307,7 @@ impl Attr {
|
||||||
Some(it) => {
|
Some(it) => {
|
||||||
it.trim_matches('#').strip_prefix('"')?.strip_suffix('"').map(Cow::Borrowed)
|
it.trim_matches('#').strip_prefix('"')?.strip_suffix('"').map(Cow::Borrowed)
|
||||||
}
|
}
|
||||||
None => {
|
None => it.text.strip_prefix('"')?.strip_suffix('"').and_then(unescape),
|
||||||
it.text.strip_prefix('"')?.strip_suffix('"').and_then(unescape).map(Cow::Owned)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
|
@ -360,37 +362,31 @@ impl Attr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unescape(s: &str) -> Option<String> {
|
fn unescape(s: &str) -> Option<Cow<'_, str>> {
|
||||||
let mut res = String::with_capacity(s.len());
|
let mut buf = String::new();
|
||||||
let mut chars = s.chars();
|
let mut prev_end = 0;
|
||||||
|
let mut has_error = false;
|
||||||
while let Some(c) = chars.next() {
|
unescape::unescape_unicode(s, unescape::Mode::Str, &mut |char_range, unescaped_char| match (
|
||||||
if c == '\\' {
|
unescaped_char,
|
||||||
match chars.next()? {
|
buf.capacity() == 0,
|
||||||
'n' => res.push('\n'),
|
) {
|
||||||
'r' => res.push('\r'),
|
(Ok(c), false) => buf.push(c),
|
||||||
't' => res.push('\t'),
|
(Ok(_), true) if char_range.len() == 1 && char_range.start == prev_end => {
|
||||||
'\\' => res.push('\\'),
|
prev_end = char_range.end
|
||||||
'\'' => res.push('\''),
|
|
||||||
'"' => res.push('"'),
|
|
||||||
'0' => res.push('\0'),
|
|
||||||
'x' => {
|
|
||||||
let hex = chars.by_ref().take(2).collect::<String>();
|
|
||||||
let c = u8::from_str_radix(&hex, 16).ok()?;
|
|
||||||
res.push(c as char);
|
|
||||||
}
|
|
||||||
'u' => {
|
|
||||||
let hex = chars.by_ref().take(4).collect::<String>();
|
|
||||||
let c = u32::from_str_radix(&hex, 16).ok()?;
|
|
||||||
res.push(char::from_u32(c)?);
|
|
||||||
}
|
|
||||||
_ => return None,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res.push(c);
|
|
||||||
}
|
}
|
||||||
|
(Ok(c), true) => {
|
||||||
|
buf.reserve_exact(s.len());
|
||||||
|
buf.push_str(&s[..prev_end]);
|
||||||
|
buf.push(c);
|
||||||
|
}
|
||||||
|
(Err(_), _) => has_error = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
match (has_error, buf.capacity() == 0) {
|
||||||
|
(true, _) => None,
|
||||||
|
(false, false) => Some(Cow::Owned(buf)),
|
||||||
|
(false, true) => Some(Cow::Borrowed(s)),
|
||||||
}
|
}
|
||||||
Some(res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn collect_attrs(
|
pub fn collect_attrs(
|
||||||
|
|
|
@ -65,6 +65,7 @@ pub use rowan::{
|
||||||
api::Preorder, Direction, GreenNode, NodeOrToken, SyntaxText, TextRange, TextSize,
|
api::Preorder, Direction, GreenNode, NodeOrToken, SyntaxText, TextRange, TextSize,
|
||||||
TokenAtOffset, WalkEvent,
|
TokenAtOffset, WalkEvent,
|
||||||
};
|
};
|
||||||
|
pub use rustc_lexer::unescape;
|
||||||
pub use smol_str::{format_smolstr, SmolStr};
|
pub use smol_str::{format_smolstr, SmolStr};
|
||||||
|
|
||||||
/// `Parse` is the result of the parsing: a syntax tree and a collection of
|
/// `Parse` is the result of the parsing: a syntax tree and a collection of
|
||||||
|
|
Loading…
Reference in a new issue