aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_expand/src/db.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_expand/src/db.rs')
-rw-r--r--crates/ra_hir_expand/src/db.rs58
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;
9use ra_syntax::{AstNode, Parse, SyntaxKind::*, SyntaxNode}; 9use ra_syntax::{AstNode, Parse, SyntaxKind::*, SyntaxNode};
10 10
11use crate::{ 11use 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
71pub(crate) fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdMap> { 75pub(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, &macro_arg.0).map_err(|err| format!("{:?}", err))?; 144 let tt = macro_rules.0.expand(db, lazy_id, &macro_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
170fn to_fragment_kind(db: &dyn AstDatabase, macro_call_id: MacroCallId) -> FragmentKind { 200fn 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,