diff options
author | Jonas Schievink <[email protected]> | 2020-06-22 14:07:06 +0100 |
---|---|---|
committer | Jonas Schievink <[email protected]> | 2020-06-24 15:53:16 +0100 |
commit | 4b03b39d5b4b00daffb120a4d2d9ea4a55a9a7ac (patch) | |
tree | 85431e53ce86bbcf16ba9b38fcc5f2ad27378722 /crates/ra_hir_def/src/body | |
parent | b94caeb88b4aab7219d4b2f5c8c6c668199247fb (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.rs | 173 |
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; | |||
5 | use hir_expand::{ | 5 | use 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 | }; |
10 | use ra_arena::Arena; | 10 | use ra_arena::Arena; |
11 | use ra_syntax::{ | 11 | use 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 | ||
36 | use super::{ExprSource, PatSource}; | 37 | use super::{ExprSource, PatSource}; |
37 | use ast::AstChildren; | 38 | use ast::AstChildren; |
39 | use std::sync::Arc; | ||
38 | 40 | ||
39 | pub(crate) struct LowerCtx { | 41 | pub(crate) struct LowerCtx { |
40 | hygiene: Hygiene, | 42 | hygiene: Hygiene, |
@@ -55,11 +57,13 @@ impl LowerCtx { | |||
55 | 57 | ||
56 | pub(super) fn lower( | 58 | pub(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 | ||
87 | impl ExprCollector<'_> { | 94 | impl 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 |