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
#![allow(incomplete_features)]
#![feature(specialization)]

use stc_ts_types::{Id, Mapped, Ref, Type};
use stc_visit::{Visit, VisitWith};

use crate::{cache_map::CacheMap, cache_mode::CacheMode, key::CacheKey};

pub mod cache_map;
pub mod cache_mode;
pub mod key;

/// TODO(kdy1): pub expand_cache: CacheMap<(RTsEntityName,
/// Option<TypeParamInstantiation>), Type, RevokeOnTypeDecl>,
#[derive(Debug, Default)]
pub struct TypeCache {
    pub expand_mapped: CacheMap<Mapped, Option<Type>, NoRefInKey>,

    /// Key should be [Type::Arc] of [Type::TypeLit].
    pub keyof_type_lit: CacheMap<Type, Type, NoRevoke>,
}

impl TypeCache {
    pub fn remove(&mut self, _key: &Id) {}
}

#[derive(Debug)]
pub struct NoRevoke {}

impl<K> CacheMode<K> for NoRevoke
where
    K: CacheKey,
{
    #[inline(always)]
    fn can_cache(_: &K) -> bool {
        true
    }
}

#[derive(Debug)]
pub struct NoRefInKey {}

impl<K> CacheMode<K> for NoRefInKey
where
    K: CacheKey + VisitWith<RefFinder>,
{
    fn can_cache(key: &K) -> bool {
        let mut v = RefFinder { found: false };
        key.visit_with(&mut v);
        !v.found
    }
}

pub struct RefFinder {
    found: bool,
}

impl Visit<Ref> for RefFinder {
    fn visit(&mut self, _: &Ref) {
        self.found = true;
    }
}