diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-06-24 16:07:37 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2020-06-24 16:07:37 +0100 |
commit | e9bdb05e9676e85bdd8fa5008e3ada3812b36fd9 (patch) | |
tree | a21d348fbfa2d06f1fba77622c5417383938e6fe /crates/ra_hir_def/src/lib.rs | |
parent | 1a3b507a007d0373a83bde203d780b860ea55ce1 (diff) | |
parent | 2928600374a8356c2c2bffee080c47cb0f463fb9 (diff) |
Merge #4990
4990: Introduce an ItemTree layer to avoid reparsing files r=matklad a=jonas-schievink
This reduces the latency of "go to definition" in a simple benchmark on rust-analyzer by around 30%.
cc https://github.com/rust-analyzer/rust-analyzer/issues/1650
Closes https://github.com/rust-analyzer/rust-analyzer/issues/3485
Co-authored-by: Aleksey Kladov <[email protected]>
Co-authored-by: Jonas Schievink <[email protected]>
Co-authored-by: Jonas Schievink <[email protected]>
Diffstat (limited to 'crates/ra_hir_def/src/lib.rs')
-rw-r--r-- | crates/ra_hir_def/src/lib.rs | 99 |
1 files changed, 80 insertions, 19 deletions
diff --git a/crates/ra_hir_def/src/lib.rs b/crates/ra_hir_def/src/lib.rs index af2a717c9..564434ccc 100644 --- a/crates/ra_hir_def/src/lib.rs +++ b/crates/ra_hir_def/src/lib.rs | |||
@@ -25,6 +25,8 @@ pub mod item_scope; | |||
25 | pub mod dyn_map; | 25 | pub mod dyn_map; |
26 | pub mod keys; | 26 | pub mod keys; |
27 | 27 | ||
28 | pub mod item_tree; | ||
29 | |||
28 | pub mod adt; | 30 | pub mod adt; |
29 | pub mod data; | 31 | pub mod data; |
30 | pub mod generics; | 32 | pub mod generics; |
@@ -48,7 +50,7 @@ pub mod import_map; | |||
48 | #[cfg(test)] | 50 | #[cfg(test)] |
49 | mod test_db; | 51 | mod test_db; |
50 | 52 | ||
51 | use std::hash::Hash; | 53 | use std::hash::{Hash, Hasher}; |
52 | 54 | ||
53 | use hir_expand::{ | 55 | use hir_expand::{ |
54 | ast_id_map::FileAstId, eager::expand_eager_macro, hygiene::Hygiene, AstId, HirFileId, InFile, | 56 | ast_id_map::FileAstId, eager::expand_eager_macro, hygiene::Hygiene, AstId, HirFileId, InFile, |
@@ -56,10 +58,13 @@ use hir_expand::{ | |||
56 | }; | 58 | }; |
57 | use ra_arena::Idx; | 59 | use ra_arena::Idx; |
58 | use ra_db::{impl_intern_key, salsa, CrateId}; | 60 | use ra_db::{impl_intern_key, salsa, CrateId}; |
59 | use ra_syntax::{ast, AstNode}; | 61 | use ra_syntax::ast; |
60 | 62 | ||
61 | use crate::body::Expander; | ||
62 | use crate::builtin_type::BuiltinType; | 63 | use crate::builtin_type::BuiltinType; |
64 | use item_tree::{ | ||
65 | Const, Enum, Function, Impl, ItemTreeId, ItemTreeNode, ModItem, Static, Struct, Trait, | ||
66 | TypeAlias, Union, | ||
67 | }; | ||
63 | 68 | ||
64 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 69 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
65 | pub struct ModuleId { | 70 | pub struct ModuleId { |
@@ -70,16 +75,62 @@ pub struct ModuleId { | |||
70 | /// An ID of a module, **local** to a specific crate | 75 | /// An ID of a module, **local** to a specific crate |
71 | pub type LocalModuleId = Idx<nameres::ModuleData>; | 76 | pub type LocalModuleId = Idx<nameres::ModuleData>; |
72 | 77 | ||
73 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 78 | #[derive(Debug)] |
74 | pub struct ItemLoc<N: AstNode> { | 79 | pub struct ItemLoc<N: ItemTreeNode> { |
75 | pub container: ContainerId, | 80 | pub container: ContainerId, |
76 | pub ast_id: AstId<N>, | 81 | pub id: ItemTreeId<N>, |
82 | } | ||
83 | |||
84 | impl<N: ItemTreeNode> Clone for ItemLoc<N> { | ||
85 | fn clone(&self) -> Self { | ||
86 | Self { container: self.container, id: self.id } | ||
87 | } | ||
77 | } | 88 | } |
78 | 89 | ||
79 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 90 | impl<N: ItemTreeNode> Copy for ItemLoc<N> {} |
80 | pub struct AssocItemLoc<N: AstNode> { | 91 | |
92 | impl<N: ItemTreeNode> PartialEq for ItemLoc<N> { | ||
93 | fn eq(&self, other: &Self) -> bool { | ||
94 | self.container == other.container && self.id == other.id | ||
95 | } | ||
96 | } | ||
97 | |||
98 | impl<N: ItemTreeNode> Eq for ItemLoc<N> {} | ||
99 | |||
100 | impl<N: ItemTreeNode> Hash for ItemLoc<N> { | ||
101 | fn hash<H: Hasher>(&self, state: &mut H) { | ||
102 | self.container.hash(state); | ||
103 | self.id.hash(state); | ||
104 | } | ||
105 | } | ||
106 | |||
107 | #[derive(Debug)] | ||
108 | pub struct AssocItemLoc<N: ItemTreeNode> { | ||
81 | pub container: AssocContainerId, | 109 | pub container: AssocContainerId, |
82 | pub ast_id: AstId<N>, | 110 | pub id: ItemTreeId<N>, |
111 | } | ||
112 | |||
113 | impl<N: ItemTreeNode> Clone for AssocItemLoc<N> { | ||
114 | fn clone(&self) -> Self { | ||
115 | Self { container: self.container, id: self.id } | ||
116 | } | ||
117 | } | ||
118 | |||
119 | impl<N: ItemTreeNode> Copy for AssocItemLoc<N> {} | ||
120 | |||
121 | impl<N: ItemTreeNode> PartialEq for AssocItemLoc<N> { | ||
122 | fn eq(&self, other: &Self) -> bool { | ||
123 | self.container == other.container && self.id == other.id | ||
124 | } | ||
125 | } | ||
126 | |||
127 | impl<N: ItemTreeNode> Eq for AssocItemLoc<N> {} | ||
128 | |||
129 | impl<N: ItemTreeNode> Hash for AssocItemLoc<N> { | ||
130 | fn hash<H: Hasher>(&self, state: &mut H) { | ||
131 | self.container.hash(state); | ||
132 | self.id.hash(state); | ||
133 | } | ||
83 | } | 134 | } |
84 | 135 | ||
85 | macro_rules! impl_intern { | 136 | macro_rules! impl_intern { |
@@ -104,22 +155,22 @@ macro_rules! impl_intern { | |||
104 | 155 | ||
105 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 156 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
106 | pub struct FunctionId(salsa::InternId); | 157 | pub struct FunctionId(salsa::InternId); |
107 | type FunctionLoc = AssocItemLoc<ast::FnDef>; | 158 | type FunctionLoc = AssocItemLoc<Function>; |
108 | impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function); | 159 | impl_intern!(FunctionId, FunctionLoc, intern_function, lookup_intern_function); |
109 | 160 | ||
110 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 161 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
111 | pub struct StructId(salsa::InternId); | 162 | pub struct StructId(salsa::InternId); |
112 | type StructLoc = ItemLoc<ast::StructDef>; | 163 | type StructLoc = ItemLoc<Struct>; |
113 | impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct); | 164 | impl_intern!(StructId, StructLoc, intern_struct, lookup_intern_struct); |
114 | 165 | ||
115 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 166 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
116 | pub struct UnionId(salsa::InternId); | 167 | pub struct UnionId(salsa::InternId); |
117 | pub type UnionLoc = ItemLoc<ast::UnionDef>; | 168 | pub type UnionLoc = ItemLoc<Union>; |
118 | impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union); | 169 | impl_intern!(UnionId, UnionLoc, intern_union, lookup_intern_union); |
119 | 170 | ||
120 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 171 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
121 | pub struct EnumId(salsa::InternId); | 172 | pub struct EnumId(salsa::InternId); |
122 | pub type EnumLoc = ItemLoc<ast::EnumDef>; | 173 | pub type EnumLoc = ItemLoc<Enum>; |
123 | impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum); | 174 | impl_intern!(EnumId, EnumLoc, intern_enum, lookup_intern_enum); |
124 | 175 | ||
125 | // FIXME: rename to `VariantId`, only enums can ave variants | 176 | // FIXME: rename to `VariantId`, only enums can ave variants |
@@ -141,27 +192,27 @@ pub type LocalFieldId = Idx<adt::FieldData>; | |||
141 | 192 | ||
142 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 193 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
143 | pub struct ConstId(salsa::InternId); | 194 | pub struct ConstId(salsa::InternId); |
144 | type ConstLoc = AssocItemLoc<ast::ConstDef>; | 195 | type ConstLoc = AssocItemLoc<Const>; |
145 | impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const); | 196 | impl_intern!(ConstId, ConstLoc, intern_const, lookup_intern_const); |
146 | 197 | ||
147 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 198 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
148 | pub struct StaticId(salsa::InternId); | 199 | pub struct StaticId(salsa::InternId); |
149 | pub type StaticLoc = ItemLoc<ast::StaticDef>; | 200 | pub type StaticLoc = ItemLoc<Static>; |
150 | impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static); | 201 | impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static); |
151 | 202 | ||
152 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 203 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
153 | pub struct TraitId(salsa::InternId); | 204 | pub struct TraitId(salsa::InternId); |
154 | pub type TraitLoc = ItemLoc<ast::TraitDef>; | 205 | pub type TraitLoc = ItemLoc<Trait>; |
155 | impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait); | 206 | impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait); |
156 | 207 | ||
157 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 208 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
158 | pub struct TypeAliasId(salsa::InternId); | 209 | pub struct TypeAliasId(salsa::InternId); |
159 | type TypeAliasLoc = AssocItemLoc<ast::TypeAliasDef>; | 210 | type TypeAliasLoc = AssocItemLoc<TypeAlias>; |
160 | impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias); | 211 | impl_intern!(TypeAliasId, TypeAliasLoc, intern_type_alias, lookup_intern_type_alias); |
161 | 212 | ||
162 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] | 213 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] |
163 | pub struct ImplId(salsa::InternId); | 214 | pub struct ImplId(salsa::InternId); |
164 | type ImplLoc = ItemLoc<ast::ImplDef>; | 215 | type ImplLoc = ItemLoc<Impl>; |
165 | impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl); | 216 | impl_intern!(ImplId, ImplLoc, intern_impl, lookup_intern_impl); |
166 | 217 | ||
167 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 218 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -365,7 +416,7 @@ impl HasModule for AssocContainerId { | |||
365 | } | 416 | } |
366 | } | 417 | } |
367 | 418 | ||
368 | impl<N: AstNode> HasModule for AssocItemLoc<N> { | 419 | impl<N: ItemTreeNode> HasModule for AssocItemLoc<N> { |
369 | fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { | 420 | fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { |
370 | self.container.module(db) | 421 | self.container.module(db) |
371 | } | 422 | } |
@@ -392,6 +443,16 @@ impl HasModule for DefWithBodyId { | |||
392 | } | 443 | } |
393 | } | 444 | } |
394 | 445 | ||
446 | impl DefWithBodyId { | ||
447 | pub fn as_mod_item(self, db: &dyn db::DefDatabase) -> ModItem { | ||
448 | match self { | ||
449 | DefWithBodyId::FunctionId(it) => it.lookup(db).id.value.into(), | ||
450 | DefWithBodyId::StaticId(it) => it.lookup(db).id.value.into(), | ||
451 | DefWithBodyId::ConstId(it) => it.lookup(db).id.value.into(), | ||
452 | } | ||
453 | } | ||
454 | } | ||
455 | |||
395 | impl HasModule for GenericDefId { | 456 | impl HasModule for GenericDefId { |
396 | fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { | 457 | fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { |
397 | match self { | 458 | match self { |