mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 22:31:43 +00:00
Make generics and attr queries use ItemTree
Now it's fast
This commit is contained in:
parent
19586bc5c6
commit
ffa0435050
5 changed files with 79 additions and 21 deletions
|
@ -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<T>(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<N: ItemTreeNode>(id: ItemTreeId<N>, 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()
|
||||
}
|
||||
|
|
|
@ -74,8 +74,53 @@ impl GenericParams {
|
|||
def: GenericDefId,
|
||||
) -> Arc<GenericParams> {
|
||||
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<SourceMap>) {
|
||||
|
|
|
@ -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<FileItemTreeId<Self>>;
|
||||
|
||||
/// Upcasts a `FileItemTreeId` to a generic `ModItem`.
|
||||
fn id_to_mod_item(id: FileItemTreeId<Self>) -> 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<Self>) -> ModItem {
|
||||
ModItem::$node(id)
|
||||
}
|
||||
}
|
||||
)+ };
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(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::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) }
|
||||
|
||||
inner items:
|
||||
FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(2):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue