4
4
//! resolves imports and expands macros.
5
5
6
6
use hir_expand:: {
7
+ builtin_derive:: find_builtin_derive,
7
8
builtin_macro:: find_builtin_macro,
8
9
name:: { self , AsName , Name } ,
9
- HirFileId , MacroCallId , MacroDefId , MacroDefKind , MacroFileKind ,
10
+ HirFileId , MacroCallId , MacroCallKind , MacroDefId , MacroDefKind , MacroFileKind ,
10
11
} ;
11
12
use ra_cfg:: CfgOptions ;
12
13
use ra_db:: { CrateId , FileId } ;
@@ -58,6 +59,7 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C
58
59
glob_imports : FxHashMap :: default ( ) ,
59
60
unresolved_imports : Vec :: new ( ) ,
60
61
unexpanded_macros : Vec :: new ( ) ,
62
+ unexpanded_attribute_macros : Vec :: new ( ) ,
61
63
mod_dirs : FxHashMap :: default ( ) ,
62
64
macro_stack_monitor : MacroStackMonitor :: default ( ) ,
63
65
poison_macros : FxHashSet :: default ( ) ,
@@ -102,6 +104,7 @@ struct DefCollector<'a, DB> {
102
104
glob_imports : FxHashMap < LocalModuleId , Vec < ( LocalModuleId , LocalImportId ) > > ,
103
105
unresolved_imports : Vec < ( LocalModuleId , LocalImportId , raw:: ImportData ) > ,
104
106
unexpanded_macros : Vec < ( LocalModuleId , AstId < ast:: MacroCall > , Path ) > ,
107
+ unexpanded_attribute_macros : Vec < ( LocalModuleId , AstId < ast:: ModuleItem > , Path ) > ,
105
108
mod_dirs : FxHashMap < LocalModuleId , ModDir > ,
106
109
107
110
/// Some macro use `$tt:tt which mean we have to handle the macro perfectly
@@ -470,6 +473,8 @@ where
470
473
471
474
fn resolve_macros ( & mut self ) -> ReachedFixedPoint {
472
475
let mut macros = std:: mem:: replace ( & mut self . unexpanded_macros , Vec :: new ( ) ) ;
476
+ let mut attribute_macros =
477
+ std:: mem:: replace ( & mut self . unexpanded_attribute_macros , Vec :: new ( ) ) ;
473
478
let mut resolved = Vec :: new ( ) ;
474
479
let mut res = ReachedFixedPoint :: Yes ;
475
480
macros. retain ( |( module_id, ast_id, path) | {
@@ -482,7 +487,19 @@ where
482
487
) ;
483
488
484
489
if let Some ( def) = resolved_res. resolved_def . take_macros ( ) {
485
- let call_id = def. as_call_id ( self . db , * ast_id) ;
490
+ let call_id = def. as_call_id ( self . db , MacroCallKind :: FnLike ( * ast_id) ) ;
491
+ resolved. push ( ( * module_id, call_id, def) ) ;
492
+ res = ReachedFixedPoint :: No ;
493
+ return false ;
494
+ }
495
+
496
+ true
497
+ } ) ;
498
+ attribute_macros. retain ( |( module_id, ast_id, path) | {
499
+ let resolved_res = self . resolve_attribute_macro ( path) ;
500
+
501
+ if let Some ( def) = resolved_res {
502
+ let call_id = def. as_call_id ( self . db , MacroCallKind :: Attr ( * ast_id) ) ;
486
503
resolved. push ( ( * module_id, call_id, def) ) ;
487
504
res = ReachedFixedPoint :: No ;
488
505
return false ;
@@ -492,6 +509,7 @@ where
492
509
} ) ;
493
510
494
511
self . unexpanded_macros = macros;
512
+ self . unexpanded_attribute_macros = attribute_macros;
495
513
496
514
for ( module_id, macro_call_id, macro_def_id) in resolved {
497
515
self . collect_macro_expansion ( module_id, macro_call_id, macro_def_id) ;
@@ -500,6 +518,20 @@ where
500
518
res
501
519
}
502
520
521
+ fn resolve_attribute_macro ( & self , path : & Path ) -> Option < MacroDefId > {
522
+ // FIXME this is currently super hacky, just enough to support the
523
+ // built-in derives
524
+ if let Some ( name) = path. as_ident ( ) {
525
+ // FIXME this should actually be handled with the normal name
526
+ // resolution; the std lib defines built-in stubs for the derives,
527
+ // but these are new-style `macro`s, which we don't support yet
528
+ if let Some ( def_id) = find_builtin_derive ( name) {
529
+ return Some ( def_id) ;
530
+ }
531
+ }
532
+ None
533
+ }
534
+
503
535
fn collect_macro_expansion (
504
536
& mut self ,
505
537
module_id : LocalModuleId ,
@@ -589,6 +621,9 @@ where
589
621
. push ( ( self . module_id , import_id, self . raw_items [ import_id] . clone ( ) ) ) ,
590
622
raw:: RawItemKind :: Def ( def) => self . define_def ( & self . raw_items [ def] ) ,
591
623
raw:: RawItemKind :: Macro ( mac) => self . collect_macro ( & self . raw_items [ mac] ) ,
624
+ raw:: RawItemKind :: AttributeMacro ( att) => {
625
+ self . collect_attribute_macro ( & self . raw_items [ att] )
626
+ }
592
627
raw:: RawItemKind :: Impl ( imp) => {
593
628
let module = ModuleId {
594
629
krate : self . def_collector . def_map . krate ,
@@ -759,8 +794,8 @@ where
759
794
if is_macro_rules ( & mac. path ) {
760
795
if let Some ( name) = & mac. name {
761
796
let macro_id = MacroDefId {
762
- ast_id,
763
- krate : self . def_collector . def_map . krate ,
797
+ ast_id : Some ( ast_id ) ,
798
+ krate : Some ( self . def_collector . def_map . krate ) ,
764
799
kind : MacroDefKind :: Declarative ,
765
800
} ;
766
801
self . def_collector . define_macro ( self . module_id , name. clone ( ) , macro_id, mac. export ) ;
@@ -773,7 +808,8 @@ where
773
808
if let Some ( macro_def) = mac. path . as_ident ( ) . and_then ( |name| {
774
809
self . def_collector . def_map [ self . module_id ] . scope . get_legacy_macro ( & name)
775
810
} ) {
776
- let macro_call_id = macro_def. as_call_id ( self . def_collector . db , ast_id) ;
811
+ let macro_call_id =
812
+ macro_def. as_call_id ( self . def_collector . db , MacroCallKind :: FnLike ( ast_id) ) ;
777
813
778
814
self . def_collector . collect_macro_expansion ( self . module_id , macro_call_id, macro_def) ;
779
815
return ;
@@ -788,6 +824,12 @@ where
788
824
self . def_collector . unexpanded_macros . push ( ( self . module_id , ast_id, path) ) ;
789
825
}
790
826
827
+ fn collect_attribute_macro ( & mut self , data : & raw:: AttributeMacroData ) {
828
+ let ast_id = AstId :: new ( self . file_id , data. ast_id ) ;
829
+ let path = data. path . clone ( ) ;
830
+ self . def_collector . unexpanded_attribute_macros . push ( ( self . module_id , ast_id, path) ) ;
831
+ }
832
+
791
833
fn import_all_legacy_macros ( & mut self , module_id : LocalModuleId ) {
792
834
let macros = self . def_collector . def_map [ module_id] . scope . legacy_macros . clone ( ) ;
793
835
for ( name, macro_) in macros {
@@ -829,6 +871,7 @@ mod tests {
829
871
glob_imports : FxHashMap :: default ( ) ,
830
872
unresolved_imports : Vec :: new ( ) ,
831
873
unexpanded_macros : Vec :: new ( ) ,
874
+ unexpanded_attribute_macros : Vec :: new ( ) ,
832
875
mod_dirs : FxHashMap :: default ( ) ,
833
876
macro_stack_monitor : monitor,
834
877
poison_macros : FxHashSet :: default ( ) ,
0 commit comments