From 9d244129296a1805f890640016719afcee66a320 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 15 Jun 2020 19:16:14 +0200 Subject: Move collector --- crates/ra_hir_def/src/nameres/collector.rs | 301 ++++++++++++++++++----------- 1 file changed, 193 insertions(+), 108 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 034f27410..b899a5fb3 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs @@ -4,6 +4,7 @@ //! resolves imports and expands macros. use hir_expand::{ + ast_id_map::FileAstId, builtin_derive::find_builtin_derive, builtin_macro::find_builtin_macro, name::{name, AsName, Name}, @@ -19,14 +20,14 @@ use test_utils::mark; use crate::{ attr::Attrs, db::DefDatabase, - item_tree::{Import, ItemTree, Mod, ModItem}, + item_tree::{Import, ItemTree, MacroCall, Mod, ModItem, ModKind, StructDefKind}, nameres::{ diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode, }, path::{ImportAlias, ModPath, PathKind}, per_ns::PerNs, - visibility::Visibility, + visibility::{RawVisibility, Visibility}, AdtId, AsMacroCall, AstId, AstIdWithPath, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, @@ -125,6 +126,13 @@ struct DeriveDirective { ast_id: AstIdWithPath, } +struct DefData<'a> { + id: ModuleDefId, + name: &'a Name, + visibility: &'a RawVisibility, + has_constructor: bool, +} + /// Walks the tree of module recursively struct DefCollector<'a> { db: &'a dyn DefDatabase, @@ -693,9 +701,9 @@ impl ModCollector<'_, '_> { // `#[macro_use] extern crate` is hoisted to imports macros before collecting // any other items. for item in items { - if self.is_cfg_enabled(&item.attrs) { - if let raw::RawItemKind::Import(import_id) = item.kind { - let import = self.item_tree[import_id].clone(); + if self.is_cfg_enabled(self.item_tree.attrs(*item)) { + if let ModItem::Import(import_id) = item { + let import = self.item_tree[*import_id].clone(); if import.is_extern_crate && import.is_macro_use { self.def_collector.import_macros_from_extern_crate(self.module_id, &import); } @@ -703,13 +711,17 @@ impl ModCollector<'_, '_> { } } - for item in items { - if self.is_cfg_enabled(&item.attrs) { - match item.kind { - raw::RawItemKind::Module(m) => { - self.collect_module(&self.item_tree[m], &item.attrs) - } - raw::RawItemKind::Import(import_id) => { + for &item in items { + let attrs = self.item_tree.attrs(item); + if self.is_cfg_enabled(attrs) { + let module = + ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id }; + let container = ContainerId::ModuleId(module); + + let mut def = None; + match item { + ModItem::Mod(m) => self.collect_module(&self.item_tree[m], attrs), + ModItem::Import(import_id) => { self.def_collector.unresolved_imports.push(ImportDirective { module_id: self.module_id, import_id, @@ -717,11 +729,8 @@ impl ModCollector<'_, '_> { status: PartialResolvedImport::Unresolved, }) } - raw::RawItemKind::Def(def) => { - self.define_def(&self.item_tree[def], &item.attrs) - } - raw::RawItemKind::Macro(mac) => self.collect_macro(&self.item_tree[mac]), - raw::RawItemKind::Impl(imp) => { + ModItem::MacroCall(mac) => self.collect_macro(&self.item_tree[mac]), + ModItem::Impl(imp) => { let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id, @@ -735,6 +744,147 @@ impl ModCollector<'_, '_> { .scope .define_impl(impl_id) } + ModItem::Function(it) => { + let it = &self.item_tree[it]; + def = Some(DefData { + id: FunctionLoc { + container: container.into(), + ast_id: AstId::new(self.file_id, it.ast_id), + } + .intern(self.def_collector.db) + .into(), + name: &it.name, + visibility: &it.visibility, + has_constructor: false, + }); + } + ModItem::Struct(it) => { + let it = &self.item_tree[it]; + + // FIXME: check attrs to see if this is an attribute macro invocation; + // in which case we don't add the invocation, just a single attribute + // macro invocation + self.collect_derives(attrs, it.ast_id.upcast()); + + def = Some(DefData { + id: StructLoc { + container, + ast_id: AstId::new(self.file_id, it.ast_id), + } + .intern(self.def_collector.db) + .into(), + name: &it.name, + visibility: &it.visibility, + has_constructor: it.kind != StructDefKind::Record, + }); + } + ModItem::Union(it) => { + let it = &self.item_tree[it]; + + // FIXME: check attrs to see if this is an attribute macro invocation; + // in which case we don't add the invocation, just a single attribute + // macro invocation + self.collect_derives(attrs, it.ast_id.upcast()); + + def = Some(DefData { + id: UnionLoc { container, ast_id: AstId::new(self.file_id, it.ast_id) } + .intern(self.def_collector.db) + .into(), + name: &it.name, + visibility: &it.visibility, + has_constructor: false, + }); + } + ModItem::Enum(it) => { + let it = &self.item_tree[it]; + + // FIXME: check attrs to see if this is an attribute macro invocation; + // in which case we don't add the invocation, just a single attribute + // macro invocation + self.collect_derives(attrs, it.ast_id.upcast()); + + def = Some(DefData { + id: EnumLoc { container, ast_id: AstId::new(self.file_id, it.ast_id) } + .intern(self.def_collector.db) + .into(), + name: &it.name, + visibility: &it.visibility, + has_constructor: false, + }); + } + ModItem::Const(it) => { + let it = &self.item_tree[it]; + + if let Some(name) = &it.name { + def = Some(DefData { + id: ConstLoc { + container: container.into(), + ast_id: AstId::new(self.file_id, it.ast_id), + } + .intern(self.def_collector.db) + .into(), + name, + visibility: &it.visibility, + has_constructor: false, + }); + } + } + ModItem::Static(it) => { + let it = &self.item_tree[it]; + + def = Some(DefData { + id: StaticLoc { + container, + ast_id: AstId::new(self.file_id, it.ast_id), + } + .intern(self.def_collector.db) + .into(), + name: &it.name, + visibility: &it.visibility, + has_constructor: false, + }); + } + ModItem::Trait(it) => { + let it = &self.item_tree[it]; + + def = Some(DefData { + id: TraitLoc { container, ast_id: AstId::new(self.file_id, it.ast_id) } + .intern(self.def_collector.db) + .into(), + name: &it.name, + visibility: &it.visibility, + has_constructor: false, + }); + } + ModItem::TypeAlias(it) => { + let it = &self.item_tree[it]; + + def = Some(DefData { + id: TypeAliasLoc { + container: container.into(), + ast_id: AstId::new(self.file_id, it.ast_id), + } + .intern(self.def_collector.db) + .into(), + name: &it.name, + visibility: &it.visibility, + has_constructor: false, + }); + } + } + + if let Some(DefData { id, name, visibility, has_constructor }) = def { + self.def_collector.def_map.modules[self.module_id].scope.define_def(id); + let vis = self + .def_collector + .def_map + .resolve_visibility(self.def_collector.db, self.module_id, visibility) + .unwrap_or(Visibility::Public); + self.def_collector.update( + self.module_id, + &[(name.clone(), PerNs::from_def(id, vis, has_constructor))], + vis, + ) } } } @@ -743,14 +893,14 @@ impl ModCollector<'_, '_> { fn collect_module(&mut self, module: &Mod, attrs: &Attrs) { let path_attr = attrs.by_key("path").string_value(); let is_macro_use = attrs.by_key("macro_use").exists(); - match module { + match &module.kind { // inline module, just recurse - raw::ModuleData::Definition { name, visibility, items, ast_id } => { + ModKind::Inline { items } => { let module_id = self.push_child_module( - name.clone(), - AstId::new(self.file_id, *ast_id), + module.name.clone(), + AstId::new(self.file_id, module.ast_id), None, - &visibility, + &module.visibility, ); ModCollector { @@ -759,7 +909,7 @@ impl ModCollector<'_, '_> { module_id, file_id: self.file_id, item_tree: self.item_tree, - mod_dir: self.mod_dir.descend_into_definition(name, path_attr), + mod_dir: self.mod_dir.descend_into_definition(&module.name, path_attr), } .collect(&*items); if is_macro_use { @@ -767,31 +917,31 @@ impl ModCollector<'_, '_> { } } // out of line module, resolve, parse and recurse - raw::ModuleData::Declaration { name, visibility, ast_id } => { - let ast_id = AstId::new(self.file_id, *ast_id); + ModKind::Outline {} => { + let ast_id = AstId::new(self.file_id, module.ast_id); match self.mod_dir.resolve_declaration( self.def_collector.db, self.file_id, - name, + &module.name, path_attr, ) { Ok((file_id, is_mod_rs, mod_dir)) => { let module_id = self.push_child_module( - name.clone(), + module.name.clone(), ast_id, Some((file_id, is_mod_rs)), - &visibility, + &module.visibility, ); - let raw_items = self.def_collector.db.raw_items(file_id.into()); + let item_tree = self.def_collector.db.item_tree(file_id.into()); ModCollector { def_collector: &mut *self.def_collector, macro_depth: self.macro_depth, module_id, file_id: file_id.into(), - item_tree: &raw_items, + item_tree: &item_tree, mod_dir, } - .collect(raw_items.items()); + .collect(item_tree.top_level_items()); if is_macro_use { self.import_all_legacy_macros(module_id); } @@ -840,77 +990,7 @@ impl ModCollector<'_, '_> { res } - fn define_def(&mut self, def: &raw::DefData, attrs: &Attrs) { - let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id }; - // FIXME: check attrs to see if this is an attribute macro invocation; - // in which case we don't add the invocation, just a single attribute - // macro invocation - self.collect_derives(attrs, def); - - let name = def.name.clone(); - let container = ContainerId::ModuleId(module); - let vis = &def.visibility; - let mut has_constructor = false; - - let def: ModuleDefId = match def.kind { - raw::DefKind::Function(ast_id) => FunctionLoc { - container: container.into(), - ast_id: AstId::new(self.file_id, ast_id), - } - .intern(self.def_collector.db) - .into(), - raw::DefKind::Struct(ast_id, mode) => { - has_constructor = mode != raw::StructDefKind::Record; - StructLoc { container, ast_id: AstId::new(self.file_id, ast_id) } - .intern(self.def_collector.db) - .into() - } - raw::DefKind::Union(ast_id) => { - UnionLoc { container, ast_id: AstId::new(self.file_id, ast_id) } - .intern(self.def_collector.db) - .into() - } - raw::DefKind::Enum(ast_id) => { - EnumLoc { container, ast_id: AstId::new(self.file_id, ast_id) } - .intern(self.def_collector.db) - .into() - } - raw::DefKind::Const(ast_id) => { - ConstLoc { container: container.into(), ast_id: AstId::new(self.file_id, ast_id) } - .intern(self.def_collector.db) - .into() - } - raw::DefKind::Static(ast_id) => { - StaticLoc { container, ast_id: AstId::new(self.file_id, ast_id) } - .intern(self.def_collector.db) - .into() - } - raw::DefKind::Trait(ast_id) => { - TraitLoc { container, ast_id: AstId::new(self.file_id, ast_id) } - .intern(self.def_collector.db) - .into() - } - raw::DefKind::TypeAlias(ast_id) => TypeAliasLoc { - container: container.into(), - ast_id: AstId::new(self.file_id, ast_id), - } - .intern(self.def_collector.db) - .into(), - }; - self.def_collector.def_map.modules[self.module_id].scope.define_def(def); - let vis = self - .def_collector - .def_map - .resolve_visibility(self.def_collector.db, self.module_id, vis) - .unwrap_or(Visibility::Public); - self.def_collector.update( - self.module_id, - &[(name, PerNs::from_def(def, vis, has_constructor))], - vis, - ) - } - - fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) { + fn collect_derives(&mut self, attrs: &Attrs, ast_id: FileAstId) { for derive_subtree in attrs.by_key("derive").tt_values() { // for #[derive(Copy, Clone)], `derive_subtree` is the `(Copy, Clone)` subtree for tt in &derive_subtree.token_trees { @@ -921,7 +1001,7 @@ impl ModCollector<'_, '_> { }; let path = ModPath::from_tt_ident(ident); - let ast_id = AstIdWithPath::new(self.file_id, def.kind.ast_id(), path); + let ast_id = AstIdWithPath::new(self.file_id, ast_id, path); self.def_collector .unexpanded_attribute_macros .push(DeriveDirective { module_id: self.module_id, ast_id }); @@ -929,11 +1009,11 @@ impl ModCollector<'_, '_> { } } - fn collect_macro(&mut self, mac: &raw::MacroData) { + fn collect_macro(&mut self, mac: &MacroCall) { let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone()); // Case 0: builtin macros - if mac.builtin { + if mac.is_builtin { if let Some(name) = &mac.name { let krate = self.def_collector.def_map.krate; if let Some(macro_id) = find_builtin_macro(name, krate, ast_id.ast_id) { @@ -941,7 +1021,7 @@ impl ModCollector<'_, '_> { self.module_id, name.clone(), macro_id, - mac.export, + mac.is_export, ); return; } @@ -955,9 +1035,14 @@ impl ModCollector<'_, '_> { ast_id: Some(ast_id.ast_id), krate: Some(self.def_collector.def_map.krate), kind: MacroDefKind::Declarative, - local_inner: mac.local_inner, + local_inner: mac.is_local_inner, }; - self.def_collector.define_macro(self.module_id, name.clone(), macro_id, mac.export); + self.def_collector.define_macro( + self.module_id, + name.clone(), + macro_id, + mac.is_export, + ); } return; } -- cgit v1.2.3