From 1fbe21a545104e85aa5f9d0d8a45ec1040396cb9 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 22 Jun 2020 16:41:10 +0200 Subject: [PATCH] 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(-) diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 697fde3d21a..921253c42d6 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 @@ pub(crate) fn type_alias_data_query( 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 9a5dd701eb6..c35d6329521 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 f2b8a941822..42af8bb5e5c 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 @@ pub(super) fn new(db: &dyn DefDatabase, hygiene: Hygiene, file: HirFileId) -> Se 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 @@ fn lower_mod_item(&mut self, item: &ast::ModuleItem, inner: bool) -> Option Option { @@ -304,6 +308,7 @@ fn lower_function(&mut self, func: &ast::FnDef) -> Option Option Option 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 @@ fn lower_type_ref_opt(&self, type_ref: Option) -> TypeRef { 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 b60e6cbb0c0..1db1ce7a9ae 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 @@ fn end() { 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 1482d3be04d..8136cb50ccf 100644 --- a/crates/ra_hir_def/src/visibility.rs +++ b/crates/ra_hir_def/src/visibility.rs @@ -6,7 +6,7 @@ use crate::{ db::DefDatabase, path::{ModPath, PathKind}, - AssocContainerId, ModuleId, + ModuleId, }; /// Visibility of an item, not yet resolved. @@ -25,25 +25,6 @@ pub(crate) const fn private() -> 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>, -- 2.44.0