use serde::Serialize;
use super::{
TransformDagEdgeV0, TransformPassKind, all_transform_pass_kinds, default_transform_dag_edges,
transform_pass_execution_phase,
};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum ObservationKindV0 {
SelectorMatching,
CascadeWinner,
CascadeWinnerEquality,
ExportedClassNames,
CustomPropertyComputedValue,
KeyframesReachability,
SourceMapTrace,
LayerRank,
Specificity,
Inheritance,
DeclarationOrder,
TargetPredicate,
ModuleResolution,
ImportContext,
ValueGraphReachability,
SemanticMarker,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum PassAssumptionKindV0 {
TokenBoundary,
SourceMapProvenance,
EquivalentLiteralValue,
SelectorSpecificity,
LonghandShorthandEquivalence,
DeclarationOrder,
TargetEnvironment,
Directionality,
NestedSelectorExpansion,
ScopedMatching,
LayerOrder,
StaticPredicate,
ImportWrapperProvenance,
ModuleNamespace,
SelectorIdentityMap,
ValueGraph,
CustomPropertyFixedPoint,
ClosedWorldReachability,
EmissionTrace,
SemanticMarkerRetention,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PassSemanticContractV0 {
pub observes: Vec<ObservationKindV0>,
pub preserves: Vec<ObservationKindV0>,
pub requires: Vec<PassAssumptionKindV0>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum PassObservationSurfaceV0 {
Declared(PassSemanticContractV0),
UnknownGap { reason: &'static str },
}
impl PassObservationSurfaceV0 {
pub fn is_declared(&self) -> bool {
matches!(self, Self::Declared(_))
}
pub fn gap_reason(&self) -> Option<&'static str> {
match self {
Self::Declared(_) => None,
Self::UnknownGap { reason } => Some(reason),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TransformPassObservationRecordV0 {
pub schema_version: &'static str,
pub product: &'static str,
pub id: &'static str,
pub kind: TransformPassKind,
pub surface: PassObservationSurfaceV0,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum TransformPassClassV0 {
Structural,
TextLocal,
ModuleEvaluation,
Emission,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TransformPassDescriptorV0 {
pub schema_version: &'static str,
pub product: &'static str,
pub id: &'static str,
pub kind: TransformPassKind,
pub pass_class: TransformPassClassV0,
pub phase: u8,
pub phase_order: u16,
pub depends_on: Vec<&'static str>,
pub conflicts_with: Vec<&'static str>,
}
impl TransformPassDescriptorV0 {
pub fn is_structural(&self) -> bool {
self.pass_class == TransformPassClassV0::Structural
}
pub fn keeps_text_local_slice_rewrite(&self) -> bool {
self.pass_class == TransformPassClassV0::TextLocal
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TransformBuildProfileV0 {
pub schema_version: &'static str,
pub product: &'static str,
pub profile_id: &'static str,
pub pass_ids: Vec<&'static str>,
}
pub const STRICT_VERIFICATION_BUILD_PROFILE_ID_V0: &str = "strict-verification";
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct TransformStrictPolicyDescriptorV0 {
pub schema_version: &'static str,
pub product: &'static str,
pub profile_id: &'static str,
pub refuse_unknown_pass_ids: bool,
pub require_closed_world_evidence: bool,
pub require_complete_decisions: bool,
pub enforce_winner_equality: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum MinifyPassProfileClassV0 {
Safe,
Semantic,
ClosedWorldOnly,
Excluded,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
#[serde(rename_all = "camelCase")]
pub enum MinifyPassClassificationDerivationV0 {
ClosedWorldRequirement,
Policy,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MinifyPassClassificationV0 {
pub pass_id: &'static str,
pub kind: TransformPassKind,
pub profile_class: MinifyPassProfileClassV0,
pub derivation: MinifyPassClassificationDerivationV0,
pub reason: &'static str,
}
pub const fn transform_pass_requires_closed_world_bundle(kind: TransformPassKind) -> bool {
matches!(
kind,
TransformPassKind::LayerFlatten
| TransformPassKind::TreeShakeClass
| TransformPassKind::TreeShakeKeyframes
| TransformPassKind::TreeShakeValue
| TransformPassKind::TreeShakeCustomProperty
)
}
pub const fn minify_pass_profile_classification(
kind: TransformPassKind,
) -> MinifyPassClassificationV0 {
let (profile_class, derivation, reason) = match kind {
TransformPassKind::WhitespaceStrip
| TransformPassKind::CommentStrip
| TransformPassKind::NumberCompression
| TransformPassKind::UnitNormalization
| TransformPassKind::ColorCompression
| TransformPassKind::UrlQuoteStrip
| TransformPassKind::StringQuoteNormalize
| TransformPassKind::CalcReduction
| TransformPassKind::PrintCss => (
MinifyPassProfileClassV0::Safe,
MinifyPassClassificationDerivationV0::Policy,
"local representation rewrite with no workspace reachability requirement",
),
TransformPassKind::SelectorIsWhereCompression
| TransformPassKind::ShorthandCombining
| TransformPassKind::RuleDeduplication
| TransformPassKind::RuleMerging
| TransformPassKind::SelectorMerging
| TransformPassKind::EmptyRuleRemoval
| TransformPassKind::StalePrefixRemoval
| TransformPassKind::ValueResolution
| TransformPassKind::StaticVarSubstitution => (
MinifyPassProfileClassV0::Semantic,
MinifyPassClassificationDerivationV0::Policy,
"requires cascade, value, or semantic evidence beyond a local representation rewrite",
),
TransformPassKind::LayerFlatten
| TransformPassKind::TreeShakeClass
| TransformPassKind::TreeShakeKeyframes
| TransformPassKind::TreeShakeValue
| TransformPassKind::TreeShakeCustomProperty => (
MinifyPassProfileClassV0::ClosedWorldOnly,
MinifyPassClassificationDerivationV0::ClosedWorldRequirement,
"requires a closed-world bundle before mutation",
),
TransformPassKind::VendorPrefixing
| TransformPassKind::LightDarkLowering
| TransformPassKind::ColorMixLowering
| TransformPassKind::OklchOklabLowering
| TransformPassKind::ColorFunctionLowering
| TransformPassKind::RelativeColorLowering
| TransformPassKind::LogicalToPhysical
| TransformPassKind::NestingUnwrap
| TransformPassKind::ScopeFlatten
| TransformPassKind::SupportsStaticEval
| TransformPassKind::MediaStaticEval
| TransformPassKind::ContainerStaticEval
| TransformPassKind::NativeCssStaticEval
| TransformPassKind::ImportInline
| TransformPassKind::ScssModuleEvaluate
| TransformPassKind::LessModuleEvaluate
| TransformPassKind::HashCssModuleClassNames
| TransformPassKind::ResolveCssModulesComposes
| TransformPassKind::DeadMediaBranchRemoval
| TransformPassKind::DeadSupportsBranchRemoval
| TransformPassKind::DesignTokenRouting => (
MinifyPassProfileClassV0::Excluded,
MinifyPassClassificationDerivationV0::Policy,
"belongs to target lowering, module evaluation, identity rewriting, or another product surface",
),
};
MinifyPassClassificationV0 {
pass_id: kind.id(),
kind,
profile_class,
derivation,
reason,
}
}
pub fn default_minify_pass_classifications() -> Vec<MinifyPassClassificationV0> {
all_transform_pass_kinds()
.into_iter()
.map(minify_pass_profile_classification)
.collect()
}
pub fn safe_minify_build_profile() -> TransformBuildProfileV0 {
minify_build_profile("safe", MinifyPassProfileClassV0::Safe)
}
pub fn semantic_minify_build_profile() -> TransformBuildProfileV0 {
minify_build_profile("semantic", MinifyPassProfileClassV0::Semantic)
}
pub fn closed_world_minify_build_profile() -> TransformBuildProfileV0 {
minify_build_profile("closed-world", MinifyPassProfileClassV0::ClosedWorldOnly)
}
pub fn default_minify_build_profiles() -> [TransformBuildProfileV0; 3] {
[
safe_minify_build_profile(),
semantic_minify_build_profile(),
closed_world_minify_build_profile(),
]
}
pub fn strict_verification_build_profile() -> TransformBuildProfileV0 {
let profile_classes = [
MinifyPassProfileClassV0::Semantic,
MinifyPassProfileClassV0::ClosedWorldOnly,
MinifyPassProfileClassV0::Excluded,
];
let mut passes = profile_classes
.into_iter()
.flat_map(|profile_class| {
default_minify_pass_classifications()
.into_iter()
.filter(move |entry| entry.profile_class == profile_class)
})
.filter(|entry| pass_requires_strict_winner_verification(entry.kind))
.map(|entry| entry.kind)
.collect::<Vec<_>>();
passes.sort_by_key(|pass| pass.ordinal());
transform_build_profile_from_passes(STRICT_VERIFICATION_BUILD_PROFILE_ID_V0, &passes)
}
pub fn strict_verification_policy_descriptor() -> TransformStrictPolicyDescriptorV0 {
TransformStrictPolicyDescriptorV0 {
schema_version: "0",
product: "omena-transform-cst.strict-policy",
profile_id: STRICT_VERIFICATION_BUILD_PROFILE_ID_V0,
refuse_unknown_pass_ids: true,
require_closed_world_evidence: true,
require_complete_decisions: true,
enforce_winner_equality: true,
}
}
pub fn strict_policy_descriptor_for_profile(
profile_id: &str,
) -> Option<TransformStrictPolicyDescriptorV0> {
(profile_id == STRICT_VERIFICATION_BUILD_PROFILE_ID_V0)
.then(strict_verification_policy_descriptor)
}
fn pass_requires_strict_winner_verification(kind: TransformPassKind) -> bool {
let PassObservationSurfaceV0::Declared(contract) = pass_observation_contract(kind) else {
return false;
};
contract
.preserves
.contains(&ObservationKindV0::CascadeWinnerEquality)
&& !contract
.preserves
.contains(&ObservationKindV0::SemanticMarker)
&& !contract
.requires
.contains(&PassAssumptionKindV0::ClosedWorldReachability)
}
fn minify_build_profile(
profile_id: &'static str,
maximum_class: MinifyPassProfileClassV0,
) -> TransformBuildProfileV0 {
let pass_ids = default_minify_pass_classifications()
.into_iter()
.filter(|entry| {
entry.profile_class != MinifyPassProfileClassV0::Excluded
&& entry.profile_class <= maximum_class
})
.map(|entry| entry.pass_id)
.collect();
TransformBuildProfileV0 {
schema_version: "0",
product: "omena-transform-cst.build-profile",
profile_id,
pass_ids,
}
}
pub fn transform_build_profile_from_passes(
profile_id: &'static str,
passes: &[TransformPassKind],
) -> TransformBuildProfileV0 {
TransformBuildProfileV0 {
schema_version: "0",
product: "omena-transform-cst.build-profile",
profile_id,
pass_ids: passes.iter().map(|pass| pass.id()).collect(),
}
}
pub fn default_transform_pass_descriptors() -> Vec<TransformPassDescriptorV0> {
let dag_edges = default_transform_dag_edges();
all_transform_pass_kinds()
.into_iter()
.map(|kind| transform_pass_descriptor_with_edges(kind, dag_edges.as_slice()))
.collect()
}
pub fn transform_pass_descriptor(kind: TransformPassKind) -> TransformPassDescriptorV0 {
let dag_edges = default_transform_dag_edges();
transform_pass_descriptor_with_edges(kind, dag_edges.as_slice())
}
pub fn default_transform_pass_observation_records() -> Vec<TransformPassObservationRecordV0> {
all_transform_pass_kinds()
.into_iter()
.map(|kind| TransformPassObservationRecordV0 {
schema_version: "0",
product: "omena-transform-cst.pass-observation-surface",
id: kind.id(),
kind,
surface: pass_observation_contract(kind),
})
.collect()
}
pub fn pass_observation_contract(kind: TransformPassKind) -> PassObservationSurfaceV0 {
match kind {
TransformPassKind::WhitespaceStrip => declared_observation_contract(
&[ObservationKindV0::SourceMapTrace],
&[
ObservationKindV0::SelectorMatching,
ObservationKindV0::CascadeWinner,
ObservationKindV0::DeclarationOrder,
ObservationKindV0::SourceMapTrace,
],
&[PassAssumptionKindV0::TokenBoundary],
),
TransformPassKind::CommentStrip => declared_observation_contract(
&[ObservationKindV0::SourceMapTrace],
&[
ObservationKindV0::SelectorMatching,
ObservationKindV0::CascadeWinner,
ObservationKindV0::DeclarationOrder,
ObservationKindV0::SourceMapTrace,
],
&[PassAssumptionKindV0::SourceMapProvenance],
),
TransformPassKind::NumberCompression
| TransformPassKind::UnitNormalization
| TransformPassKind::ColorCompression
| TransformPassKind::UrlQuoteStrip
| TransformPassKind::StringQuoteNormalize => declared_observation_contract(
&[
ObservationKindV0::CascadeWinner,
ObservationKindV0::CustomPropertyComputedValue,
ObservationKindV0::SourceMapTrace,
],
&[
ObservationKindV0::CascadeWinner,
ObservationKindV0::CustomPropertyComputedValue,
ObservationKindV0::SourceMapTrace,
],
&[PassAssumptionKindV0::EquivalentLiteralValue],
),
TransformPassKind::SelectorIsWhereCompression => declared_observation_contract(
&[
ObservationKindV0::SelectorMatching,
ObservationKindV0::Specificity,
ObservationKindV0::KeyframesReachability,
],
&[
ObservationKindV0::SelectorMatching,
ObservationKindV0::Specificity,
ObservationKindV0::KeyframesReachability,
],
&[PassAssumptionKindV0::SelectorSpecificity],
),
TransformPassKind::ShorthandCombining => declared_observation_contract(
&[
ObservationKindV0::CascadeWinner,
ObservationKindV0::DeclarationOrder,
ObservationKindV0::Inheritance,
],
&[
ObservationKindV0::CascadeWinner,
ObservationKindV0::DeclarationOrder,
ObservationKindV0::Inheritance,
],
&[PassAssumptionKindV0::LonghandShorthandEquivalence],
),
TransformPassKind::RuleDeduplication | TransformPassKind::RuleMerging => {
declared_observation_contract(
&[
ObservationKindV0::CascadeWinner,
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::LayerRank,
ObservationKindV0::Specificity,
ObservationKindV0::DeclarationOrder,
],
&[
ObservationKindV0::CascadeWinner,
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::LayerRank,
ObservationKindV0::Specificity,
ObservationKindV0::DeclarationOrder,
],
&[PassAssumptionKindV0::DeclarationOrder],
)
}
TransformPassKind::SelectorMerging => declared_observation_contract(
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::SelectorMatching,
ObservationKindV0::Specificity,
ObservationKindV0::ExportedClassNames,
],
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::SelectorMatching,
ObservationKindV0::Specificity,
ObservationKindV0::ExportedClassNames,
],
&[
PassAssumptionKindV0::SelectorSpecificity,
PassAssumptionKindV0::SelectorIdentityMap,
],
),
TransformPassKind::EmptyRuleRemoval => declared_observation_contract(
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::SemanticMarker,
ObservationKindV0::SourceMapTrace,
],
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::SemanticMarker,
ObservationKindV0::SourceMapTrace,
],
&[PassAssumptionKindV0::SemanticMarkerRetention],
),
TransformPassKind::VendorPrefixing
| TransformPassKind::StalePrefixRemoval
| TransformPassKind::LightDarkLowering
| TransformPassKind::ColorMixLowering
| TransformPassKind::OklchOklabLowering
| TransformPassKind::ColorFunctionLowering
| TransformPassKind::RelativeColorLowering => declared_observation_contract(
&[
ObservationKindV0::TargetPredicate,
ObservationKindV0::CascadeWinner,
ObservationKindV0::CustomPropertyComputedValue,
],
&[
ObservationKindV0::CascadeWinner,
ObservationKindV0::CustomPropertyComputedValue,
],
&[PassAssumptionKindV0::TargetEnvironment],
),
TransformPassKind::LogicalToPhysical => declared_observation_contract(
&[
ObservationKindV0::CascadeWinner,
ObservationKindV0::Inheritance,
],
&[
ObservationKindV0::CascadeWinner,
ObservationKindV0::Inheritance,
],
&[PassAssumptionKindV0::Directionality],
),
TransformPassKind::NestingUnwrap => declared_observation_contract(
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::SelectorMatching,
ObservationKindV0::Specificity,
],
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::SelectorMatching,
ObservationKindV0::Specificity,
],
&[PassAssumptionKindV0::NestedSelectorExpansion],
),
TransformPassKind::ScopeFlatten => declared_observation_contract(
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::SelectorMatching,
],
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::SelectorMatching,
],
&[PassAssumptionKindV0::ScopedMatching],
),
TransformPassKind::LayerFlatten => declared_observation_contract(
&[
ObservationKindV0::LayerRank,
ObservationKindV0::CascadeWinner,
ObservationKindV0::CascadeWinnerEquality,
],
&[
ObservationKindV0::LayerRank,
ObservationKindV0::CascadeWinner,
ObservationKindV0::CascadeWinnerEquality,
],
&[PassAssumptionKindV0::LayerOrder],
),
TransformPassKind::SupportsStaticEval
| TransformPassKind::MediaStaticEval
| TransformPassKind::ContainerStaticEval
| TransformPassKind::NativeCssStaticEval => declared_observation_contract(
&[
ObservationKindV0::TargetPredicate,
ObservationKindV0::CascadeWinner,
],
&[ObservationKindV0::CascadeWinner],
&[PassAssumptionKindV0::StaticPredicate],
),
TransformPassKind::CalcReduction => declared_observation_contract(
&[
ObservationKindV0::CustomPropertyComputedValue,
ObservationKindV0::CascadeWinner,
],
&[
ObservationKindV0::CustomPropertyComputedValue,
ObservationKindV0::CascadeWinner,
],
&[PassAssumptionKindV0::EquivalentLiteralValue],
),
TransformPassKind::ImportInline => declared_observation_contract(
&[
ObservationKindV0::ImportContext,
ObservationKindV0::LayerRank,
ObservationKindV0::CascadeWinner,
ObservationKindV0::SourceMapTrace,
],
&[
ObservationKindV0::ImportContext,
ObservationKindV0::LayerRank,
ObservationKindV0::CascadeWinner,
ObservationKindV0::SourceMapTrace,
],
&[PassAssumptionKindV0::ImportWrapperProvenance],
),
TransformPassKind::ScssModuleEvaluate | TransformPassKind::LessModuleEvaluate => {
declared_observation_contract(
&[
ObservationKindV0::ModuleResolution,
ObservationKindV0::CustomPropertyComputedValue,
ObservationKindV0::SourceMapTrace,
],
&[
ObservationKindV0::ModuleResolution,
ObservationKindV0::CustomPropertyComputedValue,
ObservationKindV0::SourceMapTrace,
],
&[PassAssumptionKindV0::ModuleNamespace],
)
}
TransformPassKind::HashCssModuleClassNames => declared_observation_contract(
&[
ObservationKindV0::ExportedClassNames,
ObservationKindV0::SelectorMatching,
],
&[
ObservationKindV0::ExportedClassNames,
ObservationKindV0::SelectorMatching,
],
&[PassAssumptionKindV0::SelectorIdentityMap],
),
TransformPassKind::ResolveCssModulesComposes => declared_observation_contract(
&[
ObservationKindV0::ExportedClassNames,
ObservationKindV0::ModuleResolution,
],
&[
ObservationKindV0::ExportedClassNames,
ObservationKindV0::ModuleResolution,
],
&[PassAssumptionKindV0::SelectorIdentityMap],
),
TransformPassKind::ValueResolution => declared_observation_contract(
&[ObservationKindV0::ValueGraphReachability],
&[ObservationKindV0::ValueGraphReachability],
&[PassAssumptionKindV0::ValueGraph],
),
TransformPassKind::StaticVarSubstitution => declared_observation_contract(
&[ObservationKindV0::CustomPropertyComputedValue],
&[ObservationKindV0::CustomPropertyComputedValue],
&[PassAssumptionKindV0::CustomPropertyFixedPoint],
),
TransformPassKind::TreeShakeClass => declared_observation_contract(
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::ExportedClassNames,
ObservationKindV0::SelectorMatching,
],
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::ExportedClassNames,
ObservationKindV0::SelectorMatching,
],
&[PassAssumptionKindV0::ClosedWorldReachability],
),
TransformPassKind::TreeShakeKeyframes => declared_observation_contract(
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::KeyframesReachability,
],
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::KeyframesReachability,
],
&[PassAssumptionKindV0::ClosedWorldReachability],
),
TransformPassKind::TreeShakeValue => declared_observation_contract(
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::ValueGraphReachability,
],
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::ValueGraphReachability,
],
&[PassAssumptionKindV0::ClosedWorldReachability],
),
TransformPassKind::TreeShakeCustomProperty => declared_observation_contract(
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::CustomPropertyComputedValue,
ObservationKindV0::ValueGraphReachability,
],
&[
ObservationKindV0::CascadeWinnerEquality,
ObservationKindV0::CustomPropertyComputedValue,
ObservationKindV0::ValueGraphReachability,
],
&[PassAssumptionKindV0::ClosedWorldReachability],
),
TransformPassKind::DeadMediaBranchRemoval
| TransformPassKind::DeadSupportsBranchRemoval => declared_observation_contract(
&[
ObservationKindV0::TargetPredicate,
ObservationKindV0::CascadeWinner,
],
&[ObservationKindV0::CascadeWinner],
&[PassAssumptionKindV0::StaticPredicate],
),
TransformPassKind::DesignTokenRouting => declared_observation_contract(
&[
ObservationKindV0::CustomPropertyComputedValue,
ObservationKindV0::ModuleResolution,
],
&[
ObservationKindV0::CustomPropertyComputedValue,
ObservationKindV0::ModuleResolution,
],
&[PassAssumptionKindV0::ModuleNamespace],
),
TransformPassKind::PrintCss => declared_observation_contract(
&[ObservationKindV0::SourceMapTrace],
&[ObservationKindV0::SourceMapTrace],
&[PassAssumptionKindV0::EmissionTrace],
),
}
}
fn declared_observation_contract(
observes: &[ObservationKindV0],
preserves: &[ObservationKindV0],
requires: &[PassAssumptionKindV0],
) -> PassObservationSurfaceV0 {
PassObservationSurfaceV0::Declared(PassSemanticContractV0 {
observes: observes.to_vec(),
preserves: preserves.to_vec(),
requires: requires.to_vec(),
})
}
pub const fn transform_pass_class(kind: TransformPassKind) -> TransformPassClassV0 {
match kind {
TransformPassKind::NestingUnwrap
| TransformPassKind::ScopeFlatten
| TransformPassKind::LayerFlatten
| TransformPassKind::RuleDeduplication
| TransformPassKind::RuleMerging
| TransformPassKind::SelectorMerging
| TransformPassKind::EmptyRuleRemoval
| TransformPassKind::SupportsStaticEval
| TransformPassKind::MediaStaticEval
| TransformPassKind::ContainerStaticEval
| TransformPassKind::NativeCssStaticEval
| TransformPassKind::DeadMediaBranchRemoval
| TransformPassKind::DeadSupportsBranchRemoval
| TransformPassKind::TreeShakeClass
| TransformPassKind::TreeShakeKeyframes
| TransformPassKind::TreeShakeValue
| TransformPassKind::TreeShakeCustomProperty
| TransformPassKind::ResolveCssModulesComposes
| TransformPassKind::HashCssModuleClassNames
| TransformPassKind::ImportInline
| TransformPassKind::DesignTokenRouting => TransformPassClassV0::Structural,
TransformPassKind::ScssModuleEvaluate | TransformPassKind::LessModuleEvaluate => {
TransformPassClassV0::ModuleEvaluation
}
TransformPassKind::PrintCss => TransformPassClassV0::Emission,
_ => TransformPassClassV0::TextLocal,
}
}
const fn transform_pass_phase_order(kind: TransformPassKind) -> u16 {
match kind {
TransformPassKind::WhitespaceStrip => 10,
TransformPassKind::CommentStrip => 20,
TransformPassKind::NumberCompression => 30,
TransformPassKind::UnitNormalization => 40,
TransformPassKind::ColorCompression => 50,
TransformPassKind::UrlQuoteStrip => 60,
TransformPassKind::StringQuoteNormalize => 70,
TransformPassKind::SelectorIsWhereCompression => 80,
TransformPassKind::ShorthandCombining => 90,
TransformPassKind::RuleDeduplication => 100,
TransformPassKind::RuleMerging => 110,
TransformPassKind::SelectorMerging => 120,
TransformPassKind::EmptyRuleRemoval => 130,
TransformPassKind::VendorPrefixing => 140,
TransformPassKind::StalePrefixRemoval => 150,
TransformPassKind::LightDarkLowering => 160,
TransformPassKind::ColorMixLowering => 170,
TransformPassKind::OklchOklabLowering => 180,
TransformPassKind::ColorFunctionLowering => 190,
TransformPassKind::LogicalToPhysical => 200,
TransformPassKind::NestingUnwrap => 210,
TransformPassKind::ScopeFlatten => 220,
TransformPassKind::LayerFlatten => 230,
TransformPassKind::SupportsStaticEval => 240,
TransformPassKind::MediaStaticEval => 250,
TransformPassKind::CalcReduction => 260,
TransformPassKind::ImportInline => 270,
TransformPassKind::ScssModuleEvaluate => 280,
TransformPassKind::LessModuleEvaluate => 290,
TransformPassKind::HashCssModuleClassNames => 300,
TransformPassKind::ResolveCssModulesComposes => 310,
TransformPassKind::ValueResolution => 320,
TransformPassKind::StaticVarSubstitution => 330,
TransformPassKind::TreeShakeClass => 340,
TransformPassKind::TreeShakeKeyframes => 350,
TransformPassKind::TreeShakeValue => 360,
TransformPassKind::TreeShakeCustomProperty => 370,
TransformPassKind::DeadMediaBranchRemoval => 380,
TransformPassKind::DeadSupportsBranchRemoval => 390,
TransformPassKind::DesignTokenRouting => 400,
TransformPassKind::PrintCss => 410,
TransformPassKind::RelativeColorLowering => 420,
TransformPassKind::ContainerStaticEval => 430,
TransformPassKind::NativeCssStaticEval => 440,
}
}
fn transform_pass_descriptor_with_edges(
kind: TransformPassKind,
dag_edges: &[TransformDagEdgeV0],
) -> TransformPassDescriptorV0 {
TransformPassDescriptorV0 {
schema_version: "0",
product: "omena-transform-cst.pass-descriptor",
id: kind.id(),
kind,
pass_class: transform_pass_class(kind),
phase: transform_pass_execution_phase(kind),
phase_order: transform_pass_phase_order(kind),
depends_on: dag_edges
.iter()
.filter(|edge| edge.to == kind.id())
.map(|edge| edge.from)
.collect(),
conflicts_with: transform_pass_conflicts_with(kind, dag_edges),
}
}
fn transform_pass_conflicts_with(
kind: TransformPassKind,
dag_edges: &[TransformDagEdgeV0],
) -> Vec<&'static str> {
let Some(conflict_family) = transform_pass_conflict_family(kind) else {
return Vec::new();
};
all_transform_pass_kinds()
.into_iter()
.filter(|other| *other != kind)
.filter(|other| transform_pass_conflict_family(*other) == Some(conflict_family))
.filter(|other| {
transform_pass_execution_phase(*other) == transform_pass_execution_phase(kind)
})
.filter(|other| !dag_path_exists(kind.id(), other.id(), dag_edges))
.filter(|other| !dag_path_exists(other.id(), kind.id(), dag_edges))
.map(|other| other.id())
.collect()
}
fn transform_pass_conflict_family(kind: TransformPassKind) -> Option<&'static str> {
match kind {
TransformPassKind::ColorMixLowering | TransformPassKind::ColorFunctionLowering => {
Some("nested-color-function-lowering")
}
_ => None,
}
}
fn dag_path_exists(from: &'static str, to: &'static str, dag_edges: &[TransformDagEdgeV0]) -> bool {
let mut stack = vec![from];
let mut visited = Vec::new();
while let Some(current) = stack.pop() {
if current == to {
return true;
}
if visited.contains(¤t) {
continue;
}
visited.push(current);
for edge in dag_edges.iter().filter(|edge| edge.from == current) {
stack.push(edge.to);
}
}
false
}
#[cfg(test)]
mod tests {
use super::*;
use std::collections::BTreeSet;
#[test]
fn minify_manifest_classifies_the_complete_pass_catalog() {
let manifest = default_minify_pass_classifications();
let pass_ids = manifest
.iter()
.map(|entry| entry.pass_id)
.collect::<BTreeSet<_>>();
assert_eq!(manifest.len(), crate::TRANSFORM_PASS_CATALOG_LEN);
assert_eq!(pass_ids.len(), crate::TRANSFORM_PASS_CATALOG_LEN);
assert!(manifest.iter().all(|entry| !entry.reason.is_empty()));
}
#[test]
fn minify_closed_world_classification_matches_the_runtime_gate() {
for entry in default_minify_pass_classifications() {
let requires_closed_world = transform_pass_requires_closed_world_bundle(entry.kind);
let classified_closed_world =
entry.profile_class == MinifyPassProfileClassV0::ClosedWorldOnly;
assert_eq!(
classified_closed_world, requires_closed_world,
"{}",
entry.pass_id
);
if classified_closed_world {
assert_eq!(
entry.derivation,
MinifyPassClassificationDerivationV0::ClosedWorldRequirement
);
} else {
assert_eq!(
entry.derivation,
MinifyPassClassificationDerivationV0::Policy
);
}
}
}
#[test]
fn minify_profiles_are_monotone_and_exclude_non_minify_passes() {
let [safe, semantic, closed_world] = default_minify_build_profiles();
let safe_passes = safe.pass_ids.iter().copied().collect::<BTreeSet<_>>();
let semantic_passes = semantic.pass_ids.iter().copied().collect::<BTreeSet<_>>();
let closed_world_passes = closed_world
.pass_ids
.iter()
.copied()
.collect::<BTreeSet<_>>();
assert_eq!(safe.profile_id, "safe");
assert_eq!(semantic.profile_id, "semantic");
assert_eq!(closed_world.profile_id, "closed-world");
assert!(safe_passes.is_subset(&semantic_passes));
assert!(semantic_passes.is_subset(&closed_world_passes));
assert!(safe_passes.len() < semantic_passes.len());
assert!(semantic_passes.len() < closed_world_passes.len());
for entry in default_minify_pass_classifications()
.into_iter()
.filter(|entry| entry.profile_class == MinifyPassProfileClassV0::Excluded)
{
assert!(!closed_world_passes.contains(entry.pass_id));
}
}
#[test]
fn strict_profile_is_derived_from_bucket_observation_contracts() {
let profile = strict_verification_build_profile();
let policy = strict_verification_policy_descriptor();
let expected = [
TransformPassKind::RuleDeduplication,
TransformPassKind::RuleMerging,
TransformPassKind::SelectorMerging,
TransformPassKind::NestingUnwrap,
TransformPassKind::ScopeFlatten,
TransformPassKind::LayerFlatten,
]
.into_iter()
.map(TransformPassKind::id)
.collect::<Vec<_>>();
assert_eq!(profile.profile_id, STRICT_VERIFICATION_BUILD_PROFILE_ID_V0);
assert_eq!(profile.pass_ids, expected);
assert!(
!profile
.pass_ids
.contains(&TransformPassKind::EmptyRuleRemoval.id())
);
assert_eq!(policy.profile_id, profile.profile_id);
assert!(policy.refuse_unknown_pass_ids);
assert!(policy.require_closed_world_evidence);
assert!(policy.require_complete_decisions);
assert!(policy.enforce_winner_equality);
}
}