From 1fbe21a545104e85aa5f9d0d8a45ec1040396cb9 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 22 Jun 2020 16:41:10 +0200 Subject: Make remaining item data queries use item tree --- crates/ra_hir_def/src/data.rs | 164 ++++++++----------------------- crates/ra_hir_def/src/item_tree.rs | 4 + crates/ra_hir_def/src/item_tree/lower.rs | 51 ++++++++-- crates/ra_hir_def/src/item_tree/tests.rs | 2 +- crates/ra_hir_def/src/visibility.rs | 21 +--- 5 files changed, 90 insertions(+), 152 deletions(-) (limited to 'crates/ra_hir_def/src') diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 697fde3d2..921253c42 100644 --- a/crates/ra_hir_def/src/data.rs +++ b/crates/ra_hir_def/src/data.rs @@ -2,23 +2,16 @@ use std::sync::Arc; -use hir_expand::{ - hygiene::Hygiene, - name::{name, AsName, Name}, - InFile, -}; +use hir_expand::{name::Name, InFile}; use ra_prof::profile; -use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, TypeBoundsOwner, VisibilityOwner}; +use ra_syntax::ast; use crate::{ attr::Attrs, body::Expander, - body::LowerCtx, db::DefDatabase, item_tree::{AssocItem, ItemTreeId, ModItem}, - path::{path, AssociatedTypeBinding, GenericArgs, Path}, - src::HasSource, - type_ref::{Mutability, TypeBound, TypeRef}, + type_ref::{TypeBound, TypeRef}, visibility::RawVisibility, AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc, @@ -40,82 +33,27 @@ pub struct FunctionData { impl FunctionData { pub(crate) fn fn_data_query(db: &impl DefDatabase, func: FunctionId) -> Arc { let loc = func.lookup(db); - let src = loc.source(db); - let ctx = LowerCtx::new(db, src.file_id); - let name = src.value.name().map(|n| n.as_name()).unwrap_or_else(Name::missing); - let mut params = Vec::new(); - let mut has_self_param = false; - if let Some(param_list) = src.value.param_list() { - if let Some(self_param) = param_list.self_param() { - let self_type = if let Some(type_ref) = self_param.ascribed_type() { - TypeRef::from_ast(&ctx, type_ref) - } else { - let self_type = TypeRef::Path(name![Self].into()); - match self_param.kind() { - ast::SelfParamKind::Owned => self_type, - ast::SelfParamKind::Ref => { - TypeRef::Reference(Box::new(self_type), Mutability::Shared) - } - ast::SelfParamKind::MutRef => { - TypeRef::Reference(Box::new(self_type), Mutability::Mut) - } - } - }; - params.push(self_type); - has_self_param = true; - } - for param in param_list.params() { - let type_ref = TypeRef::from_ast_opt(&ctx, param.ascribed_type()); - params.push(type_ref); - } - } - let attrs = Attrs::new(&src.value, &Hygiene::new(db.upcast(), src.file_id)); - - let ret_type = if let Some(type_ref) = src.value.ret_type().and_then(|rt| rt.type_ref()) { - TypeRef::from_ast(&ctx, type_ref) - } else { - TypeRef::unit() - }; - - let ret_type = if src.value.async_token().is_some() { - let future_impl = desugar_future_path(ret_type); - let ty_bound = TypeBound::Path(future_impl); - TypeRef::ImplTrait(vec![ty_bound]) - } else { - ret_type - }; - - let is_unsafe = src.value.unsafe_token().is_some(); - - let vis_default = RawVisibility::default_for_container(loc.container); - let visibility = - RawVisibility::from_ast_with_default(db, vis_default, src.map(|s| s.visibility())); - - let sig = - FunctionData { name, params, ret_type, has_self_param, is_unsafe, visibility, attrs }; - Arc::new(sig) + let item_tree = db.item_tree(loc.id.file_id); + let func = &item_tree[loc.id.value]; + + Arc::new(FunctionData { + name: func.name.clone(), + params: func.params.clone(), + ret_type: func.ret_type.clone(), + attrs: func.attrs.clone(), + has_self_param: func.has_self_param, + is_unsafe: func.is_unsafe, + visibility: func.visibility.clone(), + }) } } -fn desugar_future_path(orig: TypeRef) -> Path { - let path = path![core::future::Future]; - let mut generic_args: Vec<_> = std::iter::repeat(None).take(path.segments.len() - 1).collect(); - let mut last = GenericArgs::empty(); - last.bindings.push(AssociatedTypeBinding { - name: name![Output], - type_ref: Some(orig), - bounds: Vec::new(), - }); - generic_args.push(Some(Arc::new(last))); - - Path::from_known_path(path, generic_args) -} - #[derive(Debug, Clone, PartialEq, Eq)] pub struct TypeAliasData { pub name: Name, pub type_ref: Option, pub visibility: RawVisibility, + /// Bounds restricting the type alias itself (eg. `type Ty: Bound;` in a trait or impl). pub bounds: Vec, } @@ -125,22 +63,15 @@ impl TypeAliasData { typ: TypeAliasId, ) -> Arc { let loc = typ.lookup(db); - let node = loc.source(db); - let name = node.value.name().map_or_else(Name::missing, |n| n.as_name()); - let lower_ctx = LowerCtx::new(db, node.file_id); - let type_ref = node.value.type_ref().map(|it| TypeRef::from_ast(&lower_ctx, it)); - let vis_default = RawVisibility::default_for_container(loc.container); - let visibility = RawVisibility::from_ast_with_default( - db, - vis_default, - node.as_ref().map(|n| n.visibility()), - ); - let bounds = if let Some(bound_list) = node.value.type_bound_list() { - bound_list.bounds().map(|it| TypeBound::from_ast(&lower_ctx, it)).collect() - } else { - Vec::new() - }; - Arc::new(TypeAliasData { name, type_ref, visibility, bounds }) + let item_tree = db.item_tree(loc.id.file_id); + let typ = &item_tree[loc.id.value]; + + Arc::new(TypeAliasData { + name: typ.name.clone(), + type_ref: typ.type_ref.clone(), + visibility: typ.visibility.clone(), + bounds: typ.bounds.clone(), + }) } } @@ -238,22 +169,14 @@ pub struct ConstData { impl ConstData { pub(crate) fn const_data_query(db: &dyn DefDatabase, konst: ConstId) -> Arc { let loc = konst.lookup(db); - let node = loc.source(db); - let vis_default = RawVisibility::default_for_container(loc.container); - Arc::new(ConstData::new(db, vis_default, node)) - } + let item_tree = db.item_tree(loc.id.file_id); + let konst = &item_tree[loc.id.value]; - fn new( - db: &dyn DefDatabase, - vis_default: RawVisibility, - node: InFile, - ) -> ConstData { - let ctx = LowerCtx::new(db, node.file_id); - let name = node.value.name().map(|n| n.as_name()); - let type_ref = TypeRef::from_ast_opt(&ctx, node.value.ascribed_type()); - let visibility = - RawVisibility::from_ast_with_default(db, vis_default, node.map(|n| n.visibility())); - ConstData { name, type_ref, visibility } + Arc::new(ConstData { + name: konst.name.clone(), + type_ref: konst.type_ref.clone(), + visibility: konst.visibility.clone(), + }) } } @@ -267,19 +190,16 @@ pub struct StaticData { impl StaticData { pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc { - let node = konst.lookup(db).source(db); - let ctx = LowerCtx::new(db, node.file_id); - - let name = node.value.name().map(|n| n.as_name()); - let type_ref = TypeRef::from_ast_opt(&ctx, node.value.ascribed_type()); - let mutable = node.value.mut_token().is_some(); - let visibility = RawVisibility::from_ast_with_default( - db, - RawVisibility::private(), - node.map(|n| n.visibility()), - ); - - Arc::new(StaticData { name, type_ref, visibility, mutable }) + let node = konst.lookup(db); + let item_tree = db.item_tree(node.id.file_id); + let statik = &item_tree[node.id.value]; + + Arc::new(StaticData { + name: Some(statik.name.clone()), + type_ref: statik.type_ref.clone(), + visibility: statik.visibility.clone(), + mutable: statik.mutable, + }) } } diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs index 9a5dd701e..c35d63295 100644 --- a/crates/ra_hir_def/src/item_tree.rs +++ b/crates/ra_hir_def/src/item_tree.rs @@ -349,6 +349,7 @@ pub struct Function { pub visibility: RawVisibility, pub generic_params: GenericParams, pub has_self_param: bool, + pub is_unsafe: bool, pub params: Vec, pub ret_type: TypeRef, pub ast_id: FileAstId, @@ -408,6 +409,7 @@ pub struct Const { pub struct Static { pub name: Name, pub visibility: RawVisibility, + pub mutable: bool, pub type_ref: TypeRef, pub ast_id: FileAstId, } @@ -436,6 +438,8 @@ pub struct Impl { pub struct TypeAlias { pub name: Name, pub visibility: RawVisibility, + /// Bounds on the type alias itself. Only valid in trait declarations, eg. `type Assoc: Copy;`. + pub bounds: Vec, pub generic_params: GenericParams, pub type_ref: Option, pub ast_id: FileAstId, diff --git a/crates/ra_hir_def/src/item_tree/lower.rs b/crates/ra_hir_def/src/item_tree/lower.rs index f2b8a9418..42af8bb5e 100644 --- a/crates/ra_hir_def/src/item_tree/lower.rs +++ b/crates/ra_hir_def/src/item_tree/lower.rs @@ -36,6 +36,7 @@ pub(super) struct Ctx { source_ast_id_map: Arc, body_ctx: crate::body::LowerCtx, inner_items: Vec, + forced_visibility: Option, } impl Ctx { @@ -47,6 +48,7 @@ impl Ctx { source_ast_id_map: db.ast_id_map(file), body_ctx: crate::body::LowerCtx::new(db, file), inner_items: Vec::new(), + forced_visibility: None, } } @@ -117,6 +119,7 @@ impl Ctx { } fn collect_inner_items(&mut self, container: &SyntaxNode) { + let forced_vis = self.forced_visibility.take(); let mut inner_items = mem::replace(&mut self.tree.inner_items, FxHashMap::default()); inner_items.extend( container.descendants().skip(1).filter_map(ast::ModuleItem::cast).filter_map(|item| { @@ -125,6 +128,7 @@ impl Ctx { }), ); self.tree.inner_items = inner_items; + self.forced_visibility = forced_vis; } fn lower_assoc_item(&mut self, item: &ast::ModuleItem) -> Option { @@ -304,6 +308,7 @@ impl Ctx { visibility, generic_params: GenericParams::default(), has_self_param, + is_unsafe: func.unsafe_token().is_some(), params, ret_type, ast_id, @@ -320,9 +325,10 @@ impl Ctx { let name = type_alias.name()?.as_name(); let type_ref = type_alias.type_ref().map(|it| self.lower_type_ref(&it)); let visibility = self.lower_visibility(type_alias); + let bounds = self.lower_type_bounds(type_alias); let generic_params = self.lower_generic_params(GenericsOwner::TypeAlias, type_alias); let ast_id = self.source_ast_id_map.ast_id(type_alias); - let res = TypeAlias { name, visibility, generic_params, type_ref, ast_id }; + let res = TypeAlias { name, visibility, bounds, generic_params, type_ref, ast_id }; Some(id(self.tree.type_aliases.alloc(res))) } @@ -330,8 +336,9 @@ impl Ctx { let name = static_.name()?.as_name(); let type_ref = self.lower_type_ref_opt(static_.ascribed_type()); let visibility = self.lower_visibility(static_); + let mutable = static_.mut_token().is_some(); let ast_id = self.source_ast_id_map.ast_id(static_); - let res = Static { name, visibility, type_ref, ast_id }; + let res = Static { name, visibility, mutable, type_ref, ast_id }; Some(id(self.tree.statics.alloc(res))) } @@ -376,12 +383,14 @@ impl Ctx { let generic_params = self.lower_generic_params(GenericsOwner::Trait(trait_def), trait_def); let auto = trait_def.auto_token().is_some(); let items = trait_def.item_list().map(|list| { - list.items() - .flat_map(|item| { - self.collect_inner_items(item.syntax()); - self.lower_assoc_item(&item) - }) - .collect() + self.with_inherited_visibility(visibility.clone(), |this| { + list.items() + .flat_map(|item| { + this.collect_inner_items(item.syntax()); + this.lower_assoc_item(&item) + }) + .collect() + }) }); let ast_id = self.source_ast_id_map.ast_id(trait_def); let res = Trait { @@ -549,11 +558,23 @@ impl Ctx { generics } + fn lower_type_bounds(&mut self, node: &impl ast::TypeBoundsOwner) -> Vec { + if let Some(bound_list) = node.type_bound_list() { + bound_list.bounds().map(|it| TypeBound::from_ast(&self.body_ctx, it)).collect() + } else { + Vec::new() + } + } + fn lower_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs { Attrs::new(item, &self.hygiene) } fn lower_visibility(&self, item: &impl ast::VisibilityOwner) -> RawVisibility { - RawVisibility::from_ast_with_hygiene(item.visibility(), &self.hygiene) + if let Some(vis) = self.forced_visibility.as_ref() { + vis.clone() + } else { + RawVisibility::from_ast_with_hygiene(item.visibility(), &self.hygiene) + } } fn lower_type_ref(&self, type_ref: &ast::TypeRef) -> TypeRef { TypeRef::from_ast(&self.body_ctx, type_ref.clone()) @@ -562,6 +583,18 @@ impl Ctx { TypeRef::from_ast_opt(&self.body_ctx, type_ref) } + /// Forces the visibility `vis` to be used for all items lowered during execution of `f`. + fn with_inherited_visibility( + &mut self, + vis: RawVisibility, + f: impl FnOnce(&mut Self) -> R, + ) -> R { + let old = mem::replace(&mut self.forced_visibility, Some(vis)); + let res = f(self); + self.forced_visibility = old; + res + } + fn next_field_idx(&self) -> Idx { Idx::from_raw(RawId::from(self.tree.fields.len() as u32)) } diff --git a/crates/ra_hir_def/src/item_tree/tests.rs b/crates/ra_hir_def/src/item_tree/tests.rs index b60e6cbb0..1db1ce7a9 100644 --- a/crates/ra_hir_def/src/item_tree/tests.rs +++ b/crates/ra_hir_def/src/item_tree/tests.rs @@ -204,7 +204,7 @@ Impl { generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_ inner items: FileAstId::(2): -- Function { name: Name(Text("end")), attrs: Attrs { entries: None }, visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("W"))), default: None, provenance: TypeParamList }] }, where_predicates: [WherePredicate { target: TypeRef(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("W"))] }, generic_args: [None] })), bound: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Write"))] }, generic_args: [None] }) }] }, has_self_param: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::(2) } +- Function { name: Name(Text("end")), attrs: Attrs { entries: None }, visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("W"))), default: None, provenance: TypeParamList }] }, where_predicates: [WherePredicate { target: TypeRef(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("W"))] }, generic_args: [None] })), bound: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Write"))] }, generic_args: [None] }) }] }, has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::(2) } "###); } diff --git a/crates/ra_hir_def/src/visibility.rs b/crates/ra_hir_def/src/visibility.rs index 1482d3be0..8136cb50c 100644 --- a/crates/ra_hir_def/src/visibility.rs +++ b/crates/ra_hir_def/src/visibility.rs @@ -6,7 +6,7 @@ use ra_syntax::ast; use crate::{ db::DefDatabase, path::{ModPath, PathKind}, - AssocContainerId, ModuleId, + ModuleId, }; /// Visibility of an item, not yet resolved. @@ -25,25 +25,6 @@ impl RawVisibility { RawVisibility::Module(path) } - pub(crate) fn default_for_container(container_id: AssocContainerId) -> Self { - match container_id { - AssocContainerId::TraitId(_) => RawVisibility::Public, - _ => RawVisibility::private(), - } - } - - pub(crate) fn from_ast_with_default( - db: &dyn DefDatabase, - default: RawVisibility, - node: InFile>, - ) -> RawVisibility { - Self::from_ast_with_hygiene_and_default( - node.value, - default, - &Hygiene::new(db.upcast(), node.file_id), - ) - } - pub(crate) fn from_ast( db: &dyn DefDatabase, node: InFile>, -- cgit v1.2.3