diff options
Diffstat (limited to 'crates/ra_hir_expand/src/lib.rs')
-rw-r--r-- | crates/ra_hir_expand/src/lib.rs | 88 |
1 files changed, 78 insertions, 10 deletions
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index 9506f2e1c..3fce73e8a 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs | |||
@@ -12,6 +12,7 @@ pub mod diagnostics; | |||
12 | pub mod builtin_derive; | 12 | pub mod builtin_derive; |
13 | pub mod builtin_macro; | 13 | pub mod builtin_macro; |
14 | pub mod quote; | 14 | pub mod quote; |
15 | pub mod eager; | ||
15 | 16 | ||
16 | use std::hash::Hash; | 17 | use std::hash::Hash; |
17 | use std::sync::Arc; | 18 | use std::sync::Arc; |
@@ -25,7 +26,7 @@ use ra_syntax::{ | |||
25 | 26 | ||
26 | use crate::ast_id_map::FileAstId; | 27 | use crate::ast_id_map::FileAstId; |
27 | use crate::builtin_derive::BuiltinDeriveExpander; | 28 | use crate::builtin_derive::BuiltinDeriveExpander; |
28 | use crate::builtin_macro::BuiltinFnLikeExpander; | 29 | use crate::builtin_macro::{BuiltinFnLikeExpander, EagerExpander}; |
29 | 30 | ||
30 | #[cfg(test)] | 31 | #[cfg(test)] |
31 | mod test_db; | 32 | mod test_db; |
@@ -70,8 +71,17 @@ impl HirFileId { | |||
70 | match self.0 { | 71 | match self.0 { |
71 | HirFileIdRepr::FileId(file_id) => file_id, | 72 | HirFileIdRepr::FileId(file_id) => file_id, |
72 | HirFileIdRepr::MacroFile(macro_file) => { | 73 | HirFileIdRepr::MacroFile(macro_file) => { |
73 | let loc = db.lookup_intern_macro(macro_file.macro_call_id); | 74 | let file_id = match macro_file.macro_call_id { |
74 | loc.kind.file_id().original_file(db) | 75 | MacroCallId::LazyMacro(id) => { |
76 | let loc = db.lookup_intern_macro(id); | ||
77 | loc.kind.file_id() | ||
78 | } | ||
79 | MacroCallId::EagerMacro(id) => { | ||
80 | let loc = db.lookup_intern_eager_expansion(id); | ||
81 | loc.file_id | ||
82 | } | ||
83 | }; | ||
84 | file_id.original_file(db) | ||
75 | } | 85 | } |
76 | } | 86 | } |
77 | } | 87 | } |
@@ -81,7 +91,14 @@ impl HirFileId { | |||
81 | match self.0 { | 91 | match self.0 { |
82 | HirFileIdRepr::FileId(_) => None, | 92 | HirFileIdRepr::FileId(_) => None, |
83 | HirFileIdRepr::MacroFile(macro_file) => { | 93 | HirFileIdRepr::MacroFile(macro_file) => { |
84 | let loc = db.lookup_intern_macro(macro_file.macro_call_id); | 94 | let lazy_id = match macro_file.macro_call_id { |
95 | MacroCallId::LazyMacro(id) => id, | ||
96 | MacroCallId::EagerMacro(_id) => { | ||
97 | // FIXME: handle call node for eager macro | ||
98 | return None; | ||
99 | } | ||
100 | }; | ||
101 | let loc = db.lookup_intern_macro(lazy_id); | ||
85 | Some(loc.kind.node(db)) | 102 | Some(loc.kind.node(db)) |
86 | } | 103 | } |
87 | } | 104 | } |
@@ -92,7 +109,14 @@ impl HirFileId { | |||
92 | match self.0 { | 109 | match self.0 { |
93 | HirFileIdRepr::FileId(_) => None, | 110 | HirFileIdRepr::FileId(_) => None, |
94 | HirFileIdRepr::MacroFile(macro_file) => { | 111 | HirFileIdRepr::MacroFile(macro_file) => { |
95 | let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id); | 112 | let lazy_id = match macro_file.macro_call_id { |
113 | MacroCallId::LazyMacro(id) => id, | ||
114 | MacroCallId::EagerMacro(_id) => { | ||
115 | // FIXME: handle expansion_info for eager macro | ||
116 | return None; | ||
117 | } | ||
118 | }; | ||
119 | let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id); | ||
96 | 120 | ||
97 | let arg_tt = loc.kind.arg(db)?; | 121 | let arg_tt = loc.kind.arg(db)?; |
98 | let def_tt = loc.def.ast_id?.to_node(db).token_tree()?; | 122 | let def_tt = loc.def.ast_id?.to_node(db).token_tree()?; |
@@ -118,7 +142,13 @@ impl HirFileId { | |||
118 | match self.0 { | 142 | match self.0 { |
119 | HirFileIdRepr::FileId(_) => None, | 143 | HirFileIdRepr::FileId(_) => None, |
120 | HirFileIdRepr::MacroFile(macro_file) => { | 144 | HirFileIdRepr::MacroFile(macro_file) => { |
121 | let loc: MacroCallLoc = db.lookup_intern_macro(macro_file.macro_call_id); | 145 | let lazy_id = match macro_file.macro_call_id { |
146 | MacroCallId::LazyMacro(id) => id, | ||
147 | MacroCallId::EagerMacro(_id) => { | ||
148 | return None; | ||
149 | } | ||
150 | }; | ||
151 | let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id); | ||
122 | let item = match loc.def.kind { | 152 | let item = match loc.def.kind { |
123 | MacroDefKind::BuiltInDerive(_) => loc.kind.node(db), | 153 | MacroDefKind::BuiltInDerive(_) => loc.kind.node(db), |
124 | _ => return None, | 154 | _ => return None, |
@@ -137,16 +167,44 @@ pub struct MacroFile { | |||
137 | /// `MacroCallId` identifies a particular macro invocation, like | 167 | /// `MacroCallId` identifies a particular macro invocation, like |
138 | /// `println!("Hello, {}", world)`. | 168 | /// `println!("Hello, {}", world)`. |
139 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 169 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
140 | pub struct MacroCallId(salsa::InternId); | 170 | pub enum MacroCallId { |
141 | impl salsa::InternKey for MacroCallId { | 171 | LazyMacro(LazyMacroId), |
172 | EagerMacro(EagerMacroId), | ||
173 | } | ||
174 | |||
175 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
176 | pub struct LazyMacroId(salsa::InternId); | ||
177 | impl salsa::InternKey for LazyMacroId { | ||
178 | fn from_intern_id(v: salsa::InternId) -> Self { | ||
179 | LazyMacroId(v) | ||
180 | } | ||
181 | fn as_intern_id(&self) -> salsa::InternId { | ||
182 | self.0 | ||
183 | } | ||
184 | } | ||
185 | |||
186 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
187 | pub struct EagerMacroId(salsa::InternId); | ||
188 | impl salsa::InternKey for EagerMacroId { | ||
142 | fn from_intern_id(v: salsa::InternId) -> Self { | 189 | fn from_intern_id(v: salsa::InternId) -> Self { |
143 | MacroCallId(v) | 190 | EagerMacroId(v) |
144 | } | 191 | } |
145 | fn as_intern_id(&self) -> salsa::InternId { | 192 | fn as_intern_id(&self) -> salsa::InternId { |
146 | self.0 | 193 | self.0 |
147 | } | 194 | } |
148 | } | 195 | } |
149 | 196 | ||
197 | impl From<LazyMacroId> for MacroCallId { | ||
198 | fn from(it: LazyMacroId) -> Self { | ||
199 | MacroCallId::LazyMacro(it) | ||
200 | } | ||
201 | } | ||
202 | impl From<EagerMacroId> for MacroCallId { | ||
203 | fn from(it: EagerMacroId) -> Self { | ||
204 | MacroCallId::EagerMacro(it) | ||
205 | } | ||
206 | } | ||
207 | |||
150 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 208 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
151 | pub struct MacroDefId { | 209 | pub struct MacroDefId { |
152 | // FIXME: krate and ast_id are currently optional because we don't have a | 210 | // FIXME: krate and ast_id are currently optional because we don't have a |
@@ -161,7 +219,7 @@ pub struct MacroDefId { | |||
161 | } | 219 | } |
162 | 220 | ||
163 | impl MacroDefId { | 221 | impl MacroDefId { |
164 | pub fn as_call_id(self, db: &dyn db::AstDatabase, kind: MacroCallKind) -> MacroCallId { | 222 | pub fn as_lazy_macro(self, db: &dyn db::AstDatabase, kind: MacroCallKind) -> LazyMacroId { |
165 | db.intern_macro(MacroCallLoc { def: self, kind }) | 223 | db.intern_macro(MacroCallLoc { def: self, kind }) |
166 | } | 224 | } |
167 | } | 225 | } |
@@ -172,6 +230,7 @@ pub enum MacroDefKind { | |||
172 | BuiltIn(BuiltinFnLikeExpander), | 230 | BuiltIn(BuiltinFnLikeExpander), |
173 | // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander | 231 | // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander |
174 | BuiltInDerive(BuiltinDeriveExpander), | 232 | BuiltInDerive(BuiltinDeriveExpander), |
233 | BuiltInEager(EagerExpander), | ||
175 | } | 234 | } |
176 | 235 | ||
177 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 236 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
@@ -217,6 +276,14 @@ impl MacroCallId { | |||
217 | } | 276 | } |
218 | } | 277 | } |
219 | 278 | ||
279 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
280 | pub struct EagerCallLoc { | ||
281 | pub(crate) def: MacroDefId, | ||
282 | pub(crate) fragment: FragmentKind, | ||
283 | pub(crate) subtree: Arc<tt::Subtree>, | ||
284 | pub(crate) file_id: HirFileId, | ||
285 | } | ||
286 | |||
220 | /// ExpansionInfo mainly describes how to map text range between src and expanded macro | 287 | /// ExpansionInfo mainly describes how to map text range between src and expanded macro |
221 | #[derive(Debug, Clone, PartialEq, Eq)] | 288 | #[derive(Debug, Clone, PartialEq, Eq)] |
222 | pub struct ExpansionInfo { | 289 | pub struct ExpansionInfo { |
@@ -230,6 +297,7 @@ pub struct ExpansionInfo { | |||
230 | } | 297 | } |
231 | 298 | ||
232 | pub use mbe::Origin; | 299 | pub use mbe::Origin; |
300 | use ra_parser::FragmentKind; | ||
233 | 301 | ||
234 | impl ExpansionInfo { | 302 | impl ExpansionInfo { |
235 | pub fn call_node(&self) -> Option<InFile<SyntaxNode>> { | 303 | pub fn call_node(&self) -> Option<InFile<SyntaxNode>> { |