From 1d75d11d6cbd8a2d4605fd185237ec2747b0687f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Wed, 25 Mar 2020 15:33:01 +0100 Subject: Start item tree --- crates/ra_hir_def/src/body/lower.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'crates/ra_hir_def/src/body/lower.rs') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index f159f80af..113ec2b78 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -3,6 +3,7 @@ use either::Either; use hir_expand::{ + db::AstDatabase, hygiene::Hygiene, name::{name, AsName, Name}, HirFileId, MacroDefId, MacroDefKind, @@ -41,8 +42,8 @@ pub(crate) struct LowerCtx { } impl LowerCtx { - pub fn new(db: &dyn DefDatabase, file_id: HirFileId) -> Self { - LowerCtx { hygiene: Hygiene::new(db.upcast(), file_id) } + pub fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Self { + LowerCtx { hygiene: Hygiene::new(db, file_id) } } pub fn with_hygiene(hygiene: &Hygiene) -> Self { LowerCtx { hygiene: hygiene.clone() } @@ -119,7 +120,7 @@ impl ExprCollector<'_> { } fn ctx(&self) -> LowerCtx { - LowerCtx::new(self.db, self.expander.current_file_id) + LowerCtx::new(self.db.upcast(), self.expander.current_file_id) } fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr) -> ExprId { -- cgit v1.2.3 From 34bc80650b93bf422039af31844898f427cc375c Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Thu, 11 Jun 2020 19:46:56 +0200 Subject: Hook up query, add impls, lower moar --- crates/ra_hir_def/src/body/lower.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir_def/src/body/lower.rs') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 113ec2b78..f159f80af 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -3,7 +3,6 @@ use either::Either; use hir_expand::{ - db::AstDatabase, hygiene::Hygiene, name::{name, AsName, Name}, HirFileId, MacroDefId, MacroDefKind, @@ -42,8 +41,8 @@ pub(crate) struct LowerCtx { } impl LowerCtx { - pub fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Self { - LowerCtx { hygiene: Hygiene::new(db, file_id) } + pub fn new(db: &dyn DefDatabase, file_id: HirFileId) -> Self { + LowerCtx { hygiene: Hygiene::new(db.upcast(), file_id) } } pub fn with_hygiene(hygiene: &Hygiene) -> Self { LowerCtx { hygiene: hygiene.clone() } @@ -120,7 +119,7 @@ impl ExprCollector<'_> { } fn ctx(&self) -> LowerCtx { - LowerCtx::new(self.db.upcast(), self.expander.current_file_id) + LowerCtx::new(self.db, self.expander.current_file_id) } fn alloc_expr(&mut self, expr: Expr, ptr: AstPtr) -> ExprId { -- cgit v1.2.3 From 4b03b39d5b4b00daffb120a4d2d9ea4a55a9a7ac Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 22 Jun 2020 15:07:06 +0200 Subject: draw the rest of the owl --- crates/ra_hir_def/src/body/lower.rs | 173 +++++++++++++++++++++++++----------- 1 file changed, 122 insertions(+), 51 deletions(-) (limited to 'crates/ra_hir_def/src/body/lower.rs') 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; use hir_expand::{ hygiene::Hygiene, name::{name, AsName, Name}, - HirFileId, MacroDefId, MacroDefKind, + AstId, HirFileId, MacroDefId, MacroDefKind, }; use ra_arena::Arena; use ra_syntax::{ @@ -27,6 +27,7 @@ use crate::{ LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, }, item_scope::BuiltinShadowMode, + item_tree::{FileItemTreeId, ItemTree, ItemTreeSource}, path::{GenericArgs, Path}, type_ref::{Mutability, Rawness, TypeRef}, AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, @@ -35,6 +36,7 @@ use crate::{ use super::{ExprSource, PatSource}; use ast::AstChildren; +use std::sync::Arc; pub(crate) struct LowerCtx { hygiene: Hygiene, @@ -55,11 +57,13 @@ impl LowerCtx { pub(super) fn lower( db: &dyn DefDatabase, + file_id: HirFileId, def: DefWithBodyId, expander: Expander, params: Option, body: Option, ) -> (Body, BodySourceMap) { + let item_tree = db.item_tree(file_id); ExprCollector { db, def, @@ -72,6 +76,7 @@ pub(super) fn lower( body_expr: dummy_expr_id(), item_scope: Default::default(), }, + item_trees: vec![(file_id, item_tree)], } .collect(params, body) } @@ -82,6 +87,8 @@ struct ExprCollector<'a> { expander: Expander, body: Body, source_map: BodySourceMap, + + item_trees: Vec<(HirFileId, Arc)>, } impl ExprCollector<'_> { @@ -533,6 +540,9 @@ impl ExprCollector<'_> { self.source_map .expansions .insert(macro_call, self.expander.current_file_id); + + let item_tree = self.db.item_tree(self.expander.current_file_id); + self.item_trees.push((self.expander.current_file_id, item_tree)); let id = self.collect_expr(expansion); self.expander.exit(self.db, mark); id @@ -547,6 +557,21 @@ impl ExprCollector<'_> { } } + fn find_inner_item(&self, id: AstId) -> FileItemTreeId { + let index = + self.item_trees.iter().position(|(file, _)| *file == id.file_id).unwrap_or_else(|| { + panic!("couldn't find item tree for file {:?}", id.file_id); + }); + let tree = &self.item_trees[index].1; + + // Root file (non-macro). + tree.all_inner_items() + .chain(tree.top_level_items().iter().copied()) + .filter_map(|mod_item| mod_item.downcast::()) + .find(|tree_id| tree[*tree_id].ast_id().upcast() == id.value) + .unwrap() + } + fn collect_expr_opt(&mut self, expr: Option) -> ExprId { if let Some(expr) = expr { self.collect_expr(expr) @@ -578,56 +603,102 @@ impl ExprCollector<'_> { fn collect_block_items(&mut self, block: &ast::BlockExpr) { let container = ContainerId::DefWithBodyId(self.def); - for item in block.items() { - let (def, name): (ModuleDefId, Option) = match item { - ast::ModuleItem::FnDef(def) => { - let ast_id = self.expander.ast_id(&def); - ( - FunctionLoc { container: container.into(), ast_id }.intern(self.db).into(), - def.name(), - ) - } - ast::ModuleItem::TypeAliasDef(def) => { - let ast_id = self.expander.ast_id(&def); - ( - TypeAliasLoc { container: container.into(), ast_id }.intern(self.db).into(), - def.name(), - ) - } - ast::ModuleItem::ConstDef(def) => { - let ast_id = self.expander.ast_id(&def); - ( - ConstLoc { container: container.into(), ast_id }.intern(self.db).into(), - def.name(), - ) - } - ast::ModuleItem::StaticDef(def) => { - let ast_id = self.expander.ast_id(&def); - (StaticLoc { container, ast_id }.intern(self.db).into(), def.name()) - } - ast::ModuleItem::StructDef(def) => { - let ast_id = self.expander.ast_id(&def); - (StructLoc { container, ast_id }.intern(self.db).into(), def.name()) - } - ast::ModuleItem::EnumDef(def) => { - let ast_id = self.expander.ast_id(&def); - (EnumLoc { container, ast_id }.intern(self.db).into(), def.name()) - } - ast::ModuleItem::UnionDef(def) => { - let ast_id = self.expander.ast_id(&def); - (UnionLoc { container, ast_id }.intern(self.db).into(), def.name()) - } - ast::ModuleItem::TraitDef(def) => { - let ast_id = self.expander.ast_id(&def); - (TraitLoc { container, ast_id }.intern(self.db).into(), def.name()) - } - ast::ModuleItem::ExternBlock(_) => continue, // FIXME: collect from extern blocks - ast::ModuleItem::ImplDef(_) - | ast::ModuleItem::UseItem(_) - | ast::ModuleItem::ExternCrateItem(_) - | ast::ModuleItem::Module(_) - | ast::ModuleItem::MacroCall(_) => continue, - }; + + let items = block + .items() + .filter_map(|item| { + let (def, name): (ModuleDefId, Option) = match item { + ast::ModuleItem::FnDef(def) => { + let ast_id = self.expander.ast_id(&def); + let id = self.find_inner_item(ast_id.map(|id| id.upcast())); + ( + FunctionLoc { container: container.into(), id: ast_id.with_value(id) } + .intern(self.db) + .into(), + def.name(), + ) + } + ast::ModuleItem::TypeAliasDef(def) => { + let ast_id = self.expander.ast_id(&def); + let id = self.find_inner_item(ast_id.map(|id| id.upcast())); + ( + TypeAliasLoc { container: container.into(), id: ast_id.with_value(id) } + .intern(self.db) + .into(), + def.name(), + ) + } + ast::ModuleItem::ConstDef(def) => { + let ast_id = self.expander.ast_id(&def); + let id = self.find_inner_item(ast_id.map(|id| id.upcast())); + ( + ConstLoc { container: container.into(), id: ast_id.with_value(id) } + .intern(self.db) + .into(), + def.name(), + ) + } + ast::ModuleItem::StaticDef(def) => { + let ast_id = self.expander.ast_id(&def); + let id = self.find_inner_item(ast_id.map(|id| id.upcast())); + ( + StaticLoc { container, id: ast_id.with_value(id) } + .intern(self.db) + .into(), + def.name(), + ) + } + ast::ModuleItem::StructDef(def) => { + let ast_id = self.expander.ast_id(&def); + let id = self.find_inner_item(ast_id.map(|id| id.upcast())); + ( + StructLoc { container, id: ast_id.with_value(id) } + .intern(self.db) + .into(), + def.name(), + ) + } + ast::ModuleItem::EnumDef(def) => { + let ast_id = self.expander.ast_id(&def); + let id = self.find_inner_item(ast_id.map(|id| id.upcast())); + ( + EnumLoc { container, id: ast_id.with_value(id) }.intern(self.db).into(), + def.name(), + ) + } + ast::ModuleItem::UnionDef(def) => { + let ast_id = self.expander.ast_id(&def); + let id = self.find_inner_item(ast_id.map(|id| id.upcast())); + ( + UnionLoc { container, id: ast_id.with_value(id) } + .intern(self.db) + .into(), + def.name(), + ) + } + ast::ModuleItem::TraitDef(def) => { + let ast_id = self.expander.ast_id(&def); + let id = self.find_inner_item(ast_id.map(|id| id.upcast())); + ( + TraitLoc { container, id: ast_id.with_value(id) } + .intern(self.db) + .into(), + def.name(), + ) + } + ast::ModuleItem::ExternBlock(_) => return None, // FIXME: collect from extern blocks + ast::ModuleItem::ImplDef(_) + | ast::ModuleItem::UseItem(_) + | ast::ModuleItem::ExternCrateItem(_) + | ast::ModuleItem::Module(_) + | ast::ModuleItem::MacroCall(_) => return None, + }; + + Some((def, name)) + }) + .collect::>(); + + for (def, name) in items { self.body.item_scope.define_def(def); if let Some(name) = name { let vis = crate::visibility::Visibility::Public; // FIXME determine correctly -- cgit v1.2.3 From 689e147c9dc416027fd36e94673431533df545f9 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 23 Jun 2020 13:46:38 +0200 Subject: Collect inner items in expression macros --- crates/ra_hir_def/src/body/lower.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'crates/ra_hir_def/src/body/lower.rs') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index e7cf80676..bbde0b802 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -564,12 +564,14 @@ impl ExprCollector<'_> { }); let tree = &self.item_trees[index].1; + // FIXME: This probably breaks with `use` items, since they produce multiple item tree nodes + // Root file (non-macro). tree.all_inner_items() .chain(tree.top_level_items().iter().copied()) .filter_map(|mod_item| mod_item.downcast::()) .find(|tree_id| tree[*tree_id].ast_id().upcast() == id.value) - .unwrap() + .unwrap_or_else(|| panic!("couldn't find inner item for {:?}", id)) } fn collect_expr_opt(&mut self, expr: Option) -> ExprId { -- cgit v1.2.3 From f9a1a9cd3c7757ca3f8ba59287b5d36645008b9b Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Tue, 23 Jun 2020 18:46:08 +0200 Subject: Merge item tree traits The Source trait isn't needed anymore since we no longer merge extern crate items with use items. --- crates/ra_hir_def/src/body/lower.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'crates/ra_hir_def/src/body/lower.rs') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index bbde0b802..a74136b8e 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -27,7 +27,7 @@ use crate::{ LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement, }, item_scope::BuiltinShadowMode, - item_tree::{FileItemTreeId, ItemTree, ItemTreeSource}, + item_tree::{FileItemTreeId, ItemTree, ItemTreeNode}, path::{GenericArgs, Path}, type_ref::{Mutability, Rawness, TypeRef}, AdtId, ConstLoc, ContainerId, DefWithBodyId, EnumLoc, FunctionLoc, Intern, ModuleDefId, @@ -557,7 +557,7 @@ impl ExprCollector<'_> { } } - fn find_inner_item(&self, id: AstId) -> FileItemTreeId { + fn find_inner_item(&self, id: AstId) -> FileItemTreeId { let index = self.item_trees.iter().position(|(file, _)| *file == id.file_id).unwrap_or_else(|| { panic!("couldn't find item tree for file {:?}", id.file_id); -- cgit v1.2.3 From 59d4640b644fa12ecc8f5075d92e5c53124e5dd7 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 24 Jun 2020 16:21:00 +0200 Subject: Remove unneeded HirFileId argument --- crates/ra_hir_def/src/body/lower.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'crates/ra_hir_def/src/body/lower.rs') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index a74136b8e..852d5cda7 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -57,17 +57,15 @@ impl LowerCtx { pub(super) fn lower( db: &dyn DefDatabase, - file_id: HirFileId, def: DefWithBodyId, expander: Expander, params: Option, body: Option, ) -> (Body, BodySourceMap) { - let item_tree = db.item_tree(file_id); + let item_tree = db.item_tree(expander.current_file_id); ExprCollector { db, def, - expander, source_map: BodySourceMap::default(), body: Body { exprs: Arena::default(), @@ -76,7 +74,8 @@ pub(super) fn lower( body_expr: dummy_expr_id(), item_scope: Default::default(), }, - item_trees: vec![(file_id, item_tree)], + item_trees: vec![(expander.current_file_id, item_tree)], + expander, } .collect(params, body) } -- cgit v1.2.3 From 3b50b0b2b658006c23d21749627e413af5c2aa44 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Wed, 24 Jun 2020 16:26:26 +0200 Subject: Use a HashMap instead of Vec This is no longer enforcing stack discipline, so a Vec isn't necessary or helpful --- crates/ra_hir_def/src/body/lower.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'crates/ra_hir_def/src/body/lower.rs') diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index 852d5cda7..3ced648e5 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs @@ -36,6 +36,7 @@ use crate::{ use super::{ExprSource, PatSource}; use ast::AstChildren; +use rustc_hash::FxHashMap; use std::sync::Arc; pub(crate) struct LowerCtx { @@ -74,7 +75,11 @@ pub(super) fn lower( body_expr: dummy_expr_id(), item_scope: Default::default(), }, - item_trees: vec![(expander.current_file_id, item_tree)], + item_trees: { + let mut map = FxHashMap::default(); + map.insert(expander.current_file_id, item_tree); + map + }, expander, } .collect(params, body) @@ -87,7 +92,7 @@ struct ExprCollector<'a> { body: Body, source_map: BodySourceMap, - item_trees: Vec<(HirFileId, Arc)>, + item_trees: FxHashMap>, } impl ExprCollector<'_> { @@ -541,7 +546,7 @@ impl ExprCollector<'_> { .insert(macro_call, self.expander.current_file_id); let item_tree = self.db.item_tree(self.expander.current_file_id); - self.item_trees.push((self.expander.current_file_id, item_tree)); + self.item_trees.insert(self.expander.current_file_id, item_tree); let id = self.collect_expr(expansion); self.expander.exit(self.db, mark); id @@ -557,11 +562,7 @@ impl ExprCollector<'_> { } fn find_inner_item(&self, id: AstId) -> FileItemTreeId { - let index = - self.item_trees.iter().position(|(file, _)| *file == id.file_id).unwrap_or_else(|| { - panic!("couldn't find item tree for file {:?}", id.file_id); - }); - let tree = &self.item_trees[index].1; + let tree = &self.item_trees[&id.file_id]; // FIXME: This probably breaks with `use` items, since they produce multiple item tree nodes -- cgit v1.2.3