@@ -9,10 +9,37 @@ use ra_prof::profile;
99use ra_syntax:: { AstNode , Parse , SyntaxNode } ;
1010
1111use crate :: {
12- ast_id_map:: AstIdMap , HirFileId , HirFileIdRepr , MacroCallId , MacroCallLoc , MacroDefId ,
13- MacroFile , MacroFileKind ,
12+ ast_id_map:: AstIdMap , BuiltinExpander , HirFileId , HirFileIdRepr , MacroCallId , MacroCallLoc ,
13+ MacroDefId , MacroFile , MacroFileKind ,
1414} ;
1515
16+ #[ derive( Debug , Clone , Eq , PartialEq ) ]
17+ pub enum TokenExpander {
18+ MacroRules ( mbe:: MacroRules ) ,
19+ Builtin ( BuiltinExpander ) ,
20+ }
21+
22+ impl TokenExpander {
23+ pub fn expand (
24+ & self ,
25+ db : & dyn AstDatabase ,
26+ id : MacroCallId ,
27+ tt : & tt:: Subtree ,
28+ ) -> Result < tt:: Subtree , mbe:: ExpandError > {
29+ match self {
30+ TokenExpander :: MacroRules ( it) => it. expand ( tt) ,
31+ TokenExpander :: Builtin ( it) => it. expand ( tt) ,
32+ }
33+ }
34+
35+ pub fn shift ( & self ) -> u32 {
36+ match self {
37+ TokenExpander :: MacroRules ( it) => it. shift ( ) ,
38+ TokenExpander :: Builtin ( _) => 0 ,
39+ }
40+ }
41+ }
42+
1643// FIXME: rename to ExpandDatabase
1744#[ salsa:: query_group( AstDatabaseStorage ) ]
1845pub trait AstDatabase : SourceDatabase {
@@ -24,7 +51,7 @@ pub trait AstDatabase: SourceDatabase {
2451 #[ salsa:: interned]
2552 fn intern_macro ( & self , macro_call : MacroCallLoc ) -> MacroCallId ;
2653 fn macro_arg ( & self , id : MacroCallId ) -> Option < Arc < ( tt:: Subtree , mbe:: TokenMap ) > > ;
27- fn macro_def ( & self , id : MacroDefId ) -> Option < Arc < ( mbe :: MacroRules , mbe:: TokenMap ) > > ;
54+ fn macro_def ( & self , id : MacroDefId ) -> Option < Arc < ( TokenExpander , mbe:: TokenMap ) > > ;
2855 fn parse_macro (
2956 & self ,
3057 macro_file : MacroFile ,
@@ -41,18 +68,25 @@ pub(crate) fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdM
4168pub ( crate ) fn macro_def (
4269 db : & dyn AstDatabase ,
4370 id : MacroDefId ,
44- ) -> Option < Arc < ( mbe:: MacroRules , mbe:: TokenMap ) > > {
45- let macro_call = id. ast_id . to_node ( db) ;
46- let arg = macro_call. token_tree ( ) ?;
47- let ( tt, tmap) = mbe:: ast_to_token_tree ( & arg) . or_else ( || {
48- log:: warn!( "fail on macro_def to token tree: {:#?}" , arg) ;
49- None
50- } ) ?;
51- let rules = MacroRules :: parse ( & tt) . ok ( ) . or_else ( || {
52- log:: warn!( "fail on macro_def parse: {:#?}" , tt) ;
53- None
54- } ) ?;
55- Some ( Arc :: new ( ( rules, tmap) ) )
71+ ) -> Option < Arc < ( TokenExpander , mbe:: TokenMap ) > > {
72+ match id {
73+ MacroDefId :: DeclarativeMacro ( it) => {
74+ let macro_call = it. ast_id . to_node ( db) ;
75+ let arg = macro_call. token_tree ( ) ?;
76+ let ( tt, tmap) = mbe:: ast_to_token_tree ( & arg) . or_else ( || {
77+ log:: warn!( "fail on macro_def to token tree: {:#?}" , arg) ;
78+ None
79+ } ) ?;
80+ let rules = MacroRules :: parse ( & tt) . ok ( ) . or_else ( || {
81+ log:: warn!( "fail on macro_def parse: {:#?}" , tt) ;
82+ None
83+ } ) ?;
84+ Some ( Arc :: new ( ( TokenExpander :: MacroRules ( rules) , tmap) ) )
85+ }
86+ MacroDefId :: BuiltinMacro ( it) => {
87+ Some ( Arc :: new ( ( TokenExpander :: Builtin ( it. expander . clone ( ) ) , mbe:: TokenMap :: default ( ) ) ) )
88+ }
89+ }
5690}
5791
5892pub ( crate ) fn macro_arg (
@@ -74,7 +108,7 @@ pub(crate) fn macro_expand(
74108 let macro_arg = db. macro_arg ( id) . ok_or ( "Fail to args in to tt::TokenTree" ) ?;
75109
76110 let macro_rules = db. macro_def ( loc. def ) . ok_or ( "Fail to find macro definition" ) ?;
77- let tt = macro_rules. 0 . expand ( & macro_arg. 0 ) . map_err ( |err| format ! ( "{:?}" , err) ) ?;
111+ let tt = macro_rules. 0 . expand ( db , id , & macro_arg. 0 ) . map_err ( |err| format ! ( "{:?}" , err) ) ?;
78112 // Set a hard limit for the expanded tt
79113 let count = tt. count ( ) ;
80114 if count > 65536 {
0 commit comments