diff options
Diffstat (limited to 'crates/hir_def/src/item_tree')
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 49 |
1 files changed, 29 insertions, 20 deletions
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index fe348091d..a7ffc6364 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs | |||
@@ -147,9 +147,7 @@ impl<'a> Ctx<'a> { | |||
147 | ast::Item::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into), | 147 | ast::Item::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into), |
148 | ast::Item::MacroRules(ast) => self.lower_macro_rules(ast).map(Into::into), | 148 | ast::Item::MacroRules(ast) => self.lower_macro_rules(ast).map(Into::into), |
149 | ast::Item::MacroDef(ast) => self.lower_macro_def(ast).map(Into::into), | 149 | ast::Item::MacroDef(ast) => self.lower_macro_def(ast).map(Into::into), |
150 | ast::Item::ExternBlock(ast) => { | 150 | ast::Item::ExternBlock(ast) => Some(self.lower_extern_block(ast).into()), |
151 | Some(ModItems(self.lower_extern_block(ast).into_iter().collect::<SmallVec<_>>())) | ||
152 | } | ||
153 | }; | 151 | }; |
154 | 152 | ||
155 | if !attrs.is_empty() { | 153 | if !attrs.is_empty() { |
@@ -397,19 +395,7 @@ impl<'a> Ctx<'a> { | |||
397 | ret_type | 395 | ret_type |
398 | }; | 396 | }; |
399 | 397 | ||
400 | let abi = func.abi().map(|abi| { | 398 | let abi = func.abi().map(lower_abi); |
401 | // FIXME: Abi::abi() -> Option<SyntaxToken>? | ||
402 | match abi.syntax().last_token() { | ||
403 | Some(tok) if tok.kind() == SyntaxKind::STRING => { | ||
404 | // FIXME: Better way to unescape? | ||
405 | Interned::new_str(tok.text().trim_matches('"')) | ||
406 | } | ||
407 | _ => { | ||
408 | // `extern` default to be `extern "C"`. | ||
409 | Interned::new_str("C") | ||
410 | } | ||
411 | } | ||
412 | }); | ||
413 | 399 | ||
414 | let ast_id = self.source_ast_id_map.ast_id(func); | 400 | let ast_id = self.source_ast_id_map.ast_id(func); |
415 | 401 | ||
@@ -647,8 +633,10 @@ impl<'a> Ctx<'a> { | |||
647 | Some(id(self.data().macro_defs.alloc(res))) | 633 | Some(id(self.data().macro_defs.alloc(res))) |
648 | } | 634 | } |
649 | 635 | ||
650 | fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> Vec<ModItem> { | 636 | fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> FileItemTreeId<ExternBlock> { |
651 | block.extern_item_list().map_or(Vec::new(), |list| { | 637 | let ast_id = self.source_ast_id_map.ast_id(block); |
638 | let abi = block.abi().map(lower_abi); | ||
639 | let children: Box<[_]> = block.extern_item_list().map_or(Box::new([]), |list| { | ||
652 | list.extern_items() | 640 | list.extern_items() |
653 | .filter_map(|item| { | 641 | .filter_map(|item| { |
654 | self.collect_inner_items(item.syntax()); | 642 | self.collect_inner_items(item.syntax()); |
@@ -673,13 +661,20 @@ impl<'a> Ctx<'a> { | |||
673 | self.data().type_aliases[foreign_ty.index].is_extern = true; | 661 | self.data().type_aliases[foreign_ty.index].is_extern = true; |
674 | foreign_ty.into() | 662 | foreign_ty.into() |
675 | } | 663 | } |
676 | ast::ExternItem::MacroCall(_) => return None, | 664 | ast::ExternItem::MacroCall(call) => { |
665 | // FIXME: we need some way of tracking that the macro call is in an | ||
666 | // extern block | ||
667 | self.lower_macro_call(&call)?.into() | ||
668 | } | ||
677 | }; | 669 | }; |
678 | self.add_attrs(id.into(), attrs); | 670 | self.add_attrs(id.into(), attrs); |
679 | Some(id) | 671 | Some(id) |
680 | }) | 672 | }) |
681 | .collect() | 673 | .collect() |
682 | }) | 674 | }); |
675 | |||
676 | let res = ExternBlock { abi, ast_id, children }; | ||
677 | id(self.data().extern_blocks.alloc(res)) | ||
683 | } | 678 | } |
684 | 679 | ||
685 | /// Lowers generics defined on `node` and collects inner items defined within. | 680 | /// Lowers generics defined on `node` and collects inner items defined within. |
@@ -879,3 +874,17 @@ fn is_intrinsic_fn_unsafe(name: &Name) -> bool { | |||
879 | ] | 874 | ] |
880 | .contains(&name) | 875 | .contains(&name) |
881 | } | 876 | } |
877 | |||
878 | fn lower_abi(abi: ast::Abi) -> Interned<str> { | ||
879 | // FIXME: Abi::abi() -> Option<SyntaxToken>? | ||
880 | match abi.syntax().last_token() { | ||
881 | Some(tok) if tok.kind() == SyntaxKind::STRING => { | ||
882 | // FIXME: Better way to unescape? | ||
883 | Interned::new_str(tok.text().trim_matches('"')) | ||
884 | } | ||
885 | _ => { | ||
886 | // `extern` default to be `extern "C"`. | ||
887 | Interned::new_str("C") | ||
888 | } | ||
889 | } | ||
890 | } | ||