mun_hir/code_model/
type_alias.rs

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