diff options
Diffstat (limited to 'crates/ra_hir_expand/src/db.rs')
-rw-r--r-- | crates/ra_hir_expand/src/db.rs | 58 |
1 files changed, 47 insertions, 11 deletions
diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs index 70d969238..32e0d5ced 100644 --- a/crates/ra_hir_expand/src/db.rs +++ b/crates/ra_hir_expand/src/db.rs | |||
@@ -9,8 +9,9 @@ use ra_prof::profile; | |||
9 | use ra_syntax::{AstNode, Parse, SyntaxKind::*, SyntaxNode}; | 9 | use ra_syntax::{AstNode, Parse, SyntaxKind::*, SyntaxNode}; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | ast_id_map::AstIdMap, BuiltinDeriveExpander, BuiltinFnLikeExpander, HirFileId, HirFileIdRepr, | 12 | ast_id_map::AstIdMap, BuiltinDeriveExpander, BuiltinFnLikeExpander, EagerCallLoc, EagerMacroId, |
13 | MacroCallId, MacroCallLoc, MacroDefId, MacroDefKind, MacroFile, | 13 | HirFileId, HirFileIdRepr, LazyMacroId, MacroCallId, MacroCallLoc, MacroDefId, MacroDefKind, |
14 | MacroFile, | ||
14 | }; | 15 | }; |
15 | 16 | ||
16 | #[derive(Debug, Clone, Eq, PartialEq)] | 17 | #[derive(Debug, Clone, Eq, PartialEq)] |
@@ -24,7 +25,7 @@ impl TokenExpander { | |||
24 | pub fn expand( | 25 | pub fn expand( |
25 | &self, | 26 | &self, |
26 | db: &dyn AstDatabase, | 27 | db: &dyn AstDatabase, |
27 | id: MacroCallId, | 28 | id: LazyMacroId, |
28 | tt: &tt::Subtree, | 29 | tt: &tt::Subtree, |
29 | ) -> Result<tt::Subtree, mbe::ExpandError> { | 30 | ) -> Result<tt::Subtree, mbe::ExpandError> { |
30 | match self { | 31 | match self { |
@@ -60,12 +61,15 @@ pub trait AstDatabase: SourceDatabase { | |||
60 | fn parse_or_expand(&self, file_id: HirFileId) -> Option<SyntaxNode>; | 61 | fn parse_or_expand(&self, file_id: HirFileId) -> Option<SyntaxNode>; |
61 | 62 | ||
62 | #[salsa::interned] | 63 | #[salsa::interned] |
63 | fn intern_macro(&self, macro_call: MacroCallLoc) -> MacroCallId; | 64 | fn intern_macro(&self, macro_call: MacroCallLoc) -> LazyMacroId; |
64 | fn macro_arg(&self, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>>; | 65 | fn macro_arg(&self, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>>; |
65 | fn macro_def(&self, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>>; | 66 | fn macro_def(&self, id: MacroDefId) -> Option<Arc<(TokenExpander, mbe::TokenMap)>>; |
66 | fn parse_macro(&self, macro_file: MacroFile) | 67 | fn parse_macro(&self, macro_file: MacroFile) |
67 | -> Option<(Parse<SyntaxNode>, Arc<mbe::TokenMap>)>; | 68 | -> Option<(Parse<SyntaxNode>, Arc<mbe::TokenMap>)>; |
68 | fn macro_expand(&self, macro_call: MacroCallId) -> Result<Arc<tt::Subtree>, String>; | 69 | fn macro_expand(&self, macro_call: MacroCallId) -> Result<Arc<tt::Subtree>, String>; |
70 | |||
71 | #[salsa::interned] | ||
72 | fn intern_eager_expansion(&self, eager: EagerCallLoc) -> EagerMacroId; | ||
69 | } | 73 | } |
70 | 74 | ||
71 | pub(crate) fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdMap> { | 75 | pub(crate) fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdMap> { |
@@ -101,6 +105,7 @@ pub(crate) fn macro_def( | |||
101 | MacroDefKind::BuiltInDerive(expander) => { | 105 | MacroDefKind::BuiltInDerive(expander) => { |
102 | Some(Arc::new((TokenExpander::BuiltinDerive(expander), mbe::TokenMap::default()))) | 106 | Some(Arc::new((TokenExpander::BuiltinDerive(expander), mbe::TokenMap::default()))) |
103 | } | 107 | } |
108 | MacroDefKind::BuiltInEager(_expander) => None, | ||
104 | } | 109 | } |
105 | } | 110 | } |
106 | 111 | ||
@@ -108,6 +113,13 @@ pub(crate) fn macro_arg( | |||
108 | db: &dyn AstDatabase, | 113 | db: &dyn AstDatabase, |
109 | id: MacroCallId, | 114 | id: MacroCallId, |
110 | ) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> { | 115 | ) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>> { |
116 | let id = match id { | ||
117 | MacroCallId::LazyMacro(id) => id, | ||
118 | MacroCallId::EagerMacro(_id) => { | ||
119 | // FIXME: support macro_arg for eager macro | ||
120 | return None; | ||
121 | } | ||
122 | }; | ||
111 | let loc = db.lookup_intern_macro(id); | 123 | let loc = db.lookup_intern_macro(id); |
112 | let arg = loc.kind.arg(db)?; | 124 | let arg = loc.kind.arg(db)?; |
113 | let (tt, tmap) = mbe::syntax_node_to_token_tree(&arg)?; | 125 | let (tt, tmap) = mbe::syntax_node_to_token_tree(&arg)?; |
@@ -118,11 +130,18 @@ pub(crate) fn macro_expand( | |||
118 | db: &dyn AstDatabase, | 130 | db: &dyn AstDatabase, |
119 | id: MacroCallId, | 131 | id: MacroCallId, |
120 | ) -> Result<Arc<tt::Subtree>, String> { | 132 | ) -> Result<Arc<tt::Subtree>, String> { |
121 | let loc = db.lookup_intern_macro(id); | 133 | let lazy_id = match id { |
134 | MacroCallId::LazyMacro(id) => id, | ||
135 | MacroCallId::EagerMacro(id) => { | ||
136 | return Ok(db.lookup_intern_eager_expansion(id).subtree); | ||
137 | } | ||
138 | }; | ||
139 | |||
140 | let loc = db.lookup_intern_macro(lazy_id); | ||
122 | let macro_arg = db.macro_arg(id).ok_or("Fail to args in to tt::TokenTree")?; | 141 | let macro_arg = db.macro_arg(id).ok_or("Fail to args in to tt::TokenTree")?; |
123 | 142 | ||
124 | let macro_rules = db.macro_def(loc.def).ok_or("Fail to find macro definition")?; | 143 | let macro_rules = db.macro_def(loc.def).ok_or("Fail to find macro definition")?; |
125 | let tt = macro_rules.0.expand(db, id, ¯o_arg.0).map_err(|err| format!("{:?}", err))?; | 144 | let tt = macro_rules.0.expand(db, lazy_id, ¯o_arg.0).map_err(|err| format!("{:?}", err))?; |
126 | // Set a hard limit for the expanded tt | 145 | // Set a hard limit for the expanded tt |
127 | let count = tt.count(); | 146 | let count = tt.count(); |
128 | if count > 65536 { | 147 | if count > 65536 { |
@@ -153,9 +172,20 @@ pub(crate) fn parse_macro( | |||
153 | // Note: | 172 | // Note: |
154 | // The final goal we would like to make all parse_macro success, | 173 | // The final goal we would like to make all parse_macro success, |
155 | // such that the following log will not call anyway. | 174 | // such that the following log will not call anyway. |
156 | let loc: MacroCallLoc = db.lookup_intern_macro(macro_call_id); | 175 | match macro_call_id { |
157 | let node = loc.kind.node(db); | 176 | MacroCallId::LazyMacro(id) => { |
158 | log::warn!("fail on macro_parse: (reason: {} macro_call: {:#})", err, node.value); | 177 | let loc: MacroCallLoc = db.lookup_intern_macro(id); |
178 | let node = loc.kind.node(db); | ||
179 | log::warn!( | ||
180 | "fail on macro_parse: (reason: {} macro_call: {:#})", | ||
181 | err, | ||
182 | node.value | ||
183 | ); | ||
184 | } | ||
185 | _ => { | ||
186 | log::warn!("fail on macro_parse: (reason: {})", err); | ||
187 | } | ||
188 | } | ||
159 | }) | 189 | }) |
160 | .ok()?; | 190 | .ok()?; |
161 | 191 | ||
@@ -167,8 +197,14 @@ pub(crate) fn parse_macro( | |||
167 | 197 | ||
168 | /// Given a `MacroCallId`, return what `FragmentKind` it belongs to. | 198 | /// Given a `MacroCallId`, return what `FragmentKind` it belongs to. |
169 | /// FIXME: Not completed | 199 | /// FIXME: Not completed |
170 | fn to_fragment_kind(db: &dyn AstDatabase, macro_call_id: MacroCallId) -> FragmentKind { | 200 | fn to_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind { |
171 | let syn = db.lookup_intern_macro(macro_call_id).kind.node(db).value; | 201 | let lazy_id = match id { |
202 | MacroCallId::LazyMacro(id) => id, | ||
203 | MacroCallId::EagerMacro(id) => { | ||
204 | return db.lookup_intern_eager_expansion(id).fragment; | ||
205 | } | ||
206 | }; | ||
207 | let syn = db.lookup_intern_macro(lazy_id).kind.node(db).value; | ||
172 | 208 | ||
173 | let parent = match syn.parent() { | 209 | let parent = match syn.parent() { |
174 | Some(it) => it, | 210 | Some(it) => it, |