diff options
Diffstat (limited to 'crates/ra_hir/src/ids.rs')
-rw-r--r-- | crates/ra_hir/src/ids.rs | 77 |
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 | ||
84 | fn 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(¯o_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)] |
108 | enum HirFileIdRepr { | 88 | enum 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 | ||
122 | pub(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 | |||
130 | pub(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(¯o_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 | |||
142 | macro_rules! impl_intern_key { | 147 | macro_rules! impl_intern_key { |
143 | ($name:ident) => { | 148 | ($name:ident) => { |
144 | impl salsa::InternKey for $name { | 149 | impl salsa::InternKey for $name { |