X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=crates%2Fhir_def%2Fsrc%2Fitem_tree.rs;h=9a433b61c8ee61084403e86057d1cb42bc6462c5;hb=1d103cf087c574f66279490ffef8c76178aea5cc;hp=ca502ce2ba1494a5c1120784b1fe9184e5fe75ec;hpb=4039176ec63e5c75d76398f2debe26ac6fa59cbc;p=rust.git diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index ca502ce2ba1..9a433b61c8e 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs @@ -1,8 +1,6 @@ //! A simplified AST that only contains items. mod lower; -#[cfg(test)] -mod tests; use std::{ any::type_name, @@ -13,8 +11,8 @@ sync::Arc, }; -use arena::{Arena, Idx, RawId}; -use ast::{AstNode, AttrsOwner, NameOwner, StructKind}; +use ast::{AstNode, NameOwner, StructKind}; +use base_db::CrateId; use either::Either; use hir_expand::{ ast_id_map::FileAstId, @@ -22,13 +20,14 @@ name::{name, AsName, Name}, HirFileId, InFile, }; +use la_arena::{Arena, Idx, RawIdx}; use rustc_hash::FxHashMap; use smallvec::SmallVec; use syntax::{ast, match_ast}; use test_utils::mark; use crate::{ - attr::Attrs, + attr::{Attrs, RawAttrs}, db::DefDatabase, generics::GenericParams, path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind}, @@ -69,7 +68,7 @@ impl GenericParamsId { #[derive(Debug, Eq, PartialEq)] pub struct ItemTree { top_level: SmallVec<[ModItem; 1]>, - attrs: FxHashMap, + attrs: FxHashMap, inner_items: FxHashMap, SmallVec<[ModItem; 1]>>, data: Option>, @@ -90,12 +89,15 @@ pub fn item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc { - top_attrs = Some(Attrs::new(&file, &hygiene)); + top_attrs = Some(RawAttrs::new(&file, &hygiene)); ctx.lower_module_items(&file) }, ast::MacroItems(items) => { ctx.lower_module_items(&items) }, + ast::MacroStmts(stmts) => { + ctx.lower_inner_items(stmts.syntax()) + }, // Macros can expand to expressions. We return an empty item tree in this case, but // still need to collect inner items. ast::Expr(e) => { @@ -141,6 +143,8 @@ fn shrink_to_fit(&mut self) { type_aliases, mods, macro_calls, + macro_rules, + macro_defs, exprs, vis, generics, @@ -161,6 +165,8 @@ fn shrink_to_fit(&mut self) { type_aliases.shrink_to_fit(); mods.shrink_to_fit(); macro_calls.shrink_to_fit(); + macro_rules.shrink_to_fit(); + macro_defs.shrink_to_fit(); exprs.shrink_to_fit(); vis.arena.shrink_to_fit(); @@ -175,12 +181,16 @@ pub fn top_level_items(&self) -> &[ModItem] { } /// Returns the inner attributes of the source file. - pub fn top_level_attrs(&self) -> &Attrs { - self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&Attrs::EMPTY) + pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: CrateId) -> Attrs { + self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&RawAttrs::EMPTY).clone().filter(db, krate) + } + + pub(crate) fn raw_attrs(&self, of: AttrOwner) -> &RawAttrs { + self.attrs.get(&of).unwrap_or(&RawAttrs::EMPTY) } - pub fn attrs(&self, of: AttrOwner) -> &Attrs { - self.attrs.get(&of).unwrap_or(&Attrs::EMPTY) + pub fn attrs(&self, db: &dyn DefDatabase, krate: CrateId, of: AttrOwner) -> Attrs { + self.raw_attrs(of).clone().filter(db, krate) } /// Returns the lowered inner items that `ast` corresponds to. @@ -248,7 +258,11 @@ struct GenericParamsStorage { impl GenericParamsStorage { fn alloc(&mut self, params: GenericParams) -> GenericParamsId { - if params.types.is_empty() && params.where_predicates.is_empty() { + if params.types.is_empty() + && params.lifetimes.is_empty() + && params.consts.is_empty() + && params.where_predicates.is_empty() + { return GenericParamsId::EMPTY; } @@ -256,8 +270,12 @@ fn alloc(&mut self, params: GenericParams) -> GenericParamsId { } } -static EMPTY_GENERICS: GenericParams = - GenericParams { types: Arena::new(), where_predicates: Vec::new() }; +static EMPTY_GENERICS: GenericParams = GenericParams { + types: Arena::new(), + lifetimes: Arena::new(), + consts: Arena::new(), + where_predicates: Vec::new(), +}; #[derive(Default, Debug, Eq, PartialEq)] struct ItemTreeData { @@ -276,6 +294,8 @@ struct ItemTreeData { type_aliases: Arena, mods: Arena, macro_calls: Arena, + macro_rules: Arena, + macro_defs: Arena, exprs: Arena, vis: ItemVisibilities, @@ -423,6 +443,8 @@ fn index(&self, index: Idx<$typ>) -> &Self::Output { TypeAlias in type_aliases -> ast::TypeAlias, Mod in mods -> ast::Module, MacroCall in macro_calls -> ast::MacroCall, + MacroRules in macro_rules -> ast::MacroRules, + MacroDef in macro_defs -> ast::MacroDef, } macro_rules! impl_index { @@ -478,7 +500,6 @@ pub struct Import { pub alias: Option, pub visibility: RawVisibilityId, pub is_glob: bool, - pub is_prelude: bool, /// AST ID of the `use` or `extern crate` item this import was derived from. Note that many /// `Import`s can map to the same `use` item. pub ast_id: FileAstId, @@ -494,8 +515,6 @@ pub struct ExternCrate { pub name: Name, pub alias: Option, pub visibility: RawVisibilityId, - /// Whether this is a `#[macro_use] extern crate ...`. - pub is_macro_use: bool, pub ast_id: FileAstId, } @@ -507,8 +526,9 @@ pub struct Function { pub has_self_param: bool, pub has_body: bool, pub is_unsafe: bool, - /// List of function parameters names. Does not include `self`. - pub param_names: Box<[Option]>, + /// Whether the function is located in an `extern` block (*not* whether it is an + /// `extern "abi" fn`). + pub is_extern: bool, pub params: Box<[TypeRef]>, pub is_varargs: bool, pub ret_type: TypeRef, @@ -567,6 +587,8 @@ pub struct Static { pub name: Name, pub visibility: RawVisibilityId, pub mutable: bool, + /// Whether the static is in an `extern` block. + pub is_extern: bool, pub type_ref: TypeRef, pub ast_id: FileAstId, } @@ -622,19 +644,26 @@ pub enum ModKind { #[derive(Debug, Clone, Eq, PartialEq)] pub struct MacroCall { - /// For `macro_rules!` declarations, this is the name of the declared macro. - pub name: Option, /// Path to the called macro. pub path: ModPath, - /// Has `#[macro_export]`. - pub is_export: bool, - /// Has `#[macro_export(local_inner_macros)]`. - pub is_local_inner: bool, - /// Has `#[rustc_builtin_macro]`. - pub is_builtin: bool, pub ast_id: FileAstId, } +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct MacroRules { + /// The name of the declared macro. + pub name: Name, + pub ast_id: FileAstId, +} + +/// "Macros 2.0" macro definition. +#[derive(Debug, Clone, Eq, PartialEq)] +pub struct MacroDef { + pub name: Name, + pub visibility: RawVisibilityId, + pub ast_id: FileAstId, +} + // NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array // lengths, but we don't do much with them yet. #[derive(Debug, Clone, Eq, PartialEq)] @@ -663,7 +692,9 @@ pub fn as_assoc_item(&self) -> Option { | ModItem::Static(_) | ModItem::Trait(_) | ModItem::Impl(_) - | ModItem::Mod(_) => None, + | ModItem::Mod(_) + | ModItem::MacroRules(_) + | ModItem::MacroDef(_) => None, ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)), ModItem::Const(konst) => Some(AssocItem::Const(*konst)), ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)), @@ -674,6 +705,26 @@ pub fn as_assoc_item(&self) -> Option { pub fn downcast(self) -> Option> { N::id_from_mod_item(self) } + + pub fn ast_id(&self, tree: &ItemTree) -> FileAstId { + match self { + ModItem::Import(it) => tree[it.index].ast_id().upcast(), + ModItem::ExternCrate(it) => tree[it.index].ast_id().upcast(), + ModItem::Function(it) => tree[it.index].ast_id().upcast(), + ModItem::Struct(it) => tree[it.index].ast_id().upcast(), + ModItem::Union(it) => tree[it.index].ast_id().upcast(), + ModItem::Enum(it) => tree[it.index].ast_id().upcast(), + ModItem::Const(it) => tree[it.index].ast_id().upcast(), + ModItem::Static(it) => tree[it.index].ast_id().upcast(), + ModItem::Trait(it) => tree[it.index].ast_id().upcast(), + ModItem::Impl(it) => tree[it.index].ast_id().upcast(), + ModItem::TypeAlias(it) => tree[it.index].ast_id().upcast(), + ModItem::Mod(it) => tree[it.index].ast_id().upcast(), + ModItem::MacroCall(it) => tree[it.index].ast_id().upcast(), + ModItem::MacroRules(it) => tree[it.index].ast_id().upcast(), + ModItem::MacroDef(it) => tree[it.index].ast_id().upcast(), + } + } } #[derive(Debug, Copy, Clone, Eq, PartialEq)]