aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/nameres
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2020-02-17 04:57:24 +0000
committerEdwin Cheng <[email protected]>2020-02-17 04:57:24 +0000
commit2d4e79e1e6e39719d566bb58e04a7839588238fe (patch)
tree0a59dafb9ab19768c6a571fb96c6677a937af398 /crates/ra_hir_def/src/nameres
parentd9767727168c68b4ecf930c9dab5a950c0be8e7b (diff)
Introduce AsMacroCall trait
Diffstat (limited to 'crates/ra_hir_def/src/nameres')
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs77
1 files changed, 40 insertions, 37 deletions
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index b1f3f525d..51c65a5d7 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -7,7 +7,7 @@ use hir_expand::{
7 builtin_derive::find_builtin_derive, 7 builtin_derive::find_builtin_derive,
8 builtin_macro::find_builtin_macro, 8 builtin_macro::find_builtin_macro,
9 name::{name, AsName, Name}, 9 name::{name, AsName, Name},
10 HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, 10 HirFileId, MacroCallId, MacroDefId, MacroDefKind,
11}; 11};
12use ra_cfg::CfgOptions; 12use ra_cfg::CfgOptions;
13use ra_db::{CrateId, FileId}; 13use ra_db::{CrateId, FileId};
@@ -25,8 +25,9 @@ use crate::{
25 path::{ImportAlias, ModPath, PathKind}, 25 path::{ImportAlias, ModPath, PathKind},
26 per_ns::PerNs, 26 per_ns::PerNs,
27 visibility::Visibility, 27 visibility::Visibility,
28 AdtId, AstId, ConstLoc, ContainerId, EnumLoc, EnumVariantId, FunctionLoc, ImplLoc, Intern, 28 AdtId, AsMacroCall, AstId, AstIdWithPath, ConstLoc, ContainerId, EnumLoc, EnumVariantId,
29 LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc, TraitLoc, TypeAliasLoc, UnionLoc, 29 FunctionLoc, ImplLoc, Intern, LocalModuleId, ModuleDefId, ModuleId, StaticLoc, StructLoc,
30 TraitLoc, TypeAliasLoc, UnionLoc,
30}; 31};
31 32
32pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { 33pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
@@ -99,11 +100,16 @@ struct ImportDirective {
99#[derive(Clone, Debug, Eq, PartialEq)] 100#[derive(Clone, Debug, Eq, PartialEq)]
100struct MacroDirective { 101struct MacroDirective {
101 module_id: LocalModuleId, 102 module_id: LocalModuleId,
102 ast_id: AstId<ast::MacroCall>, 103 ast_id: AstIdWithPath<ast::MacroCall>,
103 path: ModPath,
104 legacy: Option<MacroCallId>, 104 legacy: Option<MacroCallId>,
105} 105}
106 106
107#[derive(Clone, Debug, Eq, PartialEq)]
108struct DeriveDirective {
109 module_id: LocalModuleId,
110 ast_id: AstIdWithPath<ast::ModuleItem>,
111}
112
107/// Walks the tree of module recursively 113/// Walks the tree of module recursively
108struct DefCollector<'a, DB> { 114struct DefCollector<'a, DB> {
109 db: &'a DB, 115 db: &'a DB,
@@ -112,7 +118,7 @@ struct DefCollector<'a, DB> {
112 unresolved_imports: Vec<ImportDirective>, 118 unresolved_imports: Vec<ImportDirective>,
113 resolved_imports: Vec<ImportDirective>, 119 resolved_imports: Vec<ImportDirective>,
114 unexpanded_macros: Vec<MacroDirective>, 120 unexpanded_macros: Vec<MacroDirective>,
115 unexpanded_attribute_macros: Vec<(LocalModuleId, AstId<ast::ModuleItem>, ModPath)>, 121 unexpanded_attribute_macros: Vec<DeriveDirective>,
116 mod_dirs: FxHashMap<LocalModuleId, ModDir>, 122 mod_dirs: FxHashMap<LocalModuleId, ModDir>,
117 cfg_options: &'a CfgOptions, 123 cfg_options: &'a CfgOptions,
118} 124}
@@ -515,16 +521,16 @@ where
515 return false; 521 return false;
516 } 522 }
517 523
518 let resolved_res = self.def_map.resolve_path_fp_with_macro( 524 if let Some(call_id) = directive.ast_id.as_call_id(self.db, |path| {
519 self.db, 525 let resolved_res = self.def_map.resolve_path_fp_with_macro(
520 ResolveMode::Other, 526 self.db,
521 directive.module_id, 527 ResolveMode::Other,
522 &directive.path, 528 directive.module_id,
523 BuiltinShadowMode::Module, 529 &path,
524 ); 530 BuiltinShadowMode::Module,
525 531 );
526 if let Some(def) = resolved_res.resolved_def.take_macros() { 532 resolved_res.resolved_def.take_macros()
527 let call_id = def.as_call_id(self.db, MacroCallKind::FnLike(directive.ast_id)); 533 }) {
528 resolved.push((directive.module_id, call_id)); 534 resolved.push((directive.module_id, call_id));
529 res = ReachedFixedPoint::No; 535 res = ReachedFixedPoint::No;
530 return false; 536 return false;
@@ -532,12 +538,11 @@ where
532 538
533 true 539 true
534 }); 540 });
535 attribute_macros.retain(|(module_id, ast_id, path)| { 541 attribute_macros.retain(|directive| {
536 let resolved_res = self.resolve_attribute_macro(path); 542 if let Some(call_id) =
537 543 directive.ast_id.as_call_id(self.db, |path| self.resolve_attribute_macro(&path))
538 if let Some(def) = resolved_res { 544 {
539 let call_id = def.as_call_id(self.db, MacroCallKind::Attr(*ast_id)); 545 resolved.push((directive.module_id, call_id));
540 resolved.push((*module_id, call_id));
541 res = ReachedFixedPoint::No; 546 res = ReachedFixedPoint::No;
542 return false; 547 return false;
543 } 548 }
@@ -833,20 +838,22 @@ where
833 }; 838 };
834 let path = ModPath::from_tt_ident(ident); 839 let path = ModPath::from_tt_ident(ident);
835 840
836 let ast_id = AstId::new(self.file_id, def.kind.ast_id()); 841 let ast_id = AstIdWithPath::new(self.file_id, def.kind.ast_id(), path);
837 self.def_collector.unexpanded_attribute_macros.push((self.module_id, ast_id, path)); 842 self.def_collector
843 .unexpanded_attribute_macros
844 .push(DeriveDirective { module_id: self.module_id, ast_id });
838 } 845 }
839 } 846 }
840 } 847 }
841 848
842 fn collect_macro(&mut self, mac: &raw::MacroData) { 849 fn collect_macro(&mut self, mac: &raw::MacroData) {
843 let ast_id = AstId::new(self.file_id, mac.ast_id); 850 let mut ast_id = AstIdWithPath::new(self.file_id, mac.ast_id, mac.path.clone());
844 851
845 // Case 0: builtin macros 852 // Case 0: builtin macros
846 if mac.builtin { 853 if mac.builtin {
847 if let Some(name) = &mac.name { 854 if let Some(name) = &mac.name {
848 let krate = self.def_collector.def_map.krate; 855 let krate = self.def_collector.def_map.krate;
849 if let Some(macro_id) = find_builtin_macro(name, krate, ast_id) { 856 if let Some(macro_id) = find_builtin_macro(name, krate, ast_id.ast_id) {
850 self.def_collector.define_macro( 857 self.def_collector.define_macro(
851 self.module_id, 858 self.module_id,
852 name.clone(), 859 name.clone(),
@@ -862,7 +869,7 @@ where
862 if is_macro_rules(&mac.path) { 869 if is_macro_rules(&mac.path) {
863 if let Some(name) = &mac.name { 870 if let Some(name) = &mac.name {
864 let macro_id = MacroDefId { 871 let macro_id = MacroDefId {
865 ast_id: Some(ast_id), 872 ast_id: Some(ast_id.ast_id),
866 krate: Some(self.def_collector.def_map.krate), 873 krate: Some(self.def_collector.def_map.krate),
867 kind: MacroDefKind::Declarative, 874 kind: MacroDefKind::Declarative,
868 }; 875 };
@@ -872,15 +879,13 @@ where
872 } 879 }
873 880
874 // Case 2: try to resolve in legacy scope and expand macro_rules 881 // Case 2: try to resolve in legacy scope and expand macro_rules
875 if let Some(macro_def) = mac.path.as_ident().and_then(|name| { 882 if let Some(macro_call_id) = ast_id.as_call_id(self.def_collector.db, |path| {
876 self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name) 883 path.as_ident().and_then(|name| {
884 self.def_collector.def_map[self.module_id].scope.get_legacy_macro(&name)
885 })
877 }) { 886 }) {
878 let macro_call_id =
879 macro_def.as_call_id(self.def_collector.db, MacroCallKind::FnLike(ast_id));
880
881 self.def_collector.unexpanded_macros.push(MacroDirective { 887 self.def_collector.unexpanded_macros.push(MacroDirective {
882 module_id: self.module_id, 888 module_id: self.module_id,
883 path: mac.path.clone(),
884 ast_id, 889 ast_id,
885 legacy: Some(macro_call_id), 890 legacy: Some(macro_call_id),
886 }); 891 });
@@ -890,14 +895,12 @@ where
890 895
891 // Case 3: resolve in module scope, expand during name resolution. 896 // Case 3: resolve in module scope, expand during name resolution.
892 // We rewrite simple path `macro_name` to `self::macro_name` to force resolve in module scope only. 897 // We rewrite simple path `macro_name` to `self::macro_name` to force resolve in module scope only.
893 let mut path = mac.path.clone(); 898 if ast_id.path.is_ident() {
894 if path.is_ident() { 899 ast_id.path.kind = PathKind::Super(0);
895 path.kind = PathKind::Super(0);
896 } 900 }
897 901
898 self.def_collector.unexpanded_macros.push(MacroDirective { 902 self.def_collector.unexpanded_macros.push(MacroDirective {
899 module_id: self.module_id, 903 module_id: self.module_id,
900 path,
901 ast_id, 904 ast_id,
902 legacy: None, 905 legacy: None,
903 }); 906 });