diff options
author | cynecx <[email protected]> | 2021-04-17 16:38:38 +0100 |
---|---|---|
committer | cynecx <[email protected]> | 2021-04-17 16:38:45 +0100 |
commit | 7ed42a3a527b2c39826cfeb3626521c11abb25f0 (patch) | |
tree | 81c956d98c4990b0555540ad9cc1c94efa68deac /crates/hir_def/src/type_ref.rs | |
parent | 14918a3870d568778473f0a5697a547b85acf20a (diff) |
hir_def: refactor expand_macro_type and cleanups
Diffstat (limited to 'crates/hir_def/src/type_ref.rs')
-rw-r--r-- | crates/hir_def/src/type_ref.rs | 78 |
1 files changed, 14 insertions, 64 deletions
diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs index 0832371c0..cf8a584ab 100644 --- a/crates/hir_def/src/type_ref.rs +++ b/crates/hir_def/src/type_ref.rs | |||
@@ -1,9 +1,8 @@ | |||
1 | //! HIR for references to types. Paths in these are not yet resolved. They can | 1 | //! HIR for references to types. Paths in these are not yet resolved. They can |
2 | //! be directly created from an ast::TypeRef, without further queries. | 2 | //! be directly created from an ast::TypeRef, without further queries. |
3 | use std::borrow::Cow; | ||
4 | 3 | ||
5 | use hir_expand::{ast_id_map::FileAstId, name::Name, ExpandResult, InFile}; | 4 | use hir_expand::{ast_id_map::FileAstId, name::Name, ExpandResult, InFile}; |
6 | use syntax::{algo::SyntaxRewriter, ast, AstNode, SyntaxKind, SyntaxNode}; | 5 | use syntax::ast; |
7 | 6 | ||
8 | use crate::{ | 7 | use crate::{ |
9 | body::{Expander, LowerCtx}, | 8 | body::{Expander, LowerCtx}, |
@@ -207,16 +206,6 @@ impl TypeRef { | |||
207 | TypeRef::Tuple(Vec::new()) | 206 | TypeRef::Tuple(Vec::new()) |
208 | } | 207 | } |
209 | 208 | ||
210 | pub fn has_macro_calls(&self) -> bool { | ||
211 | let mut has_macro_call = false; | ||
212 | self.walk(&mut |ty_ref| { | ||
213 | if let TypeRef::Macro(_) = ty_ref { | ||
214 | has_macro_call |= true | ||
215 | } | ||
216 | }); | ||
217 | has_macro_call | ||
218 | } | ||
219 | |||
220 | pub fn walk(&self, f: &mut impl FnMut(&TypeRef)) { | 209 | pub fn walk(&self, f: &mut impl FnMut(&TypeRef)) { |
221 | go(self, f); | 210 | go(self, f); |
222 | 211 | ||
@@ -315,68 +304,29 @@ impl TypeBound { | |||
315 | } | 304 | } |
316 | } | 305 | } |
317 | 306 | ||
318 | pub fn expand_type_ref<'a>( | 307 | pub fn expand_macro_type( |
319 | db: &dyn DefDatabase, | 308 | db: &dyn DefDatabase, |
320 | module_id: ModuleId, | 309 | module_id: ModuleId, |
321 | type_ref: &'a TypeRef, | 310 | macro_type: &TypeRef, |
322 | ) -> Option<Cow<'a, TypeRef>> { | 311 | ) -> Option<TypeRef> { |
323 | let macro_call = match type_ref { | 312 | let macro_call = match macro_type { |
324 | TypeRef::Macro(macro_call) => macro_call, | 313 | TypeRef::Macro(macro_call) => macro_call, |
325 | _ => return Some(Cow::Borrowed(type_ref)), | 314 | _ => panic!("expected TypeRef::Macro"), |
326 | }; | 315 | }; |
327 | 316 | ||
328 | let file_id = macro_call.file_id; | 317 | let file_id = macro_call.file_id; |
329 | let macro_call = macro_call.to_node(db.upcast()); | 318 | let macro_call = macro_call.to_node(db.upcast()); |
330 | 319 | ||
331 | let mut expander = Expander::new(db, file_id, module_id); | 320 | let mut expander = Expander::new(db, file_id, module_id); |
332 | let expanded = expand(db, &mut expander, ¯o_call, true)?; | 321 | let (file_id, expanded) = match expander.enter_expand::<ast::Type>(db, macro_call.clone()) { |
333 | 322 | Ok(ExpandResult { value: Some((mark, expanded)), .. }) => { | |
334 | let node = ast::Type::cast(expanded)?; | 323 | let file_id = expander.current_file_id(); |
335 | |||
336 | let ctx = LowerCtx::new(db, file_id); | ||
337 | return Some(Cow::Owned(TypeRef::from_ast(&ctx, node))); | ||
338 | |||
339 | fn expand( | ||
340 | db: &dyn DefDatabase, | ||
341 | expander: &mut Expander, | ||
342 | macro_call: &ast::MacroCall, | ||
343 | expect_type: bool, | ||
344 | ) -> Option<SyntaxNode> { | ||
345 | let (mark, mut expanded) = match expander.enter_expand_raw(db, macro_call.clone()) { | ||
346 | Ok(ExpandResult { value: Some((mark, expanded)), .. }) => (mark, expanded), | ||
347 | _ => return None, | ||
348 | }; | ||
349 | |||
350 | if expect_type && !ast::Type::can_cast(expanded.kind()) { | ||
351 | expander.exit(db, mark); | 324 | expander.exit(db, mark); |
352 | return None; | 325 | (file_id, expanded) |
353 | } | ||
354 | |||
355 | if ast::MacroType::can_cast(expanded.kind()) { | ||
356 | expanded = expanded.first_child()?; // MACRO_CALL | ||
357 | } | 326 | } |
327 | _ => return None, | ||
328 | }; | ||
358 | 329 | ||
359 | let mut rewriter = SyntaxRewriter::default(); | 330 | let ctx = LowerCtx::new(db, file_id); |
360 | 331 | return Some(TypeRef::from_ast(&ctx, expanded)); | |
361 | let children = expanded.descendants().filter_map(ast::MacroCall::cast); | ||
362 | for child in children { | ||
363 | if let Some(new_node) = expand(db, expander, &child, false) { | ||
364 | if expanded == *child.syntax() { | ||
365 | expanded = new_node; | ||
366 | } else { | ||
367 | let parent = child.syntax().parent(); | ||
368 | let old_node = match &parent { | ||
369 | Some(node) if node.kind() == SyntaxKind::MACRO_TYPE => node, | ||
370 | _ => child.syntax(), | ||
371 | }; | ||
372 | rewriter.replace(old_node, &new_node) | ||
373 | } | ||
374 | } | ||
375 | } | ||
376 | |||
377 | expander.exit(db, mark); | ||
378 | |||
379 | let res = rewriter.rewrite(&expanded); | ||
380 | Some(res) | ||
381 | } | ||
382 | } | 332 | } |