Skip to main content

nargo_optimizer/
lib.rs

1#![warn(missing_docs)]
2
3use nargo_ir::IRModule;
4use nargo_transformer::{CallCountPass, ConstantFoldingPass, DeadCodeEliminationPass, I18nPass, ScopedCssPass, StaticHoistingPass, StyleAnalysisPass, Transformer, TreeShakingPass};
5use nargo_types::{NargoValue, Result};
6
7/// 目标环境
8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9pub enum TargetEnvironment {
10    /// 浏览器环境
11    Browser,
12    /// 服务器端渲染环境
13    SSR,
14    /// 移动应用环境
15    Mobile,
16    /// 桌面应用环境
17    Desktop,
18    /// 嵌入式环境
19    Embedded,
20}
21
22impl Default for TargetEnvironment {
23    fn default() -> Self {
24        Self::Browser
25    }
26}
27
28/// 环境特定优化配置
29#[derive(Debug, Clone, Default)]
30pub struct EnvironmentOptimizationConfig {
31    /// 目标环境
32    pub target: TargetEnvironment,
33    /// 是否启用内存优化
34    pub memory_optimization: bool,
35    /// 是否启用性能优化
36    pub performance_optimization: bool,
37    /// 是否启用大小优化
38    pub size_optimization: bool,
39    /// 特定环境的额外配置
40    pub extra_config: std::collections::HashMap<String, String>,
41}
42
43/// 优化级别
44#[derive(Debug, Clone, PartialEq)]
45pub enum OptimizationLevel {
46    /// 无优化
47    None,
48    /// 基本优化
49    Basic,
50    /// 标准优化
51    Standard,
52    /// 激进优化
53    Aggressive,
54}
55
56/// Nargo 优化器
57///
58/// 负责对 IR 模块进行各种优化,包括常量折叠、死代码消除、静态提升等。
59pub struct Optimizer {
60    /// 上次生成的 CSS
61    pub last_css: String,
62    /// 优化级别
63    pub optimization_level: OptimizationLevel,
64    /// 环境优化配置
65    pub environment_config: EnvironmentOptimizationConfig,
66}
67
68impl Default for Optimizer {
69    fn default() -> Self {
70        Self::new()
71    }
72}
73
74impl Optimizer {
75    /// 创建新的优化器实例
76    pub fn new() -> Self {
77        Self { last_css: String::new(), optimization_level: OptimizationLevel::Standard, environment_config: EnvironmentOptimizationConfig::default() }
78    }
79
80    /// 设置优化级别
81    ///
82    /// # Arguments
83    ///
84    /// * `level` - 优化级别
85    pub fn set_optimization_level(&mut self, level: OptimizationLevel) {
86        self.optimization_level = level;
87    }
88
89    /// 设置环境优化配置
90    ///
91    /// # Arguments
92    ///
93    /// * `config` - 环境优化配置
94    pub fn set_environment_config(&mut self, config: EnvironmentOptimizationConfig) {
95        self.environment_config = config;
96    }
97
98    /// 设置目标环境
99    ///
100    /// # Arguments
101    ///
102    /// * `target` - 目标环境
103    pub fn set_target_environment(&mut self, target: TargetEnvironment) {
104        self.environment_config.target = target;
105    }
106
107    /// 优化 IR 模块
108    ///
109    /// # Arguments
110    ///
111    /// * `ir` - IR 模块
112    /// * `locale` - 国际化语言环境
113    /// * `is_prod` - 是否为生产环境
114    pub fn optimize(&mut self, ir: &mut IRModule, locale: Option<&str>, is_prod: bool) {
115        match self.optimization_level {
116            OptimizationLevel::None => {
117                // 无优化
118                return;
119            }
120            OptimizationLevel::Basic => {
121                // 基本优化
122                self.apply_basic_optimizations(ir, locale);
123            }
124            OptimizationLevel::Standard => {
125                // 标准优化
126                self.apply_basic_optimizations(ir, locale);
127                self.apply_standard_optimizations(ir);
128            }
129            OptimizationLevel::Aggressive => {
130                // 激进优化
131                self.apply_basic_optimizations(ir, locale);
132                self.apply_standard_optimizations(ir);
133                self.apply_aggressive_optimizations(ir);
134            }
135        }
136
137        // 应用环境特定优化
138        self.apply_environment_specific_optimizations(ir);
139
140        if is_prod {
141            // 生产环境的额外优化
142            self.apply_production_optimizations(ir);
143        }
144    }
145
146    /// 应用基本优化
147    ///
148    /// # Arguments
149    ///
150    /// * `ir` - IR 模块
151    /// * `locale` - 国际化语言环境
152    fn apply_basic_optimizations(&self, ir: &mut IRModule, locale: Option<&str>) {
153        let mut transformer = Transformer::new();
154
155        // 1. 常量折叠
156        let mut folding_pass = ConstantFoldingPass::new();
157        let _ = transformer.apply(ir, &mut folding_pass);
158
159        // 2. 死代码消除
160        let mut dce_pass = DeadCodeEliminationPass::new();
161        let _ = transformer.apply(ir, &mut dce_pass);
162
163        // 3. 国际化优化
164        if let Some(locale_val) = locale {
165            if let Some(i18n_map) = &ir.i18n {
166                if let Some(messages) = i18n_map.get(locale_val) {
167                    let mut i18n_pass = I18nPass::new(messages.clone());
168                    let _ = transformer.apply(ir, &mut i18n_pass);
169                }
170            }
171        }
172    }
173
174    /// 应用标准优化
175    ///
176    /// # Arguments
177    ///
178    /// * `ir` - IR 模块
179    fn apply_standard_optimizations(&self, ir: &mut IRModule) {
180        let mut transformer = Transformer::new();
181
182        // 1. 静态提升
183        let mut hoisting_pass = StaticHoistingPass::new();
184        let _ = transformer.apply(ir, &mut hoisting_pass);
185
186        // 2. 样式分析和提取
187        let mut style_pass = StyleAnalysisPass::new();
188        let _ = transformer.apply(ir, &mut style_pass);
189
190        // 3. 调用计数分析(用于内联决策)
191        let mut call_count_pass = CallCountPass::new();
192        let _ = transformer.apply(ir, &mut call_count_pass);
193    }
194
195    /// 应用激进优化
196    ///
197    /// # Arguments
198    ///
199    /// * `ir` - IR 模块
200    fn apply_aggressive_optimizations(&self, ir: &mut IRModule) {
201        let mut transformer = Transformer::new();
202
203        // 1. 树摇优化
204        let mut tree_shaking_pass = TreeShakingPass::new();
205        let _ = transformer.apply(ir, &mut tree_shaking_pass);
206    }
207
208    /// 应用生产环境优化
209    ///
210    /// # Arguments
211    ///
212    /// * `ir` - IR 模块
213    fn apply_production_optimizations(&self, ir: &mut IRModule) {
214        let mut transformer = Transformer::new();
215
216        // 1. 再次运行死代码消除(确保所有优化后没有新的死代码)
217        let mut dce_pass = DeadCodeEliminationPass::new();
218        let _ = transformer.apply(ir, &mut dce_pass);
219
220        // 2. 再次运行树摇(确保所有优化后没有新的未使用代码)
221        let mut tree_shaking_pass = TreeShakingPass::new();
222        let _ = transformer.apply(ir, &mut tree_shaking_pass);
223
224        // 3. 清理 IR 模块中的冗余信息
225        ir.cleanup();
226    }
227
228    /// 应用环境特定优化
229    ///
230    /// # Arguments
231    ///
232    /// * `ir` - IR 模块
233    fn apply_environment_specific_optimizations(&self, ir: &mut IRModule) {
234        match self.environment_config.target {
235            TargetEnvironment::Browser => {
236                self.apply_browser_optimizations(ir);
237            }
238            TargetEnvironment::SSR => {
239                self.apply_ssr_optimizations(ir);
240            }
241            TargetEnvironment::Mobile => {
242                self.apply_mobile_optimizations(ir);
243            }
244            TargetEnvironment::Desktop => {
245                self.apply_desktop_optimizations(ir);
246            }
247            TargetEnvironment::Embedded => {
248                self.apply_embedded_optimizations(ir);
249            }
250        }
251    }
252
253    /// 应用浏览器环境优化
254    ///
255    /// # Arguments
256    ///
257    /// * `ir` - IR 模块
258    fn apply_browser_optimizations(&self, ir: &mut IRModule) {
259        let mut transformer = Transformer::new();
260
261        // 1. 针对浏览器的大小优化
262        if self.environment_config.size_optimization {
263            // 额外的树摇优化
264            let mut tree_shaking_pass = TreeShakingPass::new();
265            let _ = transformer.apply(ir, &mut tree_shaking_pass);
266        }
267
268        // 2. 针对浏览器的性能优化
269        if self.environment_config.performance_optimization {
270            // 静态提升优化
271            let mut hoisting_pass = StaticHoistingPass::new();
272            let _ = transformer.apply(ir, &mut hoisting_pass);
273        }
274    }
275
276    /// 应用服务器端渲染环境优化
277    ///
278    /// # Arguments
279    ///
280    /// * `ir` - IR 模块
281    fn apply_ssr_optimizations(&self, ir: &mut IRModule) {
282        let mut transformer = Transformer::new();
283
284        // 1. 针对 SSR 的内存优化
285        if self.environment_config.memory_optimization {
286            // 死代码消除
287            let mut dce_pass = DeadCodeEliminationPass::new();
288            let _ = transformer.apply(ir, &mut dce_pass);
289        }
290
291        // 2. 针对 SSR 的性能优化
292        if self.environment_config.performance_optimization {
293            // 常量折叠
294            let mut folding_pass = ConstantFoldingPass::new();
295            let _ = transformer.apply(ir, &mut folding_pass);
296        }
297    }
298
299    /// 应用移动应用环境优化
300    ///
301    /// # Arguments
302    ///
303    /// * `ir` - IR 模块
304    fn apply_mobile_optimizations(&self, ir: &mut IRModule) {
305        let mut transformer = Transformer::new();
306
307        // 1. 针对移动应用的大小优化
308        if self.environment_config.size_optimization {
309            // 树摇优化
310            let mut tree_shaking_pass = TreeShakingPass::new();
311            let _ = transformer.apply(ir, &mut tree_shaking_pass);
312        }
313
314        // 2. 针对移动应用的内存优化
315        if self.environment_config.memory_optimization {
316            // 死代码消除
317            let mut dce_pass = DeadCodeEliminationPass::new();
318            let _ = transformer.apply(ir, &mut dce_pass);
319        }
320    }
321
322    /// 应用桌面应用环境优化
323    ///
324    /// # Arguments
325    ///
326    /// * `ir` - IR 模块
327    fn apply_desktop_optimizations(&self, ir: &mut IRModule) {
328        let mut transformer = Transformer::new();
329
330        // 1. 针对桌面应用的性能优化
331        if self.environment_config.performance_optimization {
332            // 静态提升
333            let mut hoisting_pass = StaticHoistingPass::new();
334            let _ = transformer.apply(ir, &mut hoisting_pass);
335
336            // 调用计数分析
337            let mut call_count_pass = CallCountPass::new();
338            let _ = transformer.apply(ir, &mut call_count_pass);
339        }
340    }
341
342    /// 应用嵌入式环境优化
343    ///
344    /// # Arguments
345    ///
346    /// * `ir` - IR 模块
347    fn apply_embedded_optimizations(&self, ir: &mut IRModule) {
348        let mut transformer = Transformer::new();
349
350        // 1. 针对嵌入式环境的大小优化(最优先)
351        if self.environment_config.size_optimization {
352            // 树摇优化
353            let mut tree_shaking_pass = TreeShakingPass::new();
354            let _ = transformer.apply(ir, &mut tree_shaking_pass);
355        }
356
357        // 2. 针对嵌入式环境的内存优化
358        if self.environment_config.memory_optimization {
359            // 死代码消除
360            let mut dce_pass = DeadCodeEliminationPass::new();
361            let _ = transformer.apply(ir, &mut dce_pass);
362        }
363
364        // 3. 针对嵌入式环境的性能优化
365        if self.environment_config.performance_optimization {
366            // 常量折叠
367            let mut folding_pass = ConstantFoldingPass::new();
368            let _ = transformer.apply(ir, &mut folding_pass);
369        }
370    }
371
372    /// 处理样式
373    ///
374    /// # Arguments
375    ///
376    /// * `ir` - IR 模块
377    ///
378    /// # Returns
379    ///
380    /// 处理结果
381    pub fn process_styles(&mut self, ir: &IRModule) -> Result<()> {
382        let mut final_css = String::new();
383
384        // 1. 处理常规 CSS 样式
385        for style in &ir.styles {
386            final_css.push_str(&style.code);
387            final_css.push('\n');
388        }
389
390        // 2. 处理收集的类(Tailwind)
391        if let Some(NargoValue::String(classes)) = ir.metadata.get("collected_styles") {
392            // 生成 Tailwind CSS 代码
393            final_css.push_str(&self.generate_tailwind_css(classes));
394        }
395
396        self.last_css = final_css;
397        Ok(())
398    }
399
400    /// 生成 Tailwind CSS 代码
401    ///
402    /// # Arguments
403    ///
404    /// * `classes` - 类名列表
405    ///
406    /// # Returns
407    ///
408    /// CSS 代码
409    fn generate_tailwind_css(&self, classes: &str) -> String {
410        let mut css = String::new();
411
412        // 简单的 Tailwind 类名到 CSS 的映射
413        let class_map = std::collections::HashMap::from([("p-4", "padding: 1rem;"), ("p-6", "padding: 1.5rem;"), ("m-2", "margin: 0.5rem;"), ("m-4", "margin: 1rem;"), ("flex", "display: flex;"), ("items-center", "align-items: center;"), ("bg-blue", "background-color: #0000ff;"), ("text-white", "color: #ffffff;"), ("text-blue", "color: #0000ff;"), ("rounded-lg", "border-radius: 0.5rem;"), ("shadow-sm", "box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);"), ("font-bold", "font-weight: 700;"), ("text-2xl", "font-size: 1.5rem;"), ("text-center", "text-align: center;"), ("mx-4", "margin-left: 1rem; margin-right: 1rem;")]);
414
415        for class in classes.split_whitespace() {
416            if let Some(style) = class_map.get(class) {
417                css.push_str(&format!(".{} {{ {} }}\n", class, style));
418            }
419        }
420
421        css
422    }
423
424    /// 获取生成的 CSS
425    ///
426    /// # Returns
427    ///
428    /// CSS 代码
429    pub fn get_css(&self) -> String {
430        self.last_css.clone()
431    }
432
433    /// 应用作用域 ID
434    ///
435    /// # Arguments
436    ///
437    /// * `ir` - IR 模块
438    /// * `scope_id` - 作用域 ID
439    pub fn apply_scope_id(&mut self, ir: &mut IRModule, scope_id: &str) {
440        let mut transformer = Transformer::new();
441        let mut pass = ScopedCssPass::new(scope_id.to_string());
442        let _ = transformer.apply(ir, &mut pass);
443    }
444
445    /// 生成作用域 ID
446    ///
447    /// # Arguments
448    ///
449    /// * `name` - 组件名称
450    ///
451    /// # Returns
452    ///
453    /// 作用域 ID
454    pub fn generate_scope_id(&self, name: &str) -> String {
455        use std::{
456            collections::hash_map::DefaultHasher,
457            hash::{Hash, Hasher},
458        };
459        let mut hasher = DefaultHasher::new();
460        name.hash(&mut hasher);
461        let hash = hasher.finish();
462        format!("data-h-{:x}", hash)
463    }
464
465    /// 设置是否启用详细优化(兼容旧接口)
466    ///
467    /// # Arguments
468    ///
469    /// * `enabled` - 是否启用
470    pub fn set_detailed_optimizations(&mut self, enabled: bool) {
471        if enabled {
472            self.optimization_level = OptimizationLevel::Aggressive;
473        }
474        else {
475            self.optimization_level = OptimizationLevel::Basic;
476        }
477    }
478}