From ffa0435050ae57c5171c19224ca6e9f8a4e3435d Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Mon, 22 Jun 2020 19:15:54 +0200 Subject: Make generics and attr queries use ItemTree Now it's fast --- crates/ra_hir_def/src/attr.rs | 35 ++++++++++++----------- crates/ra_hir_def/src/generics.rs | 49 ++++++++++++++++++++++++++++++-- crates/ra_hir_def/src/item_tree.rs | 7 +++++ crates/ra_hir_def/src/item_tree/lower.rs | 7 ++++- crates/ra_hir_def/src/item_tree/tests.rs | 2 +- 5 files changed, 79 insertions(+), 21 deletions(-) (limited to 'crates/ra_hir_def') diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 2eeba0572..deea83a6d 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs @@ -13,7 +13,11 @@ use ra_syntax::{ use tt::Subtree; use crate::{ - db::DefDatabase, nameres::ModuleSource, path::ModPath, src::HasChildSource, src::HasSource, + db::DefDatabase, + item_tree::{ItemTreeId, ItemTreeNode}, + nameres::ModuleSource, + path::ModPath, + src::HasChildSource, AdtId, AttrDefId, Lookup, }; @@ -65,19 +69,19 @@ impl Attrs { Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) } AttrDefId::AdtId(it) => match it { - AdtId::StructId(it) => attrs_from_loc(it.lookup(db), db), - AdtId::EnumId(it) => attrs_from_loc(it.lookup(db), db), - AdtId::UnionId(it) => attrs_from_loc(it.lookup(db), db), + AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db), + AdtId::EnumId(it) => attrs_from_item_tree(it.lookup(db).id, db), + AdtId::UnionId(it) => attrs_from_item_tree(it.lookup(db).id, db), }, - AttrDefId::TraitId(it) => attrs_from_loc(it.lookup(db), db), + AttrDefId::TraitId(it) => attrs_from_item_tree(it.lookup(db).id, db), AttrDefId::MacroDefId(it) => { it.ast_id.map_or_else(Default::default, |ast_id| attrs_from_ast(ast_id, db)) } - AttrDefId::ImplId(it) => attrs_from_loc(it.lookup(db), db), - AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db), - AttrDefId::StaticId(it) => attrs_from_loc(it.lookup(db), db), - AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db), - AttrDefId::TypeAliasId(it) => attrs_from_loc(it.lookup(db), db), + AttrDefId::ImplId(it) => attrs_from_item_tree(it.lookup(db).id, db), + AttrDefId::ConstId(it) => attrs_from_item_tree(it.lookup(db).id, db), + AttrDefId::StaticId(it) => attrs_from_item_tree(it.lookup(db).id, db), + AttrDefId::FunctionId(it) => attrs_from_item_tree(it.lookup(db).id, db), + AttrDefId::TypeAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db), } } @@ -187,11 +191,8 @@ where Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) } -fn attrs_from_loc(node: T, db: &dyn DefDatabase) -> Attrs -where - T: HasSource, - T::Value: ast::AttrsOwner, -{ - let src = node.source(db); - Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) +fn attrs_from_item_tree(id: ItemTreeId, db: &dyn DefDatabase) -> Attrs { + let tree = db.item_tree(id.file_id); + let mod_item = N::id_to_mod_item(id.value); + tree.attrs(mod_item).clone() } diff --git a/crates/ra_hir_def/src/generics.rs b/crates/ra_hir_def/src/generics.rs index ed4f60c66..c4b9f626f 100644 --- a/crates/ra_hir_def/src/generics.rs +++ b/crates/ra_hir_def/src/generics.rs @@ -74,8 +74,53 @@ impl GenericParams { def: GenericDefId, ) -> Arc { let _p = profile("generic_params_query"); - let (params, _source_map) = GenericParams::new(db, def); - Arc::new(params) + + let generics = match def { + GenericDefId::FunctionId(id) => { + let id = id.lookup(db).id; + let tree = db.item_tree(id.file_id); + let item = &tree[id.value]; + item.generic_params.clone() + } + GenericDefId::AdtId(AdtId::StructId(id)) => { + let id = id.lookup(db).id; + let tree = db.item_tree(id.file_id); + let item = &tree[id.value]; + item.generic_params.clone() + } + GenericDefId::AdtId(AdtId::EnumId(id)) => { + let id = id.lookup(db).id; + let tree = db.item_tree(id.file_id); + let item = &tree[id.value]; + item.generic_params.clone() + } + GenericDefId::AdtId(AdtId::UnionId(id)) => { + let id = id.lookup(db).id; + let tree = db.item_tree(id.file_id); + let item = &tree[id.value]; + item.generic_params.clone() + } + GenericDefId::TraitId(id) => { + let id = id.lookup(db).id; + let tree = db.item_tree(id.file_id); + let item = &tree[id.value]; + item.generic_params.clone() + } + GenericDefId::TypeAliasId(id) => { + let id = id.lookup(db).id; + let tree = db.item_tree(id.file_id); + let item = &tree[id.value]; + item.generic_params.clone() + } + GenericDefId::ImplId(id) => { + let id = id.lookup(db).id; + let tree = db.item_tree(id.file_id); + let item = &tree[id.value]; + item.generic_params.clone() + } + GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => GenericParams::default(), + }; + Arc::new(generics) } fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile) { diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs index 59a4a411a..efcb5dc60 100644 --- a/crates/ra_hir_def/src/item_tree.rs +++ b/crates/ra_hir_def/src/item_tree.rs @@ -175,6 +175,9 @@ pub trait ItemTreeNode: Clone { /// Downcasts a `ModItem` to a `FileItemTreeId` specific to this type. fn id_from_mod_item(mod_item: ModItem) -> Option>; + + /// Upcasts a `FileItemTreeId` to a generic `ModItem`. + fn id_to_mod_item(id: FileItemTreeId) -> ModItem; } /// Trait for item tree nodes that allow accessing the original AST node. @@ -232,6 +235,10 @@ macro_rules! nodes { None } } + + fn id_to_mod_item(id: FileItemTreeId) -> ModItem { + ModItem::$node(id) + } } )+ }; } diff --git a/crates/ra_hir_def/src/item_tree/lower.rs b/crates/ra_hir_def/src/item_tree/lower.rs index 42af8bb5e..841c7a852 100644 --- a/crates/ra_hir_def/src/item_tree/lower.rs +++ b/crates/ra_hir_def/src/item_tree/lower.rs @@ -553,7 +553,12 @@ impl Ctx { generics.fill(&self.body_ctx, &mut sm, node); } - GenericsOwner::Impl => {} + GenericsOwner::Impl => { + // Note that we don't add `Self` here: in `impl`s, `Self` is not a + // type-parameter, but rather is a type-alias for impl's target + // type, so this is handled by the resolver. + generics.fill(&self.body_ctx, &mut sm, node); + } } generics } diff --git a/crates/ra_hir_def/src/item_tree/tests.rs b/crates/ra_hir_def/src/item_tree/tests.rs index 1db1ce7a9..7b8523b9f 100644 --- a/crates/ra_hir_def/src/item_tree/tests.rs +++ b/crates/ra_hir_def/src/item_tree/tests.rs @@ -200,7 +200,7 @@ fn simple_inner_items() { inner attrs: Attrs { entries: None } top-level items: -Impl { generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, target_trait: Some(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("D"))] }, generic_args: [None] })), target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Response"))] }, generic_args: [Some(GenericArgs { args: [Type(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("T"))] }, generic_args: [None] }))], has_self_type: false, bindings: [] })] }), is_negative: false, items: [Function(Idx::(1))], ast_id: FileAstId::(0) } +Impl { generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("T"))), default: None, provenance: TypeParamList }] }, where_predicates: [WherePredicate { target: TypeRef(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("T"))] }, generic_args: [None] })), bound: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("A"))] }, generic_args: [None] }) }] }, target_trait: Some(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("D"))] }, generic_args: [None] })), target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Response"))] }, generic_args: [Some(GenericArgs { args: [Type(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("T"))] }, generic_args: [None] }))], has_self_type: false, bindings: [] })] }), is_negative: false, items: [Function(Idx::(1))], ast_id: FileAstId::(0) } inner items: FileAstId::(2): -- cgit v1.2.3