aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-06-22 18:15:54 +0100
committerJonas Schievink <[email protected]>2020-06-24 15:53:16 +0100
commitffa0435050ae57c5171c19224ca6e9f8a4e3435d (patch)
tree02173f630fafb0804bb6009da7216fcab8a814d2 /crates/ra_hir_def/src
parent19586bc5c62541db5253986c84ce3ba5c6392656 (diff)
Make generics and attr queries use ItemTree
Now it's fast
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r--crates/ra_hir_def/src/attr.rs35
-rw-r--r--crates/ra_hir_def/src/generics.rs49
-rw-r--r--crates/ra_hir_def/src/item_tree.rs7
-rw-r--r--crates/ra_hir_def/src/item_tree/lower.rs7
-rw-r--r--crates/ra_hir_def/src/item_tree/tests.rs2
5 files changed, 79 insertions, 21 deletions
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::{
13use tt::Subtree; 13use tt::Subtree;
14 14
15use crate::{ 15use crate::{
16 db::DefDatabase, nameres::ModuleSource, path::ModPath, src::HasChildSource, src::HasSource, 16 db::DefDatabase,
17 item_tree::{ItemTreeId, ItemTreeNode},
18 nameres::ModuleSource,
19 path::ModPath,
20 src::HasChildSource,
17 AdtId, AttrDefId, Lookup, 21 AdtId, AttrDefId, Lookup,
18}; 22};
19 23
@@ -65,19 +69,19 @@ impl Attrs {
65 Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) 69 Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner))
66 } 70 }
67 AttrDefId::AdtId(it) => match it { 71 AttrDefId::AdtId(it) => match it {
68 AdtId::StructId(it) => attrs_from_loc(it.lookup(db), db), 72 AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db),
69 AdtId::EnumId(it) => attrs_from_loc(it.lookup(db), db), 73 AdtId::EnumId(it) => attrs_from_item_tree(it.lookup(db).id, db),
70 AdtId::UnionId(it) => attrs_from_loc(it.lookup(db), db), 74 AdtId::UnionId(it) => attrs_from_item_tree(it.lookup(db).id, db),
71 }, 75 },
72 AttrDefId::TraitId(it) => attrs_from_loc(it.lookup(db), db), 76 AttrDefId::TraitId(it) => attrs_from_item_tree(it.lookup(db).id, db),
73 AttrDefId::MacroDefId(it) => { 77 AttrDefId::MacroDefId(it) => {
74 it.ast_id.map_or_else(Default::default, |ast_id| attrs_from_ast(ast_id, db)) 78 it.ast_id.map_or_else(Default::default, |ast_id| attrs_from_ast(ast_id, db))
75 } 79 }
76 AttrDefId::ImplId(it) => attrs_from_loc(it.lookup(db), db), 80 AttrDefId::ImplId(it) => attrs_from_item_tree(it.lookup(db).id, db),
77 AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db), 81 AttrDefId::ConstId(it) => attrs_from_item_tree(it.lookup(db).id, db),
78 AttrDefId::StaticId(it) => attrs_from_loc(it.lookup(db), db), 82 AttrDefId::StaticId(it) => attrs_from_item_tree(it.lookup(db).id, db),
79 AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db), 83 AttrDefId::FunctionId(it) => attrs_from_item_tree(it.lookup(db).id, db),
80 AttrDefId::TypeAliasId(it) => attrs_from_loc(it.lookup(db), db), 84 AttrDefId::TypeAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db),
81 } 85 }
82 } 86 }
83 87
@@ -187,11 +191,8 @@ where
187 Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) 191 Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner))
188} 192}
189 193
190fn attrs_from_loc<T>(node: T, db: &dyn DefDatabase) -> Attrs 194fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> Attrs {
191where 195 let tree = db.item_tree(id.file_id);
192 T: HasSource, 196 let mod_item = N::id_to_mod_item(id.value);
193 T::Value: ast::AttrsOwner, 197 tree.attrs(mod_item).clone()
194{
195 let src = node.source(db);
196 Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner))
197} 198}
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 {
74 def: GenericDefId, 74 def: GenericDefId,
75 ) -> Arc<GenericParams> { 75 ) -> Arc<GenericParams> {
76 let _p = profile("generic_params_query"); 76 let _p = profile("generic_params_query");
77 let (params, _source_map) = GenericParams::new(db, def); 77
78 Arc::new(params) 78 let generics = match def {
79 GenericDefId::FunctionId(id) => {
80 let id = id.lookup(db).id;
81 let tree = db.item_tree(id.file_id);
82 let item = &tree[id.value];
83 item.generic_params.clone()
84 }
85 GenericDefId::AdtId(AdtId::StructId(id)) => {
86 let id = id.lookup(db).id;
87 let tree = db.item_tree(id.file_id);
88 let item = &tree[id.value];
89 item.generic_params.clone()
90 }
91 GenericDefId::AdtId(AdtId::EnumId(id)) => {
92 let id = id.lookup(db).id;
93 let tree = db.item_tree(id.file_id);
94 let item = &tree[id.value];
95 item.generic_params.clone()
96 }
97 GenericDefId::AdtId(AdtId::UnionId(id)) => {
98 let id = id.lookup(db).id;
99 let tree = db.item_tree(id.file_id);
100 let item = &tree[id.value];
101 item.generic_params.clone()
102 }
103 GenericDefId::TraitId(id) => {
104 let id = id.lookup(db).id;
105 let tree = db.item_tree(id.file_id);
106 let item = &tree[id.value];
107 item.generic_params.clone()
108 }
109 GenericDefId::TypeAliasId(id) => {
110 let id = id.lookup(db).id;
111 let tree = db.item_tree(id.file_id);
112 let item = &tree[id.value];
113 item.generic_params.clone()
114 }
115 GenericDefId::ImplId(id) => {
116 let id = id.lookup(db).id;
117 let tree = db.item_tree(id.file_id);
118 let item = &tree[id.value];
119 item.generic_params.clone()
120 }
121 GenericDefId::EnumVariantId(_) | GenericDefId::ConstId(_) => GenericParams::default(),
122 };
123 Arc::new(generics)
79 } 124 }
80 125
81 fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) { 126 fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) {
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 {
175 175
176 /// Downcasts a `ModItem` to a `FileItemTreeId` specific to this type. 176 /// Downcasts a `ModItem` to a `FileItemTreeId` specific to this type.
177 fn id_from_mod_item(mod_item: ModItem) -> Option<FileItemTreeId<Self>>; 177 fn id_from_mod_item(mod_item: ModItem) -> Option<FileItemTreeId<Self>>;
178
179 /// Upcasts a `FileItemTreeId` to a generic `ModItem`.
180 fn id_to_mod_item(id: FileItemTreeId<Self>) -> ModItem;
178} 181}
179 182
180/// Trait for item tree nodes that allow accessing the original AST node. 183/// Trait for item tree nodes that allow accessing the original AST node.
@@ -232,6 +235,10 @@ macro_rules! nodes {
232 None 235 None
233 } 236 }
234 } 237 }
238
239 fn id_to_mod_item(id: FileItemTreeId<Self>) -> ModItem {
240 ModItem::$node(id)
241 }
235 } 242 }
236 )+ }; 243 )+ };
237} 244}
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 {
553 553
554 generics.fill(&self.body_ctx, &mut sm, node); 554 generics.fill(&self.body_ctx, &mut sm, node);
555 } 555 }
556 GenericsOwner::Impl => {} 556 GenericsOwner::Impl => {
557 // Note that we don't add `Self` here: in `impl`s, `Self` is not a
558 // type-parameter, but rather is a type-alias for impl's target
559 // type, so this is handled by the resolver.
560 generics.fill(&self.body_ctx, &mut sm, node);
561 }
557 } 562 }
558 generics 563 generics
559 } 564 }
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() {
200inner attrs: Attrs { entries: None } 200inner attrs: Attrs { entries: None }
201 201
202top-level items: 202top-level items:
203Impl { 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::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) } 203Impl { 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::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) }
204 204
205inner items: 205inner items:
206FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(2): 206FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(2):