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.rs66
1 files changed, 50 insertions, 16 deletions
diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs
index b4dafe1d8..343c9e6bf 100644
--- a/crates/ra_hir_expand/src/db.rs
+++ b/crates/ra_hir_expand/src/db.rs
@@ -9,10 +9,37 @@ use ra_prof::profile;
9use ra_syntax::{AstNode, Parse, SyntaxNode}; 9use ra_syntax::{AstNode, Parse, SyntaxNode};
10 10
11use crate::{ 11use crate::{
12 ast_id_map::AstIdMap, HirFileId, HirFileIdRepr, MacroCallId, MacroCallLoc, MacroDefId, 12 ast_id_map::AstIdMap, BuiltinExpander, HirFileId, HirFileIdRepr, MacroCallId, MacroCallLoc,
13 MacroFile, MacroFileKind, 13 MacroDefId, MacroFile, MacroFileKind,
14}; 14};
15 15
16#[derive(Debug, Clone, Eq, PartialEq)]
17pub enum TokenExpander {
18 MacroRules(mbe::MacroRules),
19 Builtin(BuiltinExpander),
20}
21
22impl 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
16// FIXME: rename to ExpandDatabase 43// FIXME: rename to ExpandDatabase
17#[salsa::query_group(AstDatabaseStorage)] 44#[salsa::query_group(AstDatabaseStorage)]
18pub trait AstDatabase: SourceDatabase { 45pub trait AstDatabase: SourceDatabase {
@@ -24,7 +51,7 @@ pub trait AstDatabase: SourceDatabase {
24 #[salsa::interned] 51 #[salsa::interned]
25 fn intern_macro(&self, macro_call: MacroCallLoc) -> MacroCallId; 52 fn intern_macro(&self, macro_call: MacroCallLoc) -> MacroCallId;
26 fn macro_arg(&self, id: MacroCallId) -> Option<Arc<(tt::Subtree, mbe::TokenMap)>>; 53 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)>>;
28 fn parse_macro( 55 fn parse_macro(
29 &self, 56 &self,
30 macro_file: MacroFile, 57 macro_file: MacroFile,
@@ -41,18 +68,25 @@ pub(crate) fn ast_id_map(db: &dyn AstDatabase, file_id: HirFileId) -> Arc<AstIdM
41pub(crate) fn macro_def( 68pub(crate) fn macro_def(
42 db: &dyn AstDatabase, 69 db: &dyn AstDatabase,
43 id: MacroDefId, 70 id: MacroDefId,
44) -> Option<Arc<(mbe::MacroRules, mbe::TokenMap)>> { 71) -> Option<Arc<(TokenExpander, mbe::TokenMap)>> {
45 let macro_call = id.ast_id.to_node(db); 72 match id {
46 let arg = macro_call.token_tree()?; 73 MacroDefId::DeclarativeMacro(it) => {
47 let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| { 74 let macro_call = it.ast_id.to_node(db);
48 log::warn!("fail on macro_def to token tree: {:#?}", arg); 75 let arg = macro_call.token_tree()?;
49 None 76 let (tt, tmap) = mbe::ast_to_token_tree(&arg).or_else(|| {
50 })?; 77 log::warn!("fail on macro_def to token tree: {:#?}", arg);
51 let rules = MacroRules::parse(&tt).ok().or_else(|| { 78 None
52 log::warn!("fail on macro_def parse: {:#?}", tt); 79 })?;
53 None 80 let rules = MacroRules::parse(&tt).ok().or_else(|| {
54 })?; 81 log::warn!("fail on macro_def parse: {:#?}", tt);
55 Some(Arc::new((rules, tmap))) 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 }
56} 90}
57 91
58pub(crate) fn macro_arg( 92pub(crate) fn macro_arg(
@@ -74,7 +108,7 @@ pub(crate) fn macro_expand(
74 let macro_arg = db.macro_arg(id).ok_or("Fail to args in to tt::TokenTree")?; 108 let macro_arg = db.macro_arg(id).ok_or("Fail to args in to tt::TokenTree")?;
75 109
76 let macro_rules = db.macro_def(loc.def).ok_or("Fail to find macro definition")?; 110 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))?;
78 // Set a hard limit for the expanded tt 112 // Set a hard limit for the expanded tt
79 let count = tt.count(); 113 let count = tt.count();
80 if count > 65536 { 114 if count > 65536 {