Skip to main content

nargo_ir/
lib.rs

1#![warn(missing_docs)]
2
3//! HXO IR 模块
4//!
5//! 提供 HXO 编译器的中间表示(IR)系统,支持 JavaScript 语言特性的表示、优化和验证。
6//!
7//! ## 主要功能
8//! - 支持多种 JavaScript 表达式和语句的表示
9//! - 提供访问者模式,方便遍历和处理 IR 结构
10//! - 支持常量折叠、死代码消除等优化规则
11//! - 提供类型检查、语义验证等验证功能
12//! - 支持模块级别的清理和优化
13
14use nargo_types::{Error, NargoValue, Result, Span};
15use serde::{Deserialize, Serialize};
16use std::{collections::HashMap, fmt};
17
18/// IR 错误类型
19///
20/// 表示在处理 IR 时可能遇到的各种错误情况
21#[derive(Debug, Clone, PartialEq)]
22pub enum IRError {
23    /// 无效的输入
24    ///
25    /// 当输入数据不符合预期格式时返回此错误
26    InvalidInput(String),
27    /// 结构不一致
28    ///
29    /// 当 IR 结构内部不一致时返回此错误
30    InconsistentStructure(String),
31    /// 超出大小限制
32    ///
33    /// 当 IR 元素大小超出预设限制时返回此错误
34    SizeLimitExceeded(String),
35    /// 循环引用
36    ///
37    /// 当 IR 中存在循环引用时返回此错误
38    CircularReference(String),
39    /// 无效的表达式
40    ///
41    /// 当表达式语法或语义无效时返回此错误
42    InvalidExpression(String),
43    /// 其他错误
44    ///
45    /// 其他未分类的错误
46    Other(String),
47}
48
49impl fmt::Display for IRError {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        match self {
52            IRError::InvalidInput(msg) => write!(f, "Invalid input: {}", msg),
53            IRError::InconsistentStructure(msg) => write!(f, "Inconsistent structure: {}", msg),
54            IRError::SizeLimitExceeded(msg) => write!(f, "Size limit exceeded: {}", msg),
55            IRError::CircularReference(msg) => write!(f, "Circular reference: {}", msg),
56            IRError::InvalidExpression(msg) => write!(f, "Invalid expression: {}", msg),
57            IRError::Other(msg) => write!(f, "{}", msg),
58        }
59    }
60}
61
62impl From<IRError> for Error {
63    fn from(err: IRError) -> Self {
64        Error::external_error("nargo-ir".to_string(), err.to_string(), Span::unknown())
65    }
66}
67
68/// 大小限制常量
69const MAX_STRING_LENGTH: usize = 1024 * 1024; // 1MB
70const MAX_ARRAY_LENGTH: usize = 10000;
71const MAX_OBJECT_SIZE: usize = 1000;
72const MAX_RECURSION_DEPTH: usize = 100;
73
74/// 代码中的 trivia 信息,包括空白和注释
75#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
76pub struct Trivia {
77    /// 前导空白
78    pub leading_whitespace: String,
79    /// 前导注释
80    pub leading_comments: Vec<Comment>,
81    /// 尾随注释
82    pub trailing_comments: Vec<Comment>,
83}
84
85impl Trivia {
86    /// 创建一个空的 Trivia
87    pub fn new() -> Self {
88        Self::default()
89    }
90
91    /// 检查 Trivia 是否为空
92    pub fn is_empty(&self) -> bool {
93        self.leading_whitespace.is_empty() && self.leading_comments.is_empty() && self.trailing_comments.is_empty()
94    }
95}
96
97/// 代码注释
98#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
99pub struct Comment {
100    /// 注释内容
101    pub content: String,
102    /// 是否为块注释
103    pub is_block: bool,
104    /// 注释的位置信息
105    pub span: Span,
106}
107
108impl Comment {
109    /// 创建一个新的注释
110    pub fn new(content: String, is_block: bool, span: Span) -> Self {
111        Self { content, is_block, span }
112    }
113
114    /// 检查注释是否为空
115    pub fn is_empty(&self) -> bool {
116        self.content.trim().is_empty()
117    }
118}
119
120/// JavaScript 表达式
121#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
122pub enum JsExpr {
123    /// 标识符
124    Identifier(String, #[serde(default)] Span, #[serde(default)] Trivia),
125    /// 字面量
126    Literal(NargoValue, #[serde(default)] Span, #[serde(default)] Trivia),
127    /// 一元表达式
128    Unary {
129        /// 操作符
130        op: String,
131        /// 参数
132        argument: Box<JsExpr>,
133        /// 位置信息
134        #[serde(default)]
135        span: Span,
136        /// Trivia 信息
137        #[serde(default)]
138        trivia: Trivia,
139    },
140    /// 二元表达式
141    Binary {
142        /// 左操作数
143        left: Box<JsExpr>,
144        /// 操作符
145        op: String,
146        /// 右操作数
147        right: Box<JsExpr>,
148        /// 位置信息
149        #[serde(default)]
150        span: Span,
151        /// Trivia 信息
152        #[serde(default)]
153        trivia: Trivia,
154    },
155    /// 函数调用
156    Call {
157        /// 调用目标
158        callee: Box<JsExpr>,
159        /// 参数列表
160        args: Vec<JsExpr>,
161        /// 位置信息
162        #[serde(default)]
163        span: Span,
164        /// Trivia 信息
165        #[serde(default)]
166        trivia: Trivia,
167    },
168    /// 成员访问
169    Member {
170        /// 对象
171        object: Box<JsExpr>,
172        /// 属性
173        property: Box<JsExpr>,
174        /// 是否为计算属性
175        computed: bool,
176        /// 位置信息
177        #[serde(default)]
178        span: Span,
179        /// Trivia 信息
180        #[serde(default)]
181        trivia: Trivia,
182    },
183    /// 可选链成员访问
184    OptionalMember {
185        /// 对象
186        object: Box<JsExpr>,
187        /// 属性
188        property: Box<JsExpr>,
189        /// 是否为计算属性
190        computed: bool,
191        /// 位置信息
192        #[serde(default)]
193        span: Span,
194        /// Trivia 信息
195        #[serde(default)]
196        trivia: Trivia,
197    },
198    /// 可选链函数调用
199    OptionalCall {
200        /// 调用目标
201        callee: Box<JsExpr>,
202        /// 参数列表
203        args: Vec<JsExpr>,
204        /// 位置信息
205        #[serde(default)]
206        span: Span,
207        /// Trivia 信息
208        #[serde(default)]
209        trivia: Trivia,
210    },
211    /// 空值合并表达式
212    NullishCoalescing {
213        /// 左操作数
214        left: Box<JsExpr>,
215        /// 右操作数
216        right: Box<JsExpr>,
217        /// 位置信息
218        #[serde(default)]
219        span: Span,
220        /// Trivia 信息
221        #[serde(default)]
222        trivia: Trivia,
223    },
224    /// 逻辑赋值表达式
225    LogicalAssignment {
226        /// 操作符
227        op: String,
228        /// 左操作数
229        left: Box<JsExpr>,
230        /// 右操作数
231        right: Box<JsExpr>,
232        /// 位置信息
233        #[serde(default)]
234        span: Span,
235        /// Trivia 信息
236        #[serde(default)]
237        trivia: Trivia,
238    },
239    /// 数组字面量
240    Array(Vec<JsExpr>, #[serde(default)] Span, #[serde(default)] Trivia),
241    /// 对象字面量
242    Object(HashMap<String, JsExpr>, #[serde(default)] Span, #[serde(default)] Trivia),
243    /// 箭头函数
244    ArrowFunction {
245        /// 参数列表
246        params: Vec<String>,
247        /// 函数体
248        body: Box<JsExpr>,
249        /// 位置信息
250        #[serde(default)]
251        span: Span,
252        /// Trivia 信息
253        #[serde(default)]
254        trivia: Trivia,
255    },
256    /// TSE 元素
257    TseElement {
258        /// 标签名
259        tag: String,
260        /// 属性列表
261        attributes: Vec<TseAttribute>,
262        /// 子元素
263        children: Vec<JsExpr>,
264        /// 位置信息
265        #[serde(default)]
266        span: Span,
267        /// Trivia 信息
268        #[serde(default)]
269        trivia: Trivia,
270    },
271    /// 条件表达式
272    Conditional {
273        /// 条件
274        test: Box<JsExpr>,
275        /// 真分支
276        consequent: Box<JsExpr>,
277        /// 假分支
278        alternate: Box<JsExpr>,
279        /// 位置信息
280        #[serde(default)]
281        span: Span,
282        /// Trivia 信息
283        #[serde(default)]
284        trivia: Trivia,
285    },
286    /// 模板字面量
287    TemplateLiteral {
288        /// 模板字符串片段
289        quasis: Vec<String>,
290        /// 表达式
291        expressions: Vec<JsExpr>,
292        /// 位置信息
293        #[serde(default)]
294        span: Span,
295        /// Trivia 信息
296        #[serde(default)]
297        trivia: Trivia,
298    },
299    /// 展开表达式
300    Spread(Box<JsExpr>, #[serde(default)] Span, #[serde(default)] Trivia),
301    /// 类型测试表达式
302    TypeOf(Box<JsExpr>, #[serde(default)] Span, #[serde(default)] Trivia),
303    /// 实例测试表达式
304    InstanceOf {
305        /// 左操作数
306        left: Box<JsExpr>,
307        /// 右操作数
308        right: Box<JsExpr>,
309        /// 位置信息
310        #[serde(default)]
311        span: Span,
312        /// Trivia 信息
313        #[serde(default)]
314        trivia: Trivia,
315    },
316    /// 其他表达式
317    Other(String, #[serde(default)] Span, #[serde(default)] Trivia),
318}
319
320impl JsExpr {
321    /// 获取表达式的位置信息
322    pub fn span(&self) -> Span {
323        match self {
324            JsExpr::Identifier(_, span, _) => *span,
325            JsExpr::Literal(_, span, _) => *span,
326            JsExpr::Unary { span, .. } => *span,
327            JsExpr::Binary { span, .. } => *span,
328            JsExpr::Call { span, .. } => *span,
329            JsExpr::Member { span, .. } => *span,
330            JsExpr::OptionalMember { span, .. } => *span,
331            JsExpr::OptionalCall { span, .. } => *span,
332            JsExpr::NullishCoalescing { span, .. } => *span,
333            JsExpr::LogicalAssignment { span, .. } => *span,
334            JsExpr::Array(_, span, _) => *span,
335            JsExpr::Object(_, span, _) => *span,
336            JsExpr::ArrowFunction { span, .. } => *span,
337            JsExpr::TseElement { span, .. } => *span,
338            JsExpr::Conditional { span, .. } => *span,
339            JsExpr::TemplateLiteral { span, .. } => *span,
340            JsExpr::Spread(_, span, _) => *span,
341            JsExpr::TypeOf(_, span, _) => *span,
342            JsExpr::InstanceOf { span, .. } => *span,
343            JsExpr::Other(_, span, _) => *span,
344        }
345    }
346
347    /// 获取表达式的 trivia 信息
348    pub fn trivia(&self) -> &Trivia {
349        match self {
350            JsExpr::Identifier(_, _, t) => t,
351            JsExpr::Literal(_, _, t) => t,
352            JsExpr::Unary { trivia, .. } => trivia,
353            JsExpr::Binary { trivia, .. } => trivia,
354            JsExpr::Call { trivia, .. } => trivia,
355            JsExpr::Member { trivia, .. } => trivia,
356            JsExpr::OptionalMember { trivia, .. } => trivia,
357            JsExpr::OptionalCall { trivia, .. } => trivia,
358            JsExpr::NullishCoalescing { trivia, .. } => trivia,
359            JsExpr::LogicalAssignment { trivia, .. } => trivia,
360            JsExpr::Array(_, _, t) => t,
361            JsExpr::Object(_, _, t) => t,
362            JsExpr::ArrowFunction { trivia, .. } => trivia,
363            JsExpr::TseElement { trivia, .. } => trivia,
364            JsExpr::Conditional { trivia, .. } => trivia,
365            JsExpr::TemplateLiteral { trivia, .. } => trivia,
366            JsExpr::Spread(_, _, t) => t,
367            JsExpr::TypeOf(_, _, t) => t,
368            JsExpr::InstanceOf { trivia, .. } => trivia,
369            JsExpr::Other(_, _, t) => t,
370        }
371    }
372
373    /// 验证表达式的有效性
374    pub fn validate(&self, depth: usize) -> Result<()> {
375        if depth > MAX_RECURSION_DEPTH {
376            return Err(IRError::CircularReference("Expression recursion depth exceeded".to_string()).into());
377        }
378
379        match self {
380            JsExpr::Identifier(id, _, _) => {
381                if id.len() > MAX_STRING_LENGTH {
382                    return Err(IRError::SizeLimitExceeded("Identifier length exceeded".to_string()).into());
383                }
384                Ok(())
385            }
386            JsExpr::Literal(value, _, _) => value.validate(depth + 1),
387            JsExpr::Unary { argument, .. } => argument.validate(depth + 1),
388            JsExpr::Binary { left, right, .. } => {
389                left.validate(depth + 1)?;
390                right.validate(depth + 1)
391            }
392            JsExpr::Call { callee, args, .. } => {
393                callee.validate(depth + 1)?;
394                if args.len() > MAX_ARRAY_LENGTH {
395                    return Err(IRError::SizeLimitExceeded("Call arguments length exceeded".to_string()).into());
396                }
397                for arg in args {
398                    arg.validate(depth + 1)?;
399                }
400                Ok(())
401            }
402            JsExpr::Member { object, property, .. } => {
403                object.validate(depth + 1)?;
404                property.validate(depth + 1)
405            }
406            JsExpr::OptionalMember { object, property, .. } => {
407                object.validate(depth + 1)?;
408                property.validate(depth + 1)
409            }
410            JsExpr::OptionalCall { callee, args, .. } => {
411                callee.validate(depth + 1)?;
412                if args.len() > MAX_ARRAY_LENGTH {
413                    return Err(IRError::SizeLimitExceeded("Optional call arguments length exceeded".to_string()).into());
414                }
415                for arg in args {
416                    arg.validate(depth + 1)?;
417                }
418                Ok(())
419            }
420            JsExpr::NullishCoalescing { left, right, .. } => {
421                left.validate(depth + 1)?;
422                right.validate(depth + 1)
423            }
424            JsExpr::LogicalAssignment { op, left, right, .. } => {
425                if op.len() > MAX_STRING_LENGTH {
426                    return Err(IRError::SizeLimitExceeded("Logical assignment operator length exceeded".to_string()).into());
427                }
428                left.validate(depth + 1)?;
429                right.validate(depth + 1)
430            }
431            JsExpr::Array(items, _, _) => {
432                if items.len() > MAX_ARRAY_LENGTH {
433                    return Err(IRError::SizeLimitExceeded("Array length exceeded".to_string()).into());
434                }
435                for item in items {
436                    item.validate(depth + 1)?;
437                }
438                Ok(())
439            }
440            JsExpr::Object(props, _, _) => {
441                if props.len() > MAX_OBJECT_SIZE {
442                    return Err(IRError::SizeLimitExceeded("Object size exceeded".to_string()).into());
443                }
444                for (key, value) in props {
445                    if key.len() > MAX_STRING_LENGTH {
446                        return Err(IRError::SizeLimitExceeded("Object key length exceeded".to_string()).into());
447                    }
448                    value.validate(depth + 1)?;
449                }
450                Ok(())
451            }
452            JsExpr::ArrowFunction { params, body, .. } => {
453                if params.len() > MAX_ARRAY_LENGTH {
454                    return Err(IRError::SizeLimitExceeded("Arrow function parameters length exceeded".to_string()).into());
455                }
456                for param in params {
457                    if param.len() > MAX_STRING_LENGTH {
458                        return Err(IRError::SizeLimitExceeded("Parameter name length exceeded".to_string()).into());
459                    }
460                }
461                body.validate(depth + 1)
462            }
463            JsExpr::TseElement { tag, attributes, children, .. } => {
464                if tag.len() > MAX_STRING_LENGTH {
465                    return Err(IRError::SizeLimitExceeded("TSE element tag length exceeded".to_string()).into());
466                }
467                if attributes.len() > MAX_ARRAY_LENGTH {
468                    return Err(IRError::SizeLimitExceeded("TSE element attributes length exceeded".to_string()).into());
469                }
470                for attr in attributes {
471                    attr.validate(depth + 1)?;
472                }
473                if children.len() > MAX_ARRAY_LENGTH {
474                    return Err(IRError::SizeLimitExceeded("TSE element children length exceeded".to_string()).into());
475                }
476                for child in children {
477                    child.validate(depth + 1)?;
478                }
479                Ok(())
480            }
481            JsExpr::Conditional { test, consequent, alternate, .. } => {
482                test.validate(depth + 1)?;
483                consequent.validate(depth + 1)?;
484                alternate.validate(depth + 1)
485            }
486            JsExpr::TemplateLiteral { quasis, expressions, .. } => {
487                if quasis.len() > MAX_ARRAY_LENGTH {
488                    return Err(IRError::SizeLimitExceeded("Template literal quasis length exceeded".to_string()).into());
489                }
490                for quasi in quasis {
491                    if quasi.len() > MAX_STRING_LENGTH {
492                        return Err(IRError::SizeLimitExceeded("Template literal quasi length exceeded".to_string()).into());
493                    }
494                }
495                if expressions.len() > MAX_ARRAY_LENGTH {
496                    return Err(IRError::SizeLimitExceeded("Template literal expressions length exceeded".to_string()).into());
497                }
498                for expr in expressions {
499                    expr.validate(depth + 1)?;
500                }
501                Ok(())
502            }
503            JsExpr::Spread(expr, _, _) => expr.validate(depth + 1),
504            JsExpr::TypeOf(expr, _, _) => expr.validate(depth + 1),
505            JsExpr::InstanceOf { left, right, .. } => {
506                left.validate(depth + 1)?;
507                right.validate(depth + 1)
508            }
509            JsExpr::Other(code, _, _) => {
510                if code.len() > MAX_STRING_LENGTH {
511                    return Err(IRError::SizeLimitExceeded("Other expression code length exceeded".to_string()).into());
512                }
513                Ok(())
514            }
515        }
516    }
517
518    /// 优化表达式
519    pub fn optimize(&mut self) {
520        optimizer::ExprOptimizer::optimize(self);
521    }
522
523    /// 检查表达式是否为常量
524    pub fn is_constant(&self) -> bool {
525        match self {
526            JsExpr::Literal(_, _, _) => true,
527            JsExpr::Unary { argument, .. } => argument.is_constant(),
528            JsExpr::Binary { left, right, .. } => left.is_constant() && right.is_constant(),
529            _ => false,
530        }
531    }
532}
533
534/// TSE 属性
535#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
536pub struct TseAttribute {
537    /// 属性名
538    pub name: String,
539    /// 属性值
540    pub value: Option<JsExpr>,
541    /// 是否为指令
542    pub is_directive: bool,
543    /// 位置信息
544    #[serde(default)]
545    pub span: Span,
546    /// Trivia 信息
547    #[serde(default)]
548    pub trivia: Trivia,
549}
550
551impl TseAttribute {
552    /// 验证 TSE 属性的有效性
553    pub fn validate(&self, depth: usize) -> Result<()> {
554        if self.name.len() > MAX_STRING_LENGTH {
555            return Err(IRError::SizeLimitExceeded("TSE attribute name length exceeded".to_string()).into());
556        }
557        if let Some(value) = &self.value {
558            value.validate(depth + 1)?;
559        }
560        Ok(())
561    }
562}
563
564/// JavaScript 语句
565#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
566pub enum JsStmt {
567    /// 表达式语句
568    Expr(JsExpr, #[serde(default)] Span, #[serde(default)] Trivia),
569    /// 变量声明
570    VariableDecl {
571        /// 声明类型(var, let, const)
572        kind: String,
573        /// 变量名
574        id: String,
575        /// 初始值
576        init: Option<JsExpr>,
577        /// 位置信息
578        #[serde(default)]
579        span: Span,
580        /// Trivia 信息
581        #[serde(default)]
582        trivia: Trivia,
583    },
584    /// 导入语句
585    Import {
586        /// 导入源
587        source: String,
588        /// 导入说明符
589        specifiers: Vec<String>,
590        /// 位置信息
591        #[serde(default)]
592        span: Span,
593        /// Trivia 信息
594        #[serde(default)]
595        trivia: Trivia,
596    },
597    /// 导出语句
598    Export {
599        /// 导出声明
600        declaration: Box<JsStmt>,
601        /// 位置信息
602        #[serde(default)]
603        span: Span,
604        /// Trivia 信息
605        #[serde(default)]
606        trivia: Trivia,
607    },
608    /// 导出所有
609    ExportAll {
610        /// 导出源
611        source: String,
612        /// 位置信息
613        #[serde(default)]
614        span: Span,
615        /// Trivia 信息
616        #[serde(default)]
617        trivia: Trivia,
618    },
619    /// 导出命名
620    ExportNamed {
621        /// 导出源
622        source: Option<String>,
623        /// 导出说明符
624        specifiers: Vec<String>,
625        /// 位置信息
626        #[serde(default)]
627        span: Span,
628        /// Trivia 信息
629        #[serde(default)]
630        trivia: Trivia,
631    },
632    /// 函数声明
633    FunctionDecl {
634        /// 函数名
635        id: String,
636        /// 参数列表
637        params: Vec<String>,
638        /// 函数体
639        body: Vec<JsStmt>,
640        /// 是否为异步函数
641        #[serde(default)]
642        is_async: bool,
643        /// 位置信息
644        #[serde(default)]
645        span: Span,
646        /// Trivia 信息
647        #[serde(default)]
648        trivia: Trivia,
649    },
650    /// 返回语句
651    Return(Option<JsExpr>, #[serde(default)] Span, #[serde(default)] Trivia),
652    /// if 语句
653    If {
654        /// 条件
655        test: JsExpr,
656        /// 真分支
657        consequent: Box<JsStmt>,
658        /// 假分支
659        alternate: Option<Box<JsStmt>>,
660        /// 位置信息
661        #[serde(default)]
662        span: Span,
663        /// Trivia 信息
664        #[serde(default)]
665        trivia: Trivia,
666    },
667    /// while 语句
668    While {
669        /// 条件
670        test: JsExpr,
671        /// 循环体
672        body: Box<JsStmt>,
673        /// 位置信息
674        #[serde(default)]
675        span: Span,
676        /// Trivia 信息
677        #[serde(default)]
678        trivia: Trivia,
679    },
680    /// for 语句
681    For {
682        /// 初始化
683        init: Option<Box<JsStmt>>,
684        /// 条件
685        test: Option<JsExpr>,
686        /// 更新
687        update: Option<JsExpr>,
688        /// 循环体
689        body: Box<JsStmt>,
690        /// 位置信息
691        #[serde(default)]
692        span: Span,
693        /// Trivia 信息
694        #[serde(default)]
695        trivia: Trivia,
696    },
697    /// for-in 语句
698    ForIn {
699        /// 变量
700        left: Box<JsStmt>,
701        /// 表达式
702        right: JsExpr,
703        /// 循环体
704        body: Box<JsStmt>,
705        /// 位置信息
706        #[serde(default)]
707        span: Span,
708        /// Trivia 信息
709        #[serde(default)]
710        trivia: Trivia,
711    },
712    /// for-of 语句
713    ForOf {
714        /// 变量
715        left: Box<JsStmt>,
716        /// 表达式
717        right: JsExpr,
718        /// 循环体
719        body: Box<JsStmt>,
720        /// 位置信息
721        #[serde(default)]
722        span: Span,
723        /// Trivia 信息
724        #[serde(default)]
725        trivia: Trivia,
726    },
727    /// try/catch 语句
728    Try {
729        /// try 块
730        block: Box<JsStmt>,
731        /// catch 块
732        handler: Option<(String, Box<JsStmt>)>,
733        /// finally 块
734        finalizer: Option<Box<JsStmt>>,
735        /// 位置信息
736        #[serde(default)]
737        span: Span,
738        /// Trivia 信息
739        #[serde(default)]
740        trivia: Trivia,
741    },
742    /// switch 语句
743    Switch {
744        /// 表达式
745        discriminant: JsExpr,
746        /// 分支
747        cases: Vec<(Option<JsExpr>, Vec<JsStmt>)>,
748        /// 位置信息
749        #[serde(default)]
750        span: Span,
751        /// Trivia 信息
752        #[serde(default)]
753        trivia: Trivia,
754    },
755    /// throw 语句
756    Throw(JsExpr, #[serde(default)] Span, #[serde(default)] Trivia),
757    /// 块语句
758    Block(Vec<JsStmt>, #[serde(default)] Span, #[serde(default)] Trivia),
759    /// break 语句
760    Break(#[serde(default)] Span, #[serde(default)] Trivia),
761    /// continue 语句
762    Continue(#[serde(default)] Span, #[serde(default)] Trivia),
763    /// 其他语句
764    Other(String, #[serde(default)] Span, #[serde(default)] Trivia),
765}
766
767impl JsStmt {
768    /// 获取语句的位置信息
769    pub fn span(&self) -> Span {
770        match self {
771            JsStmt::Expr(_, span, _) => *span,
772            JsStmt::VariableDecl { span, .. } => *span,
773            JsStmt::Import { span, .. } => *span,
774            JsStmt::Export { span, .. } => *span,
775            JsStmt::ExportAll { span, .. } => *span,
776            JsStmt::ExportNamed { span, .. } => *span,
777            JsStmt::FunctionDecl { span, .. } => *span,
778            JsStmt::Return(_, span, _) => *span,
779            JsStmt::If { span, .. } => *span,
780            JsStmt::While { span, .. } => *span,
781            JsStmt::For { span, .. } => *span,
782            JsStmt::ForIn { span, .. } => *span,
783            JsStmt::ForOf { span, .. } => *span,
784            JsStmt::Try { span, .. } => *span,
785            JsStmt::Switch { span, .. } => *span,
786            JsStmt::Throw(_, span, _) => *span,
787            JsStmt::Block(_, span, _) => *span,
788            JsStmt::Break(span, _) => *span,
789            JsStmt::Continue(span, _) => *span,
790            JsStmt::Other(_, span, _) => *span,
791        }
792    }
793
794    /// 获取语句的 trivia 信息
795    pub fn trivia(&self) -> &Trivia {
796        match self {
797            JsStmt::Expr(_, _, t) => t,
798            JsStmt::VariableDecl { trivia, .. } => trivia,
799            JsStmt::Import { trivia, .. } => trivia,
800            JsStmt::Export { trivia, .. } => trivia,
801            JsStmt::ExportAll { trivia, .. } => trivia,
802            JsStmt::ExportNamed { trivia, .. } => trivia,
803            JsStmt::FunctionDecl { trivia, .. } => trivia,
804            JsStmt::Return(_, _, t) => t,
805            JsStmt::If { trivia, .. } => trivia,
806            JsStmt::While { trivia, .. } => trivia,
807            JsStmt::For { trivia, .. } => trivia,
808            JsStmt::ForIn { trivia, .. } => trivia,
809            JsStmt::ForOf { trivia, .. } => trivia,
810            JsStmt::Try { trivia, .. } => trivia,
811            JsStmt::Switch { trivia, .. } => trivia,
812            JsStmt::Throw(_, _, t) => t,
813            JsStmt::Block(_, _, t) => t,
814            JsStmt::Break(_, t) => t,
815            JsStmt::Continue(_, t) => t,
816            JsStmt::Other(_, _, t) => t,
817        }
818    }
819
820    /// 验证语句的有效性
821    pub fn validate(&self, depth: usize) -> Result<()> {
822        if depth > MAX_RECURSION_DEPTH {
823            return Err(IRError::CircularReference("Statement recursion depth exceeded".to_string()).into());
824        }
825
826        match self {
827            JsStmt::Expr(expr, _, _) => expr.validate(depth + 1),
828            JsStmt::VariableDecl { id, init, .. } => {
829                if id.len() > MAX_STRING_LENGTH {
830                    return Err(IRError::SizeLimitExceeded("Variable name length exceeded".to_string()).into());
831                }
832                if let Some(init_expr) = init {
833                    init_expr.validate(depth + 1)?;
834                }
835                Ok(())
836            }
837            JsStmt::Import { source, specifiers, .. } => {
838                if source.len() > MAX_STRING_LENGTH {
839                    return Err(IRError::SizeLimitExceeded("Import source length exceeded".to_string()).into());
840                }
841                if specifiers.len() > MAX_ARRAY_LENGTH {
842                    return Err(IRError::SizeLimitExceeded("Import specifiers length exceeded".to_string()).into());
843                }
844                for specifier in specifiers {
845                    if specifier.len() > MAX_STRING_LENGTH {
846                        return Err(IRError::SizeLimitExceeded("Import specifier length exceeded".to_string()).into());
847                    }
848                }
849                Ok(())
850            }
851            JsStmt::Export { declaration, .. } => declaration.validate(depth + 1),
852            JsStmt::ExportAll { source, .. } => {
853                if source.len() > MAX_STRING_LENGTH {
854                    return Err(IRError::SizeLimitExceeded("Export all source length exceeded".to_string()).into());
855                }
856                Ok(())
857            }
858            JsStmt::ExportNamed { source, specifiers, .. } => {
859                if let Some(source_str) = source {
860                    if source_str.len() > MAX_STRING_LENGTH {
861                        return Err(IRError::SizeLimitExceeded("Export named source length exceeded".to_string()).into());
862                    }
863                }
864                if specifiers.len() > MAX_ARRAY_LENGTH {
865                    return Err(IRError::SizeLimitExceeded("Export named specifiers length exceeded".to_string()).into());
866                }
867                for specifier in specifiers {
868                    if specifier.len() > MAX_STRING_LENGTH {
869                        return Err(IRError::SizeLimitExceeded("Export specifier length exceeded".to_string()).into());
870                    }
871                }
872                Ok(())
873            }
874            JsStmt::FunctionDecl { id, params, body, .. } => {
875                if id.len() > MAX_STRING_LENGTH {
876                    return Err(IRError::SizeLimitExceeded("Function name length exceeded".to_string()).into());
877                }
878                if params.len() > MAX_ARRAY_LENGTH {
879                    return Err(IRError::SizeLimitExceeded("Function parameters length exceeded".to_string()).into());
880                }
881                for param in params {
882                    if param.len() > MAX_STRING_LENGTH {
883                        return Err(IRError::SizeLimitExceeded("Parameter name length exceeded".to_string()).into());
884                    }
885                }
886                if body.len() > MAX_ARRAY_LENGTH {
887                    return Err(IRError::SizeLimitExceeded("Function body length exceeded".to_string()).into());
888                }
889                for stmt in body {
890                    stmt.validate(depth + 1)?;
891                }
892                Ok(())
893            }
894            JsStmt::Return(expr, _, _) => {
895                if let Some(expr) = expr {
896                    expr.validate(depth + 1)?;
897                }
898                Ok(())
899            }
900            JsStmt::If { test, consequent, alternate, .. } => {
901                test.validate(depth + 1)?;
902                consequent.validate(depth + 1)?;
903                if let Some(alt) = alternate {
904                    alt.validate(depth + 1)?;
905                }
906                Ok(())
907            }
908            JsStmt::While { test, body, .. } => {
909                test.validate(depth + 1)?;
910                body.validate(depth + 1)
911            }
912            JsStmt::For { init, test, update, body, .. } => {
913                if let Some(init_stmt) = init {
914                    init_stmt.validate(depth + 1)?;
915                }
916                if let Some(test_expr) = test {
917                    test_expr.validate(depth + 1)?;
918                }
919                if let Some(update_expr) = update {
920                    update_expr.validate(depth + 1)?;
921                }
922                body.validate(depth + 1)
923            }
924            JsStmt::ForIn { left, right, body, .. } => {
925                left.validate(depth + 1)?;
926                right.validate(depth + 1)?;
927                body.validate(depth + 1)
928            }
929            JsStmt::ForOf { left, right, body, .. } => {
930                left.validate(depth + 1)?;
931                right.validate(depth + 1)?;
932                body.validate(depth + 1)
933            }
934            JsStmt::Try { block, handler, finalizer, .. } => {
935                block.validate(depth + 1)?;
936                if let Some((catch_id, catch_body)) = handler {
937                    if catch_id.len() > MAX_STRING_LENGTH {
938                        return Err(IRError::SizeLimitExceeded("Catch parameter name length exceeded".to_string()).into());
939                    }
940                    catch_body.validate(depth + 1)?;
941                }
942                if let Some(finally_body) = finalizer {
943                    finally_body.validate(depth + 1)?;
944                }
945                Ok(())
946            }
947            JsStmt::Switch { discriminant, cases, .. } => {
948                discriminant.validate(depth + 1)?;
949                if cases.len() > MAX_ARRAY_LENGTH {
950                    return Err(IRError::SizeLimitExceeded("Switch cases length exceeded".to_string()).into());
951                }
952                for (test, stmts) in cases {
953                    if let Some(test_expr) = test {
954                        test_expr.validate(depth + 1)?;
955                    }
956                    if stmts.len() > MAX_ARRAY_LENGTH {
957                        return Err(IRError::SizeLimitExceeded("Switch case statements length exceeded".to_string()).into());
958                    }
959                    for stmt in stmts {
960                        stmt.validate(depth + 1)?;
961                    }
962                }
963                Ok(())
964            }
965            JsStmt::Throw(expr, _, _) => expr.validate(depth + 1),
966            JsStmt::Block(stmts, _, _) => {
967                if stmts.len() > MAX_ARRAY_LENGTH {
968                    return Err(IRError::SizeLimitExceeded("Block statements length exceeded".to_string()).into());
969                }
970                for stmt in stmts {
971                    stmt.validate(depth + 1)?;
972                }
973                Ok(())
974            }
975            JsStmt::Break(_, _) => Ok(()),
976            JsStmt::Continue(_, _) => Ok(()),
977            JsStmt::Other(code, _, _) => {
978                if code.len() > MAX_STRING_LENGTH {
979                    return Err(IRError::SizeLimitExceeded("Other statement code length exceeded".to_string()).into());
980                }
981                Ok(())
982            }
983        }
984    }
985
986    /// 优化语句
987    pub fn optimize(&mut self) {
988        optimizer::StmtOptimizer::optimize(self);
989    }
990
991    /// 检查语句是否为空
992    pub fn is_empty(&self) -> bool {
993        match self {
994            JsStmt::Block(stmts, _, _) => stmts.is_empty(),
995            _ => false,
996        }
997    }
998}
999
1000/// JavaScript 程序
1001///
1002/// 表示一个完整的 JavaScript 程序,包含多个语句
1003#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1004pub struct JsProgram {
1005    /// 程序体
1006    ///
1007    /// 包含程序的所有语句
1008    pub body: Vec<JsStmt>,
1009    /// 位置信息
1010    ///
1011    /// 程序在源文件中的位置
1012    #[serde(default)]
1013    pub span: Span,
1014    /// Trivia 信息
1015    ///
1016    /// 包含程序的空白和注释信息
1017    #[serde(default)]
1018    pub trivia: Trivia,
1019}
1020
1021impl JsProgram {
1022    /// 验证程序的有效性
1023    ///
1024    /// 检查程序是否符合大小限制,并验证所有语句的有效性
1025    ///
1026    /// # Returns
1027    /// - `Ok(())` 如果程序有效
1028    /// - `Err(Error)` 如果程序无效
1029    pub fn validate(&self) -> Result<()> {
1030        if self.body.len() > MAX_ARRAY_LENGTH {
1031            return Err(IRError::SizeLimitExceeded("Program body length exceeded".to_string()).into());
1032        }
1033        for stmt in &self.body {
1034            stmt.validate(0)?;
1035        }
1036        Ok(())
1037    }
1038
1039    /// 优化程序
1040    pub fn optimize(&mut self) {
1041        optimizer::ProgramOptimizer::optimize(self);
1042    }
1043
1044    /// 检查程序是否为空
1045    pub fn is_empty(&self) -> bool {
1046        self.body.is_empty()
1047    }
1048}
1049
1050/// IR 模块
1051///
1052/// 表示一个完整的 HXO IR 模块,包含脚本、模板、样式等信息
1053#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1054pub struct IRModule {
1055    /// 模块名称
1056    ///
1057    /// 模块的唯一标识符
1058    pub name: String,
1059    /// 元数据
1060    ///
1061    /// 模块的附加信息
1062    pub metadata: HashMap<String, NargoValue>,
1063    /// 脚本
1064    ///
1065    /// 通用脚本代码
1066    pub script: Option<JsProgram>,
1067    /// 服务端脚本
1068    ///
1069    /// 仅在服务端执行的脚本代码
1070    pub script_server: Option<JsProgram>,
1071    /// 客户端脚本
1072    ///
1073    /// 仅在客户端执行的脚本代码
1074    pub script_client: Option<JsProgram>,
1075    /// 脚本元数据
1076    ///
1077    /// 用于脚本分析结果的元数据
1078    pub script_meta: Option<NargoValue>,
1079    /// 模板
1080    ///
1081    /// 模块的模板结构
1082    pub template: Option<TemplateIR>,
1083    /// 提升节点
1084    ///
1085    /// 被提升的模板节点
1086    pub hoisted_nodes: HashMap<String, TemplateNodeIR>,
1087    /// 样式
1088    ///
1089    /// 模块的样式定义
1090    pub styles: Vec<StyleIR>,
1091    /// 国际化
1092    ///
1093    /// 模块的国际化文本
1094    pub i18n: Option<HashMap<String, HashMap<String, String>>>,
1095    /// WASM
1096    ///
1097    /// WebAssembly 模块
1098    pub wasm: Vec<Vec<u8>>,
1099    /// 自定义块
1100    ///
1101    /// 模块的自定义块
1102    pub custom_blocks: Vec<CustomBlockIR>,
1103    /// 测试
1104    ///
1105    /// 模块的测试用例
1106    pub tests: Vec<TestIR>,
1107    /// 位置信息
1108    ///
1109    /// 模块在源文件中的位置
1110    pub span: Span,
1111}
1112
1113impl IRModule {
1114    /// 验证 IR 模块的有效性
1115    pub fn validate(&self) -> Result<()> {
1116        if self.name.len() > MAX_STRING_LENGTH {
1117            return Err(IRError::SizeLimitExceeded("Module name length exceeded".to_string()).into());
1118        }
1119
1120        // 验证元数据
1121        if self.metadata.len() > MAX_OBJECT_SIZE {
1122            return Err(IRError::SizeLimitExceeded("Metadata size exceeded".to_string()).into());
1123        }
1124        for (key, value) in &self.metadata {
1125            if key.len() > MAX_STRING_LENGTH {
1126                return Err(IRError::SizeLimitExceeded("Metadata key length exceeded".to_string()).into());
1127            }
1128            value.validate(0)?;
1129        }
1130
1131        // 验证脚本
1132        if let Some(script) = &self.script {
1133            script.validate()?;
1134        }
1135        if let Some(script_server) = &self.script_server {
1136            script_server.validate()?;
1137        }
1138        if let Some(script_client) = &self.script_client {
1139            script_client.validate()?;
1140        }
1141
1142        // 验证脚本元数据
1143        if let Some(meta) = &self.script_meta {
1144            meta.validate(0)?;
1145        }
1146
1147        // 验证模板
1148        if let Some(template) = &self.template {
1149            template.validate()?;
1150        }
1151
1152        // 验证提升节点
1153        if self.hoisted_nodes.len() > MAX_OBJECT_SIZE {
1154            return Err(IRError::SizeLimitExceeded("Hoisted nodes size exceeded".to_string()).into());
1155        }
1156        for (key, node) in &self.hoisted_nodes {
1157            if key.len() > MAX_STRING_LENGTH {
1158                return Err(IRError::SizeLimitExceeded("Hoisted node key length exceeded".to_string()).into());
1159            }
1160            node.validate(0)?;
1161        }
1162
1163        // 验证样式
1164        if self.styles.len() > MAX_ARRAY_LENGTH {
1165            return Err(IRError::SizeLimitExceeded("Styles length exceeded".to_string()).into());
1166        }
1167        for style in &self.styles {
1168            style.validate()?;
1169        }
1170
1171        // 验证国际化
1172        if let Some(i18n) = &self.i18n {
1173            if i18n.len() > MAX_OBJECT_SIZE {
1174                return Err(IRError::SizeLimitExceeded("I18n size exceeded".to_string()).into());
1175            }
1176            for (lang, translations) in i18n {
1177                if lang.len() > MAX_STRING_LENGTH {
1178                    return Err(IRError::SizeLimitExceeded("I18n language length exceeded".to_string()).into());
1179                }
1180                if translations.len() > MAX_OBJECT_SIZE {
1181                    return Err(IRError::SizeLimitExceeded("I18n translations size exceeded".to_string()).into());
1182                }
1183                for (key, value) in translations {
1184                    if key.len() > MAX_STRING_LENGTH {
1185                        return Err(IRError::SizeLimitExceeded("I18n key length exceeded".to_string()).into());
1186                    }
1187                    if value.len() > MAX_STRING_LENGTH {
1188                        return Err(IRError::SizeLimitExceeded("I18n value length exceeded".to_string()).into());
1189                    }
1190                }
1191            }
1192        }
1193
1194        // 验证 WASM
1195        if self.wasm.len() > MAX_ARRAY_LENGTH {
1196            return Err(IRError::SizeLimitExceeded("WASM length exceeded".to_string()).into());
1197        }
1198        for wasm in &self.wasm {
1199            if wasm.len() > MAX_STRING_LENGTH {
1200                return Err(IRError::SizeLimitExceeded("WASM size exceeded".to_string()).into());
1201            }
1202        }
1203
1204        // 验证自定义块
1205        if self.custom_blocks.len() > MAX_ARRAY_LENGTH {
1206            return Err(IRError::SizeLimitExceeded("Custom blocks length exceeded".to_string()).into());
1207        }
1208        for block in &self.custom_blocks {
1209            block.validate()?;
1210        }
1211
1212        // 验证测试
1213        if self.tests.len() > MAX_ARRAY_LENGTH {
1214            return Err(IRError::SizeLimitExceeded("Tests length exceeded".to_string()).into());
1215        }
1216        for test in &self.tests {
1217            test.validate()?;
1218        }
1219
1220        Ok(())
1221    }
1222
1223    /// 清理模块中的空元素
1224    pub fn cleanup(&mut self) {
1225        // 清理脚本
1226        if let Some(script) = &mut self.script {
1227            if script.body.is_empty() {
1228                self.script = None;
1229            }
1230        }
1231        if let Some(script_server) = &mut self.script_server {
1232            if script_server.body.is_empty() {
1233                self.script_server = None;
1234            }
1235        }
1236        if let Some(script_client) = &mut self.script_client {
1237            if script_client.body.is_empty() {
1238                self.script_client = None;
1239            }
1240        }
1241
1242        // 清理脚本元数据
1243        if let Some(meta) = &self.script_meta {
1244            if *meta == NargoValue::Null {
1245                self.script_meta = None;
1246            }
1247        }
1248
1249        // 清理模板
1250        if let Some(template) = &mut self.template {
1251            if template.nodes.is_empty() {
1252                self.template = None;
1253            }
1254        }
1255
1256        // 清理国际化
1257        if let Some(i18n) = &self.i18n {
1258            if i18n.is_empty() {
1259                self.i18n = None;
1260            }
1261        }
1262    }
1263
1264    /// 优化模块
1265    pub fn optimize(&mut self) {
1266        optimizer::IROptimizer::optimize(self);
1267    }
1268}
1269
1270/// 测试 IR
1271#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1272pub struct TestIR {
1273    /// 测试名称
1274    pub name: String,
1275    /// 测试体
1276    pub body: JsProgram,
1277    /// 位置信息
1278    pub span: Span,
1279}
1280
1281impl TestIR {
1282    /// 验证测试的有效性
1283    pub fn validate(&self) -> Result<()> {
1284        if self.name.len() > MAX_STRING_LENGTH {
1285            return Err(IRError::SizeLimitExceeded("Test name length exceeded".to_string()).into());
1286        }
1287        self.body.validate()
1288    }
1289}
1290
1291/// 模板 IR
1292#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1293pub struct TemplateIR {
1294    /// 模板节点
1295    pub nodes: Vec<TemplateNodeIR>,
1296    /// 位置信息
1297    #[serde(default)]
1298    pub span: Span,
1299}
1300
1301impl TemplateIR {
1302    /// 验证模板的有效性
1303    pub fn validate(&self) -> Result<()> {
1304        if self.nodes.len() > MAX_ARRAY_LENGTH {
1305            return Err(IRError::SizeLimitExceeded("Template nodes length exceeded".to_string()).into());
1306        }
1307        for node in &self.nodes {
1308            node.validate(0)?;
1309        }
1310        Ok(())
1311    }
1312}
1313
1314/// 模板节点 IR
1315#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1316pub enum TemplateNodeIR {
1317    /// 元素
1318    Element(ElementIR),
1319    /// if 节点
1320    If(IfNodeIR),
1321    /// for 节点
1322    For(ForNodeIR),
1323    /// 文本
1324    Text(String, #[serde(default)] Span, #[serde(default)] Trivia),
1325    /// 插值
1326    Interpolation(ExpressionIR),
1327    /// 注释
1328    Comment(String, #[serde(default)] Span, #[serde(default)] Trivia),
1329    /// 提升节点
1330    Hoisted(String),
1331}
1332
1333impl TemplateNodeIR {
1334    /// 验证模板节点的有效性
1335    pub fn validate(&self, depth: usize) -> Result<()> {
1336        if depth > MAX_RECURSION_DEPTH {
1337            return Err(IRError::CircularReference("Template node recursion depth exceeded".to_string()).into());
1338        }
1339
1340        match self {
1341            TemplateNodeIR::Element(element) => element.validate(depth + 1),
1342            TemplateNodeIR::If(if_node) => if_node.validate(depth + 1),
1343            TemplateNodeIR::For(for_node) => for_node.validate(depth + 1),
1344            TemplateNodeIR::Text(text, _, _) => {
1345                if text.len() > MAX_STRING_LENGTH {
1346                    return Err(IRError::SizeLimitExceeded("Text length exceeded".to_string()).into());
1347                }
1348                Ok(())
1349            }
1350            TemplateNodeIR::Interpolation(expr) => expr.validate(depth + 1),
1351            TemplateNodeIR::Comment(comment, _, _) => {
1352                if comment.len() > MAX_STRING_LENGTH {
1353                    return Err(IRError::SizeLimitExceeded("Comment length exceeded".to_string()).into());
1354                }
1355                Ok(())
1356            }
1357            TemplateNodeIR::Hoisted(key) => {
1358                if key.len() > MAX_STRING_LENGTH {
1359                    return Err(IRError::SizeLimitExceeded("Hoisted key length exceeded".to_string()).into());
1360                }
1361                Ok(())
1362            }
1363        }
1364    }
1365}
1366
1367/// if 节点 IR
1368#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1369pub struct IfNodeIR {
1370    /// 条件
1371    pub condition: ExpressionIR,
1372    /// 真分支
1373    pub consequent: Vec<TemplateNodeIR>,
1374    /// 假分支(else 或 else if)
1375    pub alternate: Option<Vec<TemplateNodeIR>>,
1376    /// else if 分支
1377    pub else_ifs: Vec<(ExpressionIR, Vec<TemplateNodeIR>)>,
1378    /// 位置信息
1379    #[serde(default)]
1380    pub span: Span,
1381}
1382
1383impl IfNodeIR {
1384    /// 验证 if 节点的有效性
1385    pub fn validate(&self, depth: usize) -> Result<()> {
1386        if depth > MAX_RECURSION_DEPTH {
1387            return Err(IRError::CircularReference("If node recursion depth exceeded".to_string()).into());
1388        }
1389
1390        self.condition.validate(depth + 1)?;
1391
1392        if self.consequent.len() > MAX_ARRAY_LENGTH {
1393            return Err(IRError::SizeLimitExceeded("If node consequent length exceeded".to_string()).into());
1394        }
1395        for node in &self.consequent {
1396            node.validate(depth + 1)?;
1397        }
1398
1399        if let Some(alternate) = &self.alternate {
1400            if alternate.len() > MAX_ARRAY_LENGTH {
1401                return Err(IRError::SizeLimitExceeded("If node alternate length exceeded".to_string()).into());
1402            }
1403            for node in alternate {
1404                node.validate(depth + 1)?;
1405            }
1406        }
1407
1408        if self.else_ifs.len() > MAX_ARRAY_LENGTH {
1409            return Err(IRError::SizeLimitExceeded("If node else ifs length exceeded".to_string()).into());
1410        }
1411        for (condition, body) in &self.else_ifs {
1412            condition.validate(depth + 1)?;
1413            if body.len() > MAX_ARRAY_LENGTH {
1414                return Err(IRError::SizeLimitExceeded("If node else if body length exceeded".to_string()).into());
1415            }
1416            for node in body {
1417                node.validate(depth + 1)?;
1418            }
1419        }
1420
1421        Ok(())
1422    }
1423}
1424
1425/// for 节点 IR
1426#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1427pub struct ForNodeIR {
1428    /// 迭代器
1429    pub iterator: ForIteratorIR,
1430    /// 循环体
1431    pub body: Vec<TemplateNodeIR>,
1432    /// 位置信息
1433    #[serde(default)]
1434    pub span: Span,
1435}
1436
1437impl ForNodeIR {
1438    /// 验证 for 节点的有效性
1439    pub fn validate(&self, depth: usize) -> Result<()> {
1440        if depth > MAX_RECURSION_DEPTH {
1441            return Err(IRError::CircularReference("For node recursion depth exceeded".to_string()).into());
1442        }
1443
1444        self.iterator.validate(depth + 1)?;
1445
1446        if self.body.len() > MAX_ARRAY_LENGTH {
1447            return Err(IRError::SizeLimitExceeded("For node body length exceeded".to_string()).into());
1448        }
1449        for node in &self.body {
1450            node.validate(depth + 1)?;
1451        }
1452
1453        Ok(())
1454    }
1455}
1456
1457/// for 迭代器 IR
1458#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1459pub struct ForIteratorIR {
1460    /// 项目
1461    pub item: String,
1462    /// 索引
1463    pub index: Option<String>,
1464    /// 集合
1465    pub collection: ExpressionIR,
1466}
1467
1468impl ForIteratorIR {
1469    /// 验证 for 迭代器的有效性
1470    pub fn validate(&self, depth: usize) -> Result<()> {
1471        if depth > MAX_RECURSION_DEPTH {
1472            return Err(IRError::CircularReference("For iterator recursion depth exceeded".to_string()).into());
1473        }
1474
1475        if self.item.len() > MAX_STRING_LENGTH {
1476            return Err(IRError::SizeLimitExceeded("For iterator item length exceeded".to_string()).into());
1477        }
1478
1479        if let Some(index) = &self.index {
1480            if index.len() > MAX_STRING_LENGTH {
1481                return Err(IRError::SizeLimitExceeded("For iterator index length exceeded".to_string()).into());
1482            }
1483        }
1484
1485        self.collection.validate(depth + 1)
1486    }
1487}
1488
1489/// 元素 IR
1490#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1491pub struct ElementIR {
1492    /// 标签名
1493    pub tag: String,
1494    /// 属性列表
1495    pub attributes: Vec<AttributeIR>,
1496    /// 子节点
1497    pub children: Vec<TemplateNodeIR>,
1498    /// 是否为静态元素
1499    pub is_static: bool,
1500    /// 位置信息
1501    #[serde(default)]
1502    pub span: Span,
1503    /// Trivia 信息
1504    #[serde(default)]
1505    pub trivia: Trivia,
1506}
1507
1508impl ElementIR {
1509    /// 验证元素的有效性
1510    pub fn validate(&self, depth: usize) -> Result<()> {
1511        if depth > MAX_RECURSION_DEPTH {
1512            return Err(IRError::CircularReference("Element recursion depth exceeded".to_string()).into());
1513        }
1514
1515        if self.tag.len() > MAX_STRING_LENGTH {
1516            return Err(IRError::SizeLimitExceeded("Element tag length exceeded".to_string()).into());
1517        }
1518
1519        if self.attributes.len() > MAX_ARRAY_LENGTH {
1520            return Err(IRError::SizeLimitExceeded("Element attributes length exceeded".to_string()).into());
1521        }
1522        for attr in &self.attributes {
1523            attr.validate(depth + 1)?;
1524        }
1525
1526        if self.children.len() > MAX_ARRAY_LENGTH {
1527            return Err(IRError::SizeLimitExceeded("Element children length exceeded".to_string()).into());
1528        }
1529        for child in &self.children {
1530            child.validate(depth + 1)?;
1531        }
1532
1533        Ok(())
1534    }
1535}
1536
1537/// 属性 IR
1538#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1539pub struct AttributeIR {
1540    /// 属性名
1541    pub name: String,
1542    /// 属性值
1543    pub value: Option<String>,
1544    /// 属性值的 AST
1545    pub value_ast: Option<JsExpr>,
1546    /// 参数
1547    pub argument: Option<String>,
1548    /// 修饰符
1549    pub modifiers: Vec<String>,
1550    /// 是否为指令
1551    pub is_directive: bool,
1552    /// 是否为动态属性
1553    pub is_dynamic: bool,
1554    /// 位置信息
1555    #[serde(default)]
1556    pub span: Span,
1557    /// Trivia 信息
1558    #[serde(default)]
1559    pub trivia: Trivia,
1560}
1561
1562impl AttributeIR {
1563    /// 验证属性的有效性
1564    pub fn validate(&self, depth: usize) -> Result<()> {
1565        if depth > MAX_RECURSION_DEPTH {
1566            return Err(IRError::CircularReference("Attribute recursion depth exceeded".to_string()).into());
1567        }
1568
1569        if self.name.len() > MAX_STRING_LENGTH {
1570            return Err(IRError::SizeLimitExceeded("Attribute name length exceeded".to_string()).into());
1571        }
1572
1573        if let Some(value) = &self.value {
1574            if value.len() > MAX_STRING_LENGTH {
1575                return Err(IRError::SizeLimitExceeded("Attribute value length exceeded".to_string()).into());
1576            }
1577        }
1578
1579        if let Some(value_ast) = &self.value_ast {
1580            value_ast.validate(depth + 1)?;
1581        }
1582
1583        if let Some(argument) = &self.argument {
1584            if argument.len() > MAX_STRING_LENGTH {
1585                return Err(IRError::SizeLimitExceeded("Attribute argument length exceeded".to_string()).into());
1586            }
1587        }
1588
1589        if self.modifiers.len() > MAX_ARRAY_LENGTH {
1590            return Err(IRError::SizeLimitExceeded("Attribute modifiers length exceeded".to_string()).into());
1591        }
1592        for modifier in &self.modifiers {
1593            if modifier.len() > MAX_STRING_LENGTH {
1594                return Err(IRError::SizeLimitExceeded("Attribute modifier length exceeded".to_string()).into());
1595            }
1596        }
1597
1598        Ok(())
1599    }
1600}
1601
1602/// 表达式 IR
1603#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1604pub struct ExpressionIR {
1605    /// 表达式代码
1606    pub code: String,
1607    /// 表达式 AST
1608    pub ast: Option<JsExpr>,
1609    /// 是否为静态表达式
1610    pub is_static: bool,
1611    /// 位置信息
1612    #[serde(default)]
1613    pub span: Span,
1614    /// Trivia 信息
1615    #[serde(default)]
1616    pub trivia: Trivia,
1617}
1618
1619impl ExpressionIR {
1620    /// 验证表达式的有效性
1621    pub fn validate(&self, depth: usize) -> Result<()> {
1622        if depth > MAX_RECURSION_DEPTH {
1623            return Err(IRError::CircularReference("Expression IR recursion depth exceeded".to_string()).into());
1624        }
1625
1626        if self.code.len() > MAX_STRING_LENGTH {
1627            return Err(IRError::SizeLimitExceeded("Expression code length exceeded".to_string()).into());
1628        }
1629
1630        if let Some(ast) = &self.ast {
1631            ast.validate(depth + 1)?;
1632        }
1633
1634        Ok(())
1635    }
1636
1637    /// 检查表达式是否为空
1638    pub fn is_empty(&self) -> bool {
1639        self.code.is_empty() && self.ast.is_none() && self.trivia.is_empty()
1640    }
1641}
1642
1643/// 自定义块 IR
1644#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1645pub struct CustomBlockIR {
1646    /// 块名称
1647    pub name: String,
1648    /// 块内容
1649    pub content: String,
1650    /// 块属性
1651    pub attributes: HashMap<String, String>,
1652    /// 位置信息
1653    #[serde(default)]
1654    pub span: Span,
1655    /// Trivia 信息
1656    #[serde(default)]
1657    pub trivia: Trivia,
1658}
1659
1660impl CustomBlockIR {
1661    /// 验证自定义块的有效性
1662    pub fn validate(&self) -> Result<()> {
1663        if self.name.len() > MAX_STRING_LENGTH {
1664            return Err(IRError::SizeLimitExceeded("Custom block name length exceeded".to_string()).into());
1665        }
1666
1667        if self.content.len() > MAX_STRING_LENGTH {
1668            return Err(IRError::SizeLimitExceeded("Custom block content length exceeded".to_string()).into());
1669        }
1670
1671        if self.attributes.len() > MAX_OBJECT_SIZE {
1672            return Err(IRError::SizeLimitExceeded("Custom block attributes size exceeded".to_string()).into());
1673        }
1674        for (key, value) in &self.attributes {
1675            if key.len() > MAX_STRING_LENGTH {
1676                return Err(IRError::SizeLimitExceeded("Custom block attribute key length exceeded".to_string()).into());
1677            }
1678            if value.len() > MAX_STRING_LENGTH {
1679                return Err(IRError::SizeLimitExceeded("Custom block attribute value length exceeded".to_string()).into());
1680            }
1681        }
1682
1683        Ok(())
1684    }
1685
1686    /// 检查自定义块是否为空
1687    pub fn is_empty(&self) -> bool {
1688        self.name.is_empty() && self.content.is_empty() && self.attributes.is_empty() && self.trivia.is_empty()
1689    }
1690}
1691
1692/// 样式 IR
1693#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
1694pub struct StyleIR {
1695    /// 样式代码
1696    pub code: String,
1697    /// 样式语言
1698    pub lang: String,
1699    /// 是否为作用域样式
1700    pub scoped: bool,
1701    /// 位置信息
1702    #[serde(default)]
1703    pub span: Span,
1704    /// Trivia 信息
1705    #[serde(default)]
1706    pub trivia: Trivia,
1707}
1708
1709impl StyleIR {
1710    /// 验证样式的有效性
1711    pub fn validate(&self) -> Result<()> {
1712        if self.code.len() > MAX_STRING_LENGTH {
1713            return Err(IRError::SizeLimitExceeded("Style code length exceeded".to_string()).into());
1714        }
1715
1716        if self.lang.len() > MAX_STRING_LENGTH {
1717            return Err(IRError::SizeLimitExceeded("Style lang length exceeded".to_string()).into());
1718        }
1719
1720        Ok(())
1721    }
1722
1723    /// 检查样式是否为空
1724    pub fn is_empty(&self) -> bool {
1725        self.code.is_empty() && self.lang.is_empty() && self.trivia.is_empty()
1726    }
1727}
1728
1729/// 表达式访问者 trait
1730pub trait JsExprVisitor<R> {
1731    /// 访问标识符表达式
1732    fn visit_identifier(&mut self, id: &String, span: &Span, trivia: &Trivia) -> R;
1733    /// 访问字面量表达式
1734    fn visit_literal(&mut self, value: &NargoValue, span: &Span, trivia: &Trivia) -> R;
1735    /// 访问一元表达式
1736    fn visit_unary(&mut self, op: &String, argument: &JsExpr, span: &Span, trivia: &Trivia) -> R;
1737    /// 访问二元表达式
1738    fn visit_binary(&mut self, left: &JsExpr, op: &String, right: &JsExpr, span: &Span, trivia: &Trivia) -> R;
1739    /// 访问函数调用表达式
1740    fn visit_call(&mut self, callee: &JsExpr, args: &Vec<JsExpr>, span: &Span, trivia: &Trivia) -> R;
1741    /// 访问成员访问表达式
1742    fn visit_member(&mut self, object: &JsExpr, property: &JsExpr, computed: bool, span: &Span, trivia: &Trivia) -> R;
1743    /// 访问可选链成员访问表达式
1744    fn visit_optional_member(&mut self, object: &JsExpr, property: &JsExpr, computed: bool, span: &Span, trivia: &Trivia) -> R;
1745    /// 访问可选链函数调用表达式
1746    fn visit_optional_call(&mut self, callee: &JsExpr, args: &Vec<JsExpr>, span: &Span, trivia: &Trivia) -> R;
1747    /// 访问空值合并表达式
1748    fn visit_nullish_coalescing(&mut self, left: &JsExpr, right: &JsExpr, span: &Span, trivia: &Trivia) -> R;
1749    /// 访问逻辑赋值表达式
1750    fn visit_logical_assignment(&mut self, op: &String, left: &JsExpr, right: &JsExpr, span: &Span, trivia: &Trivia) -> R;
1751    /// 访问数组字面量表达式
1752    fn visit_array(&mut self, items: &Vec<JsExpr>, span: &Span, trivia: &Trivia) -> R;
1753    /// 访问对象字面量表达式
1754    fn visit_object(&mut self, props: &HashMap<String, JsExpr>, span: &Span, trivia: &Trivia) -> R;
1755    /// 访问箭头函数表达式
1756    fn visit_arrow_function(&mut self, params: &Vec<String>, body: &JsExpr, span: &Span, trivia: &Trivia) -> R;
1757    /// 访问 TSE 元素表达式
1758    fn visit_tse_element(&mut self, tag: &String, attributes: &Vec<TseAttribute>, children: &Vec<JsExpr>, span: &Span, trivia: &Trivia) -> R;
1759    /// 访问条件表达式
1760    fn visit_conditional(&mut self, test: &JsExpr, consequent: &JsExpr, alternate: &JsExpr, span: &Span, trivia: &Trivia) -> R;
1761    /// 访问模板字面量表达式
1762    fn visit_template_literal(&mut self, quasis: &Vec<String>, expressions: &Vec<JsExpr>, span: &Span, trivia: &Trivia) -> R;
1763    /// 访问展开表达式
1764    fn visit_spread(&mut self, expr: &JsExpr, span: &Span, trivia: &Trivia) -> R;
1765    /// 访问类型测试表达式
1766    fn visit_type_of(&mut self, expr: &JsExpr, span: &Span, trivia: &Trivia) -> R;
1767    /// 访问实例测试表达式
1768    fn visit_instance_of(&mut self, left: &JsExpr, right: &JsExpr, span: &Span, trivia: &Trivia) -> R;
1769    /// 访问其他表达式
1770    fn visit_other(&mut self, code: &String, span: &Span, trivia: &Trivia) -> R;
1771}
1772
1773impl JsExpr {
1774    /// 接受访问者
1775    pub fn accept<R>(&self, visitor: &mut dyn JsExprVisitor<R>) -> R {
1776        match self {
1777            JsExpr::Identifier(id, span, trivia) => visitor.visit_identifier(id, span, trivia),
1778            JsExpr::Literal(value, span, trivia) => visitor.visit_literal(value, span, trivia),
1779            JsExpr::Unary { op, argument, span, trivia } => visitor.visit_unary(op, argument, span, trivia),
1780            JsExpr::Binary { left, op, right, span, trivia } => visitor.visit_binary(left, op, right, span, trivia),
1781            JsExpr::Call { callee, args, span, trivia } => visitor.visit_call(callee, args, span, trivia),
1782            JsExpr::Member { object, property, computed, span, trivia } => visitor.visit_member(object, property, *computed, span, trivia),
1783            JsExpr::OptionalMember { object, property, computed, span, trivia } => visitor.visit_optional_member(object, property, *computed, span, trivia),
1784            JsExpr::OptionalCall { callee, args, span, trivia } => visitor.visit_optional_call(callee, args, span, trivia),
1785            JsExpr::NullishCoalescing { left, right, span, trivia } => visitor.visit_nullish_coalescing(left, right, span, trivia),
1786            JsExpr::LogicalAssignment { op, left, right, span, trivia } => visitor.visit_logical_assignment(op, left, right, span, trivia),
1787            JsExpr::Array(items, span, trivia) => visitor.visit_array(items, span, trivia),
1788            JsExpr::Object(props, span, trivia) => visitor.visit_object(props, span, trivia),
1789            JsExpr::ArrowFunction { params, body, span, trivia } => visitor.visit_arrow_function(params, body, span, trivia),
1790            JsExpr::TseElement { tag, attributes, children, span, trivia } => visitor.visit_tse_element(tag, attributes, children, span, trivia),
1791            JsExpr::Conditional { test, consequent, alternate, span, trivia } => visitor.visit_conditional(test, consequent, alternate, span, trivia),
1792            JsExpr::TemplateLiteral { quasis, expressions, span, trivia } => visitor.visit_template_literal(quasis, expressions, span, trivia),
1793            JsExpr::Spread(expr, span, trivia) => visitor.visit_spread(expr, span, trivia),
1794            JsExpr::TypeOf(expr, span, trivia) => visitor.visit_type_of(expr, span, trivia),
1795            JsExpr::InstanceOf { left, right, span, trivia } => visitor.visit_instance_of(left, right, span, trivia),
1796            JsExpr::Other(code, span, trivia) => visitor.visit_other(code, span, trivia),
1797        }
1798    }
1799}
1800
1801/// 语句访问者 trait
1802pub trait JsStmtVisitor<R> {
1803    /// 访问表达式语句
1804    fn visit_expr(&mut self, expr: &JsExpr, span: &Span, trivia: &Trivia) -> R;
1805    /// 访问变量声明语句
1806    fn visit_variable_decl(&mut self, kind: &String, id: &String, init: &Option<JsExpr>, span: &Span, trivia: &Trivia) -> R;
1807    /// 访问导入语句
1808    fn visit_import(&mut self, source: &String, specifiers: &Vec<String>, span: &Span, trivia: &Trivia) -> R;
1809    /// 访问导出语句
1810    fn visit_export(&mut self, declaration: &JsStmt, span: &Span, trivia: &Trivia) -> R;
1811    /// 访问导出所有语句
1812    fn visit_export_all(&mut self, source: &String, span: &Span, trivia: &Trivia) -> R;
1813    /// 访问导出命名语句
1814    fn visit_export_named(&mut self, source: &Option<String>, specifiers: &Vec<String>, span: &Span, trivia: &Trivia) -> R;
1815    /// 访问函数声明语句
1816    fn visit_function_decl(&mut self, id: &String, params: &Vec<String>, body: &Vec<JsStmt>, is_async: bool, span: &Span, trivia: &Trivia) -> R;
1817    /// 访问返回语句
1818    fn visit_return(&mut self, expr: &Option<JsExpr>, span: &Span, trivia: &Trivia) -> R;
1819    /// 访问 if 语句
1820    fn visit_if(&mut self, test: &JsExpr, consequent: &JsStmt, alternate: &Option<Box<JsStmt>>, span: &Span, trivia: &Trivia) -> R;
1821    /// 访问 while 语句
1822    fn visit_while(&mut self, test: &JsExpr, body: &JsStmt, span: &Span, trivia: &Trivia) -> R;
1823    /// 访问 for 语句
1824    fn visit_for(&mut self, init: &Option<Box<JsStmt>>, test: &Option<JsExpr>, update: &Option<JsExpr>, body: &JsStmt, span: &Span, trivia: &Trivia) -> R;
1825    /// 访问 for-in 语句
1826    fn visit_for_in(&mut self, left: &JsStmt, right: &JsExpr, body: &JsStmt, span: &Span, trivia: &Trivia) -> R;
1827    /// 访问 for-of 语句
1828    fn visit_for_of(&mut self, left: &JsStmt, right: &JsExpr, body: &JsStmt, span: &Span, trivia: &Trivia) -> R;
1829    /// 访问 try/catch 语句
1830    fn visit_try(&mut self, block: &JsStmt, handler: &Option<(String, Box<JsStmt>)>, finalizer: &Option<Box<JsStmt>>, span: &Span, trivia: &Trivia) -> R;
1831    /// 访问 switch 语句
1832    fn visit_switch(&mut self, discriminant: &JsExpr, cases: &Vec<(Option<JsExpr>, Vec<JsStmt>)>, span: &Span, trivia: &Trivia) -> R;
1833    /// 访问 throw 语句
1834    fn visit_throw(&mut self, expr: &JsExpr, span: &Span, trivia: &Trivia) -> R;
1835    /// 访问块语句
1836    fn visit_block(&mut self, stmts: &Vec<JsStmt>, span: &Span, trivia: &Trivia) -> R;
1837    /// 访问 break 语句
1838    fn visit_break(&mut self, span: &Span, trivia: &Trivia) -> R;
1839    /// 访问 continue 语句
1840    fn visit_continue(&mut self, span: &Span, trivia: &Trivia) -> R;
1841    /// 访问其他语句
1842    fn visit_other(&mut self, code: &String, span: &Span, trivia: &Trivia) -> R;
1843}
1844
1845impl JsStmt {
1846    /// 接受访问者
1847    pub fn accept<R>(&self, visitor: &mut dyn JsStmtVisitor<R>) -> R {
1848        match self {
1849            JsStmt::Expr(expr, span, trivia) => visitor.visit_expr(expr, span, trivia),
1850            JsStmt::VariableDecl { kind, id, init, span, trivia } => visitor.visit_variable_decl(kind, id, init, span, trivia),
1851            JsStmt::Import { source, specifiers, span, trivia } => visitor.visit_import(source, specifiers, span, trivia),
1852            JsStmt::Export { declaration, span, trivia } => visitor.visit_export(declaration, span, trivia),
1853            JsStmt::ExportAll { source, span, trivia } => visitor.visit_export_all(source, span, trivia),
1854            JsStmt::ExportNamed { source, specifiers, span, trivia } => visitor.visit_export_named(source, specifiers, span, trivia),
1855            JsStmt::FunctionDecl { id, params, body, is_async, span, trivia } => visitor.visit_function_decl(id, params, body, *is_async, span, trivia),
1856            JsStmt::Return(expr, span, trivia) => visitor.visit_return(expr, span, trivia),
1857            JsStmt::If { test, consequent, alternate, span, trivia } => visitor.visit_if(test, consequent, alternate, span, trivia),
1858            JsStmt::While { test, body, span, trivia } => visitor.visit_while(test, body, span, trivia),
1859            JsStmt::For { init, test, update, body, span, trivia } => visitor.visit_for(init, test, update, body, span, trivia),
1860            JsStmt::ForIn { left, right, body, span, trivia } => visitor.visit_for_in(left, right, body, span, trivia),
1861            JsStmt::ForOf { left, right, body, span, trivia } => visitor.visit_for_of(left, right, body, span, trivia),
1862            JsStmt::Try { block, handler, finalizer, span, trivia } => visitor.visit_try(block, handler, finalizer, span, trivia),
1863            JsStmt::Switch { discriminant, cases, span, trivia } => visitor.visit_switch(discriminant, cases, span, trivia),
1864            JsStmt::Throw(expr, span, trivia) => visitor.visit_throw(expr, span, trivia),
1865            JsStmt::Block(stmts, span, trivia) => visitor.visit_block(stmts, span, trivia),
1866            JsStmt::Break(span, trivia) => visitor.visit_break(span, trivia),
1867            JsStmt::Continue(span, trivia) => visitor.visit_continue(span, trivia),
1868            JsStmt::Other(code, span, trivia) => visitor.visit_other(code, span, trivia),
1869        }
1870    }
1871}
1872
1873/// 模板节点访问者 trait
1874pub trait TemplateNodeVisitor<R> {
1875    /// 访问元素节点
1876    fn visit_element(&mut self, element: &ElementIR, depth: usize) -> R;
1877    /// 访问 if 节点
1878    fn visit_if(&mut self, if_node: &IfNodeIR, depth: usize) -> R;
1879    /// 访问 for 节点
1880    fn visit_for(&mut self, for_node: &ForNodeIR, depth: usize) -> R;
1881    /// 访问文本节点
1882    fn visit_text(&mut self, text: &String, span: &Span, trivia: &Trivia, depth: usize) -> R;
1883    /// 访问插值节点
1884    fn visit_interpolation(&mut self, expr: &ExpressionIR, depth: usize) -> R;
1885    /// 访问注释节点
1886    fn visit_comment(&mut self, comment: &String, span: &Span, trivia: &Trivia, depth: usize) -> R;
1887    /// 访问提升节点
1888    fn visit_hoisted(&mut self, key: &String, depth: usize) -> R;
1889}
1890
1891impl TemplateNodeIR {
1892    /// 接受访问者
1893    pub fn accept<R>(&self, visitor: &mut dyn TemplateNodeVisitor<R>, depth: usize) -> R {
1894        match self {
1895            TemplateNodeIR::Element(element) => visitor.visit_element(element, depth),
1896            TemplateNodeIR::If(if_node) => visitor.visit_if(if_node, depth),
1897            TemplateNodeIR::For(for_node) => visitor.visit_for(for_node, depth),
1898            TemplateNodeIR::Text(text, span, trivia) => visitor.visit_text(text, span, trivia, depth),
1899            TemplateNodeIR::Interpolation(expr) => visitor.visit_interpolation(expr, depth),
1900            TemplateNodeIR::Comment(comment, span, trivia) => visitor.visit_comment(comment, span, trivia, depth),
1901            TemplateNodeIR::Hoisted(key) => visitor.visit_hoisted(key, depth),
1902        }
1903    }
1904}
1905
1906/// 简单的默认访问者实现
1907pub struct DefaultVisitor;
1908
1909impl JsExprVisitor<()> for DefaultVisitor {
1910    fn visit_identifier(&mut self, _id: &String, _span: &Span, _trivia: &Trivia) -> () {}
1911    fn visit_literal(&mut self, _value: &NargoValue, _span: &Span, _trivia: &Trivia) -> () {}
1912    fn visit_unary(&mut self, _op: &String, argument: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
1913        argument.accept(self);
1914    }
1915    fn visit_binary(&mut self, left: &JsExpr, _op: &String, right: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
1916        left.accept(self);
1917        right.accept(self);
1918    }
1919    fn visit_call(&mut self, callee: &JsExpr, args: &Vec<JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
1920        callee.accept(self);
1921        for arg in args {
1922            arg.accept(self);
1923        }
1924    }
1925    fn visit_member(&mut self, object: &JsExpr, property: &JsExpr, _computed: bool, _span: &Span, _trivia: &Trivia) -> () {
1926        object.accept(self);
1927        property.accept(self);
1928    }
1929    fn visit_optional_member(&mut self, object: &JsExpr, property: &JsExpr, _computed: bool, _span: &Span, _trivia: &Trivia) -> () {
1930        object.accept(self);
1931        property.accept(self);
1932    }
1933    fn visit_optional_call(&mut self, callee: &JsExpr, args: &Vec<JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
1934        callee.accept(self);
1935        for arg in args {
1936            arg.accept(self);
1937        }
1938    }
1939    fn visit_nullish_coalescing(&mut self, left: &JsExpr, right: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
1940        left.accept(self);
1941        right.accept(self);
1942    }
1943    fn visit_logical_assignment(&mut self, _op: &String, left: &JsExpr, right: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
1944        left.accept(self);
1945        right.accept(self);
1946    }
1947    fn visit_array(&mut self, items: &Vec<JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
1948        for item in items {
1949            item.accept(self);
1950        }
1951    }
1952    fn visit_object(&mut self, props: &HashMap<String, JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
1953        for (_key, value) in props {
1954            value.accept(self);
1955        }
1956    }
1957    fn visit_arrow_function(&mut self, _params: &Vec<String>, body: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
1958        body.accept(self);
1959    }
1960    fn visit_tse_element(&mut self, _tag: &String, _attributes: &Vec<TseAttribute>, children: &Vec<JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
1961        for child in children {
1962            child.accept(self);
1963        }
1964    }
1965    fn visit_conditional(&mut self, test: &JsExpr, consequent: &JsExpr, alternate: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
1966        test.accept(self);
1967        consequent.accept(self);
1968        alternate.accept(self);
1969    }
1970    fn visit_template_literal(&mut self, _quasis: &Vec<String>, expressions: &Vec<JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
1971        for expr in expressions {
1972            expr.accept(self);
1973        }
1974    }
1975    fn visit_spread(&mut self, expr: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
1976        expr.accept(self);
1977    }
1978    fn visit_type_of(&mut self, expr: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
1979        expr.accept(self);
1980    }
1981    fn visit_instance_of(&mut self, left: &JsExpr, right: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
1982        left.accept(self);
1983        right.accept(self);
1984    }
1985    fn visit_other(&mut self, _code: &String, _span: &Span, _trivia: &Trivia) -> () {}
1986}
1987
1988impl JsStmtVisitor<()> for DefaultVisitor {
1989    fn visit_expr(&mut self, expr: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
1990        expr.accept(self);
1991    }
1992    fn visit_variable_decl(&mut self, _kind: &String, _id: &String, init: &Option<JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
1993        if let Some(expr) = init {
1994            expr.accept(self);
1995        }
1996    }
1997    fn visit_import(&mut self, _source: &String, _specifiers: &Vec<String>, _span: &Span, _trivia: &Trivia) -> () {}
1998    fn visit_export(&mut self, declaration: &JsStmt, _span: &Span, _trivia: &Trivia) -> () {
1999        declaration.accept(self);
2000    }
2001    fn visit_export_all(&mut self, _source: &String, _span: &Span, _trivia: &Trivia) -> () {}
2002    fn visit_export_named(&mut self, _source: &Option<String>, _specifiers: &Vec<String>, _span: &Span, _trivia: &Trivia) -> () {}
2003    fn visit_function_decl(&mut self, _id: &String, _params: &Vec<String>, body: &Vec<JsStmt>, _is_async: bool, _span: &Span, _trivia: &Trivia) -> () {
2004        for stmt in body {
2005            stmt.accept(self);
2006        }
2007    }
2008    fn visit_return(&mut self, expr: &Option<JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
2009        if let Some(expr) = expr {
2010            expr.accept(self);
2011        }
2012    }
2013    fn visit_if(&mut self, test: &JsExpr, consequent: &JsStmt, alternate: &Option<Box<JsStmt>>, _span: &Span, _trivia: &Trivia) -> () {
2014        test.accept(self);
2015        consequent.accept(self);
2016        if let Some(alt) = alternate {
2017            alt.accept(self);
2018        }
2019    }
2020    fn visit_while(&mut self, test: &JsExpr, body: &JsStmt, _span: &Span, _trivia: &Trivia) -> () {
2021        test.accept(self);
2022        body.accept(self);
2023    }
2024    fn visit_for(&mut self, init: &Option<Box<JsStmt>>, test: &Option<JsExpr>, update: &Option<JsExpr>, body: &JsStmt, _span: &Span, _trivia: &Trivia) -> () {
2025        if let Some(init_stmt) = init {
2026            init_stmt.accept(self);
2027        }
2028        if let Some(test_expr) = test {
2029            test_expr.accept(self);
2030        }
2031        if let Some(update_expr) = update {
2032            update_expr.accept(self);
2033        }
2034        body.accept(self);
2035    }
2036    fn visit_for_in(&mut self, left: &JsStmt, right: &JsExpr, body: &JsStmt, _span: &Span, _trivia: &Trivia) -> () {
2037        left.accept(self);
2038        right.accept(self);
2039        body.accept(self);
2040    }
2041    fn visit_for_of(&mut self, left: &JsStmt, right: &JsExpr, body: &JsStmt, _span: &Span, _trivia: &Trivia) -> () {
2042        left.accept(self);
2043        right.accept(self);
2044        body.accept(self);
2045    }
2046    fn visit_try(&mut self, block: &JsStmt, handler: &Option<(String, Box<JsStmt>)>, finalizer: &Option<Box<JsStmt>>, _span: &Span, _trivia: &Trivia) -> () {
2047        block.accept(self);
2048        if let Some((_id, body)) = handler {
2049            body.accept(self);
2050        }
2051        if let Some(body) = finalizer {
2052            body.accept(self);
2053        }
2054    }
2055    fn visit_switch(&mut self, discriminant: &JsExpr, cases: &Vec<(Option<JsExpr>, Vec<JsStmt>)>, _span: &Span, _trivia: &Trivia) -> () {
2056        discriminant.accept(self);
2057        for (test, stmts) in cases {
2058            if let Some(test_expr) = test {
2059                test_expr.accept(self);
2060            }
2061            for stmt in stmts {
2062                stmt.accept(self);
2063            }
2064        }
2065    }
2066    fn visit_throw(&mut self, expr: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
2067        expr.accept(self);
2068    }
2069    fn visit_block(&mut self, stmts: &Vec<JsStmt>, _span: &Span, _trivia: &Trivia) -> () {
2070        for stmt in stmts {
2071            stmt.accept(self);
2072        }
2073    }
2074    fn visit_break(&mut self, _span: &Span, _trivia: &Trivia) -> () {}
2075    fn visit_continue(&mut self, _span: &Span, _trivia: &Trivia) -> () {}
2076    fn visit_other(&mut self, _code: &String, _span: &Span, _trivia: &Trivia) -> () {}
2077}
2078
2079impl TemplateNodeVisitor<()> for DefaultVisitor {
2080    fn visit_element(&mut self, element: &ElementIR, depth: usize) -> () {
2081        for child in &element.children {
2082            child.accept(self, depth + 1);
2083        }
2084    }
2085    fn visit_if(&mut self, if_node: &IfNodeIR, depth: usize) -> () {
2086        for node in &if_node.consequent {
2087            node.accept(self, depth + 1);
2088        }
2089        if let Some(alternate) = &if_node.alternate {
2090            for node in alternate {
2091                node.accept(self, depth + 1);
2092            }
2093        }
2094        for (_condition, body) in &if_node.else_ifs {
2095            for node in body {
2096                node.accept(self, depth + 1);
2097            }
2098        }
2099    }
2100    fn visit_for(&mut self, for_node: &ForNodeIR, depth: usize) -> () {
2101        for node in &for_node.body {
2102            node.accept(self, depth + 1);
2103        }
2104    }
2105    fn visit_text(&mut self, _text: &String, _span: &Span, _trivia: &Trivia, _depth: usize) -> () {}
2106    fn visit_interpolation(&mut self, _expr: &ExpressionIR, _depth: usize) -> () {}
2107    fn visit_comment(&mut self, _comment: &String, _span: &Span, _trivia: &Trivia, _depth: usize) -> () {}
2108    fn visit_hoisted(&mut self, _key: &String, _depth: usize) -> () {}
2109}
2110
2111/// 优化器模块
2112///
2113/// 提供 IR 结构的优化功能,包括常量折叠、死代码消除等优化规则。
2114pub mod optimizer {
2115    use super::*;
2116
2117    /// 表达式优化器
2118    ///
2119    /// 负责优化 JavaScript 表达式,包括常量折叠等优化规则。
2120    pub struct ExprOptimizer;
2121
2122    impl ExprOptimizer {
2123        /// 优化表达式
2124        ///
2125        /// # Parameters
2126        /// - `expr`: 要优化的表达式
2127        pub fn optimize(expr: &mut JsExpr) {
2128            match expr {
2129                JsExpr::Unary { op, argument, .. } => {
2130                    Self::optimize(argument);
2131                    // 常量折叠:一元表达式
2132                    if let JsExpr::Literal(value, span, trivia) = &**argument {
2133                        match op.as_str() {
2134                            "!" => {
2135                                if let Some(b) = value.as_bool() {
2136                                    *expr = JsExpr::Literal(NargoValue::Bool(!b), *span, trivia.clone());
2137                                }
2138                            }
2139                            "-" => {
2140                                if let Some(n) = value.as_number() {
2141                                    *expr = JsExpr::Literal(NargoValue::Number(-n), *span, trivia.clone());
2142                                }
2143                            }
2144                            "+" => {
2145                                if let Some(n) = value.as_number() {
2146                                    *expr = JsExpr::Literal(NargoValue::Number(n), *span, trivia.clone());
2147                                }
2148                                else if let Some(s) = value.as_str() {
2149                                    if let Ok(n) = s.parse::<f64>() {
2150                                        *expr = JsExpr::Literal(NargoValue::Number(n), *span, trivia.clone());
2151                                    }
2152                                }
2153                            }
2154                            "~" => {
2155                                if let Some(n) = value.as_number() {
2156                                    let int_val = n as i64;
2157                                    *expr = JsExpr::Literal(NargoValue::Number((!int_val) as f64), *span, trivia.clone());
2158                                }
2159                            }
2160                            _ => return,
2161                        };
2162                    }
2163                }
2164                JsExpr::Binary { left, op, right, span, trivia } => {
2165                    Self::optimize(left);
2166                    Self::optimize(right);
2167                    // 常量折叠:二元表达式
2168                    if let (JsExpr::Literal(left_val, _, _), JsExpr::Literal(right_val, _, _)) = (&**left, &**right) {
2169                        match op.as_str() {
2170                            "+" => {
2171                                if let (Some(l), Some(r)) = (left_val.as_number(), right_val.as_number()) {
2172                                    *expr = JsExpr::Literal(NargoValue::Number(l + r), *span, trivia.clone());
2173                                }
2174                                else if let (Some(l), Some(r)) = (left_val.as_str(), right_val.as_str()) {
2175                                    *expr = JsExpr::Literal(NargoValue::String(format!("{}{}", l, r)), *span, trivia.clone());
2176                                }
2177                                else if let (Some(l), Some(r)) = (left_val.as_str(), right_val.as_number()) {
2178                                    *expr = JsExpr::Literal(NargoValue::String(format!("{}{}", l, r)), *span, trivia.clone());
2179                                }
2180                                else if let (Some(l), Some(r)) = (left_val.as_number(), right_val.as_str()) {
2181                                    *expr = JsExpr::Literal(NargoValue::String(format!("{}{}", l, r)), *span, trivia.clone());
2182                                }
2183                            }
2184                            "-" => {
2185                                if let (Some(l), Some(r)) = (left_val.as_number(), right_val.as_number()) {
2186                                    *expr = JsExpr::Literal(NargoValue::Number(l - r), *span, trivia.clone());
2187                                }
2188                            }
2189                            "*" => {
2190                                if let (Some(l), Some(r)) = (left_val.as_number(), right_val.as_number()) {
2191                                    *expr = JsExpr::Literal(NargoValue::Number(l * r), *span, trivia.clone());
2192                                }
2193                            }
2194                            "/" => {
2195                                if let (Some(l), Some(r)) = (left_val.as_number(), right_val.as_number()) {
2196                                    *expr = JsExpr::Literal(NargoValue::Number(l / r), *span, trivia.clone());
2197                                }
2198                            }
2199                            "%" => {
2200                                if let (Some(l), Some(r)) = (left_val.as_number(), right_val.as_number()) {
2201                                    *expr = JsExpr::Literal(NargoValue::Number(l % r), *span, trivia.clone());
2202                                }
2203                            }
2204                            "==" | "!=" | "===" | "!==" => {
2205                                let result = left_val == right_val;
2206                                let final_result = if op == "!=" || op == "!==" { !result } else { result };
2207                                *expr = JsExpr::Literal(NargoValue::Bool(final_result), *span, trivia.clone());
2208                            }
2209                            "<" => {
2210                                if let (Some(l), Some(r)) = (left_val.as_number(), right_val.as_number()) {
2211                                    *expr = JsExpr::Literal(NargoValue::Bool(l < r), *span, trivia.clone());
2212                                }
2213                            }
2214                            "<=" => {
2215                                if let (Some(l), Some(r)) = (left_val.as_number(), right_val.as_number()) {
2216                                    *expr = JsExpr::Literal(NargoValue::Bool(l <= r), *span, trivia.clone());
2217                                }
2218                            }
2219                            ">" => {
2220                                if let (Some(l), Some(r)) = (left_val.as_number(), right_val.as_number()) {
2221                                    *expr = JsExpr::Literal(NargoValue::Bool(l > r), *span, trivia.clone());
2222                                }
2223                            }
2224                            ">=" => {
2225                                if let (Some(l), Some(r)) = (left_val.as_number(), right_val.as_number()) {
2226                                    *expr = JsExpr::Literal(NargoValue::Bool(l >= r), *span, trivia.clone());
2227                                }
2228                            }
2229                            "&&" => {
2230                                if let (Some(l), Some(r)) = (left_val.as_bool(), right_val.as_bool()) {
2231                                    *expr = JsExpr::Literal(NargoValue::Bool(l && r), *span, trivia.clone());
2232                                }
2233                            }
2234                            "||" => {
2235                                if let (Some(l), Some(r)) = (left_val.as_bool(), right_val.as_bool()) {
2236                                    *expr = JsExpr::Literal(NargoValue::Bool(l || r), *span, trivia.clone());
2237                                }
2238                            }
2239                            _ => return,
2240                        };
2241                    }
2242                }
2243                JsExpr::Conditional { test, consequent, alternate, span: _, trivia: _ } => {
2244                    Self::optimize(test);
2245                    Self::optimize(consequent);
2246                    Self::optimize(alternate);
2247                    // 常量折叠:条件表达式
2248                    if let JsExpr::Literal(test_val, _, _) = &**test {
2249                        if let Some(b) = test_val.as_bool() {
2250                            let optimized = if b { consequent.clone() } else { alternate.clone() };
2251                            *expr = *optimized;
2252                        }
2253                    }
2254                }
2255                JsExpr::Array(items, ..) => {
2256                    for item in items {
2257                        Self::optimize(item);
2258                    }
2259                }
2260                JsExpr::Object(props, ..) => {
2261                    for (_, value) in props {
2262                        Self::optimize(value);
2263                    }
2264                }
2265                JsExpr::Call { callee, args, .. } => {
2266                    Self::optimize(callee);
2267                    for arg in args {
2268                        Self::optimize(arg);
2269                    }
2270                }
2271                JsExpr::Member { object, property, .. } => {
2272                    Self::optimize(object);
2273                    Self::optimize(property);
2274                }
2275                JsExpr::OptionalMember { object, property, .. } => {
2276                    Self::optimize(object);
2277                    Self::optimize(property);
2278                }
2279                JsExpr::OptionalCall { callee, args, .. } => {
2280                    Self::optimize(callee);
2281                    for arg in args {
2282                        Self::optimize(arg);
2283                    }
2284                }
2285                JsExpr::NullishCoalescing { left, right, .. } => {
2286                    Self::optimize(left);
2287                    Self::optimize(right);
2288                }
2289                JsExpr::LogicalAssignment { left, right, .. } => {
2290                    Self::optimize(left);
2291                    Self::optimize(right);
2292                }
2293                JsExpr::ArrowFunction { body, .. } => {
2294                    Self::optimize(body);
2295                }
2296                JsExpr::TseElement { children, .. } => {
2297                    for child in children {
2298                        Self::optimize(child);
2299                    }
2300                }
2301                JsExpr::TemplateLiteral { expressions, .. } => {
2302                    for expr in expressions {
2303                        Self::optimize(expr);
2304                    }
2305                }
2306                JsExpr::Spread(expr, ..) => {
2307                    Self::optimize(expr);
2308                }
2309                JsExpr::TypeOf(expr, ..) => {
2310                    Self::optimize(expr);
2311                }
2312                JsExpr::InstanceOf { left, right, .. } => {
2313                    Self::optimize(left);
2314                    Self::optimize(right);
2315                }
2316                _ => {}
2317            }
2318        }
2319    }
2320
2321    /// 语句优化器
2322    ///
2323    /// 负责优化 JavaScript 语句,包括死代码消除等优化规则。
2324    pub struct StmtOptimizer;
2325
2326    impl StmtOptimizer {
2327        /// 优化语句
2328        ///
2329        /// # Parameters
2330        /// - `stmt`: 要优化的语句
2331        pub fn optimize(stmt: &mut JsStmt) {
2332            match stmt {
2333                JsStmt::Expr(expr, ..) => {
2334                    ExprOptimizer::optimize(expr);
2335                }
2336                JsStmt::VariableDecl { init, .. } => {
2337                    if let Some(expr) = init {
2338                        ExprOptimizer::optimize(expr);
2339                    }
2340                }
2341                JsStmt::FunctionDecl { body, .. } => {
2342                    for stmt in body {
2343                        Self::optimize(stmt);
2344                    }
2345                }
2346                JsStmt::Return(expr, ..) => {
2347                    if let Some(expr) = expr {
2348                        ExprOptimizer::optimize(expr);
2349                    }
2350                }
2351                JsStmt::If { test, consequent, alternate, .. } => {
2352                    ExprOptimizer::optimize(test);
2353                    Self::optimize(consequent);
2354                    if let Some(alt) = alternate {
2355                        Self::optimize(alt);
2356                    }
2357                    // 死代码消除:常量条件
2358                    if let JsExpr::Literal(test_val, _, _) = test {
2359                        if let Some(b) = test_val.as_bool() {
2360                            if b {
2361                                *stmt = *consequent.clone();
2362                            }
2363                            else if let Some(alt) = alternate {
2364                                *stmt = *alt.clone();
2365                            }
2366                            else {
2367                                *stmt = JsStmt::Block(vec![], Span::unknown(), Trivia::new());
2368                            }
2369                        }
2370                    }
2371                }
2372                JsStmt::While { test, body, .. } => {
2373                    ExprOptimizer::optimize(test);
2374                    Self::optimize(body);
2375                    // 死代码消除:永远为 false 的条件
2376                    if let JsExpr::Literal(test_val, _, _) = test {
2377                        if let Some(b) = test_val.as_bool() {
2378                            if !b {
2379                                *stmt = JsStmt::Block(vec![], Span::unknown(), Trivia::new());
2380                            }
2381                        }
2382                    }
2383                }
2384                JsStmt::For { init, test, update, body, .. } => {
2385                    if let Some(init_stmt) = init {
2386                        Self::optimize(init_stmt);
2387                    }
2388                    if let Some(test_expr) = test {
2389                        ExprOptimizer::optimize(test_expr);
2390                    }
2391                    if let Some(update_expr) = update {
2392                        ExprOptimizer::optimize(update_expr);
2393                    }
2394                    Self::optimize(body);
2395                }
2396                JsStmt::ForIn { left, right, body, .. } => {
2397                    Self::optimize(left);
2398                    ExprOptimizer::optimize(right);
2399                    Self::optimize(body);
2400                }
2401                JsStmt::ForOf { left, right, body, .. } => {
2402                    Self::optimize(left);
2403                    ExprOptimizer::optimize(right);
2404                    Self::optimize(body);
2405                }
2406                JsStmt::Try { block, handler, finalizer, .. } => {
2407                    Self::optimize(block);
2408                    if let Some((_, body)) = handler {
2409                        Self::optimize(body);
2410                    }
2411                    if let Some(body) = finalizer {
2412                        Self::optimize(body);
2413                    }
2414                }
2415                JsStmt::Switch { discriminant, cases, .. } => {
2416                    ExprOptimizer::optimize(discriminant);
2417                    for (test, stmts) in cases {
2418                        if let Some(test_expr) = test {
2419                            ExprOptimizer::optimize(test_expr);
2420                        }
2421                        for stmt in stmts {
2422                            Self::optimize(stmt);
2423                        }
2424                    }
2425                }
2426                JsStmt::Throw(expr, ..) => {
2427                    ExprOptimizer::optimize(expr);
2428                }
2429                JsStmt::Block(stmts, ..) => {
2430                    // 移除空语句和死代码
2431                    let mut optimized_stmts = vec![];
2432                    for stmt in &mut *stmts {
2433                        let mut optimized_stmt = stmt.clone();
2434                        Self::optimize(&mut optimized_stmt);
2435                        // 移除空块
2436                        if let JsStmt::Block(inner_stmts, _, _) = optimized_stmt {
2437                            if !inner_stmts.is_empty() {
2438                                optimized_stmts.extend(inner_stmts);
2439                            }
2440                        }
2441                        else if let JsStmt::Expr(expr, _, _) = &optimized_stmt {
2442                            // 移除无效的表达式语句
2443                            if !matches!(expr, JsExpr::Identifier(_, _, _)) {
2444                                optimized_stmts.push(optimized_stmt);
2445                            }
2446                        }
2447                        else {
2448                            optimized_stmts.push(optimized_stmt);
2449                        }
2450                    }
2451                    *stmts = optimized_stmts;
2452                }
2453                _ => {}
2454            }
2455        }
2456    }
2457
2458    /// 程序优化器
2459    ///
2460    /// 负责优化 JavaScript 程序,包括移除空语句和死代码等优化规则。
2461    pub struct ProgramOptimizer;
2462
2463    impl ProgramOptimizer {
2464        /// 优化程序
2465        ///
2466        /// # Parameters
2467        /// - `program`: 要优化的程序
2468        pub fn optimize(program: &mut JsProgram) {
2469            let mut optimized_body = vec![];
2470            for stmt in &program.body {
2471                let mut optimized_stmt = stmt.clone();
2472                StmtOptimizer::optimize(&mut optimized_stmt);
2473                // 移除空块
2474                if let JsStmt::Block(inner_stmts, _, _) = optimized_stmt {
2475                    if !inner_stmts.is_empty() {
2476                        optimized_body.extend(inner_stmts);
2477                    }
2478                }
2479                else {
2480                    optimized_body.push(optimized_stmt);
2481                }
2482            }
2483            program.body = optimized_body;
2484        }
2485    }
2486
2487    /// IR 模块优化器
2488    ///
2489    /// 负责优化 IR 模块,包括优化模块中的脚本。
2490    pub struct IROptimizer;
2491
2492    impl IROptimizer {
2493        /// 优化 IR 模块
2494        ///
2495        /// # Parameters
2496        /// - `module`: 要优化的 IR 模块
2497        pub fn optimize(module: &mut IRModule) {
2498            if let Some(script) = &mut module.script {
2499                ProgramOptimizer::optimize(script);
2500            }
2501            if let Some(script_server) = &mut module.script_server {
2502                ProgramOptimizer::optimize(script_server);
2503            }
2504            if let Some(script_client) = &mut module.script_client {
2505                ProgramOptimizer::optimize(script_client);
2506            }
2507        }
2508    }
2509}
2510
2511/// 验证器模块
2512///
2513/// 提供 IR 结构的验证功能,包括类型检查、作用域分析、语义验证等。
2514pub mod validator {
2515    use super::*;
2516
2517    /// 类型信息
2518    ///
2519    /// 表示 JavaScript 表达式的类型。
2520    #[derive(Debug, Clone, PartialEq)]
2521    pub enum TypeInfo {
2522        /// 数字类型
2523        Number,
2524        /// 字符串类型
2525        String,
2526        /// 布尔类型
2527        Boolean,
2528        /// 对象类型
2529        Object,
2530        /// 数组类型
2531        Array,
2532        /// 函数类型
2533        Function,
2534        /// 未定义类型
2535        Undefined,
2536        /// 空类型
2537        Null,
2538        /// 任意类型
2539        Any,
2540    }
2541
2542    /// 类型环境
2543    pub struct TypeEnvironment {
2544        /// 变量类型映射
2545        variables: HashMap<String, TypeInfo>,
2546    }
2547
2548    impl TypeEnvironment {
2549        /// 创建新的类型环境
2550        pub fn new() -> Self {
2551            Self { variables: HashMap::new() }
2552        }
2553
2554        /// 添加变量类型
2555        pub fn add_variable(&mut self, name: String, type_info: TypeInfo) {
2556            self.variables.insert(name, type_info);
2557        }
2558
2559        /// 获取变量类型
2560        pub fn get_variable(&self, name: &String) -> Option<&TypeInfo> {
2561            self.variables.get(name)
2562        }
2563    }
2564
2565    /// 表达式验证器
2566    pub struct ExprValidator {
2567        /// 类型环境
2568        env: TypeEnvironment,
2569    }
2570
2571    impl ExprValidator {
2572        /// 创建新的表达式验证器
2573        pub fn new() -> Self {
2574            Self { env: TypeEnvironment::new() }
2575        }
2576
2577        /// 验证表达式
2578        pub fn validate(&mut self, expr: &JsExpr) -> Result<TypeInfo> {
2579            match expr {
2580                JsExpr::Identifier(id, _span, _) => {
2581                    if let Some(type_info) = self.env.get_variable(id) {
2582                        Ok(type_info.clone())
2583                    }
2584                    else {
2585                        Err(IRError::InvalidExpression(format!("Undefined variable: {}", id)).into())
2586                    }
2587                }
2588                JsExpr::Literal(value, _, _) => Ok(match value {
2589                    NargoValue::Number(_) => TypeInfo::Number,
2590                    NargoValue::String(_) => TypeInfo::String,
2591                    NargoValue::Bool(_) => TypeInfo::Boolean,
2592                    NargoValue::Object(_) => TypeInfo::Object,
2593                    NargoValue::Array(_) => TypeInfo::Array,
2594                    NargoValue::Null => TypeInfo::Null,
2595                    _ => TypeInfo::Any,
2596                }),
2597                JsExpr::Unary { op, argument, span: _, .. } => {
2598                    let arg_type = self.validate(argument)?;
2599                    match op.as_str() {
2600                        "!" => Ok(TypeInfo::Boolean),
2601                        "-" | "+" | "~" => {
2602                            if matches!(arg_type, TypeInfo::Number) {
2603                                Ok(TypeInfo::Number)
2604                            }
2605                            else {
2606                                Err(IRError::InvalidExpression(format!("Unary operator {} requires number type", op)).into())
2607                            }
2608                        }
2609                        _ => Ok(TypeInfo::Any),
2610                    }
2611                }
2612                JsExpr::Binary { left, op, right, span: _, .. } => {
2613                    let left_type = self.validate(left)?;
2614                    let right_type = self.validate(right)?;
2615                    match op.as_str() {
2616                        "+" => {
2617                            if matches!(left_type, TypeInfo::Number) && matches!(right_type, TypeInfo::Number) {
2618                                Ok(TypeInfo::Number)
2619                            }
2620                            else if matches!(left_type, TypeInfo::String) || matches!(right_type, TypeInfo::String) {
2621                                Ok(TypeInfo::String)
2622                            }
2623                            else {
2624                                Err(IRError::InvalidExpression(format!("Addition operator requires number or string types").to_string()).into())
2625                            }
2626                        }
2627                        "-" | "*" | "/" | "%" => {
2628                            if matches!(left_type, TypeInfo::Number) && matches!(right_type, TypeInfo::Number) {
2629                                Ok(TypeInfo::Number)
2630                            }
2631                            else {
2632                                Err(IRError::InvalidExpression(format!("Arithmetic operator {} requires number types", op)).into())
2633                            }
2634                        }
2635                        "==" | "!=" | "===" | "!==" => Ok(TypeInfo::Boolean),
2636                        "<" | "<=" | ">" | ">=" => {
2637                            if matches!(left_type, TypeInfo::Number) && matches!(right_type, TypeInfo::Number) {
2638                                Ok(TypeInfo::Boolean)
2639                            }
2640                            else if matches!(left_type, TypeInfo::String) && matches!(right_type, TypeInfo::String) {
2641                                Ok(TypeInfo::Boolean)
2642                            }
2643                            else {
2644                                Err(IRError::InvalidExpression(format!("Comparison operator {} requires number or string types", op)).into())
2645                            }
2646                        }
2647                        "&&" | "||" => Ok(TypeInfo::Boolean),
2648                        "&" | "|" | "^" | "<<" | ">>" | ">>>" => {
2649                            if matches!(left_type, TypeInfo::Number) && matches!(right_type, TypeInfo::Number) {
2650                                Ok(TypeInfo::Number)
2651                            }
2652                            else {
2653                                Err(IRError::InvalidExpression(format!("Bitwise operator {} requires number types", op)).into())
2654                            }
2655                        }
2656                        "=" | "+=" | "-=" | "*=" | "/=" | "%=" | "&=" | "|=" | "^=" | "<<=" | ">>=" | ">>>=" => Ok(left_type),
2657                        _ => Ok(TypeInfo::Any),
2658                    }
2659                }
2660                JsExpr::Call { callee, args, span: _, .. } => {
2661                    let callee_type = self.validate(callee)?;
2662                    if matches!(callee_type, TypeInfo::Function) {
2663                        // 验证参数
2664                        for arg in args {
2665                            self.validate(arg)?;
2666                        }
2667                        Ok(TypeInfo::Any)
2668                    }
2669                    else {
2670                        Err(IRError::InvalidExpression("Callee must be a function".to_string()).into())
2671                    }
2672                }
2673                JsExpr::Member { object, property, .. } => {
2674                    self.validate(object)?;
2675                    self.validate(property)?;
2676                    Ok(TypeInfo::Any)
2677                }
2678                JsExpr::OptionalMember { object, property, .. } => {
2679                    self.validate(object)?;
2680                    self.validate(property)?;
2681                    Ok(TypeInfo::Any)
2682                }
2683                JsExpr::OptionalCall { callee, args, .. } => {
2684                    self.validate(callee)?;
2685                    for arg in args {
2686                        self.validate(arg)?;
2687                    }
2688                    Ok(TypeInfo::Any)
2689                }
2690                JsExpr::NullishCoalescing { left, right, .. } => {
2691                    self.validate(left)?;
2692                    self.validate(right)?;
2693                    Ok(TypeInfo::Any)
2694                }
2695                JsExpr::LogicalAssignment { left, right, .. } => {
2696                    self.validate(left)?;
2697                    self.validate(right)?;
2698                    Ok(TypeInfo::Any)
2699                }
2700                JsExpr::Array(items, ..) => {
2701                    for item in items {
2702                        self.validate(item)?;
2703                    }
2704                    Ok(TypeInfo::Array)
2705                }
2706                JsExpr::Object(props, ..) => {
2707                    for (_, value) in props {
2708                        self.validate(value)?;
2709                    }
2710                    Ok(TypeInfo::Object)
2711                }
2712                JsExpr::ArrowFunction { params, body, .. } => {
2713                    // 添加参数到环境
2714                    for param in params {
2715                        self.env.add_variable(param.clone(), TypeInfo::Any);
2716                    }
2717                    self.validate(body)?;
2718                    Ok(TypeInfo::Function)
2719                }
2720                JsExpr::TseElement { children, .. } => {
2721                    for child in children {
2722                        self.validate(child)?;
2723                    }
2724                    Ok(TypeInfo::Any)
2725                }
2726                JsExpr::Conditional { test, consequent, alternate, .. } => {
2727                    let test_type = self.validate(test)?;
2728                    if !matches!(test_type, TypeInfo::Boolean) {
2729                        return Err(IRError::InvalidExpression("Condition must be a boolean".to_string()).into());
2730                    }
2731                    let _consequent_type = self.validate(consequent)?;
2732                    let _alternate_type = self.validate(alternate)?;
2733                    // 简化处理,返回任意类型
2734                    Ok(TypeInfo::Any)
2735                }
2736                JsExpr::TemplateLiteral { expressions, .. } => {
2737                    for expr in expressions {
2738                        self.validate(expr)?;
2739                    }
2740                    Ok(TypeInfo::String)
2741                }
2742                JsExpr::Spread(expr, ..) => {
2743                    self.validate(expr)?;
2744                    Ok(TypeInfo::Any)
2745                }
2746                JsExpr::TypeOf(expr, ..) => {
2747                    self.validate(expr)?;
2748                    Ok(TypeInfo::String)
2749                }
2750                JsExpr::InstanceOf { left, right, .. } => {
2751                    self.validate(left)?;
2752                    self.validate(right)?;
2753                    Ok(TypeInfo::Boolean)
2754                }
2755                JsExpr::Other(_, _, _) => Ok(TypeInfo::Any),
2756            }
2757        }
2758    }
2759
2760    /// 语句验证器
2761    pub struct StmtValidator {
2762        /// 表达式验证器
2763        expr_validator: ExprValidator,
2764    }
2765
2766    impl StmtValidator {
2767        /// 创建新的语句验证器
2768        pub fn new() -> Self {
2769            Self { expr_validator: ExprValidator::new() }
2770        }
2771
2772        /// 验证语句
2773        pub fn validate(&mut self, stmt: &JsStmt) -> Result<()> {
2774            match stmt {
2775                JsStmt::Expr(expr, ..) => {
2776                    self.expr_validator.validate(expr)?;
2777                    Ok(())
2778                }
2779                JsStmt::VariableDecl { kind: _, id, init, .. } => {
2780                    if let Some(expr) = init {
2781                        let type_info = self.expr_validator.validate(expr)?;
2782                        self.expr_validator.env.add_variable(id.clone(), type_info);
2783                    }
2784                    else {
2785                        // 未初始化的变量,默认为任意类型
2786                        self.expr_validator.env.add_variable(id.clone(), TypeInfo::Any);
2787                    }
2788                    Ok(())
2789                }
2790                JsStmt::Import { .. } => Ok(()),
2791                JsStmt::Export { declaration, .. } => self.validate(declaration),
2792                JsStmt::ExportAll { .. } => Ok(()),
2793                JsStmt::ExportNamed { .. } => Ok(()),
2794                JsStmt::FunctionDecl { id, params, body, .. } => {
2795                    // 添加函数到环境
2796                    self.expr_validator.env.add_variable(id.clone(), TypeInfo::Function);
2797                    // 添加参数到环境
2798                    for param in params {
2799                        self.expr_validator.env.add_variable(param.clone(), TypeInfo::Any);
2800                    }
2801                    // 验证函数体
2802                    for stmt in body {
2803                        self.validate(stmt)?;
2804                    }
2805                    Ok(())
2806                }
2807                JsStmt::Return(expr, ..) => {
2808                    if let Some(expr) = expr {
2809                        self.expr_validator.validate(expr)?;
2810                    }
2811                    Ok(())
2812                }
2813                JsStmt::If { test, consequent, alternate, .. } => {
2814                    let test_type = self.expr_validator.validate(test)?;
2815                    if !matches!(test_type, TypeInfo::Boolean) {
2816                        return Err(IRError::InvalidExpression("Condition must be a boolean".to_string()).into());
2817                    }
2818                    self.validate(consequent)?;
2819                    if let Some(alt) = alternate {
2820                        self.validate(alt)?;
2821                    }
2822                    Ok(())
2823                }
2824                JsStmt::While { test, body, .. } => {
2825                    let test_type = self.expr_validator.validate(test)?;
2826                    if !matches!(test_type, TypeInfo::Boolean) {
2827                        return Err(IRError::InvalidExpression("Condition must be a boolean".to_string()).into());
2828                    }
2829                    self.validate(body)?;
2830                    Ok(())
2831                }
2832                JsStmt::For { init, test, update, body, .. } => {
2833                    if let Some(init_stmt) = init {
2834                        self.validate(init_stmt)?;
2835                    }
2836                    if let Some(test_expr) = test {
2837                        let test_type = self.expr_validator.validate(test_expr)?;
2838                        if !matches!(test_type, TypeInfo::Boolean) {
2839                            return Err(IRError::InvalidExpression("Condition must be a boolean".to_string()).into());
2840                        }
2841                    }
2842                    if let Some(update_expr) = update {
2843                        self.expr_validator.validate(update_expr)?;
2844                    }
2845                    self.validate(body)?;
2846                    Ok(())
2847                }
2848                JsStmt::ForIn { left, right, body, .. } => {
2849                    self.validate(left)?;
2850                    self.expr_validator.validate(right)?;
2851                    self.validate(body)?;
2852                    Ok(())
2853                }
2854                JsStmt::ForOf { left, right, body, .. } => {
2855                    self.validate(left)?;
2856                    self.expr_validator.validate(right)?;
2857                    self.validate(body)?;
2858                    Ok(())
2859                }
2860                JsStmt::Try { block, handler, finalizer, .. } => {
2861                    self.validate(block)?;
2862                    if let Some((id, body)) = handler {
2863                        // 添加错误变量到环境
2864                        self.expr_validator.env.add_variable(id.clone(), TypeInfo::Any);
2865                        self.validate(body)?;
2866                    }
2867                    if let Some(body) = finalizer {
2868                        self.validate(body)?;
2869                    }
2870                    Ok(())
2871                }
2872                JsStmt::Switch { discriminant, cases, .. } => {
2873                    self.expr_validator.validate(discriminant)?;
2874                    for (test, stmts) in cases {
2875                        if let Some(test_expr) = test {
2876                            self.expr_validator.validate(test_expr)?;
2877                        }
2878                        for stmt in stmts {
2879                            self.validate(stmt)?;
2880                        }
2881                    }
2882                    Ok(())
2883                }
2884                JsStmt::Throw(expr, ..) => {
2885                    self.expr_validator.validate(expr)?;
2886                    Ok(())
2887                }
2888                JsStmt::Block(stmts, ..) => {
2889                    for stmt in stmts {
2890                        self.validate(stmt)?;
2891                    }
2892                    Ok(())
2893                }
2894                JsStmt::Break(_, _) => Ok(()),
2895                JsStmt::Continue(_, _) => Ok(()),
2896                JsStmt::Other(_, _, _) => Ok(()),
2897            }
2898        }
2899    }
2900
2901    /// 程序验证器
2902    pub struct ProgramValidator {
2903        /// 语句验证器
2904        stmt_validator: StmtValidator,
2905    }
2906
2907    impl ProgramValidator {
2908        /// 创建新的程序验证器
2909        pub fn new() -> Self {
2910            Self { stmt_validator: StmtValidator::new() }
2911        }
2912
2913        /// 验证程序
2914        pub fn validate(&mut self, program: &JsProgram) -> Result<()> {
2915            for stmt in &program.body {
2916                self.stmt_validator.validate(stmt)?;
2917            }
2918            Ok(())
2919        }
2920    }
2921
2922    /// IR 模块验证器
2923    pub struct IRValidator {
2924        /// 程序验证器
2925        program_validator: ProgramValidator,
2926    }
2927
2928    impl IRValidator {
2929        /// 创建新的 IR 模块验证器
2930        pub fn new() -> Self {
2931            Self { program_validator: ProgramValidator::new() }
2932        }
2933
2934        /// 验证 IR 模块
2935        pub fn validate(&mut self, module: &IRModule) -> Result<()> {
2936            // 首先执行基本验证
2937            module.validate()?;
2938
2939            // 然后执行类型检查和语义验证
2940            if let Some(script) = &module.script {
2941                self.program_validator.validate(script)?;
2942            }
2943            if let Some(script_server) = &module.script_server {
2944                self.program_validator.validate(script_server)?;
2945            }
2946            if let Some(script_client) = &module.script_client {
2947                self.program_validator.validate(script_client)?;
2948            }
2949
2950            Ok(())
2951        }
2952    }
2953}