aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_expand
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_expand')
-rw-r--r--crates/ra_hir_expand/src/builtin_derive.rs28
-rw-r--r--crates/ra_hir_expand/src/builtin_macro.rs17
-rw-r--r--crates/ra_hir_expand/src/eager.rs32
-rw-r--r--crates/ra_hir_expand/src/lib.rs16
4 files changed, 54 insertions, 39 deletions
diff --git a/crates/ra_hir_expand/src/builtin_derive.rs b/crates/ra_hir_expand/src/builtin_derive.rs
index 967d1f3a1..26b667b55 100644
--- a/crates/ra_hir_expand/src/builtin_derive.rs
+++ b/crates/ra_hir_expand/src/builtin_derive.rs
@@ -8,8 +8,7 @@ use ra_syntax::{
8 match_ast, 8 match_ast,
9}; 9};
10 10
11use crate::db::AstDatabase; 11use crate::{db::AstDatabase, name, quote, LazyMacroId, MacroDefId, MacroDefKind};
12use crate::{guess_crate, name, quote, LazyMacroId, MacroCallId, MacroDefId, MacroDefKind};
13 12
14macro_rules! register_builtin { 13macro_rules! register_builtin {
15 ( $($trait:ident => $expand:ident),* ) => { 14 ( $($trait:ident => $expand:ident),* ) => {
@@ -156,17 +155,8 @@ fn expand_simple_derive(
156fn find_builtin_crate(db: &dyn AstDatabase, id: LazyMacroId) -> tt::TokenTree { 155fn find_builtin_crate(db: &dyn AstDatabase, id: LazyMacroId) -> tt::TokenTree {
157 // FIXME: make hygiene works for builtin derive macro 156 // FIXME: make hygiene works for builtin derive macro
158 // such that $crate can be used here. 157 // such that $crate can be used here.
159
160 let m: MacroCallId = id.into();
161 let file_id = m.as_file().original_file(db);
162 let cg = db.crate_graph(); 158 let cg = db.crate_graph();
163 let krate = match guess_crate(db, file_id) { 159 let krate = db.lookup_intern_macro(id).krate;
164 Some(krate) => krate,
165 None => {
166 let tt = quote! { core };
167 return tt.token_trees[0].clone();
168 }
169 };
170 160
171 // XXX 161 // XXX
172 // All crates except core itself should have a dependency on core, 162 // All crates except core itself should have a dependency on core,
@@ -263,10 +253,12 @@ fn partial_ord_expand(
263 253
264#[cfg(test)] 254#[cfg(test)]
265mod tests { 255mod tests {
266 use super::*;
267 use crate::{test_db::TestDB, AstId, MacroCallId, MacroCallKind, MacroCallLoc};
268 use name::{known, Name}; 256 use name::{known, Name};
269 use ra_db::{fixture::WithFixture, SourceDatabase}; 257 use ra_db::{fixture::WithFixture, CrateId, SourceDatabase};
258
259 use crate::{test_db::TestDB, AstId, MacroCallId, MacroCallKind, MacroCallLoc};
260
261 use super::*;
270 262
271 fn expand_builtin_derive(s: &str, name: Name) -> String { 263 fn expand_builtin_derive(s: &str, name: Name) -> String {
272 let def = find_builtin_derive(&name).unwrap(); 264 let def = find_builtin_derive(&name).unwrap();
@@ -290,7 +282,11 @@ mod tests {
290 282
291 let attr_id = AstId::new(file_id.into(), ast_id_map.ast_id(&items[0])); 283 let attr_id = AstId::new(file_id.into(), ast_id_map.ast_id(&items[0]));
292 284
293 let loc = MacroCallLoc { def, kind: MacroCallKind::Attr(attr_id, name.to_string()) }; 285 let loc = MacroCallLoc {
286 def,
287 krate: CrateId(0),
288 kind: MacroCallKind::Attr(attr_id, name.to_string()),
289 };
294 290
295 let id: MacroCallId = db.intern_macro(loc).into(); 291 let id: MacroCallId = db.intern_macro(loc).into();
296 let parsed = db.parse_or_expand(id.as_file()).unwrap(); 292 let parsed = db.parse_or_expand(id.as_file()).unwrap();
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs
index 93da3f149..b50eb347c 100644
--- a/crates/ra_hir_expand/src/builtin_macro.rs
+++ b/crates/ra_hir_expand/src/builtin_macro.rs
@@ -1,15 +1,14 @@
1//! Builtin macro 1//! Builtin macro
2use crate::db::AstDatabase;
3use crate::{ 2use crate::{
4 ast::{self, AstToken, HasStringValue}, 3 db::AstDatabase, name, quote, AstId, CrateId, EagerMacroId, LazyMacroId, MacroCallId,
5 name, AstId, CrateId, MacroDefId, MacroDefKind, TextSize, 4 MacroDefId, MacroDefKind, TextSize,
6}; 5};
7 6
8use crate::{guess_crate, quote, EagerMacroId, LazyMacroId, MacroCallId};
9use either::Either; 7use either::Either;
10use mbe::parse_to_token_tree; 8use mbe::parse_to_token_tree;
11use ra_db::FileId; 9use ra_db::FileId;
12use ra_parser::FragmentKind; 10use ra_parser::FragmentKind;
11use ra_syntax::ast::{self, AstToken, HasStringValue};
13 12
14macro_rules! register_builtin { 13macro_rules! register_builtin {
15 ( LAZY: $(($name:ident, $kind: ident) => $expand:ident),* , EAGER: $(($e_name:ident, $e_kind: ident) => $e_expand:ident),* ) => { 14 ( LAZY: $(($name:ident, $kind: ident) => $expand:ident),* , EAGER: $(($e_name:ident, $e_kind: ident) => $e_expand:ident),* ) => {
@@ -333,9 +332,7 @@ fn include_expand(
333} 332}
334 333
335fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> { 334fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Option<String> {
336 let call_id: MacroCallId = arg_id.into(); 335 let krate = db.lookup_intern_eager_expansion(arg_id).krate;
337 let original_file = call_id.as_file().original_file(db);
338 let krate = guess_crate(db, original_file)?;
339 db.crate_graph()[krate].env.get(key) 336 db.crate_graph()[krate].env.get(key)
340} 337}
341 338
@@ -394,6 +391,7 @@ mod tests {
394 391
395 let expander = find_by_name(&macro_calls[0].name().unwrap().as_name()).unwrap(); 392 let expander = find_by_name(&macro_calls[0].name().unwrap().as_name()).unwrap();
396 393
394 let krate = CrateId(0);
397 let file_id = match expander { 395 let file_id = match expander {
398 Either::Left(expander) => { 396 Either::Left(expander) => {
399 // the first one should be a macro_rules 397 // the first one should be a macro_rules
@@ -406,6 +404,7 @@ mod tests {
406 404
407 let loc = MacroCallLoc { 405 let loc = MacroCallLoc {
408 def, 406 def,
407 krate,
409 kind: MacroCallKind::FnLike(AstId::new( 408 kind: MacroCallKind::FnLike(AstId::new(
410 file_id.into(), 409 file_id.into(),
411 ast_id_map.ast_id(&macro_calls[1]), 410 ast_id_map.ast_id(&macro_calls[1]),
@@ -418,7 +417,7 @@ mod tests {
418 Either::Right(expander) => { 417 Either::Right(expander) => {
419 // the first one should be a macro_rules 418 // the first one should be a macro_rules
420 let def = MacroDefId { 419 let def = MacroDefId {
421 krate: Some(CrateId(0)), 420 krate: Some(krate),
422 ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(&macro_calls[0]))), 421 ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(&macro_calls[0]))),
423 kind: MacroDefKind::BuiltInEager(expander), 422 kind: MacroDefKind::BuiltInEager(expander),
424 local_inner: false, 423 local_inner: false,
@@ -432,6 +431,7 @@ mod tests {
432 def, 431 def,
433 fragment: FragmentKind::Expr, 432 fragment: FragmentKind::Expr,
434 subtree: Arc::new(parsed_args.clone()), 433 subtree: Arc::new(parsed_args.clone()),
434 krate,
435 file_id: file_id.into(), 435 file_id: file_id.into(),
436 } 436 }
437 }); 437 });
@@ -441,6 +441,7 @@ mod tests {
441 def, 441 def,
442 fragment, 442 fragment,
443 subtree: Arc::new(subtree), 443 subtree: Arc::new(subtree),
444 krate,
444 file_id: file_id.into(), 445 file_id: file_id.into(),
445 }; 446 };
446 447
diff --git a/crates/ra_hir_expand/src/eager.rs b/crates/ra_hir_expand/src/eager.rs
index 932f47c30..302d2b3e0 100644
--- a/crates/ra_hir_expand/src/eager.rs
+++ b/crates/ra_hir_expand/src/eager.rs
@@ -25,12 +25,14 @@ use crate::{
25 EagerCallLoc, EagerMacroId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, 25 EagerCallLoc, EagerMacroId, InFile, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind,
26}; 26};
27 27
28use ra_db::CrateId;
28use ra_parser::FragmentKind; 29use ra_parser::FragmentKind;
29use ra_syntax::{algo::SyntaxRewriter, SyntaxNode}; 30use ra_syntax::{algo::SyntaxRewriter, SyntaxNode};
30use std::sync::Arc; 31use std::sync::Arc;
31 32
32pub fn expand_eager_macro( 33pub fn expand_eager_macro(
33 db: &dyn AstDatabase, 34 db: &dyn AstDatabase,
35 krate: CrateId,
34 macro_call: InFile<ast::MacroCall>, 36 macro_call: InFile<ast::MacroCall>,
35 def: MacroDefId, 37 def: MacroDefId,
36 resolver: &dyn Fn(ast::Path) -> Option<MacroDefId>, 38 resolver: &dyn Fn(ast::Path) -> Option<MacroDefId>,
@@ -47,6 +49,7 @@ pub fn expand_eager_macro(
47 def, 49 def,
48 fragment: FragmentKind::Expr, 50 fragment: FragmentKind::Expr,
49 subtree: Arc::new(parsed_args.clone()), 51 subtree: Arc::new(parsed_args.clone()),
52 krate,
50 file_id: macro_call.file_id, 53 file_id: macro_call.file_id,
51 } 54 }
52 }); 55 });
@@ -56,14 +59,20 @@ pub fn expand_eager_macro(
56 let result = eager_macro_recur( 59 let result = eager_macro_recur(
57 db, 60 db,
58 InFile::new(arg_file_id.as_file(), parsed_args.syntax_node()), 61 InFile::new(arg_file_id.as_file(), parsed_args.syntax_node()),
62 krate,
59 resolver, 63 resolver,
60 )?; 64 )?;
61 let subtree = to_subtree(&result)?; 65 let subtree = to_subtree(&result)?;
62 66
63 if let MacroDefKind::BuiltInEager(eager) = def.kind { 67 if let MacroDefKind::BuiltInEager(eager) = def.kind {
64 let (subtree, fragment) = eager.expand(db, arg_id, &subtree).ok()?; 68 let (subtree, fragment) = eager.expand(db, arg_id, &subtree).ok()?;
65 let eager = 69 let eager = EagerCallLoc {
66 EagerCallLoc { def, fragment, subtree: Arc::new(subtree), file_id: macro_call.file_id }; 70 def,
71 fragment,
72 subtree: Arc::new(subtree),
73 krate,
74 file_id: macro_call.file_id,
75 };
67 76
68 Some(db.intern_eager_expansion(eager)) 77 Some(db.intern_eager_expansion(eager))
69 } else { 78 } else {
@@ -81,11 +90,12 @@ fn lazy_expand(
81 db: &dyn AstDatabase, 90 db: &dyn AstDatabase,
82 def: &MacroDefId, 91 def: &MacroDefId,
83 macro_call: InFile<ast::MacroCall>, 92 macro_call: InFile<ast::MacroCall>,
93 krate: CrateId,
84) -> Option<InFile<SyntaxNode>> { 94) -> Option<InFile<SyntaxNode>> {
85 let ast_id = db.ast_id_map(macro_call.file_id).ast_id(&macro_call.value); 95 let ast_id = db.ast_id_map(macro_call.file_id).ast_id(&macro_call.value);
86 96
87 let id: MacroCallId = 97 let id: MacroCallId =
88 def.as_lazy_macro(db, MacroCallKind::FnLike(macro_call.with_value(ast_id))).into(); 98 def.as_lazy_macro(db, krate, MacroCallKind::FnLike(macro_call.with_value(ast_id))).into();
89 99
90 db.parse_or_expand(id.as_file()).map(|node| InFile::new(id.as_file(), node)) 100 db.parse_or_expand(id.as_file()).map(|node| InFile::new(id.as_file(), node))
91} 101}
@@ -93,6 +103,7 @@ fn lazy_expand(
93fn eager_macro_recur( 103fn eager_macro_recur(
94 db: &dyn AstDatabase, 104 db: &dyn AstDatabase,
95 curr: InFile<SyntaxNode>, 105 curr: InFile<SyntaxNode>,
106 krate: CrateId,
96 macro_resolver: &dyn Fn(ast::Path) -> Option<MacroDefId>, 107 macro_resolver: &dyn Fn(ast::Path) -> Option<MacroDefId>,
97) -> Option<SyntaxNode> { 108) -> Option<SyntaxNode> {
98 let original = curr.value.clone(); 109 let original = curr.value.clone();
@@ -105,18 +116,23 @@ fn eager_macro_recur(
105 let def: MacroDefId = macro_resolver(child.path()?)?; 116 let def: MacroDefId = macro_resolver(child.path()?)?;
106 let insert = match def.kind { 117 let insert = match def.kind {
107 MacroDefKind::BuiltInEager(_) => { 118 MacroDefKind::BuiltInEager(_) => {
108 let id: MacroCallId = 119 let id: MacroCallId = expand_eager_macro(
109 expand_eager_macro(db, curr.with_value(child.clone()), def, macro_resolver)? 120 db,
110 .into(); 121 krate,
122 curr.with_value(child.clone()),
123 def,
124 macro_resolver,
125 )?
126 .into();
111 db.parse_or_expand(id.as_file())? 127 db.parse_or_expand(id.as_file())?
112 } 128 }
113 MacroDefKind::Declarative 129 MacroDefKind::Declarative
114 | MacroDefKind::BuiltIn(_) 130 | MacroDefKind::BuiltIn(_)
115 | MacroDefKind::BuiltInDerive(_) 131 | MacroDefKind::BuiltInDerive(_)
116 | MacroDefKind::CustomDerive(_) => { 132 | MacroDefKind::CustomDerive(_) => {
117 let expanded = lazy_expand(db, &def, curr.with_value(child.clone()))?; 133 let expanded = lazy_expand(db, &def, curr.with_value(child.clone()), krate)?;
118 // replace macro inside 134 // replace macro inside
119 eager_macro_recur(db, expanded, macro_resolver)? 135 eager_macro_recur(db, expanded, krate, macro_resolver)?
120 } 136 }
121 }; 137 };
122 138
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs
index dc4d7f000..5eac2605b 100644
--- a/crates/ra_hir_expand/src/lib.rs
+++ b/crates/ra_hir_expand/src/lib.rs
@@ -209,8 +209,13 @@ pub struct MacroDefId {
209} 209}
210 210
211impl MacroDefId { 211impl MacroDefId {
212 pub fn as_lazy_macro(self, db: &dyn db::AstDatabase, kind: MacroCallKind) -> LazyMacroId { 212 pub fn as_lazy_macro(
213 db.intern_macro(MacroCallLoc { def: self, kind }) 213 self,
214 db: &dyn db::AstDatabase,
215 krate: CrateId,
216 kind: MacroCallKind,
217 ) -> LazyMacroId {
218 db.intern_macro(MacroCallLoc { def: self, krate, kind })
214 } 219 }
215} 220}
216 221
@@ -227,6 +232,7 @@ pub enum MacroDefKind {
227#[derive(Debug, Clone, PartialEq, Eq, Hash)] 232#[derive(Debug, Clone, PartialEq, Eq, Hash)]
228pub struct MacroCallLoc { 233pub struct MacroCallLoc {
229 pub(crate) def: MacroDefId, 234 pub(crate) def: MacroDefId,
235 pub(crate) krate: CrateId,
230 pub(crate) kind: MacroCallKind, 236 pub(crate) kind: MacroCallKind,
231} 237}
232 238
@@ -274,6 +280,7 @@ pub struct EagerCallLoc {
274 pub(crate) def: MacroDefId, 280 pub(crate) def: MacroDefId,
275 pub(crate) fragment: FragmentKind, 281 pub(crate) fragment: FragmentKind,
276 pub(crate) subtree: Arc<tt::Subtree>, 282 pub(crate) subtree: Arc<tt::Subtree>,
283 pub(crate) krate: CrateId,
277 pub(crate) file_id: HirFileId, 284 pub(crate) file_id: HirFileId,
278} 285}
279 286
@@ -424,8 +431,3 @@ impl<N: AstNode> InFile<N> {
424 self.with_value(self.value.syntax()) 431 self.with_value(self.value.syntax())
425 } 432 }
426} 433}
427
428// FIXME: this is obviously wrong, there shouldn't be any guesing here
429fn guess_crate(db: &dyn db::AstDatabase, file_id: FileId) -> Option<CrateId> {
430 db.relevant_crates(file_id).iter().next().copied()
431}