aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/ids.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/ids.rs')
-rw-r--r--crates/ra_hir/src/ids.rs77
1 files changed, 41 insertions, 36 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index b0e9b1f9a..4102951c9 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -63,47 +63,27 @@ impl HirFileId {
63 match file_id.0 { 63 match file_id.0 {
64 HirFileIdRepr::File(file_id) => db.parse(file_id), 64 HirFileIdRepr::File(file_id) => db.parse(file_id),
65 HirFileIdRepr::Macro(macro_call_id) => { 65 HirFileIdRepr::Macro(macro_call_id) => {
66 parse_macro(db, macro_call_id).unwrap_or_else(|err| { 66 match db.macro_expand(macro_call_id) {
67 // Note: 67 Ok(tt) => mbe::token_tree_to_ast_item_list(&tt),
68 // The final goal we would like to make all parse_macro success, 68 Err(err) => {
69 // such that the following log will not call anyway. 69 // Note:
70 log::warn!( 70 // The final goal we would like to make all parse_macro success,
71 "fail on macro_parse: (reason: {}) {}", 71 // such that the following log will not call anyway.
72 err, 72 log::warn!(
73 macro_call_id.debug_dump(db) 73 "fail on macro_parse: (reason: {}) {}",
74 ); 74 err,
75 75 macro_call_id.debug_dump(db)
76 // returning an empty string looks fishy... 76 );
77 SourceFile::parse("") 77
78 }) 78 // returning an empty string looks fishy...
79 SourceFile::parse("")
80 }
81 }
79 } 82 }
80 } 83 }
81 } 84 }
82} 85}
83 86
84fn parse_macro(
85 db: &impl DefDatabase,
86 macro_call_id: MacroCallId,
87) -> Result<TreeArc<SourceFile>, String> {
88 let loc = macro_call_id.loc(db);
89 let macro_call = loc.ast_id.to_node(db);
90 let (macro_arg, _) = macro_call
91 .token_tree()
92 .and_then(mbe::ast_to_token_tree)
93 .ok_or("Fail to args in to tt::TokenTree")?;
94
95 let macro_rules = db.macro_def(loc.def).ok_or("Fail to find macro definition")?;
96 let tt = macro_rules.expand(&macro_arg).map_err(|err| format!("{:?}", err))?;
97
98 // Set a hard limit for the expanded tt
99 let count = tt.count();
100 if count > 65536 {
101 return Err(format!("Total tokens count exceed limit : count = {}", count));
102 }
103
104 Ok(mbe::token_tree_to_ast_item_list(&tt))
105}
106
107#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 87#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
108enum HirFileIdRepr { 88enum HirFileIdRepr {
109 File(FileId), 89 File(FileId),
@@ -139,6 +119,31 @@ pub(crate) fn macro_def_query(db: &impl DefDatabase, id: MacroDefId) -> Option<A
139 Some(Arc::new(rules)) 119 Some(Arc::new(rules))
140} 120}
141 121
122pub(crate) fn macro_arg_query(db: &impl DefDatabase, id: MacroCallId) -> Option<Arc<tt::Subtree>> {
123 let loc = id.loc(db);
124 let macro_call = loc.ast_id.to_node(db);
125 let arg = macro_call.token_tree()?;
126 let (tt, _) = mbe::ast_to_token_tree(arg)?;
127 Some(Arc::new(tt))
128}
129
130pub(crate) fn macro_expand_query(
131 db: &impl DefDatabase,
132 id: MacroCallId,
133) -> Result<Arc<tt::Subtree>, String> {
134 let loc = id.loc(db);
135 let macro_arg = db.macro_arg(id).ok_or("Fail to args in to tt::TokenTree")?;
136
137 let macro_rules = db.macro_def(loc.def).ok_or("Fail to find macro definition")?;
138 let tt = macro_rules.expand(&macro_arg).map_err(|err| format!("{:?}", err))?;
139 // Set a hard limit for the expanded tt
140 let count = tt.count();
141 if count > 65536 {
142 return Err(format!("Total tokens count exceed limit : count = {}", count));
143 }
144 Ok(Arc::new(tt))
145}
146
142macro_rules! impl_intern_key { 147macro_rules! impl_intern_key {
143 ($name:ident) => { 148 ($name:ident) => {
144 impl salsa::InternKey for $name { 149 impl salsa::InternKey for $name {