1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
use std::sync::Arc; use crate::{ ids::Lookup, ids::TypeAliasId, type_ref::{LocalTypeRefId, TypeRefBuilder, TypeRefMap, TypeRefSourceMap}, visibility::RawVisibility, DefDatabase, DiagnosticSink, FileId, HasVisibility, HirDatabase, Name, Visibility, }; use super::Module; use crate::expr::validator::TypeAliasValidator; use crate::resolve::HasResolver; use crate::ty::lower::LowerBatchResult; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct TypeAlias { pub(crate) id: TypeAliasId, } impl From<TypeAliasId> for TypeAlias { fn from(id: TypeAliasId) -> Self { TypeAlias { id } } } impl TypeAlias { pub fn module(self, db: &dyn HirDatabase) -> Module { Module { id: self.id.lookup(db.upcast()).module, } } pub fn file_id(self, db: &dyn HirDatabase) -> FileId { self.id.lookup(db.upcast()).id.file_id } pub fn data(self, db: &dyn DefDatabase) -> Arc<TypeAliasData> { db.type_alias_data(self.id) } pub fn name(self, db: &dyn HirDatabase) -> Name { self.data(db.upcast()).name.clone() } pub fn type_ref(self, db: &dyn HirDatabase) -> LocalTypeRefId { self.data(db.upcast()).type_ref_id } pub fn lower(self, db: &dyn HirDatabase) -> Arc<LowerBatchResult> { db.lower_type_alias(self) } pub fn diagnostics(self, db: &dyn HirDatabase, sink: &mut DiagnosticSink) { let data = self.data(db.upcast()); let lower = self.lower(db); lower.add_diagnostics(db, self.file_id(db), data.type_ref_source_map(), sink); let validator = TypeAliasValidator::new(self, db); validator.validate_target_type_existence(sink); } } #[derive(Debug, PartialEq, Eq)] pub struct TypeAliasData { pub name: Name, pub visibility: RawVisibility, pub type_ref_id: LocalTypeRefId, type_ref_map: TypeRefMap, type_ref_source_map: TypeRefSourceMap, } impl TypeAliasData { pub(crate) fn type_alias_data_query( db: &dyn DefDatabase, id: TypeAliasId, ) -> Arc<TypeAliasData> { let loc = id.lookup(db); let item_tree = db.item_tree(loc.id.file_id); let alias = &item_tree[loc.id.value]; let src = item_tree.source(db, loc.id.value); let mut type_ref_builder = TypeRefBuilder::default(); let type_ref_opt = src.type_ref(); let type_ref_id = type_ref_builder.alloc_from_node_opt(type_ref_opt.as_ref()); let (type_ref_map, type_ref_source_map) = type_ref_builder.finish(); Arc::new(TypeAliasData { name: alias.name.clone(), visibility: item_tree[alias.visibility].clone(), type_ref_id, type_ref_map, type_ref_source_map, }) } pub fn type_ref_source_map(&self) -> &TypeRefSourceMap { &self.type_ref_source_map } pub fn type_ref_map(&self) -> &TypeRefMap { &self.type_ref_map } } impl HasVisibility for TypeAlias { fn visibility(&self, db: &dyn HirDatabase) -> Visibility { self.data(db.upcast()) .visibility .resolve(db.upcast(), &self.id.resolver(db.upcast())) } }