mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-27 20:42:04 +00:00
Move ChildbySource and HasSource impls to their corresponding modules
This commit is contained in:
parent
1ef7a2329b
commit
74eb3ecbc1
7 changed files with 229 additions and 218 deletions
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{attrs::collect_attrs, HirFileId};
|
use hir_expand::{attrs::collect_attrs, HirFileId};
|
||||||
|
use syntax::ast;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
|
@ -17,8 +18,9 @@ use crate::{
|
||||||
item_tree::ItemTreeNode,
|
item_tree::ItemTreeNode,
|
||||||
nameres::DefMap,
|
nameres::DefMap,
|
||||||
src::{HasChildSource, HasSource},
|
src::{HasChildSource, HasSource},
|
||||||
AdtId, AssocItemId, DefWithBodyId, EnumId, FieldId, ImplId, ItemTreeLoc, Lookup, MacroId,
|
AdtId, AssocItemId, DefWithBodyId, EnumId, FieldId, GenericDefId, ImplId, ItemTreeLoc,
|
||||||
ModuleDefId, ModuleId, TraitId, VariantId,
|
LifetimeParamId, Lookup, MacroId, ModuleDefId, ModuleId, TraitId, TypeOrConstParamId,
|
||||||
|
VariantId,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait ChildBySource {
|
pub trait ChildBySource {
|
||||||
|
@ -59,14 +61,6 @@ impl ChildBySource for ImplId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_assoc_item(db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId, item: AssocItemId) {
|
|
||||||
match item {
|
|
||||||
AssocItemId::FunctionId(func) => insert_item_loc(db, res, file_id, func, keys::FUNCTION),
|
|
||||||
AssocItemId::ConstId(konst) => insert_item_loc(db, res, file_id, konst, keys::CONST),
|
|
||||||
AssocItemId::TypeAliasId(ty) => insert_item_loc(db, res, file_id, ty, keys::TYPE_ALIAS),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ChildBySource for ModuleId {
|
impl ChildBySource for ModuleId {
|
||||||
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
|
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
|
||||||
let def_map = self.def_map(db);
|
let def_map = self.def_map(db);
|
||||||
|
@ -118,14 +112,6 @@ impl ChildBySource for ItemScope {
|
||||||
file_id: HirFileId,
|
file_id: HirFileId,
|
||||||
item: ModuleDefId,
|
item: ModuleDefId,
|
||||||
) {
|
) {
|
||||||
macro_rules! insert {
|
|
||||||
($map:ident[$key:path].$insert:ident($id:ident)) => {{
|
|
||||||
let loc = $id.lookup(db);
|
|
||||||
if loc.id.file_id() == file_id {
|
|
||||||
$map[$key].$insert(loc.source(db).value, $id)
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
match item {
|
match item {
|
||||||
ModuleDefId::FunctionId(id) => {
|
ModuleDefId::FunctionId(id) => {
|
||||||
insert_item_loc(db, map, file_id, id, keys::FUNCTION)
|
insert_item_loc(db, map, file_id, id, keys::FUNCTION)
|
||||||
|
@ -145,9 +131,13 @@ impl ChildBySource for ItemScope {
|
||||||
AdtId::EnumId(id) => insert_item_loc(db, map, file_id, id, keys::ENUM),
|
AdtId::EnumId(id) => insert_item_loc(db, map, file_id, id, keys::ENUM),
|
||||||
},
|
},
|
||||||
ModuleDefId::MacroId(id) => match id {
|
ModuleDefId::MacroId(id) => match id {
|
||||||
MacroId::Macro2Id(id) => insert!(map[keys::MACRO2].insert(id)),
|
MacroId::Macro2Id(id) => insert_item_loc(db, map, file_id, id, keys::MACRO2),
|
||||||
MacroId::MacroRulesId(id) => insert!(map[keys::MACRO_RULES].insert(id)),
|
MacroId::MacroRulesId(id) => {
|
||||||
MacroId::ProcMacroId(id) => insert!(map[keys::PROC_MACRO].insert(id)),
|
insert_item_loc(db, map, file_id, id, keys::MACRO_RULES)
|
||||||
|
}
|
||||||
|
MacroId::ProcMacroId(id) => {
|
||||||
|
insert_item_loc(db, map, file_id, id, keys::PROC_MACRO)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
ModuleDefId::ModuleId(_)
|
ModuleDefId::ModuleId(_)
|
||||||
| ModuleDefId::EnumVariantId(_)
|
| ModuleDefId::EnumVariantId(_)
|
||||||
|
@ -207,6 +197,40 @@ impl ChildBySource for DefWithBodyId {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ChildBySource for GenericDefId {
|
||||||
|
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
|
||||||
|
let (gfile_id, generic_params_list) = self.file_id_and_params_of(db);
|
||||||
|
if gfile_id != file_id {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let generic_params = db.generic_params(*self);
|
||||||
|
let mut toc_idx_iter = generic_params.type_or_consts.iter().map(|(idx, _)| idx);
|
||||||
|
let lts_idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx);
|
||||||
|
|
||||||
|
// For traits the first type index is `Self`, skip it.
|
||||||
|
if let GenericDefId::TraitId(_) = *self {
|
||||||
|
toc_idx_iter.next().unwrap(); // advance_by(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(generic_params_list) = generic_params_list {
|
||||||
|
for (local_id, ast_param) in
|
||||||
|
toc_idx_iter.zip(generic_params_list.type_or_const_params())
|
||||||
|
{
|
||||||
|
let id = TypeOrConstParamId { parent: *self, local_id };
|
||||||
|
match ast_param {
|
||||||
|
ast::TypeOrConstParam::Type(a) => res[keys::TYPE_PARAM].insert(a, id),
|
||||||
|
ast::TypeOrConstParam::Const(a) => res[keys::CONST_PARAM].insert(a, id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (local_id, ast_param) in lts_idx_iter.zip(generic_params_list.lifetime_params()) {
|
||||||
|
let id = LifetimeParamId { parent: *self, local_id };
|
||||||
|
res[keys::LIFETIME_PARAM].insert(ast_param, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn insert_item_loc<ID, N, Data>(
|
fn insert_item_loc<ID, N, Data>(
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
res: &mut DynMap,
|
res: &mut DynMap,
|
||||||
|
@ -224,3 +248,11 @@ fn insert_item_loc<ID, N, Data>(
|
||||||
res[key].insert(loc.source(db).value, id)
|
res[key].insert(loc.source(db).value, id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_assoc_item(db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId, item: AssocItemId) {
|
||||||
|
match item {
|
||||||
|
AssocItemId::FunctionId(func) => insert_item_loc(db, res, file_id, func, keys::FUNCTION),
|
||||||
|
AssocItemId::ConstId(konst) => insert_item_loc(db, res, file_id, konst, keys::CONST),
|
||||||
|
AssocItemId::TypeAliasId(ty) => insert_item_loc(db, res, file_id, ty, keys::TYPE_ALIAS),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ use hir_expand::{
|
||||||
HirFileId, InFile,
|
HirFileId, InFile,
|
||||||
};
|
};
|
||||||
use intern::Interned;
|
use intern::Interned;
|
||||||
use la_arena::{Arena, ArenaMap};
|
use la_arena::Arena;
|
||||||
use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions};
|
use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions};
|
||||||
use syntax::ast::{self, HasName, HasVisibility};
|
use syntax::ast::{self, HasName, HasVisibility};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
@ -22,13 +22,11 @@ use crate::{
|
||||||
lang_item::LangItem,
|
lang_item::LangItem,
|
||||||
lower::LowerCtx,
|
lower::LowerCtx,
|
||||||
nameres::diagnostics::{DefDiagnostic, DefDiagnostics},
|
nameres::diagnostics::{DefDiagnostic, DefDiagnostics},
|
||||||
src::HasChildSource,
|
|
||||||
src::HasSource,
|
|
||||||
trace::Trace,
|
trace::Trace,
|
||||||
tt::{Delimiter, DelimiterKind, Leaf, Subtree, TokenTree},
|
tt::{Delimiter, DelimiterKind, Leaf, Subtree, TokenTree},
|
||||||
type_ref::TypeRef,
|
type_ref::TypeRef,
|
||||||
visibility::RawVisibility,
|
visibility::RawVisibility,
|
||||||
EnumId, EnumVariantId, LocalFieldId, LocalModuleId, Lookup, StructId, UnionId, VariantId,
|
EnumId, EnumVariantId, LocalFieldId, LocalModuleId, Lookup, StructId, UnionId,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Note that we use `StructData` for unions as well!
|
/// Note that we use `StructData` for unions as well!
|
||||||
|
@ -387,46 +385,6 @@ impl VariantData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasChildSource<LocalFieldId> for VariantId {
|
|
||||||
type Value = Either<ast::TupleField, ast::RecordField>;
|
|
||||||
|
|
||||||
fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<LocalFieldId, Self::Value>> {
|
|
||||||
let item_tree;
|
|
||||||
let (src, fields, container) = match *self {
|
|
||||||
VariantId::EnumVariantId(it) => {
|
|
||||||
let lookup = it.lookup(db);
|
|
||||||
item_tree = lookup.id.item_tree(db);
|
|
||||||
(
|
|
||||||
lookup.source(db).map(|it| it.kind()),
|
|
||||||
&item_tree[lookup.id.value].fields,
|
|
||||||
lookup.parent.lookup(db).container,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
VariantId::StructId(it) => {
|
|
||||||
let lookup = it.lookup(db);
|
|
||||||
item_tree = lookup.id.item_tree(db);
|
|
||||||
(
|
|
||||||
lookup.source(db).map(|it| it.kind()),
|
|
||||||
&item_tree[lookup.id.value].fields,
|
|
||||||
lookup.container,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
VariantId::UnionId(it) => {
|
|
||||||
let lookup = it.lookup(db);
|
|
||||||
item_tree = lookup.id.item_tree(db);
|
|
||||||
(
|
|
||||||
lookup.source(db).map(|it| it.kind()),
|
|
||||||
&item_tree[lookup.id.value].fields,
|
|
||||||
lookup.container,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let mut trace = Trace::new_for_map();
|
|
||||||
lower_struct(db, &mut trace, &src, container.krate, &item_tree, fields);
|
|
||||||
src.with_value(trace.into_map())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum StructKind {
|
pub enum StructKind {
|
||||||
Tuple,
|
Tuple,
|
||||||
|
@ -434,7 +392,7 @@ pub enum StructKind {
|
||||||
Unit,
|
Unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_struct(
|
pub(crate) fn lower_struct(
|
||||||
db: &dyn DefDatabase,
|
db: &dyn DefDatabase,
|
||||||
trace: &mut Trace<FieldData, Either<ast::TupleField, ast::RecordField>>,
|
trace: &mut Trace<FieldData, Either<ast::TupleField, ast::RecordField>>,
|
||||||
ast: &InFile<ast::StructKind>,
|
ast: &InFile<ast::StructKind>,
|
||||||
|
|
|
@ -3,31 +3,27 @@
|
||||||
//! generic parameters. See also the `Generics` type and the `generics_of` query
|
//! generic parameters. See also the `Generics` type and the `generics_of` query
|
||||||
//! in rustc.
|
//! in rustc.
|
||||||
|
|
||||||
use base_db::FileId;
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
use hir_expand::{
|
use hir_expand::{
|
||||||
name::{AsName, Name},
|
name::{AsName, Name},
|
||||||
ExpandResult, HirFileId, InFile,
|
ExpandResult,
|
||||||
};
|
};
|
||||||
use intern::Interned;
|
use intern::Interned;
|
||||||
use la_arena::{Arena, ArenaMap, Idx};
|
use la_arena::{Arena, Idx};
|
||||||
use once_cell::unsync::Lazy;
|
use once_cell::unsync::Lazy;
|
||||||
use stdx::impl_from;
|
use stdx::impl_from;
|
||||||
use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds};
|
use syntax::ast::{self, HasGenericParams, HasName, HasTypeBounds};
|
||||||
use triomphe::Arc;
|
use triomphe::Arc;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
child_by_source::ChildBySource,
|
|
||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
dyn_map::{keys, DynMap},
|
|
||||||
expander::Expander,
|
expander::Expander,
|
||||||
item_tree::ItemTree,
|
item_tree::ItemTree,
|
||||||
lower::LowerCtx,
|
lower::LowerCtx,
|
||||||
nameres::{DefMap, MacroSubNs},
|
nameres::{DefMap, MacroSubNs},
|
||||||
src::{HasChildSource, HasSource},
|
|
||||||
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef},
|
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRef},
|
||||||
AdtId, ConstParamId, GenericDefId, HasModule, LifetimeParamId, LocalLifetimeParamId,
|
AdtId, ConstParamId, GenericDefId, HasModule, LocalTypeOrConstParamId, Lookup,
|
||||||
LocalTypeOrConstParamId, Lookup, TypeOrConstParamId, TypeParamId,
|
TypeOrConstParamId, TypeParamId,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Data about a generic type parameter (to a function, struct, impl, ...).
|
/// Data about a generic type parameter (to a function, struct, impl, ...).
|
||||||
|
@ -507,130 +503,3 @@ impl GenericParams {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file_id_and_params_of(
|
|
||||||
db: &dyn DefDatabase,
|
|
||||||
def: GenericDefId,
|
|
||||||
) -> (HirFileId, Option<ast::GenericParamList>) {
|
|
||||||
match def {
|
|
||||||
GenericDefId::FunctionId(it) => file_id_and_params_of_item_loc(db, it),
|
|
||||||
GenericDefId::TypeAliasId(it) => file_id_and_params_of_item_loc(db, it),
|
|
||||||
GenericDefId::ConstId(_) => (FileId::BOGUS.into(), None),
|
|
||||||
GenericDefId::AdtId(AdtId::StructId(it)) => file_id_and_params_of_item_loc(db, it),
|
|
||||||
GenericDefId::AdtId(AdtId::UnionId(it)) => file_id_and_params_of_item_loc(db, it),
|
|
||||||
GenericDefId::AdtId(AdtId::EnumId(it)) => file_id_and_params_of_item_loc(db, it),
|
|
||||||
GenericDefId::TraitId(it) => file_id_and_params_of_item_loc(db, it),
|
|
||||||
GenericDefId::TraitAliasId(it) => file_id_and_params_of_item_loc(db, it),
|
|
||||||
GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it),
|
|
||||||
// We won't be using this ID anyway
|
|
||||||
GenericDefId::EnumVariantId(_) => (FileId::BOGUS.into(), None),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn file_id_and_params_of_item_loc<Loc>(
|
|
||||||
db: &dyn DefDatabase,
|
|
||||||
def: impl for<'db> Lookup<Database<'db> = dyn DefDatabase + 'db, Data = Loc>,
|
|
||||||
) -> (HirFileId, Option<ast::GenericParamList>)
|
|
||||||
where
|
|
||||||
Loc: HasSource,
|
|
||||||
Loc::Value: HasGenericParams,
|
|
||||||
{
|
|
||||||
let src = def.lookup(db).source(db);
|
|
||||||
(src.file_id, src.value.generic_param_list())
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
|
|
||||||
type Value = Either<ast::TypeOrConstParam, ast::TraitOrAlias>;
|
|
||||||
fn child_source(
|
|
||||||
&self,
|
|
||||||
db: &dyn DefDatabase,
|
|
||||||
) -> InFile<ArenaMap<LocalTypeOrConstParamId, Self::Value>> {
|
|
||||||
let generic_params = db.generic_params(*self);
|
|
||||||
let mut idx_iter = generic_params.type_or_consts.iter().map(|(idx, _)| idx);
|
|
||||||
|
|
||||||
let (file_id, generic_params_list) = file_id_and_params_of(db, *self);
|
|
||||||
|
|
||||||
let mut params = ArenaMap::default();
|
|
||||||
|
|
||||||
// For traits and trait aliases the first type index is `Self`, we need to add it before
|
|
||||||
// the other params.
|
|
||||||
match *self {
|
|
||||||
GenericDefId::TraitId(id) => {
|
|
||||||
let trait_ref = id.lookup(db).source(db).value;
|
|
||||||
let idx = idx_iter.next().unwrap();
|
|
||||||
params.insert(idx, Either::Right(ast::TraitOrAlias::Trait(trait_ref)));
|
|
||||||
}
|
|
||||||
GenericDefId::TraitAliasId(id) => {
|
|
||||||
let alias = id.lookup(db).source(db).value;
|
|
||||||
let idx = idx_iter.next().unwrap();
|
|
||||||
params.insert(idx, Either::Right(ast::TraitOrAlias::TraitAlias(alias)));
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(generic_params_list) = generic_params_list {
|
|
||||||
for (idx, ast_param) in idx_iter.zip(generic_params_list.type_or_const_params()) {
|
|
||||||
params.insert(idx, Either::Left(ast_param));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InFile::new(file_id, params)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl HasChildSource<LocalLifetimeParamId> for GenericDefId {
|
|
||||||
type Value = ast::LifetimeParam;
|
|
||||||
fn child_source(
|
|
||||||
&self,
|
|
||||||
db: &dyn DefDatabase,
|
|
||||||
) -> InFile<ArenaMap<LocalLifetimeParamId, Self::Value>> {
|
|
||||||
let generic_params = db.generic_params(*self);
|
|
||||||
let idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx);
|
|
||||||
|
|
||||||
let (file_id, generic_params_list) = file_id_and_params_of(db, *self);
|
|
||||||
|
|
||||||
let mut params = ArenaMap::default();
|
|
||||||
|
|
||||||
if let Some(generic_params_list) = generic_params_list {
|
|
||||||
for (idx, ast_param) in idx_iter.zip(generic_params_list.lifetime_params()) {
|
|
||||||
params.insert(idx, ast_param);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InFile::new(file_id, params)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ChildBySource for GenericDefId {
|
|
||||||
fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
|
|
||||||
let (gfile_id, generic_params_list) = file_id_and_params_of(db, *self);
|
|
||||||
if gfile_id != file_id {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let generic_params = db.generic_params(*self);
|
|
||||||
let mut toc_idx_iter = generic_params.type_or_consts.iter().map(|(idx, _)| idx);
|
|
||||||
let lts_idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx);
|
|
||||||
|
|
||||||
// For traits the first type index is `Self`, skip it.
|
|
||||||
if let GenericDefId::TraitId(_) = *self {
|
|
||||||
toc_idx_iter.next().unwrap(); // advance_by(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(generic_params_list) = generic_params_list {
|
|
||||||
for (local_id, ast_param) in
|
|
||||||
toc_idx_iter.zip(generic_params_list.type_or_const_params())
|
|
||||||
{
|
|
||||||
let id = TypeOrConstParamId { parent: *self, local_id };
|
|
||||||
match ast_param {
|
|
||||||
ast::TypeOrConstParam::Type(a) => res[keys::TYPE_PARAM].insert(a, id),
|
|
||||||
ast::TypeOrConstParam::Const(a) => res[keys::CONST_PARAM].insert(a, id),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (local_id, ast_param) in lts_idx_iter.zip(generic_params_list.lifetime_params()) {
|
|
||||||
let id = LifetimeParamId { parent: *self, local_id };
|
|
||||||
res[keys::LIFETIME_PARAM].insert(ast_param, id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ use hir_expand::{
|
||||||
use item_tree::ExternBlock;
|
use item_tree::ExternBlock;
|
||||||
use la_arena::Idx;
|
use la_arena::Idx;
|
||||||
use nameres::DefMap;
|
use nameres::DefMap;
|
||||||
use span::Span;
|
use span::{FileId, Span};
|
||||||
use stdx::impl_from;
|
use stdx::impl_from;
|
||||||
use syntax::{ast, AstNode};
|
use syntax::{ast, AstNode};
|
||||||
|
|
||||||
|
@ -892,6 +892,39 @@ impl_from!(
|
||||||
for GenericDefId
|
for GenericDefId
|
||||||
);
|
);
|
||||||
|
|
||||||
|
impl GenericDefId {
|
||||||
|
fn file_id_and_params_of(
|
||||||
|
self,
|
||||||
|
db: &dyn DefDatabase,
|
||||||
|
) -> (HirFileId, Option<ast::GenericParamList>) {
|
||||||
|
fn file_id_and_params_of_item_loc<Loc>(
|
||||||
|
db: &dyn DefDatabase,
|
||||||
|
def: impl for<'db> Lookup<Database<'db> = dyn DefDatabase + 'db, Data = Loc>,
|
||||||
|
) -> (HirFileId, Option<ast::GenericParamList>)
|
||||||
|
where
|
||||||
|
Loc: src::HasSource,
|
||||||
|
Loc::Value: ast::HasGenericParams,
|
||||||
|
{
|
||||||
|
let src = def.lookup(db).source(db);
|
||||||
|
(src.file_id, ast::HasGenericParams::generic_param_list(&src.value))
|
||||||
|
}
|
||||||
|
|
||||||
|
match self {
|
||||||
|
GenericDefId::FunctionId(it) => file_id_and_params_of_item_loc(db, it),
|
||||||
|
GenericDefId::TypeAliasId(it) => file_id_and_params_of_item_loc(db, it),
|
||||||
|
GenericDefId::ConstId(_) => (FileId::BOGUS.into(), None),
|
||||||
|
GenericDefId::AdtId(AdtId::StructId(it)) => file_id_and_params_of_item_loc(db, it),
|
||||||
|
GenericDefId::AdtId(AdtId::UnionId(it)) => file_id_and_params_of_item_loc(db, it),
|
||||||
|
GenericDefId::AdtId(AdtId::EnumId(it)) => file_id_and_params_of_item_loc(db, it),
|
||||||
|
GenericDefId::TraitId(it) => file_id_and_params_of_item_loc(db, it),
|
||||||
|
GenericDefId::TraitAliasId(it) => file_id_and_params_of_item_loc(db, it),
|
||||||
|
GenericDefId::ImplId(it) => file_id_and_params_of_item_loc(db, it),
|
||||||
|
// We won't be using this ID anyway
|
||||||
|
GenericDefId::EnumVariantId(_) => (FileId::BOGUS.into(), None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<AssocItemId> for GenericDefId {
|
impl From<AssocItemId> for GenericDefId {
|
||||||
fn from(item: AssocItemId) -> Self {
|
fn from(item: AssocItemId) -> Self {
|
||||||
match item {
|
match item {
|
||||||
|
|
|
@ -27,9 +27,9 @@ use crate::{
|
||||||
visibility::{RawVisibility, Visibility},
|
visibility::{RawVisibility, Visibility},
|
||||||
AdtId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId,
|
AdtId, ConstId, ConstParamId, CrateRootModuleId, DefWithBodyId, EnumId, EnumVariantId,
|
||||||
ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId,
|
ExternBlockId, ExternCrateId, FunctionId, GenericDefId, GenericParamId, HasModule, ImplId,
|
||||||
ItemContainerId, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId, MacroRulesId,
|
ItemContainerId, ItemTreeLoc, LifetimeParamId, LocalModuleId, Lookup, Macro2Id, MacroId,
|
||||||
ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId,
|
MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId,
|
||||||
TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId,
|
TypeAliasId, TypeOrConstParamId, TypeOwnerId, TypeParamId, UseId, VariantId,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
|
@ -1014,13 +1014,13 @@ impl HasResolver for CrateRootModuleId {
|
||||||
|
|
||||||
impl HasResolver for TraitId {
|
impl HasResolver for TraitId {
|
||||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
|
lookup_resolver(db, self).push_generic_params_scope(db, self.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasResolver for TraitAliasId {
|
impl HasResolver for TraitAliasId {
|
||||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
|
lookup_resolver(db, self).push_generic_params_scope(db, self.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1036,25 +1036,25 @@ impl<T: Into<AdtId> + Copy> HasResolver for T {
|
||||||
|
|
||||||
impl HasResolver for FunctionId {
|
impl HasResolver for FunctionId {
|
||||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
|
lookup_resolver(db, self).push_generic_params_scope(db, self.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasResolver for ConstId {
|
impl HasResolver for ConstId {
|
||||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
self.lookup(db).container.resolver(db)
|
lookup_resolver(db, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasResolver for StaticId {
|
impl HasResolver for StaticId {
|
||||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
self.lookup(db).container.resolver(db)
|
lookup_resolver(db, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasResolver for TypeAliasId {
|
impl HasResolver for TypeAliasId {
|
||||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
self.lookup(db).container.resolver(db).push_generic_params_scope(db, self.into())
|
lookup_resolver(db, self).push_generic_params_scope(db, self.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1071,19 +1071,19 @@ impl HasResolver for ImplId {
|
||||||
impl HasResolver for ExternBlockId {
|
impl HasResolver for ExternBlockId {
|
||||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
// Same as parent's
|
// Same as parent's
|
||||||
self.lookup(db).container.resolver(db)
|
lookup_resolver(db, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasResolver for ExternCrateId {
|
impl HasResolver for ExternCrateId {
|
||||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
self.lookup(db).container.resolver(db)
|
lookup_resolver(db, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasResolver for UseId {
|
impl HasResolver for UseId {
|
||||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
self.lookup(db).container.resolver(db)
|
lookup_resolver(db, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1170,18 +1170,28 @@ impl HasResolver for MacroId {
|
||||||
|
|
||||||
impl HasResolver for Macro2Id {
|
impl HasResolver for Macro2Id {
|
||||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
self.lookup(db).container.resolver(db)
|
lookup_resolver(db, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasResolver for ProcMacroId {
|
impl HasResolver for ProcMacroId {
|
||||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
self.lookup(db).container.resolver(db)
|
lookup_resolver(db, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HasResolver for MacroRulesId {
|
impl HasResolver for MacroRulesId {
|
||||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
fn resolver(self, db: &dyn DefDatabase) -> Resolver {
|
||||||
self.lookup(db).container.resolver(db)
|
lookup_resolver(db, self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn lookup_resolver<'db>(
|
||||||
|
db: &(dyn DefDatabase + 'db),
|
||||||
|
lookup: impl Lookup<
|
||||||
|
Database<'db> = dyn DefDatabase + 'db,
|
||||||
|
Data = impl ItemTreeLoc<Container = impl HasResolver>,
|
||||||
|
>,
|
||||||
|
) -> Resolver {
|
||||||
|
lookup.lookup(db).container().resolver(db)
|
||||||
|
}
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
//! Utilities for mapping between hir IDs and the surface syntax.
|
//! Utilities for mapping between hir IDs and the surface syntax.
|
||||||
|
|
||||||
|
use either::Either;
|
||||||
use hir_expand::InFile;
|
use hir_expand::InFile;
|
||||||
use la_arena::ArenaMap;
|
use la_arena::ArenaMap;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
|
|
||||||
use crate::{db::DefDatabase, item_tree::ItemTreeNode, ItemTreeLoc, Lookup, UseId};
|
use crate::{
|
||||||
|
data::adt::lower_struct, db::DefDatabase, item_tree::ItemTreeNode, trace::Trace, GenericDefId,
|
||||||
|
ItemTreeLoc, LocalFieldId, LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup, UseId,
|
||||||
|
VariantId,
|
||||||
|
};
|
||||||
|
|
||||||
pub trait HasSource {
|
pub trait HasSource {
|
||||||
type Value;
|
type Value;
|
||||||
|
@ -49,3 +54,105 @@ impl HasChildSource<la_arena::Idx<ast::UseTree>> for UseId {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl HasChildSource<LocalTypeOrConstParamId> for GenericDefId {
|
||||||
|
type Value = Either<ast::TypeOrConstParam, ast::TraitOrAlias>;
|
||||||
|
fn child_source(
|
||||||
|
&self,
|
||||||
|
db: &dyn DefDatabase,
|
||||||
|
) -> InFile<ArenaMap<LocalTypeOrConstParamId, Self::Value>> {
|
||||||
|
let generic_params = db.generic_params(*self);
|
||||||
|
let mut idx_iter = generic_params.type_or_consts.iter().map(|(idx, _)| idx);
|
||||||
|
|
||||||
|
let (file_id, generic_params_list) = self.file_id_and_params_of(db);
|
||||||
|
|
||||||
|
let mut params = ArenaMap::default();
|
||||||
|
|
||||||
|
// For traits and trait aliases the first type index is `Self`, we need to add it before
|
||||||
|
// the other params.
|
||||||
|
match *self {
|
||||||
|
GenericDefId::TraitId(id) => {
|
||||||
|
let trait_ref = id.lookup(db).source(db).value;
|
||||||
|
let idx = idx_iter.next().unwrap();
|
||||||
|
params.insert(idx, Either::Right(ast::TraitOrAlias::Trait(trait_ref)));
|
||||||
|
}
|
||||||
|
GenericDefId::TraitAliasId(id) => {
|
||||||
|
let alias = id.lookup(db).source(db).value;
|
||||||
|
let idx = idx_iter.next().unwrap();
|
||||||
|
params.insert(idx, Either::Right(ast::TraitOrAlias::TraitAlias(alias)));
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(generic_params_list) = generic_params_list {
|
||||||
|
for (idx, ast_param) in idx_iter.zip(generic_params_list.type_or_const_params()) {
|
||||||
|
params.insert(idx, Either::Left(ast_param));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InFile::new(file_id, params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasChildSource<LocalLifetimeParamId> for GenericDefId {
|
||||||
|
type Value = ast::LifetimeParam;
|
||||||
|
fn child_source(
|
||||||
|
&self,
|
||||||
|
db: &dyn DefDatabase,
|
||||||
|
) -> InFile<ArenaMap<LocalLifetimeParamId, Self::Value>> {
|
||||||
|
let generic_params = db.generic_params(*self);
|
||||||
|
let idx_iter = generic_params.lifetimes.iter().map(|(idx, _)| idx);
|
||||||
|
|
||||||
|
let (file_id, generic_params_list) = self.file_id_and_params_of(db);
|
||||||
|
|
||||||
|
let mut params = ArenaMap::default();
|
||||||
|
|
||||||
|
if let Some(generic_params_list) = generic_params_list {
|
||||||
|
for (idx, ast_param) in idx_iter.zip(generic_params_list.lifetime_params()) {
|
||||||
|
params.insert(idx, ast_param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InFile::new(file_id, params)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HasChildSource<LocalFieldId> for VariantId {
|
||||||
|
type Value = Either<ast::TupleField, ast::RecordField>;
|
||||||
|
|
||||||
|
fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<LocalFieldId, Self::Value>> {
|
||||||
|
let item_tree;
|
||||||
|
let (src, fields, container) = match *self {
|
||||||
|
VariantId::EnumVariantId(it) => {
|
||||||
|
let lookup = it.lookup(db);
|
||||||
|
item_tree = lookup.id.item_tree(db);
|
||||||
|
(
|
||||||
|
lookup.source(db).map(|it| it.kind()),
|
||||||
|
&item_tree[lookup.id.value].fields,
|
||||||
|
lookup.parent.lookup(db).container,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
VariantId::StructId(it) => {
|
||||||
|
let lookup = it.lookup(db);
|
||||||
|
item_tree = lookup.id.item_tree(db);
|
||||||
|
(
|
||||||
|
lookup.source(db).map(|it| it.kind()),
|
||||||
|
&item_tree[lookup.id.value].fields,
|
||||||
|
lookup.container,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
VariantId::UnionId(it) => {
|
||||||
|
let lookup = it.lookup(db);
|
||||||
|
item_tree = lookup.id.item_tree(db);
|
||||||
|
(
|
||||||
|
lookup.source(db).map(|it| it.kind()),
|
||||||
|
&item_tree[lookup.id.value].fields,
|
||||||
|
lookup.container,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut trace = Trace::new_for_map();
|
||||||
|
lower_struct(db, &mut trace, &src, container.krate, &item_tree, fields);
|
||||||
|
src.with_value(trace.into_map())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
//! projections.
|
//! projections.
|
||||||
use la_arena::{Arena, ArenaMap, Idx, RawIdx};
|
use la_arena::{Arena, ArenaMap, Idx, RawIdx};
|
||||||
|
|
||||||
|
// FIXME: This isn't really used anymore, at least not in a way where it does anything useful.
|
||||||
|
// Check if we should get rid of this or make proper use of it instead.
|
||||||
pub(crate) struct Trace<T, V> {
|
pub(crate) struct Trace<T, V> {
|
||||||
arena: Option<Arena<T>>,
|
arena: Option<Arena<T>>,
|
||||||
map: Option<ArenaMap<Idx<T>, V>>,
|
map: Option<ArenaMap<Idx<T>, V>>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue