mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-03 07:04:49 +00:00
Nicer API for attrs
This commit is contained in:
parent
1956d57ed4
commit
4b74fb1d89
4 changed files with 39 additions and 33 deletions
|
@ -4,7 +4,6 @@ use std::{ops, sync::Arc};
|
|||
|
||||
use hir_expand::{either::Either, hygiene::Hygiene, AstId, Source};
|
||||
use mbe::ast_to_token_tree;
|
||||
use ra_cfg::CfgOptions;
|
||||
use ra_syntax::{
|
||||
ast::{self, AstNode, AttrsOwner},
|
||||
SmolStr,
|
||||
|
@ -85,17 +84,8 @@ impl Attrs {
|
|||
Attrs { entries }
|
||||
}
|
||||
|
||||
pub fn has_atom(&self, atom: &str) -> bool {
|
||||
self.iter().any(|it| it.is_simple_atom(atom))
|
||||
}
|
||||
|
||||
pub fn find_string_value(&self, key: &str) -> Option<SmolStr> {
|
||||
self.iter().filter(|attr| attr.is_simple_atom(key)).find_map(|attr| {
|
||||
match attr.input.as_ref()? {
|
||||
AttrInput::Literal(it) => Some(it.clone()),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> {
|
||||
AttrQuery { attrs: self, key }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -128,25 +118,37 @@ impl Attr {
|
|||
|
||||
Some(Attr { path, input })
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_simple_atom(&self, name: &str) -> bool {
|
||||
// FIXME: Avoid cloning
|
||||
self.path.as_ident().map_or(false, |s| s.to_string() == name)
|
||||
}
|
||||
pub struct AttrQuery<'a> {
|
||||
attrs: &'a Attrs,
|
||||
key: &'static str,
|
||||
}
|
||||
|
||||
// FIXME: handle cfg_attr :-)
|
||||
pub fn as_cfg(&self) -> Option<&Subtree> {
|
||||
if !self.is_simple_atom("cfg") {
|
||||
return None;
|
||||
}
|
||||
match &self.input {
|
||||
Some(AttrInput::TokenTree(subtree)) => Some(subtree),
|
||||
impl<'a> AttrQuery<'a> {
|
||||
pub fn tt_values(self) -> impl Iterator<Item = &'a Subtree> {
|
||||
self.attrs().filter_map(|attr| match attr.input.as_ref()? {
|
||||
AttrInput::TokenTree(it) => Some(it),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> Option<bool> {
|
||||
cfg_options.is_cfg_enabled(self.as_cfg()?)
|
||||
pub fn string_value(self) -> Option<&'a SmolStr> {
|
||||
self.attrs().find_map(|attr| match attr.input.as_ref()? {
|
||||
AttrInput::Literal(it) => Some(it),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn exists(self) -> bool {
|
||||
self.attrs().next().is_some()
|
||||
}
|
||||
|
||||
fn attrs(self) -> impl Iterator<Item = &'a Attr> {
|
||||
let key = self.key;
|
||||
self.attrs
|
||||
.iter()
|
||||
.filter(move |attr| attr.path.as_ident().map_or(false, |s| s.to_string() == key))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ impl LangItems {
|
|||
T: Into<AttrDefId> + Copy,
|
||||
{
|
||||
let attrs = db.attrs(item.into());
|
||||
if let Some(lang_item_name) = attrs.find_string_value("lang") {
|
||||
if let Some(lang_item_name) = attrs.by_key("lang").string_value() {
|
||||
self.items.entry(lang_item_name.clone()).or_insert_with(|| constructor(item));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -599,8 +599,8 @@ where
|
|||
}
|
||||
|
||||
fn collect_module(&mut self, module: &raw::ModuleData, attrs: &Attrs) {
|
||||
let path_attr = attrs.find_string_value("path");
|
||||
let is_macro_use = attrs.has_atom("macro_use");
|
||||
let path_attr = attrs.by_key("path").string_value();
|
||||
let is_macro_use = attrs.by_key("macro_use").exists();
|
||||
match module {
|
||||
// inline module, just recurse
|
||||
raw::ModuleData::Definition { name, items, ast_id } => {
|
||||
|
@ -612,7 +612,7 @@ where
|
|||
module_id,
|
||||
file_id: self.file_id,
|
||||
raw_items: self.raw_items,
|
||||
mod_dir: self.mod_dir.descend_into_definition(name, path_attr.as_ref()),
|
||||
mod_dir: self.mod_dir.descend_into_definition(name, path_attr),
|
||||
}
|
||||
.collect(&*items);
|
||||
if is_macro_use {
|
||||
|
@ -626,7 +626,7 @@ where
|
|||
self.def_collector.db,
|
||||
self.file_id,
|
||||
name,
|
||||
path_attr.as_ref(),
|
||||
path_attr,
|
||||
) {
|
||||
Ok((file_id, mod_dir)) => {
|
||||
let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id));
|
||||
|
@ -796,7 +796,11 @@ where
|
|||
}
|
||||
|
||||
fn is_cfg_enabled(&self, attrs: &Attrs) -> bool {
|
||||
attrs.iter().all(|attr| attr.is_cfg_enabled(&self.def_collector.cfg_options) != Some(false))
|
||||
// FIXME: handle cfg_attr :-)
|
||||
attrs
|
||||
.by_key("cfg")
|
||||
.tt_values()
|
||||
.all(|tt| self.def_collector.cfg_options.is_cfg_enabled(tt) != Some(false))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -288,7 +288,7 @@ impl Completions {
|
|||
}
|
||||
|
||||
fn is_deprecated(node: impl HasAttrs, db: &impl HirDatabase) -> bool {
|
||||
node.attrs(db).has_atom("deprecated")
|
||||
node.attrs(db).by_key("deprecated").exists()
|
||||
}
|
||||
|
||||
fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue