Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-expand/src/attrs.rs')
| -rw-r--r-- | crates/hir-expand/src/attrs.rs | 106 |
1 files changed, 50 insertions, 56 deletions
diff --git a/crates/hir-expand/src/attrs.rs b/crates/hir-expand/src/attrs.rs index c9c793d54f..5dae27f7a1 100644 --- a/crates/hir-expand/src/attrs.rs +++ b/crates/hir-expand/src/attrs.rs @@ -1,26 +1,26 @@ //! A higher level attributes based on TokenTree, with also some shortcuts. use std::{borrow::Cow, fmt, ops}; -use base_db::CrateId; +use base_db::Crate; use cfg::CfgExpr; use either::Either; -use intern::{sym, Interned, Symbol}; +use intern::{Interned, Symbol, sym}; use mbe::{DelimiterKind, Punct}; -use smallvec::{smallvec, SmallVec}; -use span::{Span, SyntaxContextId}; +use smallvec::{SmallVec, smallvec}; +use span::{Span, SyntaxContext}; use syntax::unescape; -use syntax::{ast, match_ast, AstNode, AstToken, SyntaxNode}; -use syntax_bridge::{desugar_doc_comment_text, syntax_node_to_token_tree, DocCommentDesugarMode}; +use syntax::{AstNode, AstToken, SyntaxNode, ast, match_ast}; +use syntax_bridge::{DocCommentDesugarMode, desugar_doc_comment_text, syntax_node_to_token_tree}; use triomphe::ThinArc; use crate::name::Name; use crate::{ + InFile, db::ExpandDatabase, mod_path::ModPath, span_map::SpanMapRef, - tt::{self, token_to_literal, TopSubtree}, - InFile, + tt::{self, TopSubtree, token_to_literal}, }; /// Syntactical attributes, without filtering of `cfg_attr`s. @@ -66,10 +66,7 @@ impl RawAttrs { kind, suffix: None, }))), - path: Interned::new(ModPath::from(Name::new_symbol( - sym::doc.clone(), - span.ctx, - ))), + path: Interned::new(ModPath::from(Name::new_symbol(sym::doc, span.ctx))), ctxt: span.ctx, } }), @@ -119,50 +116,48 @@ impl RawAttrs { /// Processes `cfg_attr`s, returning the resulting semantic `Attrs`. // FIXME: This should return a different type, signaling it was filtered? - pub fn filter(self, db: &dyn ExpandDatabase, krate: CrateId) -> RawAttrs { - let has_cfg_attrs = self - .iter() - .any(|attr| attr.path.as_ident().is_some_and(|name| *name == sym::cfg_attr.clone())); + pub fn filter(self, db: &dyn ExpandDatabase, krate: Crate) -> RawAttrs { + let has_cfg_attrs = + self.iter().any(|attr| attr.path.as_ident().is_some_and(|name| *name == sym::cfg_attr)); if !has_cfg_attrs { return self; } - let crate_graph = db.crate_graph(); - let new_attrs = - self.iter() - .flat_map(|attr| -> SmallVec<[_; 1]> { - let is_cfg_attr = - attr.path.as_ident().is_some_and(|name| *name == sym::cfg_attr.clone()); - if !is_cfg_attr { - return smallvec![attr.clone()]; - } + let cfg_options = krate.cfg_options(db); + let new_attrs = self + .iter() + .flat_map(|attr| -> SmallVec<[_; 1]> { + let is_cfg_attr = attr.path.as_ident().is_some_and(|name| *name == sym::cfg_attr); + if !is_cfg_attr { + return smallvec![attr.clone()]; + } - let subtree = match attr.token_tree_value() { - Some(it) => it, - _ => return smallvec![attr.clone()], - }; - - let (cfg, parts) = match parse_cfg_attr_input(subtree) { - Some(it) => it, - None => return smallvec![attr.clone()], - }; - let index = attr.id; - let attrs = parts.enumerate().take(1 << AttrId::CFG_ATTR_BITS).filter_map( - |(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx)), - ); - - let cfg_options = &crate_graph[krate].cfg_options; - let cfg = TopSubtree::from_token_trees(subtree.top_subtree().delimiter, cfg); - let cfg = CfgExpr::parse(&cfg); - if cfg_options.check(&cfg) == Some(false) { - smallvec![] - } else { - cov_mark::hit!(cfg_attr_active); - - attrs.collect() - } - }) - .collect::<Vec<_>>(); + let subtree = match attr.token_tree_value() { + Some(it) => it, + _ => return smallvec![attr.clone()], + }; + + let (cfg, parts) = match parse_cfg_attr_input(subtree) { + Some(it) => it, + None => return smallvec![attr.clone()], + }; + let index = attr.id; + let attrs = parts + .enumerate() + .take(1 << AttrId::CFG_ATTR_BITS) + .filter_map(|(idx, attr)| Attr::from_tt(db, attr, index.with_cfg_attr(idx))); + + let cfg = TopSubtree::from_token_trees(subtree.top_subtree().delimiter, cfg); + let cfg = CfgExpr::parse(&cfg); + if cfg_options.check(&cfg) == Some(false) { + smallvec![] + } else { + cov_mark::hit!(cfg_attr_active); + + attrs.collect() + } + }) + .collect::<Vec<_>>(); let entries = if new_attrs.is_empty() { None } else { @@ -211,7 +206,7 @@ pub struct Attr { pub id: AttrId, pub path: Interned<ModPath>, pub input: Option<Box<AttrInput>>, - pub ctxt: SyntaxContextId, + pub ctxt: SyntaxContext, } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -306,13 +301,12 @@ impl Attr { Some(Box::new(AttrInput::TokenTree(tt::TopSubtree::from_subtree(tree)))) } (Some(tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '=', .. }))), _) => { - let input = match input.flat_tokens().get(1) { + match input.flat_tokens().get(1) { Some(tt::TokenTree::Leaf(tt::Leaf::Literal(lit))) => { Some(Box::new(AttrInput::Literal(lit.clone()))) } _ => None, - }; - input + } } _ => None, }; @@ -403,7 +397,7 @@ impl Attr { } pub fn cfg(&self) -> Option<CfgExpr> { - if *self.path.as_ident()? == sym::cfg.clone() { + if *self.path.as_ident()? == sym::cfg { self.token_tree_value().map(CfgExpr::parse) } else { None |