diff options
Diffstat (limited to 'crates/hir_expand/src/lib.rs')
-rw-r--r-- | crates/hir_expand/src/lib.rs | 58 |
1 files changed, 45 insertions, 13 deletions
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index 7532d00b8..b8045fda9 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs | |||
@@ -15,6 +15,7 @@ pub mod proc_macro; | |||
15 | pub mod quote; | 15 | pub mod quote; |
16 | pub mod eager; | 16 | pub mod eager; |
17 | 17 | ||
18 | use either::Either; | ||
18 | pub use mbe::{ExpandError, ExpandResult}; | 19 | pub use mbe::{ExpandError, ExpandResult}; |
19 | 20 | ||
20 | use std::hash::Hash; | 21 | use std::hash::Hash; |
@@ -83,7 +84,11 @@ impl HirFileId { | |||
83 | } | 84 | } |
84 | MacroCallId::EagerMacro(id) => { | 85 | MacroCallId::EagerMacro(id) => { |
85 | let loc = db.lookup_intern_eager_expansion(id); | 86 | let loc = db.lookup_intern_eager_expansion(id); |
86 | loc.call.file_id | 87 | if let Some(included_file) = loc.included_file { |
88 | return included_file; | ||
89 | } else { | ||
90 | loc.call.file_id | ||
91 | } | ||
87 | } | 92 | } |
88 | }; | 93 | }; |
89 | file_id.original_file(db) | 94 | file_id.original_file(db) |
@@ -143,7 +148,7 @@ impl HirFileId { | |||
143 | 148 | ||
144 | let arg_tt = loc.kind.arg(db)?; | 149 | let arg_tt = loc.kind.arg(db)?; |
145 | 150 | ||
146 | let def = loc.def.ast_id.and_then(|id| { | 151 | let def = loc.def.ast_id().left().and_then(|id| { |
147 | let def_tt = match id.to_node(db) { | 152 | let def_tt = match id.to_node(db) { |
148 | ast::Macro::MacroRules(mac) => mac.token_tree()?, | 153 | ast::Macro::MacroRules(mac) => mac.token_tree()?, |
149 | ast::Macro::MacroDef(_) => return None, | 154 | ast::Macro::MacroDef(_) => return None, |
@@ -180,13 +185,28 @@ impl HirFileId { | |||
180 | }; | 185 | }; |
181 | let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id); | 186 | let loc: MacroCallLoc = db.lookup_intern_macro(lazy_id); |
182 | let item = match loc.def.kind { | 187 | let item = match loc.def.kind { |
183 | MacroDefKind::BuiltInDerive(_) => loc.kind.node(db), | 188 | MacroDefKind::BuiltInDerive(..) => loc.kind.node(db), |
184 | _ => return None, | 189 | _ => return None, |
185 | }; | 190 | }; |
186 | Some(item.with_value(ast::Item::cast(item.value.clone())?)) | 191 | Some(item.with_value(ast::Item::cast(item.value.clone())?)) |
187 | } | 192 | } |
188 | } | 193 | } |
189 | } | 194 | } |
195 | |||
196 | /// Return whether this file is an include macro | ||
197 | pub fn is_include_macro(&self, db: &dyn db::AstDatabase) -> bool { | ||
198 | match self.0 { | ||
199 | HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { | ||
200 | MacroCallId::EagerMacro(id) => { | ||
201 | let loc = db.lookup_intern_eager_expansion(id); | ||
202 | return loc.included_file.is_some(); | ||
203 | } | ||
204 | _ => {} | ||
205 | }, | ||
206 | _ => {} | ||
207 | } | ||
208 | false | ||
209 | } | ||
190 | } | 210 | } |
191 | 211 | ||
192 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 212 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -224,7 +244,6 @@ impl From<EagerMacroId> for MacroCallId { | |||
224 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 244 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
225 | pub struct MacroDefId { | 245 | pub struct MacroDefId { |
226 | pub krate: CrateId, | 246 | pub krate: CrateId, |
227 | pub ast_id: Option<AstId<ast::Macro>>, | ||
228 | pub kind: MacroDefKind, | 247 | pub kind: MacroDefKind, |
229 | 248 | ||
230 | pub local_inner: bool, | 249 | pub local_inner: bool, |
@@ -239,16 +258,27 @@ impl MacroDefId { | |||
239 | ) -> LazyMacroId { | 258 | ) -> LazyMacroId { |
240 | db.intern_macro(MacroCallLoc { def: self, krate, kind }) | 259 | db.intern_macro(MacroCallLoc { def: self, krate, kind }) |
241 | } | 260 | } |
261 | |||
262 | pub fn ast_id(&self) -> Either<AstId<ast::Macro>, AstId<ast::Fn>> { | ||
263 | let id = match &self.kind { | ||
264 | MacroDefKind::Declarative(id) => id, | ||
265 | MacroDefKind::BuiltIn(_, id) => id, | ||
266 | MacroDefKind::BuiltInDerive(_, id) => id, | ||
267 | MacroDefKind::BuiltInEager(_, id) => id, | ||
268 | MacroDefKind::ProcMacro(_, id) => return Either::Right(*id), | ||
269 | }; | ||
270 | Either::Left(*id) | ||
271 | } | ||
242 | } | 272 | } |
243 | 273 | ||
244 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 274 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
245 | pub enum MacroDefKind { | 275 | pub enum MacroDefKind { |
246 | Declarative, | 276 | Declarative(AstId<ast::Macro>), |
247 | BuiltIn(BuiltinFnLikeExpander), | 277 | BuiltIn(BuiltinFnLikeExpander, AstId<ast::Macro>), |
248 | // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander | 278 | // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander |
249 | BuiltInDerive(BuiltinDeriveExpander), | 279 | BuiltInDerive(BuiltinDeriveExpander, AstId<ast::Macro>), |
250 | BuiltInEager(EagerExpander), | 280 | BuiltInEager(EagerExpander, AstId<ast::Macro>), |
251 | ProcMacro(ProcMacroExpander), | 281 | ProcMacro(ProcMacroExpander, AstId<ast::Fn>), |
252 | } | 282 | } |
253 | 283 | ||
254 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 284 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
@@ -261,21 +291,21 @@ pub struct MacroCallLoc { | |||
261 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 291 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
262 | pub enum MacroCallKind { | 292 | pub enum MacroCallKind { |
263 | FnLike(AstId<ast::MacroCall>), | 293 | FnLike(AstId<ast::MacroCall>), |
264 | Attr(AstId<ast::Item>, String), | 294 | Derive(AstId<ast::Item>, String), |
265 | } | 295 | } |
266 | 296 | ||
267 | impl MacroCallKind { | 297 | impl MacroCallKind { |
268 | fn file_id(&self) -> HirFileId { | 298 | fn file_id(&self) -> HirFileId { |
269 | match self { | 299 | match self { |
270 | MacroCallKind::FnLike(ast_id) => ast_id.file_id, | 300 | MacroCallKind::FnLike(ast_id) => ast_id.file_id, |
271 | MacroCallKind::Attr(ast_id, _) => ast_id.file_id, | 301 | MacroCallKind::Derive(ast_id, _) => ast_id.file_id, |
272 | } | 302 | } |
273 | } | 303 | } |
274 | 304 | ||
275 | fn node(&self, db: &dyn db::AstDatabase) -> InFile<SyntaxNode> { | 305 | fn node(&self, db: &dyn db::AstDatabase) -> InFile<SyntaxNode> { |
276 | match self { | 306 | match self { |
277 | MacroCallKind::FnLike(ast_id) => ast_id.with_value(ast_id.to_node(db).syntax().clone()), | 307 | MacroCallKind::FnLike(ast_id) => ast_id.with_value(ast_id.to_node(db).syntax().clone()), |
278 | MacroCallKind::Attr(ast_id, _) => { | 308 | MacroCallKind::Derive(ast_id, _) => { |
279 | ast_id.with_value(ast_id.to_node(db).syntax().clone()) | 309 | ast_id.with_value(ast_id.to_node(db).syntax().clone()) |
280 | } | 310 | } |
281 | } | 311 | } |
@@ -286,7 +316,7 @@ impl MacroCallKind { | |||
286 | MacroCallKind::FnLike(ast_id) => { | 316 | MacroCallKind::FnLike(ast_id) => { |
287 | Some(ast_id.to_node(db).token_tree()?.syntax().clone()) | 317 | Some(ast_id.to_node(db).token_tree()?.syntax().clone()) |
288 | } | 318 | } |
289 | MacroCallKind::Attr(ast_id, _) => Some(ast_id.to_node(db).syntax().clone()), | 319 | MacroCallKind::Derive(ast_id, _) => Some(ast_id.to_node(db).syntax().clone()), |
290 | } | 320 | } |
291 | } | 321 | } |
292 | } | 322 | } |
@@ -304,6 +334,8 @@ pub struct EagerCallLoc { | |||
304 | pub(crate) subtree: Arc<tt::Subtree>, | 334 | pub(crate) subtree: Arc<tt::Subtree>, |
305 | pub(crate) krate: CrateId, | 335 | pub(crate) krate: CrateId, |
306 | pub(crate) call: AstId<ast::MacroCall>, | 336 | pub(crate) call: AstId<ast::MacroCall>, |
337 | // The included file ID of the include macro. | ||
338 | pub(crate) included_file: Option<FileId>, | ||
307 | } | 339 | } |
308 | 340 | ||
309 | /// ExpansionInfo mainly describes how to map text range between src and expanded macro | 341 | /// ExpansionInfo mainly describes how to map text range between src and expanded macro |