presolve_compiler/
component_ir_optimization.rs1use crate::{ComponentIrReport, SourceProvenance};
2
3#[derive(Debug, Clone, PartialEq, Eq, Default)]
10pub struct OptimizedComponentIrReport {
11 pub source_report: ComponentIrReport,
12 pub optimized_report: ComponentIrReport,
13 pub eliminated_instruction_provenance: Vec<SourceProvenance>,
14}
15
16#[must_use]
22pub fn optimize_component_ir(report: &ComponentIrReport) -> OptimizedComponentIrReport {
23 OptimizedComponentIrReport {
24 source_report: report.clone(),
25 optimized_report: report.clone(),
26 eliminated_instruction_provenance: Vec::new(),
27 }
28}
29
30#[must_use]
31pub fn validate_optimized_component_ir(report: &OptimizedComponentIrReport) -> Vec<String> {
32 let expected = optimize_component_ir(&report.source_report);
33 (report != &expected)
34 .then(|| {
35 "optimized component IR does not preserve the canonical observable stream".to_string()
36 })
37 .into_iter()
38 .collect()
39}
40
41#[cfg(test)]
42mod tests {
43 use crate::{
44 build_application_semantic_model, optimize_component_ir, validate_optimized_component_ir,
45 };
46
47 #[test]
48 fn preserves_every_observable_component_identity_and_order() {
49 let model = build_application_semantic_model(&presolve_parser::parse_file(
50 "src/Optimize.tsx",
51 r#"
52@component("x-card") class Card extends Component { @slot() children!: SlotContent; render() { return <article><slot /></article>; } }
53@component("x-page") class Page extends Component { render() { return <Card><p /></Card>; } }
54"#,
55 ));
56 let optimized = optimize_component_ir(&model.component_ir);
57 assert_eq!(optimized.source_report, model.component_ir);
58 assert_eq!(optimized.optimized_report, model.component_ir);
59 assert!(optimized.eliminated_instruction_provenance.is_empty());
60 assert!(validate_optimized_component_ir(&optimized).is_empty());
61 }
62
63 #[test]
64 fn asm_validation_rejects_mutated_optimized_component_ir() {
65 let mut model = build_application_semantic_model(&presolve_parser::parse_file(
66 "src/OptimizeValidate.tsx",
67 r#"@component("x-page") class Page extends Component { render() { return <main />; } }"#,
68 ));
69 model
70 .component_ir_optimization
71 .optimized_report
72 .instructions
73 .clear();
74 assert!(crate::validate_application_semantic_model(&model)
75 .iter()
76 .any(|diagnostic| diagnostic.code == "PSASM1200"));
77 }
78}