mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-29 21:35:20 +00:00
Fix API of Attr
This commit is contained in:
parent
71efdaa636
commit
5a4b4f507e
9 changed files with 32 additions and 54 deletions
|
@ -1,10 +1,8 @@
|
|||
//! Various extension methods to ast Nodes, which are hard to code-generate.
|
||||
//! Extensions for various expressions live in a sibling `expr_extensions` module.
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::{
|
||||
ast::{self, child_opt, children, AstChildren, AstNode, SyntaxNode},
|
||||
ast::{self, child_opt, children, AstChildren, AstNode, AttrInput, SyntaxNode},
|
||||
SmolStr, SyntaxElement,
|
||||
SyntaxKind::*,
|
||||
SyntaxToken, T,
|
||||
|
@ -39,12 +37,7 @@ fn text_of_first_token(node: &SyntaxNode) -> &SmolStr {
|
|||
|
||||
impl ast::Attr {
|
||||
pub fn is_inner(&self) -> bool {
|
||||
let tt = match self.value() {
|
||||
None => return false,
|
||||
Some(tt) => tt,
|
||||
};
|
||||
|
||||
let prev = match tt.syntax().prev_sibling() {
|
||||
let prev = match self.syntax().prev_sibling() {
|
||||
None => return false,
|
||||
Some(prev) => prev,
|
||||
};
|
||||
|
@ -52,48 +45,37 @@ impl ast::Attr {
|
|||
prev.kind() == T![!]
|
||||
}
|
||||
|
||||
pub fn as_atom(&self) -> Option<SmolStr> {
|
||||
let tt = self.value()?;
|
||||
let (_bra, attr, _ket) = tt.syntax().children_with_tokens().collect_tuple()?;
|
||||
if attr.kind() == IDENT {
|
||||
Some(attr.as_token()?.text().clone())
|
||||
} else {
|
||||
None
|
||||
pub fn as_simple_atom(&self) -> Option<SmolStr> {
|
||||
match self.input() {
|
||||
None => self.simple_name(),
|
||||
Some(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_call(&self) -> Option<(SmolStr, ast::TokenTree)> {
|
||||
let tt = self.value()?;
|
||||
let (_bra, attr, args, _ket) = tt.syntax().children_with_tokens().collect_tuple()?;
|
||||
let args = ast::TokenTree::cast(args.as_node()?.clone())?;
|
||||
if attr.kind() == IDENT {
|
||||
Some((attr.as_token()?.text().clone(), args))
|
||||
} else {
|
||||
None
|
||||
pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> {
|
||||
match self.input() {
|
||||
Some(AttrInput::TokenTree(tt)) => Some((self.simple_name()?, tt)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_named(&self) -> Option<SmolStr> {
|
||||
let tt = self.value()?;
|
||||
let attr = tt.syntax().children_with_tokens().nth(1)?;
|
||||
if attr.kind() == IDENT {
|
||||
Some(attr.as_token()?.text().clone())
|
||||
} else {
|
||||
None
|
||||
pub fn as_simple_key_value(&self) -> Option<(SmolStr, SmolStr)> {
|
||||
match self.input() {
|
||||
Some(AttrInput::Literal(lit)) => {
|
||||
let key = self.simple_name()?;
|
||||
// FIXME: escape? raw string?
|
||||
let value = lit.syntax().first_token()?.text().trim_matches('"').into();
|
||||
Some((key, value))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_key_value(&self) -> Option<(SmolStr, SmolStr)> {
|
||||
let tt = self.value()?;
|
||||
let tt_node = tt.syntax();
|
||||
let attr = tt_node.children_with_tokens().nth(1)?;
|
||||
if attr.kind() == IDENT {
|
||||
let key = attr.as_token()?.text().clone();
|
||||
let val_node = tt_node.children_with_tokens().find(|t| t.kind() == STRING)?;
|
||||
let val = val_node.as_token()?.text().trim_start_matches('"').trim_end_matches('"');
|
||||
Some((key, SmolStr::new(val)))
|
||||
} else {
|
||||
None
|
||||
pub fn simple_name(&self) -> Option<SmolStr> {
|
||||
let path = self.path()?;
|
||||
match (path.segment(), path.qualifier()) {
|
||||
(Some(segment), None) => Some(segment.syntax().first_token()?.text().clone()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -172,9 +172,6 @@ impl Attr {
|
|||
pub fn input(&self) -> Option<AttrInput> {
|
||||
AstChildren::new(&self.syntax).next()
|
||||
}
|
||||
pub fn value(&self) -> Option<TokenTree> {
|
||||
AstChildren::new(&self.syntax).next()
|
||||
}
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum AttrInput {
|
||||
|
|
|
@ -99,7 +99,7 @@ pub trait AttrsOwner: AstNode {
|
|||
children(self)
|
||||
}
|
||||
fn has_atom_attr(&self, atom: &str) -> bool {
|
||||
self.attrs().filter_map(|x| x.as_atom()).any(|x| x == atom)
|
||||
self.attrs().filter_map(|x| x.as_simple_atom()).any(|x| x == atom)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue