aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2019-04-21 22:28:06 +0100
committerbors[bot] <bors[bot]@users.noreply.github.com>2019-04-21 22:28:06 +0100
commitbbc5c1d24e1a641b134f634516828301e8cfc320 (patch)
treef10fe8412874714edcc2d317ab7822b9bbf80a74 /crates/ra_hir/src
parentee94edc722c9649bd16bb754959ad349593045e2 (diff)
parent120bfde3c22ed662cd4d3c35e91a739a86d0e990 (diff)
Merge #1189
1189: Fix #1178 r=matklad a=edwin0cheng This PR improves / fixes mbe : 1. Fixed a offest bug in `SourceTreeWalker` 2. Handle `*+` matcher properly 3. Add missing separator in rhs macro expansion. 4. Fixed bug in single token with empty delimiter subtree case. It is because the current `mbe_expander` will create an delimiter subtree for each expansion. But in `tt` case, all puncts expansion will be incorrect because of it. 5. Fixed lifetime bug 6. Add more information on parse_macro fail 7. Add tests for above. Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r--crates/ra_hir/src/ids.rs37
1 files changed, 27 insertions, 10 deletions
diff --git a/crates/ra_hir/src/ids.rs b/crates/ra_hir/src/ids.rs
index 2a1ed9b81..e771a311c 100644
--- a/crates/ra_hir/src/ids.rs
+++ b/crates/ra_hir/src/ids.rs
@@ -63,11 +63,15 @@ 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(|| { 66 parse_macro(db, macro_call_id).unwrap_or_else(|err| {
67 // Note: 67 // Note:
68 // The final goal we would like to make all parse_macro success, 68 // The final goal we would like to make all parse_macro success,
69 // such that the following log will not call anyway. 69 // such that the following log will not call anyway.
70 log::warn!("fail on macro_parse: {}", macro_call_id.debug_dump(db)); 70 log::warn!(
71 "fail on macro_parse: (reason: {}) {}",
72 err,
73 macro_call_id.debug_dump(db)
74 );
71 75
72 // returning an empty string looks fishy... 76 // returning an empty string looks fishy...
73 SourceFile::parse("") 77 SourceFile::parse("")
@@ -77,14 +81,20 @@ impl HirFileId {
77 } 81 }
78} 82}
79 83
80fn parse_macro(db: &impl DefDatabase, macro_call_id: MacroCallId) -> Option<TreeArc<SourceFile>> { 84fn parse_macro(
85 db: &impl DefDatabase,
86 macro_call_id: MacroCallId,
87) -> Result<TreeArc<SourceFile>, String> {
81 let loc = macro_call_id.loc(db); 88 let loc = macro_call_id.loc(db);
82 let macro_call = loc.ast_id.to_node(db); 89 let macro_call = loc.ast_id.to_node(db);
83 let (macro_arg, _) = macro_call.token_tree().and_then(mbe::ast_to_token_tree)?; 90 let (macro_arg, _) = macro_call
84 91 .token_tree()
85 let macro_rules = db.macro_def(loc.def)?; 92 .and_then(mbe::ast_to_token_tree)
86 let tt = macro_rules.expand(&macro_arg).ok()?; 93 .ok_or("Fail to args in to tt::TokenTree")?;
87 Some(mbe::token_tree_to_ast_item_list(&tt)) 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 Ok(mbe::token_tree_to_ast_item_list(&tt))
88} 98}
89 99
90#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 100#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -311,11 +321,18 @@ impl MacroCallId {
311 pub fn debug_dump(&self, db: &impl DefDatabase) -> String { 321 pub fn debug_dump(&self, db: &impl DefDatabase) -> String {
312 let loc = self.clone().loc(db); 322 let loc = self.clone().loc(db);
313 let node = loc.ast_id.to_node(db); 323 let node = loc.ast_id.to_node(db);
314 let syntax_str = node.syntax().to_string(); 324 let syntax_str = node.syntax().text().chunks().collect::<Vec<_>>().join(" ");
315 325
316 // dump the file name 326 // dump the file name
317 let file_id: HirFileId = self.clone().into(); 327 let file_id: HirFileId = self.clone().into();
318 let original = file_id.original_file(db); 328 let original = file_id.original_file(db);
319 format!("macro call [file: {:#?}] : {}", db.file_relative_path(original), syntax_str) 329 let macro_rules = db.macro_def(loc.def);
330
331 format!(
332 "macro call [file: {:#?}] : {}\nhas rules: {}",
333 db.file_relative_path(original),
334 syntax_str,
335 macro_rules.is_some()
336 )
320 } 337 }
321} 338}