diff options
author | Jonas Schievink <[email protected]> | 2020-06-22 18:15:54 +0100 |
---|---|---|
committer | Jonas Schievink <[email protected]> | 2020-06-24 15:53:16 +0100 |
commit | ffa0435050ae57c5171c19224ca6e9f8a4e3435d (patch) | |
tree | 02173f630fafb0804bb6009da7216fcab8a814d2 /crates | |
parent | 19586bc5c62541db5253986c84ce3ba5c6392656 (diff) |
Make generics and attr queries use ItemTree
Now it's fast
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir_def/src/attr.rs | 35 | ||||
-rw-r--r-- | crates/ra_hir_def/src/generics.rs | 49 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree/lower.rs | 7 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree/tests.rs | 2 |
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::{ | |||
13 | use tt::Subtree; | 13 | use tt::Subtree; |
14 | 14 | ||
15 | use crate::{ | 15 | use 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 | ||
190 | fn attrs_from_loc<T>(node: T, db: &dyn DefDatabase) -> Attrs | 194 | fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> Attrs { |
191 | where | 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() { | |||
200 | inner attrs: Attrs { entries: None } | 200 | inner attrs: Attrs { entries: None } |
201 | 201 | ||
202 | top-level items: | 202 | top-level items: |
203 | 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::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) } | 203 | 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::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) } |
204 | 204 | ||
205 | inner items: | 205 | inner items: |
206 | FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(2): | 206 | FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(2): |