1use engine_input_producers::EngineInputV2;
4use omena_semantic::{
5 CssModulesSemanticSummaryV0, DesignTokenSemanticSummaryV0, LosslessCstContractV0,
6 ParserBoundarySyntaxFactsV0, SelectorIdentityEngineSummaryV0, StyleSemanticBoundarySummaryV0,
7 StyleSemanticFactsV0, Stylesheet,
8};
9pub use omena_semantic::{
10 DesignTokenExternalDeclarationCandidateScopeV0, DesignTokenWorkspaceDeclarationFactV0,
11 ParserRangeV0 as OmenaBridgeParserRangeV0,
12};
13use serde::Serialize;
14
15mod bundler_config_alias;
16mod cache_root;
17mod external_sif_signature;
18mod promotion_evidence;
19mod selector_references;
20mod source_cfg;
21mod source_evidence;
22mod source_imports;
23mod source_language;
24mod source_syntax;
25mod style_intelligence;
26mod style_resolution;
27mod utility_intelligence;
28
29pub type OmenaBridgeSourceTypeFactControlFlowGraphV0 =
30 engine_input_producers::TypeFactControlFlowGraphV2;
31
32pub use bundler_config_alias::{
33 OmenaBridgeBundlerAliasUnrecognizedEntryV0, OmenaBridgeBundlerPathAliasMappingV0,
34 OmenaBridgeBundlerPathAliasSummaryV0, summarize_omena_bridge_bundler_path_aliases_for_config,
35};
36pub use promotion_evidence::{
37 SemanticPromotionEvidenceItemV0, SemanticPromotionEvidenceSummaryV0,
38 summarize_omena_bridge_promotion_evidence_with_source_input,
39 summarize_omena_bridge_semantic_promotion_evidence,
40};
41pub use selector_references::{
42 SelectorEditableDirectReferenceSiteV0, SelectorReferenceEngineSummaryV0,
43 SelectorReferenceSiteV0, SelectorReferenceSummaryV0,
44 summarize_omena_bridge_selector_reference_engine,
45};
46pub use source_cfg::{
47 SourceControlFlowGraphCaptureV0, SourceFlowBindingRefV0, SourceFlowBlockGraphSnapshotV0,
48 SourceFlowBlockSnapshotV0, source_type_fact_control_flow_graph_from_snapshot,
49 summarize_omena_bridge_source_control_flow_graph_for_source_language,
50 summarize_omena_bridge_source_type_fact_control_flow_graph_for_source_language,
51};
52pub use source_evidence::{
53 BindingOriginEvidenceV0, CertaintyReasonEvidenceV0, ReferenceSiteIdentityEvidenceV0,
54 SourceInputPromotionEvidenceSummaryV0, StyleModuleEdgeEvidenceV0,
55 ValueDomainExplanationEvidenceV0, summarize_omena_bridge_source_input_evidence,
56};
57pub use source_imports::{
58 SourceImportDeclarationSummaryV0, SourceImportDeclarationV0, SourceStyleImportResolutionV0,
59 summarize_omena_bridge_source_import_declarations,
60 summarize_omena_bridge_source_import_declarations_for_path,
61 summarize_omena_bridge_source_import_declarations_for_source_language,
62};
63pub use source_language::{
64 SourceLanguageParserBoundarySummaryV0, SourceLanguageParserDescriptorV0,
65 summarize_omena_bridge_source_language_parser_boundary_v0,
66};
67pub use source_syntax::{
68 SOURCE_INLINE_STYLE_IMPORTANT_SUFFIX_TIER_V0, SOURCE_INLINE_STYLE_TIER_V0,
69 SourceBindingDeclFactV0, SourceBindingIndexV0, SourceBindingScopeFactV0,
70 SourceBindingStyleImportFactV0, SourceClassAttributeSiteFactV0,
71 SourceClassExpressionNodeFactV0, SourceClassUtilityBindingFactV0,
72 SourceClassValuePatternMatcherV0, SourceClassValuePatternV0, SourceClassValueUniverseAxisV0,
73 SourceClassValueUniverseEntryV0, SourceClassValueUnresolvedV0,
74 SourceClassnamesBindUtilityBindingFactV0, SourceDeclaresStyleImportFactV0,
75 SourceDeclaresUtilityBindingFactV0, SourceDomainClassReferenceFactV0, SourceElementFactV0,
76 SourceElementIdentityFactV0, SourceElementParentFactV0, SourceExpressionTargetsModuleFactV0,
77 SourceGuardedClassTokenFactV0, SourceImportedStyleBindingV0,
78 SourceInlineStyleDeclarationFactV0, SourceModuleSpecifierFactV0, SourceScopeContainsDeclFactV0,
79 SourceScopeParentFactV0, SourceSelectorReferenceFactV0, SourceSelectorReferenceMatchKindV0,
80 SourceSelectorReferenceSurfaceV0, SourceStyleAccessUsesStyleImportFactV0,
81 SourceStyleImportResolvesModuleFactV0, SourceStylePropertyAccessFactV0,
82 SourceSymbolRefUsesDeclFactV0, SourceSyntaxIndexV0, SourceSyntaxIndexWithTypeFactAttemptsV0,
83 SourceTypeFactExpressionShapeV0, SourceTypeFactLexicalAttemptV0,
84 SourceTypeFactLexicalDispositionV0, SourceTypeFactProviderUnavailableFactV0,
85 SourceTypeFactTargetSkippedFactV0, SourceTypeFactTargetV0, SourceUtilityUsesStyleImportFactV0,
86 canonicalize_source_selector_references, collect_omena_bridge_vue_style_module_bindings,
87 summarize_omena_bridge_source_binding_index,
88 summarize_omena_bridge_source_binding_index_for_source_language,
89 summarize_omena_bridge_source_syntax_index,
90 summarize_omena_bridge_source_syntax_index_for_source_language,
91 summarize_omena_bridge_source_syntax_index_for_source_language_with_type_fact_attempts,
92 summarize_omena_bridge_source_syntax_index_with_type_fact_attempts,
93};
94pub use style_intelligence::{
95 BuiltInStyleIntelligenceProviderV0, StyleIntelligenceClassUniverseV0,
96 StyleIntelligenceCompletionV0, StyleIntelligenceGraphBindingV0, StyleIntelligenceHoverV0,
97 StyleIntelligenceProvider, StyleIntelligenceProviderMetadataV0, StyleIntelligenceSnapshotV0,
98 StyleIntelligenceSourceContextV0, built_in_style_intelligence_provider,
99 built_in_style_intelligence_providers, style_intelligence_completions_at_offset,
100 style_intelligence_hover_at_offset,
101};
102pub use style_resolution::{
103 OmenaBridgeExternalSifCacheContextV0, OmenaBridgeExternalSifShardRefusalV1,
104 OmenaBridgeExternalSifStorageV0, OmenaBridgeExternalSifTrustSourceV1,
105 OmenaBridgeExternalSifWithTrustV1, OmenaBridgeStyleResolutionInputsV0,
106 OmenaBridgeStyleResolutionSummaryV0, generate_omena_bridge_lif_exports_for_resolved_style_path,
107 generate_omena_bridge_sif_for_resolved_style_path,
108 generate_omena_bridge_sif_for_resolved_style_path_with_cache_context,
109 generate_omena_bridge_sif_for_resolved_style_path_with_cache_context_and_storage,
110 generate_omena_bridge_sif_for_resolved_style_path_with_cache_context_storage_and_trust,
111 generate_omena_bridge_sif_for_resolved_style_path_with_canonical_url_cache_context_storage_and_trust,
112 load_omena_bridge_workspace_style_resolution_inputs,
113 resolve_omena_bridge_style_uri_for_specifier,
114 resolve_omena_bridge_style_uri_for_specifier_with_package_manifests,
115 resolve_omena_bridge_style_uri_for_specifier_with_resolution_inputs,
116 summarize_omena_bridge_style_resolution_boundary,
117};
118pub use utility_intelligence::{
119 UtilityClassIntelligenceReportV0, UtilityClassLintSignalV0, UtilityClassMembershipKindV0,
120 UtilityConfigKindV0, append_omena_bridge_utility_class_intelligence,
121 classify_omena_bridge_utility_class, load_omena_bridge_workspace_utility_class_intelligence,
122 summarize_omena_bridge_utility_class_intelligence_for_config,
123};
124
125pub fn collect_omena_bridge_design_token_workspace_declarations(
126 style_path: &str,
127 sheet: &Stylesheet,
128) -> Vec<DesignTokenWorkspaceDeclarationFactV0> {
129 let parser_facts = omena_semantic::summarize_parser_contract_facts(sheet);
130 omena_semantic::collect_design_token_workspace_declarations(style_path, &parser_facts)
131}
132
133pub fn collect_omena_bridge_design_token_workspace_declarations_from_source(
134 style_path: &str,
135 style_source: &str,
136) -> Vec<DesignTokenWorkspaceDeclarationFactV0> {
137 let boundary = omena_semantic::summarize_omena_parser_style_semantic_boundary_from_source(
138 style_path,
139 style_source,
140 );
141 omena_semantic::collect_design_token_workspace_declarations(style_path, &boundary.parser_facts)
142}
143
144#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
145#[serde(rename_all = "camelCase")]
146pub struct OmenaBridgeBoundarySummaryV0 {
147 pub schema_version: &'static str,
148 pub product: &'static str,
149 pub bridge_name: &'static str,
150 pub graph_product: &'static str,
151 pub delegated_semantic_boundary_product: &'static str,
152 pub selector_reference_product: &'static str,
153 pub source_input_evidence_product: &'static str,
154 pub binder_plugin_product: &'static str,
155 pub bridge_owned_surfaces: Vec<&'static str>,
156 pub cme_coupled_surfaces: Vec<&'static str>,
157 pub next_decoupling_targets: Vec<&'static str>,
158}
159
160#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
161#[serde(rename_all = "camelCase")]
162pub struct BinderPluginBoundarySummaryV0 {
163 pub schema_version: &'static str,
164 pub product: &'static str,
165 pub owner_crate: &'static str,
166 pub contract_name: &'static str,
167 pub external_plugin_abi_stable: bool,
168 pub default_plugin: BinderPluginSummaryV0,
169 pub built_in_plugins: Vec<BinderPluginSummaryV0>,
170 pub request_path_policy: Vec<&'static str>,
171 pub next_plugin_targets: Vec<&'static str>,
172}
173
174#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
175#[serde(rename_all = "camelCase")]
176pub struct BinderPluginSummaryV0 {
177 pub id: &'static str,
178 pub version: &'static str,
179 pub stability: &'static str,
180 pub domains: Vec<&'static str>,
181 pub owns_surfaces: Vec<&'static str>,
182 pub import_targets: Vec<&'static str>,
183 pub utility_targets: Vec<&'static str>,
184}
185
186#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
187#[serde(rename_all = "camelCase")]
188pub struct StyleSemanticGraphSummaryV0 {
189 pub schema_version: &'static str,
190 pub product: &'static str,
191 pub language: &'static str,
192 pub parser_facts: ParserBoundarySyntaxFactsV0,
193 pub semantic_facts: StyleSemanticFactsV0,
194 pub css_modules_semantics: CssModulesSemanticSummaryV0,
195 pub design_token_semantics: DesignTokenSemanticSummaryV0,
196 pub selector_identity_engine: SelectorIdentityEngineSummaryV0,
197 pub selector_reference_engine: SelectorReferenceEngineSummaryV0,
198 pub source_input_evidence: SourceInputPromotionEvidenceSummaryV0,
199 pub promotion_evidence: SemanticPromotionEvidenceSummaryV0,
200 pub lossless_cst_contract: LosslessCstContractV0,
201}
202
203pub fn summarize_omena_bridge_boundary() -> OmenaBridgeBoundarySummaryV0 {
204 OmenaBridgeBoundarySummaryV0 {
205 schema_version: "0",
206 product: "omena-bridge.cme-semantic-bridge",
207 bridge_name: "cme-semantic-bridge",
208 graph_product: "omena-semantic.style-semantic-graph",
209 delegated_semantic_boundary_product: "omena-semantic.style-semantic-boundary",
210 selector_reference_product: "omena-semantic.selector-references",
211 source_input_evidence_product: "omena-semantic.source-input-evidence",
212 binder_plugin_product: "omena-bridge.binder-plugin-boundary",
213 bridge_owned_surfaces: vec![
214 "styleSemanticGraph",
215 "styleSemanticGraphFromSource",
216 "omenaParserBackedStyleSemanticBoundaryFromSource",
217 "selectorReferenceEngine",
218 "designTokenWorkspaceDeclarationsFromSource",
219 "sourceInputEvidence",
220 "sourceImportDeclarations",
221 "styleResolution",
222 "sourceSyntaxIndex",
223 "promotionEvidenceWithSourceInput",
224 "binderPluginBoundary",
225 ],
226 cme_coupled_surfaces: vec![
227 "EngineInputV2",
228 "sourceInputEvidence",
229 "selectorReferenceEngine",
230 "promotionEvidenceWithSourceInput",
231 "styleSemanticGraphFromSource",
232 "cssModulesClassnameBinding",
233 "sourceSyntaxIndex",
234 "styleResolution",
235 ],
236 next_decoupling_targets: Vec::new(),
237 }
238}
239
240pub fn summarize_omena_bridge_binder_plugin_boundary() -> BinderPluginBoundarySummaryV0 {
241 let providers = built_in_style_intelligence_providers();
242 BinderPluginBoundarySummaryV0 {
243 schema_version: "0",
244 product: "omena-bridge.binder-plugin-boundary",
245 owner_crate: "omena-bridge",
246 contract_name: "BinderPluginV0",
247 external_plugin_abi_stable: false,
248 default_plugin: binder_plugin_summary_from_provider(&providers[0]),
249 built_in_plugins: providers
250 .iter()
251 .filter(|provider| provider.binder_summary_visible)
252 .map(binder_plugin_summary_from_provider)
253 .collect(),
254 request_path_policy: vec![
255 "builtInPluginsOnlyUntilAbiStabilizes",
256 "pluginOutputFeedsEngineInputV2",
257 "sourceExpressionProjectionMustPreserveBindingIdentity",
258 "styleImportResolutionMustRemainTargetAware",
259 "styleSourceExtractionIsOptionalForUtilityDomains",
260 ],
261 next_plugin_targets: Vec::new(),
262 }
263}
264
265fn binder_plugin_summary_from_provider(
266 provider: &BuiltInStyleIntelligenceProviderV0,
267) -> BinderPluginSummaryV0 {
268 let metadata = provider.metadata();
269 BinderPluginSummaryV0 {
270 id: metadata.provider_id,
271 version: metadata.version,
272 stability: metadata.stability,
273 domains: metadata.domains.to_vec(),
274 owns_surfaces: metadata.owns_surfaces.to_vec(),
275 import_targets: metadata.import_targets.to_vec(),
276 utility_targets: metadata.utility_targets.to_vec(),
277 }
278}
279
280pub fn summarize_omena_bridge_style_semantic_graph(
281 sheet: &Stylesheet,
282 input: &EngineInputV2,
283) -> StyleSemanticGraphSummaryV0 {
284 summarize_omena_bridge_style_semantic_graph_for_path(sheet, input, None)
285}
286
287pub fn summarize_omena_bridge_style_semantic_graph_for_path(
288 sheet: &Stylesheet,
289 input: &EngineInputV2,
290 style_path: Option<&str>,
291) -> StyleSemanticGraphSummaryV0 {
292 summarize_omena_bridge_style_semantic_graph_for_path_with_workspace_declarations(
293 sheet,
294 input,
295 style_path,
296 &[],
297 )
298}
299
300pub fn summarize_omena_bridge_style_semantic_graph_for_path_with_workspace_declarations(
301 sheet: &Stylesheet,
302 input: &EngineInputV2,
303 style_path: Option<&str>,
304 workspace_declarations: &[DesignTokenWorkspaceDeclarationFactV0],
305) -> StyleSemanticGraphSummaryV0 {
306 summarize_omena_bridge_style_semantic_graph_for_path_with_scoped_workspace_declarations(
307 sheet,
308 input,
309 style_path,
310 workspace_declarations,
311 DesignTokenExternalDeclarationCandidateScopeV0::Workspace,
312 )
313}
314
315pub fn summarize_omena_bridge_style_semantic_graph_for_path_with_scoped_workspace_declarations(
316 sheet: &Stylesheet,
317 input: &EngineInputV2,
318 style_path: Option<&str>,
319 workspace_declarations: &[DesignTokenWorkspaceDeclarationFactV0],
320 candidate_scope: DesignTokenExternalDeclarationCandidateScopeV0,
321) -> StyleSemanticGraphSummaryV0 {
322 let boundary = omena_semantic::summarize_style_semantic_boundary(sheet);
323 let css_modules_semantics = omena_semantic::summarize_css_modules_semantics(sheet);
324 summarize_omena_bridge_style_semantic_graph_with_boundary(
325 boundary,
326 css_modules_semantics,
327 input,
328 style_path,
329 workspace_declarations,
330 candidate_scope,
331 )
332}
333
334fn summarize_omena_bridge_style_semantic_graph_with_boundary(
335 boundary: StyleSemanticBoundarySummaryV0,
336 css_modules_semantics: CssModulesSemanticSummaryV0,
337 input: &EngineInputV2,
338 style_path: Option<&str>,
339 workspace_declarations: &[DesignTokenWorkspaceDeclarationFactV0],
340 candidate_scope: DesignTokenExternalDeclarationCandidateScopeV0,
341) -> StyleSemanticGraphSummaryV0 {
342 let parser_facts = boundary.parser_facts;
343 let semantic_facts = boundary.semantic_facts;
344 let design_token_semantics =
345 omena_semantic::summarize_design_token_semantics_with_scoped_workspace_declarations(
346 &parser_facts,
347 &semantic_facts,
348 style_path,
349 workspace_declarations,
350 candidate_scope,
351 );
352 let selector_identity_engine = boundary.selector_identity_engine;
353 let selector_reference_engine =
354 summarize_omena_bridge_selector_reference_engine(input, style_path);
355 let source_input_evidence = summarize_omena_bridge_source_input_evidence(input);
356 let promotion_evidence = summarize_omena_bridge_promotion_evidence_with_source_input(
357 &parser_facts,
358 &semantic_facts,
359 input,
360 );
361 let lossless_cst_contract = boundary.lossless_cst_contract;
362
363 StyleSemanticGraphSummaryV0 {
364 schema_version: "0",
365 product: "omena-semantic.style-semantic-graph",
366 language: boundary.language,
367 parser_facts,
368 semantic_facts,
369 css_modules_semantics,
370 design_token_semantics,
371 selector_identity_engine,
372 selector_reference_engine,
373 source_input_evidence,
374 promotion_evidence,
375 lossless_cst_contract,
376 }
377}
378
379pub fn summarize_omena_bridge_style_semantic_graph_from_source(
380 style_path: &str,
381 style_source: &str,
382 input: &EngineInputV2,
383) -> Option<StyleSemanticGraphSummaryV0> {
384 summarize_omena_bridge_style_semantic_graph_from_source_with_scoped_workspace_declarations(
385 style_path,
386 style_source,
387 input,
388 &[],
389 DesignTokenExternalDeclarationCandidateScopeV0::Workspace,
390 )
391}
392
393pub fn summarize_omena_bridge_style_semantic_graph_from_source_with_scoped_workspace_declarations(
394 style_path: &str,
395 style_source: &str,
396 input: &EngineInputV2,
397 workspace_declarations: &[DesignTokenWorkspaceDeclarationFactV0],
398 candidate_scope: DesignTokenExternalDeclarationCandidateScopeV0,
399) -> Option<StyleSemanticGraphSummaryV0> {
400 let css_modules_semantics =
401 omena_semantic::summarize_css_modules_semantics_from_source(style_path, style_source)?;
402 let boundary = omena_semantic::summarize_omena_parser_style_semantic_boundary_from_source(
403 style_path,
404 style_source,
405 );
406 Some(summarize_omena_bridge_style_semantic_graph_with_boundary(
407 boundary,
408 css_modules_semantics,
409 input,
410 Some(style_path),
411 workspace_declarations,
412 candidate_scope,
413 ))
414}
415
416#[cfg(test)]
417mod tests {
418 use super::{
419 collect_omena_bridge_design_token_workspace_declarations_from_source,
420 summarize_omena_bridge_binder_plugin_boundary, summarize_omena_bridge_boundary,
421 summarize_omena_bridge_promotion_evidence_with_source_input,
422 summarize_omena_bridge_selector_reference_engine,
423 summarize_omena_bridge_source_import_declarations,
424 summarize_omena_bridge_source_input_evidence,
425 summarize_omena_bridge_style_semantic_graph_from_source,
426 };
427 use engine_input_producers::{
428 ClassExpressionInputV2, EngineInputV2, PositionV2, RangeV2, SourceAnalysisInputV2,
429 SourceDocumentV2, StringTypeFactsV2, StyleAnalysisInputV2, StyleDocumentV2,
430 StyleSelectorV2, TypeFactEntryV2,
431 };
432 use omena_syntax::ident::PropertyNameV0;
433
434 #[test]
435 fn declares_cme_coupled_bridge_boundary() {
436 let boundary = summarize_omena_bridge_boundary();
437
438 assert_eq!(boundary.schema_version, "0");
439 assert_eq!(boundary.product, "omena-bridge.cme-semantic-bridge");
440 assert_eq!(
441 boundary.graph_product,
442 "omena-semantic.style-semantic-graph"
443 );
444 assert_eq!(
445 boundary.delegated_semantic_boundary_product,
446 "omena-semantic.style-semantic-boundary"
447 );
448 assert_eq!(
449 boundary.selector_reference_product,
450 "omena-semantic.selector-references"
451 );
452 assert_eq!(
453 boundary.source_input_evidence_product,
454 "omena-semantic.source-input-evidence"
455 );
456 assert_eq!(
457 boundary.binder_plugin_product,
458 "omena-bridge.binder-plugin-boundary"
459 );
460 assert!(
461 boundary
462 .bridge_owned_surfaces
463 .contains(&"styleSemanticGraphFromSource")
464 );
465 assert!(
466 boundary
467 .bridge_owned_surfaces
468 .contains(&"omenaParserBackedStyleSemanticBoundaryFromSource")
469 );
470 assert!(
471 boundary
472 .bridge_owned_surfaces
473 .contains(&"selectorReferenceEngine")
474 );
475 assert!(
476 boundary
477 .bridge_owned_surfaces
478 .contains(&"designTokenWorkspaceDeclarationsFromSource")
479 );
480 assert!(
481 boundary
482 .bridge_owned_surfaces
483 .contains(&"sourceInputEvidence")
484 );
485 assert!(
486 boundary
487 .bridge_owned_surfaces
488 .contains(&"promotionEvidenceWithSourceInput")
489 );
490 assert!(
491 boundary
492 .bridge_owned_surfaces
493 .contains(&"sourceImportDeclarations")
494 );
495 assert!(boundary.bridge_owned_surfaces.contains(&"styleResolution"));
496 assert!(
497 boundary
498 .bridge_owned_surfaces
499 .contains(&"sourceSyntaxIndex")
500 );
501 assert!(
502 boundary
503 .bridge_owned_surfaces
504 .contains(&"binderPluginBoundary")
505 );
506 assert!(
507 boundary
508 .cme_coupled_surfaces
509 .contains(&"promotionEvidenceWithSourceInput")
510 );
511 assert!(
512 boundary.next_decoupling_targets.is_empty(),
513 "all current omena-bridge decoupling targets should be bridge-owned"
514 );
515 }
516
517 #[test]
518 fn declares_built_in_binder_plugin_boundary() {
519 let boundary = summarize_omena_bridge_binder_plugin_boundary();
520
521 assert_eq!(boundary.schema_version, "0");
522 assert_eq!(boundary.product, "omena-bridge.binder-plugin-boundary");
523 assert_eq!(boundary.contract_name, "BinderPluginV0");
524 assert!(
525 !boundary.external_plugin_abi_stable,
526 "the first boundary cut should not promise a stable external plugin ABI"
527 );
528 assert_eq!(boundary.default_plugin.id, "css-modules-classnames-bind");
529 assert_eq!(boundary.default_plugin.stability, "builtIn");
530 assert!(boundary.default_plugin.domains.contains(&"css-modules"));
531 assert!(
532 boundary
533 .default_plugin
534 .owns_surfaces
535 .contains(&"classReferenceExtraction")
536 );
537 assert!(
538 boundary
539 .default_plugin
540 .utility_targets
541 .contains(&"classnames/bind")
542 );
543 assert!(
544 boundary
545 .request_path_policy
546 .contains(&"pluginOutputFeedsEngineInputV2")
547 );
548 assert!(
549 boundary
550 .request_path_policy
551 .contains(&"styleSourceExtractionIsOptionalForUtilityDomains")
552 );
553 assert!(boundary.built_in_plugins.iter().any(|plugin| {
554 plugin.id == "tailwind-uno-utility-domain"
555 && plugin.domains.contains(&"tailwind-utilities")
556 && plugin
557 .owns_surfaces
558 .contains(&"domainClassReferenceExtraction")
559 }));
560 assert!(
561 !boundary
562 .next_plugin_targets
563 .contains(&"tailwind-utility-domain")
564 );
565 assert!(boundary.built_in_plugins.iter().any(|plugin| {
566 plugin.id == "vanilla-extract-recipe-domain"
567 && plugin.domains.contains(&"vanilla-extract-recipes")
568 && plugin
569 .owns_surfaces
570 .contains(&"domainClassReferenceExtraction")
571 }));
572 assert!(
573 !boundary
574 .next_plugin_targets
575 .contains(&"vanilla-extract-recipe-domain")
576 );
577 assert!(boundary.built_in_plugins.iter().any(|plugin| {
578 plugin.id == "vue-style-module-domain"
579 && plugin.domains.contains(&"vue-style-modules")
580 && plugin
581 .owns_surfaces
582 .contains(&"domainClassReferenceExtraction")
583 }));
584 assert!(
585 boundary.next_plugin_targets.is_empty(),
586 "all planned BinderPluginV0 proof-point domains should now be built in"
587 );
588 }
589
590 #[test]
591 fn summarizes_source_import_declarations_for_css_modules_binding_inputs() {
592 let summary = summarize_omena_bridge_source_import_declarations(
593 r#"
594import bind from "classnames/bind";
595import styles from "./Button.module.scss";
596import * as tokens from "./tokens.module.css";
597import { type BadgeProps } from "./types";
598const lazy = import("./ignored.module.scss");
599"#,
600 );
601
602 assert_eq!(summary.product, "omena-bridge.source-import-declarations");
603 assert_eq!(summary.import_count, 3);
604 assert_eq!(
605 summary
606 .imports
607 .iter()
608 .map(|import| (import.binding.as_str(), import.specifier.as_str()))
609 .collect::<Vec<_>>(),
610 vec![
611 ("bind", "classnames/bind"),
612 ("styles", "./Button.module.scss"),
613 ("tokens", "./tokens.module.css"),
614 ]
615 );
616 }
617
618 #[test]
619 fn exposes_source_input_evidence_through_bridge() {
620 let evidence = summarize_omena_bridge_source_input_evidence(&sample_engine_input());
621
622 assert_eq!(evidence.product, "omena-semantic.source-input-evidence");
623 assert_eq!(evidence.reference_site_identity.status, "ready");
624 assert_eq!(evidence.reference_site_identity.reference_site_count, 1);
625 assert_eq!(evidence.certainty_reason.status, "ready");
626 assert_eq!(evidence.binding_origin.status, "ready");
627 assert!(evidence.blocking_gaps.is_empty());
628 }
629
630 #[test]
631 fn exposes_style_semantic_graph_through_bridge() -> Result<(), String> {
632 let graph = summarize_omena_bridge_style_semantic_graph_from_source(
633 "/tmp/Component.module.scss",
634 ".button { color: red; }",
635 &sample_engine_input(),
636 )
637 .ok_or_else(|| "SCSS module source should parse".to_string())?;
638
639 assert_eq!(graph.product, "omena-semantic.style-semantic-graph");
640 assert_eq!(graph.selector_reference_engine.selector_count, 1);
641 assert_eq!(graph.selector_reference_engine.referenced_selector_count, 1);
642 assert_eq!(
643 graph.source_input_evidence.product,
644 "omena-semantic.source-input-evidence"
645 );
646 assert!(graph.promotion_evidence.blocking_gaps.is_empty());
647 Ok(())
648 }
649
650 #[test]
651 fn exposes_style_semantic_graph_from_source_through_bridge() -> Result<(), String> {
652 let graph = summarize_omena_bridge_style_semantic_graph_from_source(
653 "/tmp/Component.module.scss",
654 r#"@use "./tokens" as tokens; .button { --brand: red; color: var(--brand); color: tokens.$brand; }"#,
655 &sample_engine_input(),
656 )
657 .ok_or_else(|| "bridge should parse SCSS module source".to_string())?;
658
659 assert_eq!(graph.product, "omena-semantic.style-semantic-graph");
660 assert_eq!(
661 graph.parser_facts.custom_properties.decl_names[0].to_custom_key(),
662 PropertyNameV0::canonical_custom_key("--brand")
663 );
664 assert_eq!(
665 graph.parser_facts.custom_properties.ref_names[0].to_custom_key(),
666 PropertyNameV0::canonical_custom_key("--brand")
667 );
668 assert_eq!(
669 graph.parser_facts.sass.module_use_edges[0].namespace_kind,
670 "alias"
671 );
672 assert_eq!(
673 graph.parser_facts.sass.variable_ref_names,
674 vec!["brand".to_string()]
675 );
676 assert_eq!(
677 graph.selector_reference_engine.style_path,
678 Some("/tmp/Component.module.scss".to_string())
679 );
680 assert_eq!(
681 graph.source_input_evidence.reference_site_identity.status,
682 "ready"
683 );
684 Ok(())
685 }
686
687 #[test]
688 fn collects_design_token_workspace_declarations_from_source_through_bridge() {
689 let declarations = collect_omena_bridge_design_token_workspace_declarations_from_source(
690 "/tmp/tokens.module.scss",
691 r#":root { --brand: red; } .button { --local: blue; color: var(--brand); }"#,
692 );
693
694 assert_eq!(
695 declarations
696 .iter()
697 .map(|declaration| declaration.name.to_custom_key())
698 .collect::<Vec<_>>(),
699 vec![
700 PropertyNameV0::canonical_custom_key("--brand"),
701 PropertyNameV0::canonical_custom_key("--local")
702 ]
703 );
704 assert!(
705 declarations
706 .iter()
707 .all(|declaration| declaration.file_path == "/tmp/tokens.module.scss")
708 );
709 assert_eq!(declarations[0].source_order, 0);
710 assert_eq!(declarations[1].source_order, 1);
711 }
712
713 #[test]
714 fn owns_selector_reference_engine_without_changing_host_product() {
715 let bridge_references = summarize_omena_bridge_selector_reference_engine(
716 &sample_engine_input(),
717 Some("/tmp/Component.module.scss"),
718 );
719 let semantic_references = omena_semantic::summarize_selector_reference_engine(
720 &sample_engine_input(),
721 Some("/tmp/Component.module.scss"),
722 );
723
724 assert_eq!(
725 bridge_references.product,
726 "omena-semantic.selector-references"
727 );
728 assert_eq!(bridge_references.product, semantic_references.product);
729 assert_eq!(bridge_references.style_path, semantic_references.style_path);
730 assert_eq!(
731 bridge_references.selector_count,
732 semantic_references.selector_count
733 );
734 assert_eq!(
735 bridge_references.referenced_selector_count,
736 semantic_references.referenced_selector_count
737 );
738 assert_eq!(
739 bridge_references.total_reference_sites,
740 semantic_references.total_reference_sites
741 );
742 assert_eq!(
743 bridge_references.selectors[0].canonical_id,
744 semantic_references.selectors[0].canonical_id
745 );
746 assert_eq!(
747 bridge_references.selectors[0].editable_direct_reference_count,
748 semantic_references.selectors[0].editable_direct_reference_count
749 );
750 }
751
752 #[test]
753 fn owns_source_input_evidence_without_changing_host_product() {
754 let bridge_evidence = summarize_omena_bridge_source_input_evidence(&sample_engine_input());
755 let semantic_evidence =
756 omena_semantic::summarize_source_input_evidence(&sample_engine_input());
757
758 assert_bridge_source_input_evidence_matches_semantic(&bridge_evidence, &semantic_evidence);
759 }
760
761 #[test]
762 fn owns_source_backed_promotion_evidence_without_changing_host_product() -> Result<(), String> {
763 let boundary = omena_semantic::summarize_omena_parser_style_semantic_boundary_from_source(
764 "/tmp/Component.module.scss",
765 ".button { color: red; }",
766 );
767 let input = sample_engine_input();
768 let bridge_evidence = summarize_omena_bridge_promotion_evidence_with_source_input(
769 &boundary.parser_facts,
770 &boundary.semantic_facts,
771 &input,
772 );
773 let semantic_evidence =
774 omena_semantic::summarize_semantic_promotion_evidence_with_source_input(
775 &boundary.parser_facts,
776 &boundary.semantic_facts,
777 &input,
778 );
779
780 assert_bridge_promotion_evidence_matches_semantic(&bridge_evidence, &semantic_evidence);
781 Ok(())
782 }
783
784 #[test]
785 fn owns_graph_assembly_without_changing_host_product() -> Result<(), String> {
786 let bridge_graph = summarize_omena_bridge_style_semantic_graph_from_source(
787 "/tmp/Component.module.scss",
788 ".button { color: red; }",
789 &sample_engine_input(),
790 )
791 .ok_or_else(|| "bridge should parse SCSS module source".to_string())?;
792 let semantic_graph = omena_semantic::summarize_style_semantic_graph_from_source(
793 "/tmp/Component.module.scss",
794 ".button { color: red; }",
795 &sample_engine_input(),
796 )
797 .ok_or_else(|| "semantic should parse SCSS module source".to_string())?;
798
799 assert_eq!(bridge_graph.product, "omena-semantic.style-semantic-graph");
800 assert_eq!(bridge_graph.product, semantic_graph.product);
801 assert_eq!(bridge_graph.language, semantic_graph.language);
802 assert_eq!(
803 bridge_graph.selector_reference_engine.product,
804 semantic_graph.selector_reference_engine.product
805 );
806 assert_eq!(
807 bridge_graph.selector_reference_engine.selector_count,
808 semantic_graph.selector_reference_engine.selector_count
809 );
810 assert_eq!(
811 bridge_graph.selector_reference_engine.total_reference_sites,
812 semantic_graph
813 .selector_reference_engine
814 .total_reference_sites
815 );
816 assert_bridge_source_input_evidence_matches_semantic(
817 &bridge_graph.source_input_evidence,
818 &semantic_graph.source_input_evidence,
819 );
820 assert_eq!(
821 bridge_graph.design_token_semantics,
822 semantic_graph.design_token_semantics
823 );
824 assert_bridge_promotion_evidence_matches_semantic(
825 &bridge_graph.promotion_evidence,
826 &semantic_graph.promotion_evidence,
827 );
828 Ok(())
829 }
830
831 fn assert_bridge_promotion_evidence_matches_semantic(
832 bridge: &super::SemanticPromotionEvidenceSummaryV0,
833 semantic: &omena_semantic::SemanticPromotionEvidenceSummaryV0,
834 ) {
835 assert_eq!(bridge.schema_version, semantic.schema_version);
836 assert_eq!(bridge.product, semantic.product);
837 assert_eq!(bridge.blocking_gaps, semantic.blocking_gaps);
838 assert_eq!(bridge.next_priorities, semantic.next_priorities);
839 assert_eq!(bridge.items.len(), semantic.items.len());
840
841 for (bridge_item, semantic_item) in bridge.items.iter().zip(&semantic.items) {
842 assert_eq!(bridge_item.evidence, semantic_item.evidence);
843 assert_eq!(bridge_item.status, semantic_item.status);
844 assert_eq!(bridge_item.provider, semantic_item.provider);
845 assert_eq!(bridge_item.observed_count, semantic_item.observed_count);
846 assert_eq!(bridge_item.reason, semantic_item.reason);
847 }
848 }
849
850 fn assert_bridge_source_input_evidence_matches_semantic(
851 bridge: &super::SourceInputPromotionEvidenceSummaryV0,
852 semantic: &omena_semantic::SourceInputPromotionEvidenceSummaryV0,
853 ) {
854 assert_eq!(bridge.schema_version, semantic.schema_version);
855 assert_eq!(bridge.product, semantic.product);
856 assert_eq!(bridge.input_version, semantic.input_version);
857 assert_eq!(
858 bridge.reference_site_identity.status,
859 semantic.reference_site_identity.status
860 );
861 assert_eq!(
862 bridge.reference_site_identity.selector_count,
863 semantic.reference_site_identity.selector_count
864 );
865 assert_eq!(
866 bridge.reference_site_identity.reference_site_count,
867 semantic.reference_site_identity.reference_site_count
868 );
869 assert_eq!(
870 bridge.reference_site_identity.direct_reference_site_count,
871 semantic.reference_site_identity.direct_reference_site_count
872 );
873 assert_eq!(
874 bridge.reference_site_identity.expanded_reference_site_count,
875 semantic
876 .reference_site_identity
877 .expanded_reference_site_count
878 );
879 assert_eq!(
880 bridge
881 .reference_site_identity
882 .style_dependency_reference_site_count,
883 semantic
884 .reference_site_identity
885 .style_dependency_reference_site_count
886 );
887 assert_eq!(
888 bridge.reference_site_identity.editable_direct_site_count,
889 semantic.reference_site_identity.editable_direct_site_count
890 );
891 assert_eq!(
892 bridge.reference_site_identity.reference_kind_counts,
893 semantic.reference_site_identity.reference_kind_counts
894 );
895 assert_eq!(
896 bridge.certainty_reason.status,
897 semantic.certainty_reason.status
898 );
899 assert_eq!(
900 bridge.certainty_reason.expression_count,
901 semantic.certainty_reason.expression_count
902 );
903 assert_eq!(
904 bridge.certainty_reason.exact_count,
905 semantic.certainty_reason.exact_count
906 );
907 assert_eq!(
908 bridge.certainty_reason.inferred_count,
909 semantic.certainty_reason.inferred_count
910 );
911 assert_eq!(
912 bridge.certainty_reason.possible_count,
913 semantic.certainty_reason.possible_count
914 );
915 assert_eq!(
916 bridge.certainty_reason.missing_reason_count,
917 semantic.certainty_reason.missing_reason_count
918 );
919 assert_eq!(
920 bridge.certainty_reason.reason_counts,
921 semantic.certainty_reason.reason_counts
922 );
923 assert_eq!(
924 bridge.certainty_reason.shape_kind_counts,
925 semantic.certainty_reason.shape_kind_counts
926 );
927 assert_eq!(
928 bridge.certainty_reason.shape_label_counts,
929 semantic.certainty_reason.shape_label_counts
930 );
931 assert_eq!(bridge.binding_origin.status, semantic.binding_origin.status);
932 assert_eq!(
933 bridge.binding_origin.expression_count,
934 semantic.binding_origin.expression_count
935 );
936 assert_eq!(
937 bridge.binding_origin.direct_class_name_count,
938 semantic.binding_origin.direct_class_name_count
939 );
940 assert_eq!(
941 bridge.binding_origin.root_binding_count,
942 semantic.binding_origin.root_binding_count
943 );
944 assert_eq!(
945 bridge.binding_origin.access_path_count,
946 semantic.binding_origin.access_path_count
947 );
948 assert_eq!(
949 bridge.binding_origin.access_path_segment_count,
950 semantic.binding_origin.access_path_segment_count
951 );
952 assert_eq!(
953 bridge.binding_origin.expression_kind_counts,
954 semantic.binding_origin.expression_kind_counts
955 );
956 assert_eq!(
957 bridge.style_module_edge.status,
958 semantic.style_module_edge.status
959 );
960 assert_eq!(
961 bridge.style_module_edge.source_style_edge_count,
962 semantic.style_module_edge.source_style_edge_count
963 );
964 assert_eq!(
965 bridge.style_module_edge.distinct_style_module_count,
966 semantic.style_module_edge.distinct_style_module_count
967 );
968 assert_eq!(
969 bridge.style_module_edge.missing_style_document_edge_count,
970 semantic.style_module_edge.missing_style_document_edge_count
971 );
972 assert_eq!(
973 bridge.style_module_edge.composed_edge_count,
974 semantic.style_module_edge.composed_edge_count
975 );
976 assert_eq!(
977 bridge.style_module_edge.imported_composed_edge_count,
978 semantic.style_module_edge.imported_composed_edge_count
979 );
980 assert_eq!(
981 bridge.style_module_edge.global_composed_edge_count,
982 semantic.style_module_edge.global_composed_edge_count
983 );
984 assert_eq!(
985 bridge.value_domain_explanation.status,
986 semantic.value_domain_explanation.status
987 );
988 assert_eq!(
989 bridge.value_domain_explanation.expression_count,
990 semantic.value_domain_explanation.expression_count
991 );
992 assert_eq!(
993 bridge.value_domain_explanation.exact_expression_count,
994 semantic.value_domain_explanation.exact_expression_count
995 );
996 assert_eq!(
997 bridge
998 .value_domain_explanation
999 .finite_value_expression_count,
1000 semantic
1001 .value_domain_explanation
1002 .finite_value_expression_count
1003 );
1004 assert_eq!(
1005 bridge.value_domain_explanation.constrained_expression_count,
1006 semantic
1007 .value_domain_explanation
1008 .constrained_expression_count
1009 );
1010 assert_eq!(
1011 bridge.value_domain_explanation.unknown_expression_count,
1012 semantic.value_domain_explanation.unknown_expression_count
1013 );
1014 assert_eq!(
1015 bridge.value_domain_explanation.finite_value_count,
1016 semantic.value_domain_explanation.finite_value_count
1017 );
1018 assert_eq!(
1019 bridge.value_domain_explanation.derivation_count,
1020 semantic.value_domain_explanation.derivation_count
1021 );
1022 assert_eq!(
1023 bridge.value_domain_explanation.derivation_step_count,
1024 semantic.value_domain_explanation.derivation_step_count
1025 );
1026 assert_eq!(
1027 bridge.value_domain_explanation.value_domain_kind_counts,
1028 semantic.value_domain_explanation.value_domain_kind_counts
1029 );
1030 assert_eq!(
1031 bridge.value_domain_explanation.constraint_kind_counts,
1032 semantic.value_domain_explanation.constraint_kind_counts
1033 );
1034 assert_eq!(
1035 bridge.value_domain_explanation.derivation_product_counts,
1036 semantic.value_domain_explanation.derivation_product_counts
1037 );
1038 assert_eq!(
1039 bridge
1040 .value_domain_explanation
1041 .derivation_reduced_kind_counts,
1042 semantic
1043 .value_domain_explanation
1044 .derivation_reduced_kind_counts
1045 );
1046 assert_eq!(
1047 bridge.value_domain_explanation.derivation_operation_counts,
1048 semantic
1049 .value_domain_explanation
1050 .derivation_operation_counts
1051 );
1052 assert_eq!(bridge.blocking_gaps, semantic.blocking_gaps);
1053 assert_eq!(bridge.next_priorities, semantic.next_priorities);
1054 }
1055
1056 fn sample_engine_input() -> EngineInputV2 {
1057 EngineInputV2 {
1058 version: "2".to_string(),
1059 sources: vec![SourceAnalysisInputV2 {
1060 document: SourceDocumentV2 {
1061 class_expressions: vec![ClassExpressionInputV2 {
1062 id: "expr-literal".to_string(),
1063 kind: "literal".to_string(),
1064 scss_module_path: "/tmp/Component.module.scss".to_string(),
1065 range: range(4, 12, 4, 18),
1066 class_name: Some("button".to_string()),
1067 root_binding_decl_id: None,
1068 access_path: None,
1069 }],
1070 },
1071 }],
1072 styles: vec![StyleAnalysisInputV2 {
1073 file_path: "/tmp/Component.module.scss".to_string(),
1074 source: None,
1075 document: StyleDocumentV2 {
1076 selectors: vec![StyleSelectorV2 {
1077 name: "button".to_string(),
1078 view_kind: "canonical".to_string(),
1079 canonical_name: Some("button".to_string()),
1080 range: range(0, 1, 0, 7),
1081 nested_safety: Some("flat".to_string()),
1082 composes: None,
1083 bem_suffix: None,
1084 }],
1085 },
1086 }],
1087 type_facts: vec![TypeFactEntryV2 {
1088 file_path: "/tmp/Component.tsx".to_string(),
1089 expression_id: "expr-literal".to_string(),
1090 facts: StringTypeFactsV2 {
1091 kind: "exact".to_string(),
1092 constraint_kind: None,
1093 values: Some(vec!["button".to_string()]),
1094 prefix: None,
1095 suffix: None,
1096 min_len: None,
1097 max_len: None,
1098 char_must: None,
1099 char_may: None,
1100 may_include_other_chars: None,
1101 provenance: None,
1102 },
1103 control_flow_graph: None,
1104 }],
1105 }
1106 }
1107
1108 fn range(
1109 start_line: usize,
1110 start_character: usize,
1111 end_line: usize,
1112 end_character: usize,
1113 ) -> RangeV2 {
1114 RangeV2 {
1115 start: PositionV2 {
1116 line: start_line,
1117 character: start_character,
1118 },
1119 end: PositionV2 {
1120 line: end_line,
1121 character: end_character,
1122 },
1123 }
1124 }
1125}