diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-06-24 16:07:37 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-06-24 16:07:37 +0100 |
commit | e9bdb05e9676e85bdd8fa5008e3ada3812b36fd9 (patch) | |
tree | a21d348fbfa2d06f1fba77622c5417383938e6fe /crates/ra_hir_def/src/nameres/collector.rs | |
parent | 1a3b507a007d0373a83bde203d780b860ea55ce1 (diff) | |
parent | 2928600374a8356c2c2bffee080c47cb0f463fb9 (diff) |
Merge #4990
4990: Introduce an ItemTree layer to avoid reparsing files r=matklad a=jonas-schievink
This reduces the latency of "go to definition" in a simple benchmark on rust-analyzer by around 30%.
cc https://github.com/rust-analyzer/rust-analyzer/issues/1650
Closes https://github.com/rust-analyzer/rust-analyzer/issues/3485
Co-authored-by: Aleksey Kladov <[email protected]>
Co-authored-by: Jonas Schievink <[email protected]>
Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/ra_hir_def/src/nameres/collector.rs')
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 386 |
1 files changed, 254 insertions, 132 deletions
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index cbce04315..94da700ad 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -4,6 +4,7 @@ | |||
4 | //! resolves imports and expands macros. | 4 | //! resolves imports and expands macros. |
5 | 5 | ||
6 | use hir_expand::{ | 6 | use hir_expand::{ |
7 | ast_id_map::FileAstId, | ||
7 | builtin_derive::find_builtin_derive, | 8 | builtin_derive::find_builtin_derive, |
8 | builtin_macro::find_builtin_macro, | 9 | builtin_macro::find_builtin_macro, |
9 | name::{name, AsName, Name}, | 10 | name::{name, AsName, Name}, |
@@ -19,13 +20,16 @@ use test_utils::mark; | |||
19 | use crate::{ | 20 | use crate::{ |
20 | attr::Attrs, | 21 | attr::Attrs, |
21 | db::DefDatabase, | 22 | db::DefDatabase, |
23 | item_tree::{ | ||
24 | self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, Mod, ModItem, ModKind, StructDefKind, | ||
25 | }, | ||
22 | nameres::{ | 26 | nameres::{ |
23 | diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, | 27 | diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, |
24 | raw, BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode, | 28 | BuiltinShadowMode, CrateDefMap, ModuleData, ModuleOrigin, ResolveMode, |
25 | }, | 29 | }, |
26 | path::{ImportAlias, ModPath, PathKind}, | 30 | path::{ImportAlias, ModPath, PathKind}, |
27 | per_ns::PerNs, | 31 | per_ns::PerNs, |
28 | visibility::Visibility, | 32 | visibility::{RawVisibility, Visibility}, |
29 | AdtId, AsMacroCall, AstId, AstIdWithPath, ConstLoc, ContainerId, EnumLoc, EnumVariantId, | 33 | AdtId, AsMacroCall, AstId, AstIdWithPath, ConstLoc, ContainerId, EnumLoc, EnumVariantId, |
30 | FunctionLoc, ImplLoc, Intern, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, | 34 | FunctionLoc, ImplLoc, Intern, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, |
31 | TraitLoc, TypeAliasLoc, UnionLoc, | 35 | TraitLoc, TypeAliasLoc, UnionLoc, |
@@ -102,10 +106,50 @@ impl PartialResolvedImport { | |||
102 | } | 106 | } |
103 | 107 | ||
104 | #[derive(Clone, Debug, Eq, PartialEq)] | 108 | #[derive(Clone, Debug, Eq, PartialEq)] |
109 | struct Import { | ||
110 | pub path: ModPath, | ||
111 | pub alias: Option<ImportAlias>, | ||
112 | pub visibility: RawVisibility, | ||
113 | pub is_glob: bool, | ||
114 | pub is_prelude: bool, | ||
115 | pub is_extern_crate: bool, | ||
116 | pub is_macro_use: bool, | ||
117 | } | ||
118 | |||
119 | impl Import { | ||
120 | fn from_use(tree: &ItemTree, id: FileItemTreeId<item_tree::Import>) -> Self { | ||
121 | let it = &tree[id]; | ||
122 | let visibility = &tree[it.visibility]; | ||
123 | Self { | ||
124 | path: it.path.clone(), | ||
125 | alias: it.alias.clone(), | ||
126 | visibility: visibility.clone(), | ||
127 | is_glob: it.is_glob, | ||
128 | is_prelude: it.is_prelude, | ||
129 | is_extern_crate: false, | ||
130 | is_macro_use: false, | ||
131 | } | ||
132 | } | ||
133 | |||
134 | fn from_extern_crate(tree: &ItemTree, id: FileItemTreeId<item_tree::ExternCrate>) -> Self { | ||
135 | let it = &tree[id]; | ||
136 | let visibility = &tree[it.visibility]; | ||
137 | Self { | ||
138 | path: it.path.clone(), | ||
139 | alias: it.alias.clone(), | ||
140 | visibility: visibility.clone(), | ||
141 | is_glob: false, | ||
142 | is_prelude: false, | ||
143 | is_extern_crate: true, | ||
144 | is_macro_use: it.is_macro_use, | ||
145 | } | ||
146 | } | ||
147 | } | ||
148 | |||
149 | #[derive(Clone, Debug, Eq, PartialEq)] | ||
105 | struct ImportDirective { | 150 | struct ImportDirective { |
106 | module_id: LocalModuleId, | 151 | module_id: LocalModuleId, |
107 | import_id: raw::Import, | 152 | import: Import, |
108 | import: raw::ImportData, | ||
109 | status: PartialResolvedImport, | 153 | status: PartialResolvedImport, |
110 | } | 154 | } |
111 | 155 | ||
@@ -123,6 +167,13 @@ struct DeriveDirective { | |||
123 | ast_id: AstIdWithPath<ast::ModuleItem>, | 167 | ast_id: AstIdWithPath<ast::ModuleItem>, |
124 | } | 168 | } |
125 | 169 | ||
170 | struct DefData<'a> { | ||
171 | id: ModuleDefId, | ||
172 | name: &'a Name, | ||
173 | visibility: &'a RawVisibility, | ||
174 | has_constructor: bool, | ||
175 | } | ||
176 | |||
126 | /// Walks the tree of module recursively | 177 | /// Walks the tree of module recursively |
127 | struct DefCollector<'a> { | 178 | struct DefCollector<'a> { |
128 | db: &'a dyn DefDatabase, | 179 | db: &'a dyn DefDatabase, |
@@ -140,7 +191,7 @@ struct DefCollector<'a> { | |||
140 | impl DefCollector<'_> { | 191 | impl DefCollector<'_> { |
141 | fn collect(&mut self) { | 192 | fn collect(&mut self) { |
142 | let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id; | 193 | let file_id = self.db.crate_graph()[self.def_map.krate].root_file_id; |
143 | let raw_items = self.db.raw_items(file_id.into()); | 194 | let item_tree = self.db.item_tree(file_id.into()); |
144 | let module_id = self.def_map.root; | 195 | let module_id = self.def_map.root; |
145 | self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; | 196 | self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; |
146 | ModCollector { | 197 | ModCollector { |
@@ -148,10 +199,10 @@ impl DefCollector<'_> { | |||
148 | macro_depth: 0, | 199 | macro_depth: 0, |
149 | module_id, | 200 | module_id, |
150 | file_id: file_id.into(), | 201 | file_id: file_id.into(), |
151 | raw_items: &raw_items, | 202 | item_tree: &item_tree, |
152 | mod_dir: ModDir::root(), | 203 | mod_dir: ModDir::root(), |
153 | } | 204 | } |
154 | .collect(raw_items.items()); | 205 | .collect(item_tree.top_level_items()); |
155 | 206 | ||
156 | // main name resolution fixed-point loop. | 207 | // main name resolution fixed-point loop. |
157 | let mut i = 0; | 208 | let mut i = 0; |
@@ -286,7 +337,7 @@ impl DefCollector<'_> { | |||
286 | fn import_macros_from_extern_crate( | 337 | fn import_macros_from_extern_crate( |
287 | &mut self, | 338 | &mut self, |
288 | current_module_id: LocalModuleId, | 339 | current_module_id: LocalModuleId, |
289 | import: &raw::ImportData, | 340 | import: &item_tree::ExternCrate, |
290 | ) { | 341 | ) { |
291 | log::debug!( | 342 | log::debug!( |
292 | "importing macros from extern crate: {:?} ({:?})", | 343 | "importing macros from extern crate: {:?} ({:?})", |
@@ -352,11 +403,7 @@ impl DefCollector<'_> { | |||
352 | } | 403 | } |
353 | } | 404 | } |
354 | 405 | ||
355 | fn resolve_import( | 406 | fn resolve_import(&self, module_id: LocalModuleId, import: &Import) -> PartialResolvedImport { |
356 | &self, | ||
357 | module_id: LocalModuleId, | ||
358 | import: &raw::ImportData, | ||
359 | ) -> PartialResolvedImport { | ||
360 | log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition); | 407 | log::debug!("resolving import: {:?} ({:?})", import, self.def_map.edition); |
361 | if import.is_extern_crate { | 408 | if import.is_extern_crate { |
362 | let res = self.def_map.resolve_name_in_extern_prelude( | 409 | let res = self.def_map.resolve_name_in_extern_prelude( |
@@ -649,17 +696,17 @@ impl DefCollector<'_> { | |||
649 | depth: usize, | 696 | depth: usize, |
650 | ) { | 697 | ) { |
651 | let file_id: HirFileId = macro_call_id.as_file(); | 698 | let file_id: HirFileId = macro_call_id.as_file(); |
652 | let raw_items = self.db.raw_items(file_id); | 699 | let item_tree = self.db.item_tree(file_id); |
653 | let mod_dir = self.mod_dirs[&module_id].clone(); | 700 | let mod_dir = self.mod_dirs[&module_id].clone(); |
654 | ModCollector { | 701 | ModCollector { |
655 | def_collector: &mut *self, | 702 | def_collector: &mut *self, |
656 | macro_depth: depth, | 703 | macro_depth: depth, |
657 | file_id, | 704 | file_id, |
658 | module_id, | 705 | module_id, |
659 | raw_items: &raw_items, | 706 | item_tree: &item_tree, |
660 | mod_dir, | 707 | mod_dir, |
661 | } | 708 | } |
662 | .collect(raw_items.items()); | 709 | .collect(item_tree.top_level_items()); |
663 | } | 710 | } |
664 | 711 | ||
665 | fn finish(self) -> CrateDefMap { | 712 | fn finish(self) -> CrateDefMap { |
@@ -673,12 +720,12 @@ struct ModCollector<'a, 'b> { | |||
673 | macro_depth: usize, | 720 | macro_depth: usize, |
674 | module_id: LocalModuleId, | 721 | module_id: LocalModuleId, |
675 | file_id: HirFileId, | 722 | file_id: HirFileId, |
676 | raw_items: &'a raw::RawItems, | 723 | item_tree: &'a ItemTree, |
677 | mod_dir: ModDir, | 724 | mod_dir: ModDir, |
678 | } | 725 | } |
679 | 726 | ||
680 | impl ModCollector<'_, '_> { | 727 | impl ModCollector<'_, '_> { |
681 | fn collect(&mut self, items: &[raw::RawItem]) { | 728 | fn collect(&mut self, items: &[ModItem]) { |
682 | // Note: don't assert that inserted value is fresh: it's simply not true | 729 | // Note: don't assert that inserted value is fresh: it's simply not true |
683 | // for macros. | 730 | // for macros. |
684 | self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone()); | 731 | self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone()); |
@@ -695,64 +742,204 @@ impl ModCollector<'_, '_> { | |||
695 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting | 742 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting |
696 | // any other items. | 743 | // any other items. |
697 | for item in items { | 744 | for item in items { |
698 | if self.is_cfg_enabled(&item.attrs) { | 745 | if self.is_cfg_enabled(self.item_tree.attrs(*item)) { |
699 | if let raw::RawItemKind::Import(import_id) = item.kind { | 746 | if let ModItem::ExternCrate(id) = item { |
700 | let import = self.raw_items[import_id].clone(); | 747 | let import = self.item_tree[*id].clone(); |
701 | if import.is_extern_crate && import.is_macro_use { | 748 | if import.is_macro_use { |
702 | self.def_collector.import_macros_from_extern_crate(self.module_id, &import); | 749 | self.def_collector.import_macros_from_extern_crate(self.module_id, &import); |
703 | } | 750 | } |
704 | } | 751 | } |
705 | } | 752 | } |
706 | } | 753 | } |
707 | 754 | ||
708 | for item in items { | 755 | for &item in items { |
709 | if self.is_cfg_enabled(&item.attrs) { | 756 | let attrs = self.item_tree.attrs(item); |
710 | match item.kind { | 757 | if self.is_cfg_enabled(attrs) { |
711 | raw::RawItemKind::Module(m) => { | 758 | let module = |
712 | self.collect_module(&self.raw_items[m], &item.attrs) | 759 | ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id }; |
713 | } | 760 | let container = ContainerId::ModuleId(module); |
714 | raw::RawItemKind::Import(import_id) => { | 761 | |
762 | let mut def = None; | ||
763 | match item { | ||
764 | ModItem::Mod(m) => self.collect_module(&self.item_tree[m], attrs), | ||
765 | ModItem::Import(import_id) => { | ||
715 | self.def_collector.unresolved_imports.push(ImportDirective { | 766 | self.def_collector.unresolved_imports.push(ImportDirective { |
716 | module_id: self.module_id, | 767 | module_id: self.module_id, |
717 | import_id, | 768 | import: Import::from_use(&self.item_tree, import_id), |
718 | import: self.raw_items[import_id].clone(), | ||
719 | status: PartialResolvedImport::Unresolved, | 769 | status: PartialResolvedImport::Unresolved, |
720 | }) | 770 | }) |
721 | } | 771 | } |
722 | raw::RawItemKind::Def(def) => { | 772 | ModItem::ExternCrate(import_id) => { |
723 | self.define_def(&self.raw_items[def], &item.attrs) | 773 | self.def_collector.unresolved_imports.push(ImportDirective { |
774 | module_id: self.module_id, | ||
775 | import: Import::from_extern_crate(&self.item_tree, import_id), | ||
776 | status: PartialResolvedImport::Unresolved, | ||
777 | }) | ||
724 | } | 778 | } |
725 | raw::RawItemKind::Macro(mac) => self.collect_macro(&self.raw_items[mac]), | 779 | ModItem::MacroCall(mac) => self.collect_macro(&self.item_tree[mac]), |
726 | raw::RawItemKind::Impl(imp) => { | 780 | ModItem::Impl(imp) => { |
727 | let module = ModuleId { | 781 | let module = ModuleId { |
728 | krate: self.def_collector.def_map.krate, | 782 | krate: self.def_collector.def_map.krate, |
729 | local_id: self.module_id, | 783 | local_id: self.module_id, |
730 | }; | 784 | }; |
731 | let container = ContainerId::ModuleId(module); | 785 | let container = ContainerId::ModuleId(module); |
732 | let ast_id = self.raw_items[imp].ast_id; | 786 | let impl_id = ImplLoc { container, id: ItemTreeId::new(self.file_id, imp) } |
733 | let impl_id = | 787 | .intern(self.def_collector.db); |
734 | ImplLoc { container, ast_id: AstId::new(self.file_id, ast_id) } | ||
735 | .intern(self.def_collector.db); | ||
736 | self.def_collector.def_map.modules[self.module_id] | 788 | self.def_collector.def_map.modules[self.module_id] |
737 | .scope | 789 | .scope |
738 | .define_impl(impl_id) | 790 | .define_impl(impl_id) |
739 | } | 791 | } |
792 | ModItem::Function(id) => { | ||
793 | let func = &self.item_tree[id]; | ||
794 | def = Some(DefData { | ||
795 | id: FunctionLoc { | ||
796 | container: container.into(), | ||
797 | id: ItemTreeId::new(self.file_id, id), | ||
798 | } | ||
799 | .intern(self.def_collector.db) | ||
800 | .into(), | ||
801 | name: &func.name, | ||
802 | visibility: &self.item_tree[func.visibility], | ||
803 | has_constructor: false, | ||
804 | }); | ||
805 | } | ||
806 | ModItem::Struct(id) => { | ||
807 | let it = &self.item_tree[id]; | ||
808 | |||
809 | // FIXME: check attrs to see if this is an attribute macro invocation; | ||
810 | // in which case we don't add the invocation, just a single attribute | ||
811 | // macro invocation | ||
812 | self.collect_derives(attrs, it.ast_id.upcast()); | ||
813 | |||
814 | def = Some(DefData { | ||
815 | id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) } | ||
816 | .intern(self.def_collector.db) | ||
817 | .into(), | ||
818 | name: &it.name, | ||
819 | visibility: &self.item_tree[it.visibility], | ||
820 | has_constructor: it.kind != StructDefKind::Record, | ||
821 | }); | ||
822 | } | ||
823 | ModItem::Union(id) => { | ||
824 | let it = &self.item_tree[id]; | ||
825 | |||
826 | // FIXME: check attrs to see if this is an attribute macro invocation; | ||
827 | // in which case we don't add the invocation, just a single attribute | ||
828 | // macro invocation | ||
829 | self.collect_derives(attrs, it.ast_id.upcast()); | ||
830 | |||
831 | def = Some(DefData { | ||
832 | id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) } | ||
833 | .intern(self.def_collector.db) | ||
834 | .into(), | ||
835 | name: &it.name, | ||
836 | visibility: &self.item_tree[it.visibility], | ||
837 | has_constructor: false, | ||
838 | }); | ||
839 | } | ||
840 | ModItem::Enum(id) => { | ||
841 | let it = &self.item_tree[id]; | ||
842 | |||
843 | // FIXME: check attrs to see if this is an attribute macro invocation; | ||
844 | // in which case we don't add the invocation, just a single attribute | ||
845 | // macro invocation | ||
846 | self.collect_derives(attrs, it.ast_id.upcast()); | ||
847 | |||
848 | def = Some(DefData { | ||
849 | id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) } | ||
850 | .intern(self.def_collector.db) | ||
851 | .into(), | ||
852 | name: &it.name, | ||
853 | visibility: &self.item_tree[it.visibility], | ||
854 | has_constructor: false, | ||
855 | }); | ||
856 | } | ||
857 | ModItem::Const(id) => { | ||
858 | let it = &self.item_tree[id]; | ||
859 | |||
860 | if let Some(name) = &it.name { | ||
861 | def = Some(DefData { | ||
862 | id: ConstLoc { | ||
863 | container: container.into(), | ||
864 | id: ItemTreeId::new(self.file_id, id), | ||
865 | } | ||
866 | .intern(self.def_collector.db) | ||
867 | .into(), | ||
868 | name, | ||
869 | visibility: &self.item_tree[it.visibility], | ||
870 | has_constructor: false, | ||
871 | }); | ||
872 | } | ||
873 | } | ||
874 | ModItem::Static(id) => { | ||
875 | let it = &self.item_tree[id]; | ||
876 | |||
877 | def = Some(DefData { | ||
878 | id: StaticLoc { container, id: ItemTreeId::new(self.file_id, id) } | ||
879 | .intern(self.def_collector.db) | ||
880 | .into(), | ||
881 | name: &it.name, | ||
882 | visibility: &self.item_tree[it.visibility], | ||
883 | has_constructor: false, | ||
884 | }); | ||
885 | } | ||
886 | ModItem::Trait(id) => { | ||
887 | let it = &self.item_tree[id]; | ||
888 | |||
889 | def = Some(DefData { | ||
890 | id: TraitLoc { container, id: ItemTreeId::new(self.file_id, id) } | ||
891 | .intern(self.def_collector.db) | ||
892 | .into(), | ||
893 | name: &it.name, | ||
894 | visibility: &self.item_tree[it.visibility], | ||
895 | has_constructor: false, | ||
896 | }); | ||
897 | } | ||
898 | ModItem::TypeAlias(id) => { | ||
899 | let it = &self.item_tree[id]; | ||
900 | |||
901 | def = Some(DefData { | ||
902 | id: TypeAliasLoc { | ||
903 | container: container.into(), | ||
904 | id: ItemTreeId::new(self.file_id, id), | ||
905 | } | ||
906 | .intern(self.def_collector.db) | ||
907 | .into(), | ||
908 | name: &it.name, | ||
909 | visibility: &self.item_tree[it.visibility], | ||
910 | has_constructor: false, | ||
911 | }); | ||
912 | } | ||
913 | } | ||
914 | |||
915 | if let Some(DefData { id, name, visibility, has_constructor }) = def { | ||
916 | self.def_collector.def_map.modules[self.module_id].scope.define_def(id); | ||
917 | let vis = self | ||
918 | .def_collector | ||
919 | .def_map | ||
920 | .resolve_visibility(self.def_collector.db, self.module_id, visibility) | ||
921 | .unwrap_or(Visibility::Public); | ||
922 | self.def_collector.update( | ||
923 | self.module_id, | ||
924 | &[(name.clone(), PerNs::from_def(id, vis, has_constructor))], | ||
925 | vis, | ||
926 | ) | ||
740 | } | 927 | } |
741 | } | 928 | } |
742 | } | 929 | } |
743 | } | 930 | } |
744 | 931 | ||
745 | fn collect_module(&mut self, module: &raw::ModuleData, attrs: &Attrs) { | 932 | fn collect_module(&mut self, module: &Mod, attrs: &Attrs) { |
746 | let path_attr = attrs.by_key("path").string_value(); | 933 | let path_attr = attrs.by_key("path").string_value(); |
747 | let is_macro_use = attrs.by_key("macro_use").exists(); | 934 | let is_macro_use = attrs.by_key("macro_use").exists(); |
748 | match module { | 935 | match &module.kind { |
749 | // inline module, just recurse | 936 | // inline module, just recurse |
750 | raw::ModuleData::Definition { name, visibility, items, ast_id } => { | 937 | ModKind::Inline { items } => { |
751 | let module_id = self.push_child_module( | 938 | let module_id = self.push_child_module( |
752 | name.clone(), | 939 | module.name.clone(), |
753 | AstId::new(self.file_id, *ast_id), | 940 | AstId::new(self.file_id, module.ast_id), |
754 | None, | 941 | None, |
755 | &visibility, | 942 | &self.item_tree[module.visibility], |
756 | ); | 943 | ); |
757 | 944 | ||
758 | ModCollector { | 945 | ModCollector { |
@@ -760,8 +947,8 @@ impl ModCollector<'_, '_> { | |||
760 | macro_depth: self.macro_depth, | 947 | macro_depth: self.macro_depth, |
761 | module_id, | 948 | module_id, |
762 | file_id: self.file_id, | 949 | file_id: self.file_id, |
763 | raw_items: self.raw_items, | 950 | item_tree: self.item_tree, |
764 | mod_dir: self.mod_dir.descend_into_definition(name, path_attr), | 951 | mod_dir: self.mod_dir.descend_into_definition(&module.name, path_attr), |
765 | } | 952 | } |
766 | .collect(&*items); | 953 | .collect(&*items); |
767 | if is_macro_use { | 954 | if is_macro_use { |
@@ -769,31 +956,31 @@ impl ModCollector<'_, '_> { | |||
769 | } | 956 | } |
770 | } | 957 | } |
771 | // out of line module, resolve, parse and recurse | 958 | // out of line module, resolve, parse and recurse |
772 | raw::ModuleData::Declaration { name, visibility, ast_id } => { | 959 | ModKind::Outline {} => { |
773 | let ast_id = AstId::new(self.file_id, *ast_id); | 960 | let ast_id = AstId::new(self.file_id, module.ast_id); |
774 | match self.mod_dir.resolve_declaration( | 961 | match self.mod_dir.resolve_declaration( |
775 | self.def_collector.db, | 962 | self.def_collector.db, |
776 | self.file_id, | 963 | self.file_id, |
777 | name, | 964 | &module.name, |
778 | path_attr, | 965 | path_attr, |
779 | ) { | 966 | ) { |
780 | Ok((file_id, is_mod_rs, mod_dir)) => { | 967 | Ok((file_id, is_mod_rs, mod_dir)) => { |
781 | let module_id = self.push_child_module( | 968 | let module_id = self.push_child_module( |
782 | name.clone(), | 969 | module.name.clone(), |
783 | ast_id, | 970 | ast_id, |
784 | Some((file_id, is_mod_rs)), | 971 | Some((file_id, is_mod_rs)), |
785 | &visibility, | 972 | &self.item_tree[module.visibility], |
786 | ); | 973 | ); |
787 | let raw_items = self.def_collector.db.raw_items(file_id.into()); | 974 | let item_tree = self.def_collector.db.item_tree(file_id.into()); |
788 | ModCollector { | 975 | ModCollector { |
789 | def_collector: &mut *self.def_collector, | 976 | def_collector: &mut *self.def_collector, |
790 | macro_depth: self.macro_depth, | 977 | macro_depth: self.macro_depth, |
791 | module_id, | 978 | module_id, |
792 | file_id: file_id.into(), | 979 | file_id: file_id.into(), |
793 | raw_items: &raw_items, | 980 | item_tree: &item_tree, |
794 | mod_dir, | 981 | mod_dir, |
795 | } | 982 | } |
796 | .collect(raw_items.items()); | 983 | .collect(item_tree.top_level_items()); |
797 | if is_macro_use { | 984 | if is_macro_use { |
798 | self.import_all_legacy_macros(module_id); | 985 | self.import_all_legacy_macros(module_id); |
799 | } | 986 | } |
@@ -842,77 +1029,7 @@ impl ModCollector<'_, '_> { | |||
842 | res | 1029 | res |
843 | } | 1030 | } |
844 | 1031 | ||
845 | fn define_def(&mut self, def: &raw::DefData, attrs: &Attrs) { | 1032 | fn collect_derives(&mut self, attrs: &Attrs, ast_id: FileAstId<ast::ModuleItem>) { |
846 | let module = ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id }; | ||
847 | // FIXME: check attrs to see if this is an attribute macro invocation; | ||
848 | // in which case we don't add the invocation, just a single attribute | ||
849 | // macro invocation | ||
850 | self.collect_derives(attrs, def); | ||
851 | |||
852 | let name = def.name.clone(); | ||
853 | let container = ContainerId::ModuleId(module); | ||
854 | let vis = &def.visibility; | ||
855 | let mut has_constructor = false; | ||
856 | |||
857 | let def: ModuleDefId = match def.kind { | ||
858 | raw::DefKind::Function(ast_id) => FunctionLoc { | ||
859 | container: container.into(), | ||
860 | ast_id: AstId::new(self.file_id, ast_id), | ||
861 | } | ||
862 | .intern(self.def_collector.db) | ||
863 | .into(), | ||
864 | raw::DefKind::Struct(ast_id, mode) => { | ||
865 | has_constructor = mode != raw::StructDefKind::Record; | ||
866 | StructLoc { container, ast_id: AstId::new(self.file_id, ast_id) } | ||
867 | .intern(self.def_collector.db) | ||
868 | .into() | ||
869 | } | ||
870 | raw::DefKind::Union(ast_id) => { | ||
871 | UnionLoc { container, ast_id: AstId::new(self.file_id, ast_id) } | ||
872 | .intern(self.def_collector.db) | ||
873 | .into() | ||
874 | } | ||
875 | raw::DefKind::Enum(ast_id) => { | ||
876 | EnumLoc { container, ast_id: AstId::new(self.file_id, ast_id) } | ||
877 | .intern(self.def_collector.db) | ||
878 | .into() | ||
879 | } | ||
880 | raw::DefKind::Const(ast_id) => { | ||
881 | ConstLoc { container: container.into(), ast_id: AstId::new(self.file_id, ast_id) } | ||
882 | .intern(self.def_collector.db) | ||
883 | .into() | ||
884 | } | ||
885 | raw::DefKind::Static(ast_id) => { | ||
886 | StaticLoc { container, ast_id: AstId::new(self.file_id, ast_id) } | ||
887 | .intern(self.def_collector.db) | ||
888 | .into() | ||
889 | } | ||
890 | raw::DefKind::Trait(ast_id) => { | ||
891 | TraitLoc { container, ast_id: AstId::new(self.file_id, ast_id) } | ||
892 | .intern(self.def_collector.db) | ||
893 | .into() | ||
894 | } | ||
895 | raw::DefKind::TypeAlias(ast_id) => TypeAliasLoc { | ||
896 | container: container.into(), | ||
897 | ast_id: AstId::new(self.file_id, ast_id), | ||
898 | } | ||
899 | .intern(self.def_collector.db) | ||
900 | .into(), | ||
901 | }; | ||
902 | self.def_collector.def_map.modules[self.module_id].scope.define_def(def); | ||
903 | let vis = self | ||
904 | .def_collector | ||
905 | .def_map | ||
906 | .resolve_visibility(self.def_collector.db, self.module_id, vis) | ||
907 | .unwrap_or(Visibility::Public); | ||
908 | self.def_collector.update( | ||
909 | self.module_id, | ||
910 | &[(name, PerNs::from_def(def, vis, has_constructor))], | ||
911 | vis, | ||
912 | ) | ||
913 | } | ||
914 | |||
915 | fn collect_derives(&mut self, attrs: &Attrs, def: &raw::DefData) { | ||
916 | for derive_subtree in attrs.by_key("derive").tt_values() { | 1033 | for derive_subtree in attrs.by_key("derive").tt_values() { |
917 | // for #[derive(Copy, Clone)], `derive_subtree` is the `(Copy, Clone)` subtree | 1034 | // for #[derive(Copy, Clone)], `derive_subtree` is the `(Copy, Clone)` subtree |
918 | for tt in &derive_subtree.token_trees { | 1035 | for tt in &derive_subtree.token_trees { |
@@ -923,7 +1040,7 @@ impl ModCollector<'_, '_> { | |||
923 | }; | 1040 | }; |
924 | let path = ModPath::from_tt_ident(ident); | 1041 | let path = ModPath::from_tt_ident(ident); |
925 | 1042 | ||
926 | let ast_id = AstIdWithPath::new(self.file_id, def.kind.ast_id(), path); | 1043 | let ast_id = AstIdWithPath::new(self.file_id, ast_id, path); |
927 | self.def_collector | 1044 | self.def_collector |
928 | .unexpanded_attribute_macros | 1045 | .unexpanded_attribute_macros |
929 | .push(DeriveDirective { module_id: self.module_id, ast_id }); | 1046 | .push(DeriveDirective { module_id: self.module_id, ast_id }); |
@@ -931,11 +1048,11 @@ impl ModCollector<'_, '_> { | |||
931 | } | 1048 | } |
932 | } | 1049 | } |
933 | 1050 | ||
934 | fn collect_macro(&mut self, mac: &raw::MacroData) { | 1051 | fn collect_macro(&mut self, mac: &MacroCall) { |
935 | let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone()); | 1052 | let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone()); |
936 | 1053 | ||
937 | // Case 0: builtin macros | 1054 | // Case 0: builtin macros |
938 | if mac.builtin { | 1055 | if mac.is_builtin { |
939 | if let Some(name) = &mac.name { | 1056 | if let Some(name) = &mac.name { |
940 | let krate = self.def_collector.def_map.krate; | 1057 | let krate = self.def_collector.def_map.krate; |
941 | if let Some(macro_id) = find_builtin_macro(name, krate, ast_id.ast_id) { | 1058 | if let Some(macro_id) = find_builtin_macro(name, krate, ast_id.ast_id) { |
@@ -943,7 +1060,7 @@ impl ModCollector<'_, '_> { | |||
943 | self.module_id, | 1060 | self.module_id, |
944 | name.clone(), | 1061 | name.clone(), |
945 | macro_id, | 1062 | macro_id, |
946 | mac.export, | 1063 | mac.is_export, |
947 | ); | 1064 | ); |
948 | return; | 1065 | return; |
949 | } | 1066 | } |
@@ -957,9 +1074,14 @@ impl ModCollector<'_, '_> { | |||
957 | ast_id: Some(ast_id.ast_id), | 1074 | ast_id: Some(ast_id.ast_id), |
958 | krate: Some(self.def_collector.def_map.krate), | 1075 | krate: Some(self.def_collector.def_map.krate), |
959 | kind: MacroDefKind::Declarative, | 1076 | kind: MacroDefKind::Declarative, |
960 | local_inner: mac.local_inner, | 1077 | local_inner: mac.is_local_inner, |
961 | }; | 1078 | }; |
962 | self.def_collector.define_macro(self.module_id, name.clone(), macro_id, mac.export); | 1079 | self.def_collector.define_macro( |
1080 | self.module_id, | ||
1081 | name.clone(), | ||
1082 | macro_id, | ||
1083 | mac.is_export, | ||
1084 | ); | ||
963 | } | 1085 | } |
964 | return; | 1086 | return; |
965 | } | 1087 | } |