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
//! Shared operations on TypeScript types.
//!
//! This crate is used to reduce compile time.
#![feature(box_patterns)]
#![feature(box_syntax)]
#![feature(specialization)]
#![allow(incomplete_features)]
#![allow(clippy::needless_update)]

use stc_ts_ast_rnode::RTsLit;
use stc_ts_types::{LitType, Type, TypeElement, Union};
use swc_ecma_ast::TruePlusMinus;

pub mod bindings;
pub mod fix;

pub fn apply_mapped_flags(el: &mut TypeElement, optional: Option<TruePlusMinus>, readonly: Option<TruePlusMinus>) {
    if let Some(v) = optional {
        match el {
            TypeElement::Call(_) => {}
            TypeElement::Constructor(_) => {}
            TypeElement::Property(p) => match v {
                TruePlusMinus::True => {
                    p.optional = true;
                }
                TruePlusMinus::Plus => {
                    p.optional = true;
                }
                TruePlusMinus::Minus => {
                    p.optional = false;
                }
            },
            TypeElement::Method(m) => match v {
                TruePlusMinus::True => {
                    m.optional = true;
                }
                TruePlusMinus::Plus => {
                    m.optional = true;
                }
                TruePlusMinus::Minus => {
                    m.optional = false;
                }
            },
            TypeElement::Index(_) => {}
        }
    }

    if let Some(v) = readonly {
        match el {
            TypeElement::Call(_) => {}
            TypeElement::Constructor(_) => {}
            TypeElement::Property(p) => match v {
                TruePlusMinus::True => {
                    p.readonly = true;
                }
                TruePlusMinus::Plus => {
                    p.readonly = true;
                }
                TruePlusMinus::Minus => {
                    p.readonly = false;
                }
            },
            TypeElement::Index(_) => {}
            TypeElement::Method(m) => match v {
                TruePlusMinus::True => {
                    m.readonly = true;
                }
                TruePlusMinus::Plus => {
                    m.readonly = true;
                }
                TruePlusMinus::Minus => {
                    m.readonly = false;
                }
            },
        }
    }
}

pub fn is_str_lit_or_union(t: &Type) -> bool {
    match t.normalize() {
        Type::Lit(LitType { lit: RTsLit::Str(..), .. }) => true,
        Type::Union(Union { ref types, .. }) => types.iter().all(is_str_lit_or_union),
        _ => false,
    }
}