aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/nameres/collector.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/nameres/collector.rs')
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs60
1 files changed, 53 insertions, 7 deletions
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 5b292c250..9c125f32f 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -7,6 +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 proc_macro::ProcMacroExpander,
10 HirFileId, MacroCallId, MacroDefId, MacroDefKind, 11 HirFileId, MacroCallId, MacroDefId, MacroDefKind,
11}; 12};
12use ra_cfg::CfgOptions; 13use ra_cfg::CfgOptions;
@@ -64,6 +65,9 @@ pub(super) fn collect_defs(db: &dyn DefDatabase, mut def_map: CrateDefMap) -> Cr
64 unexpanded_attribute_macros: Vec::new(), 65 unexpanded_attribute_macros: Vec::new(),
65 mod_dirs: FxHashMap::default(), 66 mod_dirs: FxHashMap::default(),
66 cfg_options, 67 cfg_options,
68
69 // FIXME: pass proc-macro from crate-graph
70 proc_macros: Default::default(),
67 }; 71 };
68 collector.collect(); 72 collector.collect();
69 collector.finish() 73 collector.finish()
@@ -122,6 +126,7 @@ struct DefCollector<'a> {
122 unexpanded_attribute_macros: Vec<DeriveDirective>, 126 unexpanded_attribute_macros: Vec<DeriveDirective>,
123 mod_dirs: FxHashMap<LocalModuleId, ModDir>, 127 mod_dirs: FxHashMap<LocalModuleId, ModDir>,
124 cfg_options: &'a CfgOptions, 128 cfg_options: &'a CfgOptions,
129 proc_macros: Vec<(Name, ProcMacroExpander)>,
125} 130}
126 131
127impl DefCollector<'_> { 132impl DefCollector<'_> {
@@ -177,6 +182,24 @@ impl DefCollector<'_> {
177 for directive in unresolved_imports { 182 for directive in unresolved_imports {
178 self.record_resolved_import(&directive) 183 self.record_resolved_import(&directive)
179 } 184 }
185
186 // Record proc-macros
187 self.collect_proc_macro();
188 }
189
190 fn collect_proc_macro(&mut self) {
191 let proc_macros = std::mem::take(&mut self.proc_macros);
192 for (name, expander) in proc_macros {
193 let krate = self.def_map.krate;
194
195 let macro_id = MacroDefId {
196 ast_id: None,
197 krate: Some(krate),
198 kind: MacroDefKind::CustomDerive(expander),
199 };
200
201 self.define_proc_macro(name.clone(), macro_id);
202 }
180 } 203 }
181 204
182 /// Define a macro with `macro_rules`. 205 /// Define a macro with `macro_rules`.
@@ -238,6 +261,18 @@ impl DefCollector<'_> {
238 self.def_map.modules[module_id].scope.define_legacy_macro(name, mac); 261 self.def_map.modules[module_id].scope.define_legacy_macro(name, mac);
239 } 262 }
240 263
264 /// Define a proc macro
265 ///
266 /// A proc macro is similar to normal macro scope, but it would not visiable in legacy textual scoped.
267 /// And unconditionally exported.
268 fn define_proc_macro(&mut self, name: Name, macro_: MacroDefId) {
269 self.update(
270 self.def_map.root,
271 &[(name, PerNs::macros(macro_, Visibility::Public))],
272 Visibility::Public,
273 );
274 }
275
241 /// Import macros from `#[macro_use] extern crate`. 276 /// Import macros from `#[macro_use] extern crate`.
242 fn import_macros_from_extern_crate( 277 fn import_macros_from_extern_crate(
243 &mut self, 278 &mut self,
@@ -537,8 +572,9 @@ impl DefCollector<'_> {
537 true 572 true
538 }); 573 });
539 attribute_macros.retain(|directive| { 574 attribute_macros.retain(|directive| {
540 if let Some(call_id) = 575 if let Some(call_id) = directive
541 directive.ast_id.as_call_id(self.db, |path| self.resolve_attribute_macro(&path)) 576 .ast_id
577 .as_call_id(self.db, |path| self.resolve_attribute_macro(&directive, &path))
542 { 578 {
543 resolved.push((directive.module_id, call_id, 0)); 579 resolved.push((directive.module_id, call_id, 0));
544 res = ReachedFixedPoint::No; 580 res = ReachedFixedPoint::No;
@@ -562,9 +598,11 @@ impl DefCollector<'_> {
562 res 598 res
563 } 599 }
564 600
565 fn resolve_attribute_macro(&self, path: &ModPath) -> Option<MacroDefId> { 601 fn resolve_attribute_macro(
566 // FIXME this is currently super hacky, just enough to support the 602 &self,
567 // built-in derives 603 directive: &DeriveDirective,
604 path: &ModPath,
605 ) -> Option<MacroDefId> {
568 if let Some(name) = path.as_ident() { 606 if let Some(name) = path.as_ident() {
569 // FIXME this should actually be handled with the normal name 607 // FIXME this should actually be handled with the normal name
570 // resolution; the std lib defines built-in stubs for the derives, 608 // resolution; the std lib defines built-in stubs for the derives,
@@ -573,7 +611,15 @@ impl DefCollector<'_> {
573 return Some(def_id); 611 return Some(def_id);
574 } 612 }
575 } 613 }
576 None 614 let resolved_res = self.def_map.resolve_path_fp_with_macro(
615 self.db,
616 ResolveMode::Other,
617 directive.module_id,
618 &path,
619 BuiltinShadowMode::Module,
620 );
621
622 resolved_res.resolved_def.take_macros()
577 } 623 }
578 624
579 fn collect_macro_expansion( 625 fn collect_macro_expansion(
@@ -776,7 +822,6 @@ impl ModCollector<'_, '_> {
776 // FIXME: check attrs to see if this is an attribute macro invocation; 822 // FIXME: check attrs to see if this is an attribute macro invocation;
777 // in which case we don't add the invocation, just a single attribute 823 // in which case we don't add the invocation, just a single attribute
778 // macro invocation 824 // macro invocation
779
780 self.collect_derives(attrs, def); 825 self.collect_derives(attrs, def);
781 826
782 let name = def.name.clone(); 827 let name = def.name.clone();
@@ -955,6 +1000,7 @@ mod tests {
955 unexpanded_attribute_macros: Vec::new(), 1000 unexpanded_attribute_macros: Vec::new(),
956 mod_dirs: FxHashMap::default(), 1001 mod_dirs: FxHashMap::default(),
957 cfg_options: &CfgOptions::default(), 1002 cfg_options: &CfgOptions::default(),
1003 proc_macros: Default::default(),
958 }; 1004 };
959 collector.collect(); 1005 collector.collect();
960 collector.def_map 1006 collector.def_map