Skip to main content

omena_query/boundary/
evaluator.rs

1use omena_query_transform_runner::{
2    NATIVE_CSS_STATIC_EVAL_DIALECT_RESTRICTION_V0, NATIVE_CSS_STATIC_EVAL_OPT_IN_POLICY_V0,
3    NATIVE_CSS_STATIC_EVAL_SPEC_SNAPSHOT_V0,
4};
5use omena_scss_eval::{
6    OmenaScssEvalControlFlowOracleCorpusReportV0, OmenaScssEvalControlFlowWideningWitnessV0,
7    OmenaScssEvalStaticStylesheetEvaluationV0, OmenaScssEvalStaticStylesheetOracleCorpusReportV0,
8    OmenaScssEvalStaticValueResolutionReportV0, analyze_scss_control_flow_values,
9    derive_static_stylesheet_module_evaluation, summarize_native_css_function_call_evaluations,
10    summarize_native_css_function_surface, summarize_native_css_if_function_decisions,
11    summarize_native_css_static_edit_plan, summarize_scss_call_return_ir,
12    summarize_scss_control_flow_ir, summarize_scss_control_flow_oracle_corpus,
13    summarize_scss_control_flow_prune_reachability, summarize_static_stylesheet_oracle_corpus,
14    summarize_static_stylesheet_value_resolution,
15};
16use serde::Serialize;
17
18use crate::{
19    EngineInputV2, OMENA_QUERY_CURRENT_SCHEMA_VERSION, OmenaParserStyleDialect,
20    OmenaQueryScssEvalCallReturnIrSummaryV0, OmenaQueryScssEvalControlFlowIrSummaryV0,
21    OmenaQueryScssEvalControlFlowPruneReachabilityV0, OmenaQueryScssEvalControlFlowValueAnalysisV0,
22    OmenaQueryScssEvalNativeCssFunctionCallEvaluationSurfaceV0,
23    OmenaQueryScssEvalNativeCssFunctionSurfaceV0,
24    OmenaQueryScssEvalNativeCssIfFunctionDecisionSurfaceV0,
25    OmenaQueryScssEvalNativeCssStaticEditPlanV0,
26};
27
28#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
29#[serde(rename_all = "camelCase")]
30pub struct OmenaQueryScssEvaluatorControlFlowSummaryV0 {
31    pub schema_version: &'static str,
32    pub product: &'static str,
33    pub mode: &'static str,
34    pub dialect: &'static str,
35    pub value_type: &'static str,
36    pub supported_dialect: bool,
37    pub flat_css_cfg_built: bool,
38    pub merged_cross_file_graph: bool,
39    pub control_flow_block_count: usize,
40    pub control_flow_branch_block_count: usize,
41    pub control_flow_loop_block_count: usize,
42    pub control_flow_back_edge_count: usize,
43    pub call_return_node_count: usize,
44    pub call_return_edge_count: usize,
45    pub call_resolved_return_value_count: usize,
46    pub exact_call_resolved_return_value_count: usize,
47    pub value_analysis_converged: bool,
48    pub value_analysis_iteration_count: usize,
49    pub value_analysis_widened_to_top_count: usize,
50    pub prune_reachability_available: bool,
51    pub prune_reachability_converged: bool,
52    pub prune_reachability_flat_css_cfg_built: bool,
53    pub prune_reachability_have_terminals_changed: bool,
54    pub prune_reachability_reachable_block_count: usize,
55    pub prune_reachability_unreachable_block_count: usize,
56    pub ready_surfaces: Vec<&'static str>,
57    pub control_flow_ir: Option<OmenaQueryScssEvalControlFlowIrSummaryV0>,
58    pub value_analysis: Option<OmenaQueryScssEvalControlFlowValueAnalysisV0>,
59    pub prune_reachability: Option<OmenaQueryScssEvalControlFlowPruneReachabilityV0>,
60    pub call_return_ir: Option<OmenaQueryScssEvalCallReturnIrSummaryV0>,
61}
62
63#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
64#[serde(rename_all = "camelCase")]
65pub struct OmenaQueryScssEvaluatorControlFlowOracleCorpusSummaryV0 {
66    pub schema_version: &'static str,
67    pub product: &'static str,
68    pub mode: &'static str,
69    pub value_type: &'static str,
70    pub node_key_type: &'static str,
71    pub recursion_cap: usize,
72    pub fixture_count: usize,
73    pub scss_fixture_count: usize,
74    pub sass_fixture_count: usize,
75    pub supported_fixture_count: usize,
76    pub rejected_flat_css_fixture_count: usize,
77    pub control_flow_fixture_count: usize,
78    pub branch_fixture_count: usize,
79    pub loop_fixture_count: usize,
80    pub back_edge_fixture_count: usize,
81    pub call_return_fixture_count: usize,
82    pub resolved_call_return_fixture_count: usize,
83    pub top_call_return_fixture_count: usize,
84    pub recursive_call_fixture_count: usize,
85    pub converged_value_analysis_fixture_count: usize,
86    pub widened_to_top_fixture_count: usize,
87    pub widening_witness_widened_to_top_count: usize,
88    pub widening_witness_converged: bool,
89    pub prune_reachability_fixture_count: usize,
90    pub prune_reachability_changed_fixture_count: usize,
91    pub prune_reachability_flat_css_cfg_built_count: usize,
92    pub flat_css_cfg_built_count: usize,
93    pub merged_cross_file_graph_count: usize,
94    pub all_supported_fixtures_converged: bool,
95    pub no_flat_css_cfg_built: bool,
96    pub no_merged_cross_file_graph: bool,
97    pub widening_witness: OmenaScssEvalControlFlowWideningWitnessV0,
98    pub corpus: OmenaScssEvalControlFlowOracleCorpusReportV0,
99}
100
101#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
102#[serde(rename_all = "camelCase")]
103pub struct OmenaQueryNativeCssEvaluatorSummaryV0 {
104    pub schema_version: &'static str,
105    pub product: &'static str,
106    pub mode: &'static str,
107    pub dialect: &'static str,
108    pub supported_dialect: bool,
109    pub native_static_eval_spec_snapshot: &'static str,
110    pub native_static_eval_opt_in_policy: &'static str,
111    pub native_static_eval_dialect_restriction: &'static str,
112    pub native_static_eval_explicit_opt_in_required: bool,
113    pub native_function_surface_available: bool,
114    pub native_function_call_evaluation_available: bool,
115    pub native_static_edit_plan_available: bool,
116    pub if_function_decision_available: bool,
117    pub native_function_count: usize,
118    pub native_function_parameter_count: usize,
119    pub native_function_typed_parameter_count: usize,
120    pub native_function_result_count: usize,
121    pub native_function_call_count: usize,
122    pub native_function_call_foldable_count: usize,
123    pub native_function_call_preserved_count: usize,
124    pub native_function_call_structural_error_count: usize,
125    pub native_function_call_runtime_dependent_count: usize,
126    pub native_function_call_missing_result_count: usize,
127    pub native_static_edit_count: usize,
128    pub native_static_edit_output_changed: bool,
129    pub if_function_count: usize,
130    pub if_function_foldable_count: usize,
131    pub if_function_preserved_count: usize,
132    pub if_function_static_supports_branch_count: usize,
133    pub if_function_runtime_branch_count: usize,
134    pub ready_surfaces: Vec<&'static str>,
135    pub native_function_surface: Option<OmenaQueryScssEvalNativeCssFunctionSurfaceV0>,
136    pub native_function_call_evaluations:
137        Option<OmenaQueryScssEvalNativeCssFunctionCallEvaluationSurfaceV0>,
138    pub native_static_edit_plan: Option<OmenaQueryScssEvalNativeCssStaticEditPlanV0>,
139    pub if_function_decisions: Option<OmenaQueryScssEvalNativeCssIfFunctionDecisionSurfaceV0>,
140}
141
142#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
143#[serde(rename_all = "camelCase")]
144pub struct OmenaQueryStaticStylesheetEvaluatorSummaryV0 {
145    pub schema_version: &'static str,
146    pub product: &'static str,
147    pub mode: &'static str,
148    pub dialect: &'static str,
149    pub value_type: &'static str,
150    pub supported_dialect: bool,
151    pub product_output_source: &'static str,
152    pub legacy_output_retained_as_oracle: bool,
153    pub legacy_output_consumed_until_cutover: bool,
154    pub evaluation_available: bool,
155    pub value_resolution_available: bool,
156    pub native_edit_output: Option<String>,
157    pub divergence_count: usize,
158    pub all_legacy_declaration_values_preserved: bool,
159    pub native_replacement_count: usize,
160    pub native_replacement_legacy_reflection_count: usize,
161    pub native_replacement_legacy_unreflected_count: usize,
162    pub native_edit_count: usize,
163    pub native_value_edit_count: usize,
164    pub native_structural_edit_count: usize,
165    pub native_edit_output_matches_evaluated_css: bool,
166    pub native_value_reference_count: usize,
167    pub native_resolved_value_count: usize,
168    pub native_raw_value_count: usize,
169    pub native_top_value_count: usize,
170    pub native_cycle_value_count: usize,
171    pub native_fuel_exhausted_value_count: usize,
172    pub native_unresolved_reference_value_count: usize,
173    pub native_unsupported_dynamic_value_count: usize,
174    pub evaluation: Option<OmenaScssEvalStaticStylesheetEvaluationV0>,
175    pub value_resolution: Option<OmenaScssEvalStaticValueResolutionReportV0>,
176}
177
178#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
179#[serde(rename_all = "camelCase")]
180pub struct OmenaQueryStaticStylesheetEvaluatorOracleCorpusSummaryV0 {
181    pub schema_version: &'static str,
182    pub product: &'static str,
183    pub mode: &'static str,
184    pub value_type: &'static str,
185    pub product_output_source: &'static str,
186    pub legacy_output_retained_as_oracle_count: usize,
187    pub legacy_output_consumed_until_cutover_count: usize,
188    pub all_legacy_outputs_retained_as_oracle: bool,
189    pub fixture_count: usize,
190    pub scss_fixture_count: usize,
191    pub sass_fixture_count: usize,
192    pub less_fixture_count: usize,
193    pub evaluated_fixture_count: usize,
194    pub missing_evaluation_count: usize,
195    pub divergence_count: usize,
196    pub native_replacement_count: usize,
197    pub native_replacement_legacy_reflection_count: usize,
198    pub native_replacement_legacy_unreflected_count: usize,
199    pub native_edit_count: usize,
200    pub native_value_edit_count: usize,
201    pub native_structural_edit_count: usize,
202    pub scss_control_flow_value_truthiness_count: usize,
203    pub scss_control_flow_contextual_truthiness_fallback_count: usize,
204    pub scss_control_flow_contextual_truthiness_conflict_count: usize,
205    pub scss_control_flow_prune_reachability_fixture_count: usize,
206    pub scss_control_flow_prune_reachability_changed_fixture_count: usize,
207    pub scss_control_flow_prune_reachability_flat_css_cfg_built_count: usize,
208    pub native_edit_output_match_count: usize,
209    pub native_value_reference_count: usize,
210    pub native_resolved_value_count: usize,
211    pub native_raw_value_count: usize,
212    pub native_top_value_count: usize,
213    pub native_cycle_value_count: usize,
214    pub native_fuel_exhausted_value_count: usize,
215    pub native_unresolved_reference_value_count: usize,
216    pub native_unsupported_dynamic_value_count: usize,
217    pub all_legacy_declaration_values_preserved: bool,
218    pub all_native_edit_outputs_match_evaluated_css: bool,
219    pub native_product_output_corpus_ready: bool,
220    pub corpus: OmenaScssEvalStaticStylesheetOracleCorpusReportV0,
221}
222
223#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
224#[serde(rename_all = "camelCase")]
225pub struct OmenaQueryStaticLifExportsSummaryV0 {
226    pub schema_version: &'static str,
227    pub product: &'static str,
228    pub mode: &'static str,
229    pub dialect: &'static str,
230    pub source_syntax: &'static str,
231    pub sif_superset: bool,
232    pub less_specific_export_count: usize,
233    pub less_variable_count: usize,
234    pub less_mixin_count: usize,
235    pub less_detached_ruleset_count: usize,
236    pub less_variable_names: Vec<String>,
237    pub less_mixin_names: Vec<String>,
238    pub less_detached_ruleset_names: Vec<String>,
239    pub sif_variable_count: usize,
240    pub sif_mixin_count: usize,
241    pub sif_function_count: usize,
242    pub sif_placeholder_count: usize,
243    pub sif_forward_count: usize,
244    pub exports: omena_sif::OmenaLifExportsV1,
245}
246
247pub fn summarize_omena_query_static_stylesheet_evaluator_from_source(
248    source: &str,
249    dialect: OmenaParserStyleDialect,
250) -> OmenaQueryStaticStylesheetEvaluatorSummaryV0 {
251    let evaluation = derive_static_stylesheet_module_evaluation(source, dialect);
252    let value_resolution = evaluation
253        .as_ref()
254        .map(|evaluation| evaluation.value_resolution.clone())
255        .or_else(|| summarize_static_stylesheet_value_resolution(source, dialect));
256    let oracle = evaluation.as_ref().map(|evaluation| &evaluation.oracle);
257    let supported_dialect = matches!(
258        dialect,
259        OmenaParserStyleDialect::Scss
260            | OmenaParserStyleDialect::Sass
261            | OmenaParserStyleDialect::Less
262    );
263
264    OmenaQueryStaticStylesheetEvaluatorSummaryV0 {
265        schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
266        product: "omena-query.static-stylesheet-evaluator",
267        mode: "oracleOnly",
268        dialect: omena_query_boundary_style_dialect_label(dialect),
269        value_type: "AbstractCssValueV0",
270        supported_dialect,
271        product_output_source: evaluation
272            .as_ref()
273            .map_or("none", |evaluation| evaluation.product_output_source),
274        legacy_output_retained_as_oracle: evaluation
275            .as_ref()
276            .is_some_and(|evaluation| evaluation.legacy_output_retained_as_oracle),
277        legacy_output_consumed_until_cutover: evaluation
278            .as_ref()
279            .is_some_and(|evaluation| evaluation.legacy_output_consumed_until_cutover),
280        evaluation_available: evaluation.is_some(),
281        value_resolution_available: value_resolution.is_some(),
282        native_edit_output: evaluation
283            .as_ref()
284            .map(|evaluation| evaluation.native_edit_output.clone()),
285        divergence_count: oracle.map_or(0, |oracle| oracle.divergence_count),
286        all_legacy_declaration_values_preserved: oracle
287            .is_some_and(|oracle| oracle.all_legacy_declaration_values_preserved),
288        native_replacement_count: evaluation
289            .as_ref()
290            .map_or(0, |evaluation| evaluation.replacement_count),
291        native_replacement_legacy_reflection_count: evaluation.as_ref().map_or(0, |evaluation| {
292            evaluation.native_replacement_legacy_reflection_count
293        }),
294        native_replacement_legacy_unreflected_count: evaluation.as_ref().map_or(0, |evaluation| {
295            evaluation.native_replacement_legacy_unreflected_count
296        }),
297        native_edit_count: evaluation
298            .as_ref()
299            .map_or(0, |evaluation| evaluation.native_edit_count),
300        native_value_edit_count: evaluation
301            .as_ref()
302            .map_or(0, |evaluation| evaluation.native_value_edit_count),
303        native_structural_edit_count: evaluation
304            .as_ref()
305            .map_or(0, |evaluation| evaluation.native_structural_edit_count),
306        native_edit_output_matches_evaluated_css: evaluation
307            .as_ref()
308            .is_some_and(|evaluation| evaluation.native_edit_output_matches_evaluated_css),
309        native_value_reference_count: value_resolution
310            .as_ref()
311            .map_or(0, |resolution| resolution.reference_count),
312        native_resolved_value_count: value_resolution
313            .as_ref()
314            .map_or(0, |resolution| resolution.resolved_count),
315        native_raw_value_count: value_resolution
316            .as_ref()
317            .map_or(0, |resolution| resolution.raw_count),
318        native_top_value_count: value_resolution
319            .as_ref()
320            .map_or(0, |resolution| resolution.top_count),
321        native_cycle_value_count: value_resolution
322            .as_ref()
323            .map_or(0, |resolution| resolution.cycle_count),
324        native_fuel_exhausted_value_count: value_resolution
325            .as_ref()
326            .map_or(0, |resolution| resolution.fuel_exhausted_count),
327        native_unresolved_reference_value_count: value_resolution
328            .as_ref()
329            .map_or(0, |resolution| resolution.unresolved_reference_count),
330        native_unsupported_dynamic_value_count: value_resolution
331            .as_ref()
332            .map_or(0, |resolution| resolution.unsupported_dynamic_count),
333        evaluation,
334        value_resolution,
335    }
336}
337
338pub fn summarize_omena_query_static_stylesheet_evaluator_from_engine_input(
339    input: &EngineInputV2,
340    target_style_path: &str,
341) -> Option<OmenaQueryStaticStylesheetEvaluatorSummaryV0> {
342    let target = input
343        .styles
344        .iter()
345        .find(|style| style.file_path == target_style_path)?;
346    let source = target.source.as_deref()?;
347    Some(
348        summarize_omena_query_static_stylesheet_evaluator_from_source(
349            source,
350            omena_query_style_dialect_for_path(target_style_path),
351        ),
352    )
353}
354
355pub fn summarize_omena_query_static_lif_exports_from_source(
356    source: &str,
357    dialect: OmenaParserStyleDialect,
358) -> OmenaQueryStaticLifExportsSummaryV0 {
359    let source_syntax = omena_query_boundary_sif_source_syntax(dialect);
360    let exports = omena_sif::generate_static_omena_lif_exports_v1(
361        omena_sif::OmenaSifStaticGeneratorInputV1 {
362            canonical_url: "memory:omena-query-static-lif",
363            source,
364            syntax: source_syntax.clone(),
365        },
366    );
367    let less_variable_names = exports
368        .less_variables
369        .iter()
370        .map(|variable| variable.name.clone())
371        .collect::<Vec<_>>();
372    let less_mixin_names = exports
373        .less_mixins
374        .iter()
375        .map(|mixin| mixin.name.clone())
376        .collect::<Vec<_>>();
377    let less_detached_ruleset_names = exports
378        .less_detached_rulesets
379        .iter()
380        .map(|ruleset| ruleset.name.clone())
381        .collect::<Vec<_>>();
382
383    OmenaQueryStaticLifExportsSummaryV0 {
384        schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
385        product: "omena-query.static-lif-exports",
386        mode: "staticInterfaceOnly",
387        dialect: omena_query_boundary_style_dialect_label(dialect),
388        source_syntax: omena_query_boundary_sif_source_syntax_label(source_syntax),
389        sif_superset: true,
390        less_specific_export_count: exports.less_variables.len()
391            + exports.less_mixins.len()
392            + exports.less_detached_rulesets.len(),
393        less_variable_count: exports.less_variables.len(),
394        less_mixin_count: exports.less_mixins.len(),
395        less_detached_ruleset_count: exports.less_detached_rulesets.len(),
396        less_variable_names,
397        less_mixin_names,
398        less_detached_ruleset_names,
399        sif_variable_count: exports.sif_exports.variables.len(),
400        sif_mixin_count: exports.sif_exports.mixins.len(),
401        sif_function_count: exports.sif_exports.functions.len(),
402        sif_placeholder_count: exports.sif_exports.placeholders.len(),
403        sif_forward_count: exports.sif_exports.forwards.len(),
404        exports,
405    }
406}
407
408pub fn summarize_omena_query_static_lif_exports_from_engine_input(
409    input: &EngineInputV2,
410    target_style_path: &str,
411) -> Option<OmenaQueryStaticLifExportsSummaryV0> {
412    let target = input
413        .styles
414        .iter()
415        .find(|style| style.file_path == target_style_path)?;
416    let source = target.source.as_deref()?;
417    Some(summarize_omena_query_static_lif_exports_from_source(
418        source,
419        omena_query_style_dialect_for_path(target_style_path),
420    ))
421}
422
423pub fn summarize_omena_query_static_stylesheet_evaluator_oracle_corpus()
424-> OmenaQueryStaticStylesheetEvaluatorOracleCorpusSummaryV0 {
425    let corpus = summarize_static_stylesheet_oracle_corpus();
426    OmenaQueryStaticStylesheetEvaluatorOracleCorpusSummaryV0 {
427        schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
428        product: "omena-query.static-stylesheet-evaluator-oracle-corpus",
429        mode: corpus.mode,
430        value_type: corpus.value_type,
431        product_output_source: corpus.product_output_source,
432        legacy_output_retained_as_oracle_count: corpus.legacy_output_retained_as_oracle_count,
433        legacy_output_consumed_until_cutover_count: corpus
434            .legacy_output_consumed_until_cutover_count,
435        all_legacy_outputs_retained_as_oracle: corpus.all_legacy_outputs_retained_as_oracle,
436        fixture_count: corpus.fixture_count,
437        scss_fixture_count: corpus.scss_fixture_count,
438        sass_fixture_count: corpus.sass_fixture_count,
439        less_fixture_count: corpus.less_fixture_count,
440        evaluated_fixture_count: corpus.evaluated_fixture_count,
441        missing_evaluation_count: corpus.missing_evaluation_count,
442        divergence_count: corpus.divergence_count,
443        native_replacement_count: corpus.native_replacement_count,
444        native_replacement_legacy_reflection_count: corpus
445            .native_replacement_legacy_reflection_count,
446        native_replacement_legacy_unreflected_count: corpus
447            .native_replacement_legacy_unreflected_count,
448        native_edit_count: corpus.native_edit_count,
449        native_value_edit_count: corpus.native_value_edit_count,
450        native_structural_edit_count: corpus.native_structural_edit_count,
451        scss_control_flow_value_truthiness_count: corpus.scss_control_flow_value_truthiness_count,
452        scss_control_flow_contextual_truthiness_fallback_count: corpus
453            .scss_control_flow_contextual_truthiness_fallback_count,
454        scss_control_flow_contextual_truthiness_conflict_count: corpus
455            .scss_control_flow_contextual_truthiness_conflict_count,
456        scss_control_flow_prune_reachability_fixture_count: corpus
457            .scss_control_flow_prune_reachability_fixture_count,
458        scss_control_flow_prune_reachability_changed_fixture_count: corpus
459            .scss_control_flow_prune_reachability_changed_fixture_count,
460        scss_control_flow_prune_reachability_flat_css_cfg_built_count: corpus
461            .scss_control_flow_prune_reachability_flat_css_cfg_built_count,
462        native_edit_output_match_count: corpus.native_edit_output_match_count,
463        native_value_reference_count: corpus.native_value_reference_count,
464        native_resolved_value_count: corpus.native_resolved_value_count,
465        native_raw_value_count: corpus.native_raw_value_count,
466        native_top_value_count: corpus.native_top_value_count,
467        native_cycle_value_count: corpus.native_cycle_value_count,
468        native_fuel_exhausted_value_count: corpus.native_fuel_exhausted_value_count,
469        native_unresolved_reference_value_count: corpus.native_unresolved_reference_value_count,
470        native_unsupported_dynamic_value_count: corpus.native_unsupported_dynamic_value_count,
471        all_legacy_declaration_values_preserved: corpus.all_legacy_declaration_values_preserved,
472        all_native_edit_outputs_match_evaluated_css: corpus
473            .all_native_edit_outputs_match_evaluated_css,
474        native_product_output_corpus_ready: corpus.native_product_output_corpus_ready,
475        corpus,
476    }
477}
478
479pub fn summarize_omena_query_scss_evaluator_control_flow_from_source(
480    source: &str,
481    dialect: OmenaParserStyleDialect,
482) -> OmenaQueryScssEvaluatorControlFlowSummaryV0 {
483    let control_flow_ir = summarize_scss_control_flow_ir(source, dialect);
484    let value_analysis = analyze_scss_control_flow_values(source, dialect);
485    let prune_reachability = summarize_scss_control_flow_prune_reachability(source, dialect);
486    let call_return_ir = summarize_scss_call_return_ir(source, dialect);
487    let supported_dialect = matches!(
488        dialect,
489        OmenaParserStyleDialect::Scss | OmenaParserStyleDialect::Sass
490    );
491
492    OmenaQueryScssEvaluatorControlFlowSummaryV0 {
493        schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
494        product: "omena-query.scss-evaluator-control-flow",
495        mode: "oracleOnly",
496        dialect: omena_query_boundary_style_dialect_label(dialect),
497        value_type: "AbstractCssValueV0",
498        supported_dialect,
499        flat_css_cfg_built: control_flow_ir
500            .as_ref()
501            .is_some_and(|summary| summary.flat_css_cfg_built),
502        merged_cross_file_graph: control_flow_ir
503            .as_ref()
504            .is_some_and(|summary| summary.merged_cross_file_graph),
505        control_flow_block_count: control_flow_ir
506            .as_ref()
507            .map_or(0, |summary| summary.block_count),
508        control_flow_branch_block_count: control_flow_ir
509            .as_ref()
510            .map_or(0, |summary| summary.branch_block_count),
511        control_flow_loop_block_count: control_flow_ir
512            .as_ref()
513            .map_or(0, |summary| summary.loop_block_count),
514        control_flow_back_edge_count: control_flow_ir
515            .as_ref()
516            .map_or(0, |summary| summary.back_edge_count),
517        call_return_node_count: call_return_ir
518            .as_ref()
519            .map_or(0, |summary| summary.node_count),
520        call_return_edge_count: call_return_ir
521            .as_ref()
522            .map_or(0, |summary| summary.edge_count),
523        call_resolved_return_value_count: call_return_ir
524            .as_ref()
525            .map_or(0, |summary| summary.call_resolved_return_value_count),
526        exact_call_resolved_return_value_count: call_return_ir
527            .as_ref()
528            .map_or(0, |summary| summary.exact_call_resolved_return_value_count),
529        value_analysis_converged: value_analysis
530            .as_ref()
531            .is_some_and(|summary| summary.converged),
532        value_analysis_iteration_count: value_analysis
533            .as_ref()
534            .map_or(0, |summary| summary.iteration_count),
535        value_analysis_widened_to_top_count: value_analysis
536            .as_ref()
537            .map_or(0, |summary| summary.widened_to_top_count),
538        prune_reachability_available: prune_reachability.is_some(),
539        prune_reachability_converged: prune_reachability
540            .as_ref()
541            .is_some_and(|summary| summary.converged),
542        prune_reachability_flat_css_cfg_built: prune_reachability
543            .as_ref()
544            .is_some_and(|summary| summary.flat_css_cfg_built),
545        prune_reachability_have_terminals_changed: prune_reachability
546            .as_ref()
547            .is_some_and(|summary| summary.have_terminals_changed),
548        prune_reachability_reachable_block_count: prune_reachability
549            .as_ref()
550            .map_or(0, |summary| summary.reachable_block_count),
551        prune_reachability_unreachable_block_count: prune_reachability
552            .as_ref()
553            .map_or(0, |summary| summary.unreachable_block_count),
554        ready_surfaces: vec![
555            "scssEvaluatorControlFlowIr",
556            "scssEvaluatorControlFlowValueAnalysis",
557            "scssEvaluatorControlFlowPruneReachability",
558            "scssEvaluatorCallReturnIr",
559        ],
560        control_flow_ir,
561        value_analysis,
562        prune_reachability,
563        call_return_ir,
564    }
565}
566
567pub fn summarize_omena_query_scss_evaluator_control_flow_from_engine_input(
568    input: &EngineInputV2,
569    target_style_path: &str,
570) -> Option<OmenaQueryScssEvaluatorControlFlowSummaryV0> {
571    let target = input
572        .styles
573        .iter()
574        .find(|style| style.file_path == target_style_path)?;
575    let source = target.source.as_deref()?;
576    Some(
577        summarize_omena_query_scss_evaluator_control_flow_from_source(
578            source,
579            omena_query_style_dialect_for_path(target_style_path),
580        ),
581    )
582}
583
584pub fn summarize_omena_query_native_css_evaluator_from_source(
585    source: &str,
586    dialect: OmenaParserStyleDialect,
587) -> OmenaQueryNativeCssEvaluatorSummaryV0 {
588    let native_function_surface = summarize_native_css_function_surface(source, dialect);
589    let native_function_call_evaluations =
590        summarize_native_css_function_call_evaluations(source, dialect);
591    let native_static_edit_plan = summarize_native_css_static_edit_plan(source, dialect);
592    let if_function_decisions = summarize_native_css_if_function_decisions(source, dialect);
593    let supported_dialect = dialect == OmenaParserStyleDialect::Css;
594
595    OmenaQueryNativeCssEvaluatorSummaryV0 {
596        schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
597        product: "omena-query.native-css-evaluator",
598        mode: "oracleOnlyPruneButKeep",
599        dialect: omena_query_boundary_style_dialect_label(dialect),
600        supported_dialect,
601        native_static_eval_spec_snapshot: NATIVE_CSS_STATIC_EVAL_SPEC_SNAPSHOT_V0,
602        native_static_eval_opt_in_policy: NATIVE_CSS_STATIC_EVAL_OPT_IN_POLICY_V0,
603        native_static_eval_dialect_restriction: NATIVE_CSS_STATIC_EVAL_DIALECT_RESTRICTION_V0,
604        native_static_eval_explicit_opt_in_required: true,
605        native_function_surface_available: native_function_surface.is_some(),
606        native_function_call_evaluation_available: native_function_call_evaluations.is_some(),
607        native_static_edit_plan_available: native_static_edit_plan.is_some(),
608        if_function_decision_available: if_function_decisions.is_some(),
609        native_function_count: native_function_surface
610            .as_ref()
611            .map_or(0, |summary| summary.function_count),
612        native_function_parameter_count: native_function_surface
613            .as_ref()
614            .map_or(0, |summary| summary.parameter_count),
615        native_function_typed_parameter_count: native_function_surface
616            .as_ref()
617            .map_or(0, |summary| summary.typed_parameter_count),
618        native_function_result_count: native_function_surface
619            .as_ref()
620            .map_or(0, |summary| summary.result_count),
621        native_function_call_count: native_function_call_evaluations
622            .as_ref()
623            .map_or(0, |summary| summary.call_count),
624        native_function_call_foldable_count: native_function_call_evaluations
625            .as_ref()
626            .map_or(0, |summary| summary.foldable_call_count),
627        native_function_call_preserved_count: native_function_call_evaluations
628            .as_ref()
629            .map_or(0, |summary| summary.preserved_call_count),
630        native_function_call_structural_error_count: native_function_call_evaluations
631            .as_ref()
632            .map_or(0, |summary| summary.structural_error_count),
633        native_function_call_runtime_dependent_count: native_function_call_evaluations
634            .as_ref()
635            .map_or(0, |summary| summary.runtime_dependent_call_count),
636        native_function_call_missing_result_count: native_function_call_evaluations
637            .as_ref()
638            .map_or(0, |summary| summary.missing_result_count),
639        native_static_edit_count: native_static_edit_plan
640            .as_ref()
641            .map_or(0, |summary| summary.edit_count),
642        native_static_edit_output_changed: native_static_edit_plan
643            .as_ref()
644            .is_some_and(|summary| summary.output_changed),
645        if_function_count: if_function_decisions
646            .as_ref()
647            .map_or(0, |summary| summary.function_count),
648        if_function_foldable_count: if_function_decisions
649            .as_ref()
650            .map_or(0, |summary| summary.foldable_function_count),
651        if_function_preserved_count: if_function_decisions
652            .as_ref()
653            .map_or(0, |summary| summary.preserved_function_count),
654        if_function_static_supports_branch_count: if_function_decisions
655            .as_ref()
656            .map_or(0, |summary| summary.static_supports_branch_count),
657        if_function_runtime_branch_count: if_function_decisions
658            .as_ref()
659            .map_or(0, |summary| summary.runtime_branch_count),
660        ready_surfaces: vec![
661            "nativeCssFunctionSurface",
662            "nativeCssFunctionCallEvaluationSurface",
663            "nativeCssStaticEditPlanSurface",
664            "nativeCssIfFunctionDecisionSurface",
665        ],
666        native_function_surface,
667        native_function_call_evaluations,
668        native_static_edit_plan,
669        if_function_decisions,
670    }
671}
672
673pub fn summarize_omena_query_native_css_evaluator_from_engine_input(
674    input: &EngineInputV2,
675    target_style_path: &str,
676) -> Option<OmenaQueryNativeCssEvaluatorSummaryV0> {
677    let target = input
678        .styles
679        .iter()
680        .find(|style| style.file_path == target_style_path)?;
681    let source = target.source.as_deref()?;
682    Some(summarize_omena_query_native_css_evaluator_from_source(
683        source,
684        omena_query_style_dialect_for_path(target_style_path),
685    ))
686}
687
688pub fn summarize_omena_query_scss_evaluator_control_flow_oracle_corpus()
689-> OmenaQueryScssEvaluatorControlFlowOracleCorpusSummaryV0 {
690    let corpus = summarize_scss_control_flow_oracle_corpus();
691    OmenaQueryScssEvaluatorControlFlowOracleCorpusSummaryV0 {
692        schema_version: OMENA_QUERY_CURRENT_SCHEMA_VERSION,
693        product: "omena-query.scss-evaluator-control-flow-oracle-corpus",
694        mode: corpus.mode,
695        value_type: corpus.value_type,
696        node_key_type: corpus.node_key_type,
697        recursion_cap: corpus.recursion_cap,
698        fixture_count: corpus.fixture_count,
699        scss_fixture_count: corpus.scss_fixture_count,
700        sass_fixture_count: corpus.sass_fixture_count,
701        supported_fixture_count: corpus.supported_fixture_count,
702        rejected_flat_css_fixture_count: corpus.rejected_flat_css_fixture_count,
703        control_flow_fixture_count: corpus.control_flow_fixture_count,
704        branch_fixture_count: corpus.branch_fixture_count,
705        loop_fixture_count: corpus.loop_fixture_count,
706        back_edge_fixture_count: corpus.back_edge_fixture_count,
707        call_return_fixture_count: corpus.call_return_fixture_count,
708        resolved_call_return_fixture_count: corpus.resolved_call_return_fixture_count,
709        top_call_return_fixture_count: corpus.top_call_return_fixture_count,
710        recursive_call_fixture_count: corpus.recursive_call_fixture_count,
711        converged_value_analysis_fixture_count: corpus.converged_value_analysis_fixture_count,
712        widened_to_top_fixture_count: corpus.widened_to_top_fixture_count,
713        widening_witness_widened_to_top_count: corpus.widening_witness_widened_to_top_count,
714        widening_witness_converged: corpus.widening_witness_converged,
715        prune_reachability_fixture_count: corpus.prune_reachability_fixture_count,
716        prune_reachability_changed_fixture_count: corpus.prune_reachability_changed_fixture_count,
717        prune_reachability_flat_css_cfg_built_count: corpus
718            .prune_reachability_flat_css_cfg_built_count,
719        flat_css_cfg_built_count: corpus.flat_css_cfg_built_count,
720        merged_cross_file_graph_count: corpus.merged_cross_file_graph_count,
721        all_supported_fixtures_converged: corpus.all_supported_fixtures_converged,
722        no_flat_css_cfg_built: corpus.no_flat_css_cfg_built,
723        no_merged_cross_file_graph: corpus.no_merged_cross_file_graph,
724        widening_witness: corpus.widening_witness.clone(),
725        corpus,
726    }
727}
728
729fn omena_query_style_dialect_for_path(style_path: &str) -> OmenaParserStyleDialect {
730    if style_path.ends_with(".sass") {
731        OmenaParserStyleDialect::Sass
732    } else if style_path.ends_with(".scss") {
733        OmenaParserStyleDialect::Scss
734    } else if style_path.ends_with(".less") {
735        OmenaParserStyleDialect::Less
736    } else {
737        OmenaParserStyleDialect::Css
738    }
739}
740
741fn omena_query_boundary_style_dialect_label(dialect: OmenaParserStyleDialect) -> &'static str {
742    match dialect {
743        OmenaParserStyleDialect::Css => "css",
744        OmenaParserStyleDialect::Scss => "scss",
745        OmenaParserStyleDialect::Sass => "sass",
746        OmenaParserStyleDialect::Less => "less",
747    }
748}
749
750fn omena_query_boundary_sif_source_syntax(
751    dialect: OmenaParserStyleDialect,
752) -> omena_sif::OmenaSifSourceSyntaxV1 {
753    match dialect {
754        OmenaParserStyleDialect::Css => omena_sif::OmenaSifSourceSyntaxV1::Css,
755        OmenaParserStyleDialect::Scss => omena_sif::OmenaSifSourceSyntaxV1::Scss,
756        OmenaParserStyleDialect::Sass => omena_sif::OmenaSifSourceSyntaxV1::Sass,
757        OmenaParserStyleDialect::Less => omena_sif::OmenaSifSourceSyntaxV1::Less,
758    }
759}
760
761fn omena_query_boundary_sif_source_syntax_label(
762    syntax: omena_sif::OmenaSifSourceSyntaxV1,
763) -> &'static str {
764    match syntax {
765        omena_sif::OmenaSifSourceSyntaxV1::Css => "css",
766        omena_sif::OmenaSifSourceSyntaxV1::Scss => "scss",
767        omena_sif::OmenaSifSourceSyntaxV1::Sass => "sass",
768        omena_sif::OmenaSifSourceSyntaxV1::Less => "less",
769    }
770}