aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_def/src/item_tree
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_def/src/item_tree')
-rw-r--r--crates/hir_def/src/item_tree/lower.rs49
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
878fn 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}