Skip to main content

typescript_webidl/type_checker/
mod.rs

1/// WebIDL 类型检查模块
2use crate::types::WebIdlResult;
3use oak_idl::ast::{IdlItem, IdlRoot};
4
5/// WebIDL 类型检查器
6pub struct WebIdlTypeChecker {
7    /// WebIDL 解析结果
8    pub webidl_result: WebIdlResult,
9}
10
11impl WebIdlTypeChecker {
12    /// 创建新的 WebIDL 类型检查器
13    ///
14    /// # 参数
15    /// - `webidl_result`: WebIDL 解析结果
16    ///
17    /// # 返回值
18    /// - 新的 WebIDL 类型检查器
19    pub fn new(webidl_result: WebIdlResult) -> Self {
20        Self { webidl_result }
21    }
22
23    /// 检查 TypeScript 类型是否与 WebIDL 类型兼容
24    ///
25    /// # 参数
26    /// - `ts_type`: TypeScript 类型名称
27    /// - `webidl_type`: WebIDL 类型名称
28    ///
29    /// # 返回值
30    /// - `true` 如果类型兼容,`false` 否则
31    pub fn check_type_compatibility(&self, ts_type: &str, webidl_type: &str) -> bool {
32        // 基本类型映射
33        let type_map = vec![
34            ("string", "DOMString"),
35            ("string", "ByteString"),
36            ("string", "USVString"),
37            ("string", "string"),
38            ("number", "byte"),
39            ("number", "octet"),
40            ("number", "short"),
41            ("number", "unsigned short"),
42            ("number", "long"),
43            ("number", "unsigned long"),
44            ("number", "long long"),
45            ("number", "unsigned long long"),
46            ("number", "float"),
47            ("number", "unrestricted float"),
48            ("number", "double"),
49            ("number", "unrestricted double"),
50            ("number", "integer"),
51            ("number", "unsigned integer"),
52            ("boolean", "boolean"),
53            ("any", "any"),
54            ("undefined", "undefined"),
55            ("null", "null"),
56            ("void", "void"),
57        ];
58
59        // 检查直接映射
60        for (ts, webidl) in type_map {
61            if ts == ts_type && webidl == webidl_type {
62                return true;
63            }
64        }
65
66        // 检查复杂类型兼容性
67        if self.check_complex_type_compatibility(ts_type, webidl_type) {
68            return true;
69        }
70
71        // 检查用户定义的类型
72        self.check_user_defined_types(ts_type, webidl_type)
73    }
74
75    /// 检查复杂类型兼容性
76    ///
77    /// # 参数
78    /// - `ts_type`: TypeScript 类型名称
79    /// - `webidl_type`: WebIDL 类型名称
80    ///
81    /// # 返回值
82    /// - `true` 如果类型兼容,`false` 否则
83    fn check_complex_type_compatibility(&self, ts_type: &str, webidl_type: &str) -> bool {
84        // 检查数组类型
85        if ts_type.starts_with("Array<") && webidl_type.starts_with("sequence<") {
86            let ts_inner = &ts_type[6..ts_type.len() - 1];
87            let webidl_inner = &webidl_type[9..webidl_type.len() - 1];
88            return self.check_type_compatibility(ts_inner, webidl_inner);
89        }
90
91        // 检查 Promise 类型
92        if ts_type.starts_with("Promise<") && webidl_type.starts_with("Promise<") {
93            let ts_inner = &ts_type[8..ts_type.len() - 1];
94            let webidl_inner = &webidl_type[8..webidl_type.len() - 1];
95            return self.check_type_compatibility(ts_inner, webidl_inner);
96        }
97
98        // 检查联合类型
99        if ts_type.contains("|") && webidl_type.contains("or") {
100            let ts_types: Vec<&str> = ts_type.split("|").map(|t| t.trim()).collect();
101            let webidl_types: Vec<&str> = webidl_type.split("or").map(|t| t.trim()).collect();
102
103            if ts_types.len() != webidl_types.len() {
104                return false;
105            }
106
107            for (ts, webidl) in ts_types.iter().zip(webidl_types.iter()) {
108                if !self.check_type_compatibility(ts, webidl) {
109                    return false;
110                }
111            }
112
113            return true;
114        }
115
116        // 检查映射类型
117        if ts_type.starts_with("{") && ts_type.contains("[key:") && webidl_type.starts_with("record<") {
118            return true;
119        }
120
121        false
122    }
123
124    /// 检查用户定义的类型是否兼容
125    ///
126    /// # 参数
127    /// - `ts_type`: TypeScript 类型名称
128    /// - `webidl_type`: WebIDL 类型名称
129    ///
130    /// # 返回值
131    /// - `true` 如果类型兼容,`false` 否则
132    fn check_user_defined_types(&self, ts_type: &str, webidl_type: &str) -> bool {
133        // 简单的名称匹配
134        if ts_type == webidl_type {
135            return true;
136        }
137
138        // 检查类型别名
139        self.check_type_alias_compatibility(ts_type, webidl_type)
140    }
141
142    /// 检查类型别名兼容性
143    ///
144    /// # 参数
145    /// - `ts_type`: TypeScript 类型名称
146    /// - `webidl_type`: WebIDL 类型名称
147    ///
148    /// # 返回值
149    /// - `true` 如果类型兼容,`false` 否则
150    fn check_type_alias_compatibility(&self, ts_type: &str, webidl_type: &str) -> bool {
151        // 遍历所有类型定义,检查是否存在类型别名
152        for item in &self.webidl_result.root.items {
153            if let IdlItem::Typedef(typedef) = item {
154                if typedef.name == webidl_type {
155                    // 检查类型别名的底层类型
156                    return self.check_type_compatibility(ts_type, &typedef.type_name);
157                }
158            }
159        }
160
161        false
162    }
163
164    /// 验证 WebIDL 类型定义的完整性
165    ///
166    /// # 返回值
167    /// - `true` 如果类型定义完整,`false` 否则
168    pub fn validate_webidl_types(&self) -> bool {
169        // 检查是否至少有一个类型定义
170        if self.webidl_result.root.items.is_empty() {
171            return false;
172        }
173
174        // 检查所有类型定义的有效性
175        self.validate_items(&self.webidl_result.root)
176    }
177
178    /// 验证 WebIDL 项目的有效性
179    ///
180    /// # 参数
181    /// - `root`: WebIDL AST 根节点
182    ///
183    /// # 返回值
184    /// - `true` 如果所有项目有效,`false` 否则
185    fn validate_items(&self, root: &IdlRoot) -> bool {
186        for item in &root.items {
187            match item {
188                IdlItem::Interface(interface) => {
189                    // 检查接口名称是否为空
190                    if interface.name.is_empty() {
191                        return false;
192                    }
193                }
194                IdlItem::Struct(struct_) => {
195                    // 检查结构体名称是否为空
196                    if struct_.name.is_empty() {
197                        return false;
198                    }
199                }
200                IdlItem::Enum(enum_) => {
201                    // 检查枚举名称是否为空
202                    if enum_.name.is_empty() {
203                        return false;
204                    }
205                    // 检查枚举是否至少有一个变体
206                    if enum_.variants.is_empty() {
207                        return false;
208                    }
209                }
210                IdlItem::Typedef(typedef) => {
211                    // 检查类型别名名称是否为空
212                    if typedef.name.is_empty() {
213                        return false;
214                    }
215                }
216                IdlItem::Const(const_) => {
217                    // 检查常量名称是否为空
218                    if const_.name.is_empty() {
219                        return false;
220                    }
221                }
222                IdlItem::Module(module) => {
223                    // 检查模块名称是否为空
224                    if module.name.is_empty() {
225                        return false;
226                    }
227                    // 递归检查模块内的项目
228                    if !self.validate_items(&IdlRoot { items: module.items.clone() }) {
229                        return false;
230                    }
231                }
232                _ => {
233                    // 忽略未知类型
234                }
235            }
236        }
237
238        true
239    }
240}