Skip to main content

presolve_compiler/
component_ir_optimization.rs

1use crate::{ComponentIrReport, SourceProvenance};
2
3/// Immutable H12 component-IR optimization result.
4///
5/// Component creation, Context initialization, template materialization, and
6/// Slot placement are observable roots. The H11 lowering already excludes
7/// blocked and statically empty work, so this first optimization projection
8/// intentionally retains the complete operation stream unchanged.
9#[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/// Optimizes only semantically unobservable component work.
17///
18/// No current H11 instruction satisfies that condition. Keeping the identity
19/// projection explicit makes the H12 boundary authoritative while preserving
20/// every instance, Context slot, Slot binding, and observable order.
21#[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}