aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/body
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-06-22 14:07:06 +0100
committerJonas Schievink <[email protected]>2020-06-24 15:53:16 +0100
commit4b03b39d5b4b00daffb120a4d2d9ea4a55a9a7ac (patch)
tree85431e53ce86bbcf16ba9b38fcc5f2ad27378722 /crates/ra_hir_def/src/body
parentb94caeb88b4aab7219d4b2f5c8c6c668199247fb (diff)
draw the rest of the owl
Diffstat (limited to 'crates/ra_hir_def/src/body')
-rw-r--r--crates/ra_hir_def/src/body/lower.rs173
1 files changed, 122 insertions, 51 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index f159f80af..e7cf80676 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -5,7 +5,7 @@ use either::Either;
5use hir_expand::{ 5use hir_expand::{
6 hygiene::Hygiene, 6 hygiene::Hygiene,
7 name::{name, AsName, Name}, 7 name::{name, AsName, Name},
8 HirFileId, MacroDefId, MacroDefKind, 8 AstId, HirFileId, MacroDefId, MacroDefKind,
9}; 9};
10use ra_arena::Arena; 10use ra_arena::Arena;
11use ra_syntax::{ 11use ra_syntax::{
@@ -27,6 +27,7 @@ use crate::{
27 LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, 27 LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
28 }, 28 },
29 item_scope::BuiltinShadowMode, 29 item_scope::BuiltinShadowMode,
30 item_tree::{FileItemTreeId, ItemTree, ItemTreeSource},
30 path::{GenericArgs, Path}, 31 path::{GenericArgs, Path},
31 type_ref::{Mutability, Rawness, TypeRef}, 32 type_ref::{Mutability, Rawness, TypeRef},
32 AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, 33 AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId,
@@ -35,6 +36,7 @@ use crate::{
35 36
36use super::{ExprSource, PatSource}; 37use super::{ExprSource, PatSource};
37use ast::AstChildren; 38use ast::AstChildren;
39use std::sync::Arc;
38 40
39pub(crate) struct LowerCtx { 41pub(crate) struct LowerCtx {
40 hygiene: Hygiene, 42 hygiene: Hygiene,
@@ -55,11 +57,13 @@ impl LowerCtx {
55 57
56pub(super) fn lower( 58pub(super) fn lower(
57 db: &dyn DefDatabase, 59 db: &dyn DefDatabase,
60 file_id: HirFileId,
58 def: DefWithBodyId, 61 def: DefWithBodyId,
59 expander: Expander, 62 expander: Expander,
60 params: Option<ast::ParamList>, 63 params: Option<ast::ParamList>,
61 body: Option<ast::Expr>, 64 body: Option<ast::Expr>,
62) -> (Body, BodySourceMap) { 65) -> (Body, BodySourceMap) {
66 let item_tree = db.item_tree(file_id);
63 ExprCollector { 67 ExprCollector {
64 db, 68 db,
65 def, 69 def,
@@ -72,6 +76,7 @@ pub(super) fn lower(
72 body_expr: dummy_expr_id(), 76 body_expr: dummy_expr_id(),
73 item_scope: Default::default(), 77 item_scope: Default::default(),
74 }, 78 },
79 item_trees: vec![(file_id, item_tree)],
75 } 80 }
76 .collect(params, body) 81 .collect(params, body)
77} 82}
@@ -82,6 +87,8 @@ struct ExprCollector<'a> {
82 expander: Expander, 87 expander: Expander,
83 body: Body, 88 body: Body,
84 source_map: BodySourceMap, 89 source_map: BodySourceMap,
90
91 item_trees: Vec<(HirFileId, Arc<ItemTree>)>,
85} 92}
86 93
87impl ExprCollector<'_> { 94impl ExprCollector<'_> {
@@ -533,6 +540,9 @@ impl ExprCollector<'_> {
533 self.source_map 540 self.source_map
534 .expansions 541 .expansions
535 .insert(macro_call, self.expander.current_file_id); 542 .insert(macro_call, self.expander.current_file_id);
543
544 let item_tree = self.db.item_tree(self.expander.current_file_id);
545 self.item_trees.push((self.expander.current_file_id, item_tree));
536 let id = self.collect_expr(expansion); 546 let id = self.collect_expr(expansion);
537 self.expander.exit(self.db, mark); 547 self.expander.exit(self.db, mark);
538 id 548 id
@@ -547,6 +557,21 @@ impl ExprCollector<'_> {
547 } 557 }
548 } 558 }
549 559
560 fn find_inner_item<S: ItemTreeSource>(&self, id: AstId<ast::ModuleItem>) -> FileItemTreeId<S> {
561 let index =
562 self.item_trees.iter().position(|(file, _)| *file == id.file_id).unwrap_or_else(|| {
563 panic!("couldn't find item tree for file {:?}", id.file_id);
564 });
565 let tree = &self.item_trees[index].1;
566
567 // Root file (non-macro).
568 tree.all_inner_items()
569 .chain(tree.top_level_items().iter().copied())
570 .filter_map(|mod_item| mod_item.downcast::<S>())
571 .find(|tree_id| tree[*tree_id].ast_id().upcast() == id.value)
572 .unwrap()
573 }
574
550 fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId { 575 fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId {
551 if let Some(expr) = expr { 576 if let Some(expr) = expr {
552 self.collect_expr(expr) 577 self.collect_expr(expr)
@@ -578,56 +603,102 @@ impl ExprCollector<'_> {
578 603
579 fn collect_block_items(&mut self, block: &ast::BlockExpr) { 604 fn collect_block_items(&mut self, block: &ast::BlockExpr) {
580 let container = ContainerId::DefWithBodyId(self.def); 605 let container = ContainerId::DefWithBodyId(self.def);
581 for item in block.items() { 606
582 let (def, name): (ModuleDefId, Option<ast::Name>) = match item { 607 let items = block
583 ast::ModuleItem::FnDef(def) => { 608 .items()
584 let ast_id = self.expander.ast_id(&def); 609 .filter_map(|item| {
585 ( 610 let (def, name): (ModuleDefId, Option<ast::Name>) = match item {
586 FunctionLoc { container: container.into(), ast_id }.intern(self.db).into(), 611 ast::ModuleItem::FnDef(def) => {
587 def.name(), 612 let ast_id = self.expander.ast_id(&def);
588 ) 613 let id = self.find_inner_item(ast_id.map(|id| id.upcast()));
589 } 614 (
590 ast::ModuleItem::TypeAliasDef(def) => { 615 FunctionLoc { container: container.into(), id: ast_id.with_value(id) }
591 let ast_id = self.expander.ast_id(&def); 616 .intern(self.db)
592 ( 617 .into(),
593 TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into(), 618 def.name(),
594 def.name(), 619 )
595 ) 620 }
596 } 621 ast::ModuleItem::TypeAliasDef(def) => {
597 ast::ModuleItem::ConstDef(def) => { 622 let ast_id = self.expander.ast_id(&def);
598 let ast_id = self.expander.ast_id(&def); 623 let id = self.find_inner_item(ast_id.map(|id| id.upcast()));
599 ( 624 (
600 ConstLoc { container: container.into(), ast_id }.intern(self.db).into(), 625 TypeAliasLoc { container: container.into(), id: ast_id.with_value(id) }
601 def.name(), 626 .intern(self.db)
602 ) 627 .into(),
603 } 628 def.name(),
604 ast::ModuleItem::StaticDef(def) => { 629 )
605 let ast_id = self.expander.ast_id(&def); 630 }
606 (StaticLoc { container, ast_id }.intern(self.db).into(), def.name()) 631 ast::ModuleItem::ConstDef(def) => {
607 } 632 let ast_id = self.expander.ast_id(&def);
608 ast::ModuleItem::StructDef(def) => { 633 let id = self.find_inner_item(ast_id.map(|id| id.upcast()));
609 let ast_id = self.expander.ast_id(&def); 634 (
610 (StructLoc { container, ast_id }.intern(self.db).into(), def.name()) 635 ConstLoc { container: container.into(), id: ast_id.with_value(id) }
611 } 636 .intern(self.db)
612 ast::ModuleItem::EnumDef(def) => { 637 .into(),
613 let ast_id = self.expander.ast_id(&def); 638 def.name(),
614 (EnumLoc { container, ast_id }.intern(self.db).into(), def.name()) 639 )
615 } 640 }
616 ast::ModuleItem::UnionDef(def) => { 641 ast::ModuleItem::StaticDef(def) => {
617 let ast_id = self.expander.ast_id(&def); 642 let ast_id = self.expander.ast_id(&def);
618 (UnionLoc { container, ast_id }.intern(self.db).into(), def.name()) 643 let id = self.find_inner_item(ast_id.map(|id| id.upcast()));
619 } 644 (
620 ast::ModuleItem::TraitDef(def) => { 645 StaticLoc { container, id: ast_id.with_value(id) }
621 let ast_id = self.expander.ast_id(&def); 646 .intern(self.db)
622 (TraitLoc { container, ast_id }.intern(self.db).into(), def.name()) 647 .into(),
623 } 648 def.name(),
624 ast::ModuleItem::ExternBlock(_) => continue, // FIXME: collect from extern blocks 649 )
625 ast::ModuleItem::ImplDef(_) 650 }
626 | ast::ModuleItem::UseItem(_) 651 ast::ModuleItem::StructDef(def) => {
627 | ast::ModuleItem::ExternCrateItem(_) 652 let ast_id = self.expander.ast_id(&def);
628 | ast::ModuleItem::Module(_) 653 let id = self.find_inner_item(ast_id.map(|id| id.upcast()));
629 | ast::ModuleItem::MacroCall(_) => continue, 654 (
630 }; 655 StructLoc { container, id: ast_id.with_value(id) }
656 .intern(self.db)
657 .into(),
658 def.name(),
659 )
660 }
661 ast::ModuleItem::EnumDef(def) => {
662 let ast_id = self.expander.ast_id(&def);
663 let id = self.find_inner_item(ast_id.map(|id| id.upcast()));
664 (
665 EnumLoc { container, id: ast_id.with_value(id) }.intern(self.db).into(),
666 def.name(),
667 )
668 }
669 ast::ModuleItem::UnionDef(def) => {
670 let ast_id = self.expander.ast_id(&def);
671 let id = self.find_inner_item(ast_id.map(|id| id.upcast()));
672 (
673 UnionLoc { container, id: ast_id.with_value(id) }
674 .intern(self.db)
675 .into(),
676 def.name(),
677 )
678 }
679 ast::ModuleItem::TraitDef(def) => {
680 let ast_id = self.expander.ast_id(&def);
681 let id = self.find_inner_item(ast_id.map(|id| id.upcast()));
682 (
683 TraitLoc { container, id: ast_id.with_value(id) }
684 .intern(self.db)
685 .into(),
686 def.name(),
687 )
688 }
689 ast::ModuleItem::ExternBlock(_) => return None, // FIXME: collect from extern blocks
690 ast::ModuleItem::ImplDef(_)
691 | ast::ModuleItem::UseItem(_)
692 | ast::ModuleItem::ExternCrateItem(_)
693 | ast::ModuleItem::Module(_)
694 | ast::ModuleItem::MacroCall(_) => return None,
695 };
696
697 Some((def, name))
698 })
699 .collect::<Vec<_>>();
700
701 for (def, name) in items {
631 self.body.item_scope.define_def(def); 702 self.body.item_scope.define_def(def);
632 if let Some(name) = name { 703 if let Some(name) = name {
633 let vis = crate::visibility::Visibility::Public; // FIXME determine correctly 704 let vis = crate::visibility::Visibility::Public; // FIXME determine correctly