mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Fix API of Attr
This commit is contained in:
parent
71efdaa636
commit
5a4b4f507e
@ -13,7 +13,7 @@ pub(crate) fn add_derive(mut ctx: AssistCtx<impl HirDatabase>) -> Option<Assist>
|
|||||||
ctx.add_action(AssistId("add_derive"), "add `#[derive]`", |edit| {
|
ctx.add_action(AssistId("add_derive"), "add `#[derive]`", |edit| {
|
||||||
let derive_attr = nominal
|
let derive_attr = nominal
|
||||||
.attrs()
|
.attrs()
|
||||||
.filter_map(|x| x.as_call())
|
.filter_map(|x| x.as_simple_call())
|
||||||
.filter(|(name, _arg)| name == "derive")
|
.filter(|(name, _arg)| name == "derive")
|
||||||
.map(|(_name, arg)| arg)
|
.map(|(_name, arg)| arg)
|
||||||
.next();
|
.next();
|
||||||
|
@ -151,7 +151,7 @@ impl LangItems {
|
|||||||
|
|
||||||
fn lang_item_name<T: AttrsOwner>(node: &T) -> Option<SmolStr> {
|
fn lang_item_name<T: AttrsOwner>(node: &T) -> Option<SmolStr> {
|
||||||
node.attrs()
|
node.attrs()
|
||||||
.filter_map(|a| a.as_key_value())
|
.filter_map(|a| a.as_simple_key_value())
|
||||||
.filter(|(key, _)| key == "lang")
|
.filter(|(key, _)| key == "lang")
|
||||||
.map(|(_, val)| val)
|
.map(|(_, val)| val)
|
||||||
.nth(0)
|
.nth(0)
|
||||||
|
@ -353,8 +353,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
|
|||||||
|
|
||||||
let name = m.name().map(|it| it.as_name());
|
let name = m.name().map(|it| it.as_name());
|
||||||
let ast_id = self.source_ast_id_map.ast_id(&m);
|
let ast_id = self.source_ast_id_map.ast_id(&m);
|
||||||
let export = m.has_atom_attr("macro_export")
|
let export = m.attrs().filter_map(|x| x.simple_name()).any(|name| name == "macro_export");
|
||||||
|| m.attrs().filter_map(|x| x.as_call()).any(|(name, _)| name == "macro_export");
|
|
||||||
|
|
||||||
let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export });
|
let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export });
|
||||||
self.push_item(current_module, RawItem::Macro(m));
|
self.push_item(current_module, RawItem::Macro(m));
|
||||||
@ -385,7 +384,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
|
|||||||
|
|
||||||
fn extract_mod_path_attribute(module: &ast::Module) -> Option<SmolStr> {
|
fn extract_mod_path_attribute(module: &ast::Module) -> Option<SmolStr> {
|
||||||
module.attrs().into_iter().find_map(|attr| {
|
module.attrs().into_iter().find_map(|attr| {
|
||||||
attr.as_key_value().and_then(|(name, value)| {
|
attr.as_simple_key_value().and_then(|(name, value)| {
|
||||||
let is_path = name == "path";
|
let is_path = name == "path";
|
||||||
if is_path {
|
if is_path {
|
||||||
Some(value)
|
Some(value)
|
||||||
|
@ -77,7 +77,7 @@ fn structure_node(node: &SyntaxNode) -> Option<StructureNode> {
|
|||||||
node_range: node.syntax().text_range(),
|
node_range: node.syntax().text_range(),
|
||||||
kind: node.syntax().kind(),
|
kind: node.syntax().kind(),
|
||||||
detail,
|
detail,
|
||||||
deprecated: node.attrs().filter_map(|x| x.as_named()).any(|x| x == "deprecated"),
|
deprecated: node.attrs().filter_map(|x| x.simple_name()).any(|x| x == "deprecated"),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||||||
.keyword\.unsafe { color: #DFAF8F; }
|
.keyword\.unsafe { color: #DFAF8F; }
|
||||||
.keyword\.control { color: #F0DFAF; font-weight: bold; }
|
.keyword\.control { color: #F0DFAF; font-weight: bold; }
|
||||||
</style>
|
</style>
|
||||||
<pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="attribute">derive</span><span class="attribute">(</span><span class="attribute">Clone</span><span class="attribute">,</span><span class="attribute"> </span><span class="attribute">Debug</span><span class="attribute">)</span><span class="attribute">]</span>
|
<pre><code><span class="attribute">#</span><span class="attribute">[</span><span class="attribute text">derive</span><span class="attribute">(</span><span class="attribute">Clone</span><span class="attribute">,</span><span class="attribute"> </span><span class="attribute">Debug</span><span class="attribute">)</span><span class="attribute">]</span>
|
||||||
<span class="keyword">struct</span> <span class="type">Foo</span> {
|
<span class="keyword">struct</span> <span class="type">Foo</span> {
|
||||||
<span class="keyword">pub</span> <span class="field">x</span>: <span class="type">i32</span>,
|
<span class="keyword">pub</span> <span class="field">x</span>: <span class="type">i32</span>,
|
||||||
<span class="keyword">pub</span> <span class="field">y</span>: <span class="type">i32</span>,
|
<span class="keyword">pub</span> <span class="field">y</span>: <span class="type">i32</span>,
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
//! Various extension methods to ast Nodes, which are hard to code-generate.
|
//! Various extension methods to ast Nodes, which are hard to code-generate.
|
||||||
//! Extensions for various expressions live in a sibling `expr_extensions` module.
|
//! Extensions for various expressions live in a sibling `expr_extensions` module.
|
||||||
|
|
||||||
use itertools::Itertools;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{self, child_opt, children, AstChildren, AstNode, SyntaxNode},
|
ast::{self, child_opt, children, AstChildren, AstNode, AttrInput, SyntaxNode},
|
||||||
SmolStr, SyntaxElement,
|
SmolStr, SyntaxElement,
|
||||||
SyntaxKind::*,
|
SyntaxKind::*,
|
||||||
SyntaxToken, T,
|
SyntaxToken, T,
|
||||||
@ -39,12 +37,7 @@ fn text_of_first_token(node: &SyntaxNode) -> &SmolStr {
|
|||||||
|
|
||||||
impl ast::Attr {
|
impl ast::Attr {
|
||||||
pub fn is_inner(&self) -> bool {
|
pub fn is_inner(&self) -> bool {
|
||||||
let tt = match self.value() {
|
let prev = match self.syntax().prev_sibling() {
|
||||||
None => return false,
|
|
||||||
Some(tt) => tt,
|
|
||||||
};
|
|
||||||
|
|
||||||
let prev = match tt.syntax().prev_sibling() {
|
|
||||||
None => return false,
|
None => return false,
|
||||||
Some(prev) => prev,
|
Some(prev) => prev,
|
||||||
};
|
};
|
||||||
@ -52,48 +45,37 @@ impl ast::Attr {
|
|||||||
prev.kind() == T![!]
|
prev.kind() == T![!]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_atom(&self) -> Option<SmolStr> {
|
pub fn as_simple_atom(&self) -> Option<SmolStr> {
|
||||||
let tt = self.value()?;
|
match self.input() {
|
||||||
let (_bra, attr, _ket) = tt.syntax().children_with_tokens().collect_tuple()?;
|
None => self.simple_name(),
|
||||||
if attr.kind() == IDENT {
|
Some(_) => None,
|
||||||
Some(attr.as_token()?.text().clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_call(&self) -> Option<(SmolStr, ast::TokenTree)> {
|
pub fn as_simple_call(&self) -> Option<(SmolStr, ast::TokenTree)> {
|
||||||
let tt = self.value()?;
|
match self.input() {
|
||||||
let (_bra, attr, args, _ket) = tt.syntax().children_with_tokens().collect_tuple()?;
|
Some(AttrInput::TokenTree(tt)) => Some((self.simple_name()?, tt)),
|
||||||
let args = ast::TokenTree::cast(args.as_node()?.clone())?;
|
_ => None,
|
||||||
if attr.kind() == IDENT {
|
|
||||||
Some((attr.as_token()?.text().clone(), args))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_named(&self) -> Option<SmolStr> {
|
pub fn as_simple_key_value(&self) -> Option<(SmolStr, SmolStr)> {
|
||||||
let tt = self.value()?;
|
match self.input() {
|
||||||
let attr = tt.syntax().children_with_tokens().nth(1)?;
|
Some(AttrInput::Literal(lit)) => {
|
||||||
if attr.kind() == IDENT {
|
let key = self.simple_name()?;
|
||||||
Some(attr.as_token()?.text().clone())
|
// FIXME: escape? raw string?
|
||||||
} else {
|
let value = lit.syntax().first_token()?.text().trim_matches('"').into();
|
||||||
None
|
Some((key, value))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_key_value(&self) -> Option<(SmolStr, SmolStr)> {
|
pub fn simple_name(&self) -> Option<SmolStr> {
|
||||||
let tt = self.value()?;
|
let path = self.path()?;
|
||||||
let tt_node = tt.syntax();
|
match (path.segment(), path.qualifier()) {
|
||||||
let attr = tt_node.children_with_tokens().nth(1)?;
|
(Some(segment), None) => Some(segment.syntax().first_token()?.text().clone()),
|
||||||
if attr.kind() == IDENT {
|
_ => None,
|
||||||
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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,9 +172,6 @@ impl Attr {
|
|||||||
pub fn input(&self) -> Option<AttrInput> {
|
pub fn input(&self) -> Option<AttrInput> {
|
||||||
AstChildren::new(&self.syntax).next()
|
AstChildren::new(&self.syntax).next()
|
||||||
}
|
}
|
||||||
pub fn value(&self) -> Option<TokenTree> {
|
|
||||||
AstChildren::new(&self.syntax).next()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub enum AttrInput {
|
pub enum AttrInput {
|
||||||
|
@ -99,7 +99,7 @@ pub trait AttrsOwner: AstNode {
|
|||||||
children(self)
|
children(self)
|
||||||
}
|
}
|
||||||
fn has_atom_attr(&self, atom: &str) -> bool {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,7 +577,7 @@ Grammar(
|
|||||||
options: [ "TokenTree", "Path" ],
|
options: [ "TokenTree", "Path" ],
|
||||||
),
|
),
|
||||||
"AttrInput": ( enum: [ "Literal", "TokenTree" ] ),
|
"AttrInput": ( enum: [ "Literal", "TokenTree" ] ),
|
||||||
"Attr": ( options: [ "Path", [ "input", "AttrInput" ], [ "value", "TokenTree" ] ] ),
|
"Attr": ( options: [ "Path", [ "input", "AttrInput" ] ] ),
|
||||||
"TokenTree": (),
|
"TokenTree": (),
|
||||||
"TypeParamList": (
|
"TypeParamList": (
|
||||||
collections: [
|
collections: [
|
||||||
|
Loading…
x
Reference in New Issue
Block a user