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,
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
433 #[test]
434 fn declares_cme_coupled_bridge_boundary() {
435 let boundary = summarize_omena_bridge_boundary();
436
437 assert_eq!(boundary.schema_version, "0");
438 assert_eq!(boundary.product, "omena-bridge.cme-semantic-bridge");
439 assert_eq!(
440 boundary.graph_product,
441 "omena-semantic.style-semantic-graph"
442 );
443 assert_eq!(
444 boundary.delegated_semantic_boundary_product,
445 "omena-semantic.style-semantic-boundary"
446 );
447 assert_eq!(
448 boundary.selector_reference_product,
449 "omena-semantic.selector-references"
450 );
451 assert_eq!(
452 boundary.source_input_evidence_product,
453 "omena-semantic.source-input-evidence"
454 );
455 assert_eq!(
456 boundary.binder_plugin_product,
457 "omena-bridge.binder-plugin-boundary"
458 );
459 assert!(
460 boundary
461 .bridge_owned_surfaces
462 .contains(&"styleSemanticGraphFromSource")
463 );
464 assert!(
465 boundary
466 .bridge_owned_surfaces
467 .contains(&"omenaParserBackedStyleSemanticBoundaryFromSource")
468 );
469 assert!(
470 boundary
471 .bridge_owned_surfaces
472 .contains(&"selectorReferenceEngine")
473 );
474 assert!(
475 boundary
476 .bridge_owned_surfaces
477 .contains(&"designTokenWorkspaceDeclarationsFromSource")
478 );
479 assert!(
480 boundary
481 .bridge_owned_surfaces
482 .contains(&"sourceInputEvidence")
483 );
484 assert!(
485 boundary
486 .bridge_owned_surfaces
487 .contains(&"promotionEvidenceWithSourceInput")
488 );
489 assert!(
490 boundary
491 .bridge_owned_surfaces
492 .contains(&"sourceImportDeclarations")
493 );
494 assert!(boundary.bridge_owned_surfaces.contains(&"styleResolution"));
495 assert!(
496 boundary
497 .bridge_owned_surfaces
498 .contains(&"sourceSyntaxIndex")
499 );
500 assert!(
501 boundary
502 .bridge_owned_surfaces
503 .contains(&"binderPluginBoundary")
504 );
505 assert!(
506 boundary
507 .cme_coupled_surfaces
508 .contains(&"promotionEvidenceWithSourceInput")
509 );
510 assert!(
511 boundary.next_decoupling_targets.is_empty(),
512 "all current omena-bridge decoupling targets should be bridge-owned"
513 );
514 }
515
516 #[test]
517 fn declares_built_in_binder_plugin_boundary() {
518 let boundary = summarize_omena_bridge_binder_plugin_boundary();
519
520 assert_eq!(boundary.schema_version, "0");
521 assert_eq!(boundary.product, "omena-bridge.binder-plugin-boundary");
522 assert_eq!(boundary.contract_name, "BinderPluginV0");
523 assert!(
524 !boundary.external_plugin_abi_stable,
525 "the first boundary cut should not promise a stable external plugin ABI"
526 );
527 assert_eq!(boundary.default_plugin.id, "css-modules-classnames-bind");
528 assert_eq!(boundary.default_plugin.stability, "builtIn");
529 assert!(boundary.default_plugin.domains.contains(&"css-modules"));
530 assert!(
531 boundary
532 .default_plugin
533 .owns_surfaces
534 .contains(&"classReferenceExtraction")
535 );
536 assert!(
537 boundary
538 .default_plugin
539 .utility_targets
540 .contains(&"classnames/bind")
541 );
542 assert!(
543 boundary
544 .request_path_policy
545 .contains(&"pluginOutputFeedsEngineInputV2")
546 );
547 assert!(
548 boundary
549 .request_path_policy
550 .contains(&"styleSourceExtractionIsOptionalForUtilityDomains")
551 );
552 assert!(boundary.built_in_plugins.iter().any(|plugin| {
553 plugin.id == "tailwind-uno-utility-domain"
554 && plugin.domains.contains(&"tailwind-utilities")
555 && plugin
556 .owns_surfaces
557 .contains(&"domainClassReferenceExtraction")
558 }));
559 assert!(
560 !boundary
561 .next_plugin_targets
562 .contains(&"tailwind-utility-domain")
563 );
564 assert!(boundary.built_in_plugins.iter().any(|plugin| {
565 plugin.id == "vanilla-extract-recipe-domain"
566 && plugin.domains.contains(&"vanilla-extract-recipes")
567 && plugin
568 .owns_surfaces
569 .contains(&"domainClassReferenceExtraction")
570 }));
571 assert!(
572 !boundary
573 .next_plugin_targets
574 .contains(&"vanilla-extract-recipe-domain")
575 );
576 assert!(boundary.built_in_plugins.iter().any(|plugin| {
577 plugin.id == "vue-style-module-domain"
578 && plugin.domains.contains(&"vue-style-modules")
579 && plugin
580 .owns_surfaces
581 .contains(&"domainClassReferenceExtraction")
582 }));
583 assert!(
584 boundary.next_plugin_targets.is_empty(),
585 "all planned BinderPluginV0 proof-point domains should now be built in"
586 );
587 }
588
589 #[test]
590 fn summarizes_source_import_declarations_for_css_modules_binding_inputs() {
591 let summary = summarize_omena_bridge_source_import_declarations(
592 r#"
593import bind from "classnames/bind";
594import styles from "./Button.module.scss";
595import * as tokens from "./tokens.module.css";
596import { type BadgeProps } from "./types";
597const lazy = import("./ignored.module.scss");
598"#,
599 );
600
601 assert_eq!(summary.product, "omena-bridge.source-import-declarations");
602 assert_eq!(summary.import_count, 3);
603 assert_eq!(
604 summary
605 .imports
606 .iter()
607 .map(|import| (import.binding.as_str(), import.specifier.as_str()))
608 .collect::<Vec<_>>(),
609 vec![
610 ("bind", "classnames/bind"),
611 ("styles", "./Button.module.scss"),
612 ("tokens", "./tokens.module.css"),
613 ]
614 );
615 }
616
617 #[test]
618 fn exposes_source_input_evidence_through_bridge() {
619 let evidence = summarize_omena_bridge_source_input_evidence(&sample_engine_input());
620
621 assert_eq!(evidence.product, "omena-semantic.source-input-evidence");
622 assert_eq!(evidence.reference_site_identity.status, "ready");
623 assert_eq!(evidence.reference_site_identity.reference_site_count, 1);
624 assert_eq!(evidence.certainty_reason.status, "ready");
625 assert_eq!(evidence.binding_origin.status, "ready");
626 assert!(evidence.blocking_gaps.is_empty());
627 }
628
629 #[test]
630 fn exposes_style_semantic_graph_through_bridge() -> Result<(), String> {
631 let graph = summarize_omena_bridge_style_semantic_graph_from_source(
632 "/tmp/Component.module.scss",
633 ".button { color: red; }",
634 &sample_engine_input(),
635 )
636 .ok_or_else(|| "SCSS module source should parse".to_string())?;
637
638 assert_eq!(graph.product, "omena-semantic.style-semantic-graph");
639 assert_eq!(graph.selector_reference_engine.selector_count, 1);
640 assert_eq!(graph.selector_reference_engine.referenced_selector_count, 1);
641 assert_eq!(
642 graph.source_input_evidence.product,
643 "omena-semantic.source-input-evidence"
644 );
645 assert!(graph.promotion_evidence.blocking_gaps.is_empty());
646 Ok(())
647 }
648
649 #[test]
650 fn exposes_style_semantic_graph_from_source_through_bridge() -> Result<(), String> {
651 let graph = summarize_omena_bridge_style_semantic_graph_from_source(
652 "/tmp/Component.module.scss",
653 r#"@use "./tokens" as tokens; .button { --brand: red; color: var(--brand); color: tokens.$brand; }"#,
654 &sample_engine_input(),
655 )
656 .ok_or_else(|| "bridge should parse SCSS module source".to_string())?;
657
658 assert_eq!(graph.product, "omena-semantic.style-semantic-graph");
659 assert_eq!(
660 graph.parser_facts.custom_properties.decl_names,
661 vec!["--brand".to_string()]
662 );
663 assert_eq!(
664 graph.parser_facts.custom_properties.ref_names,
665 vec!["--brand".to_string()]
666 );
667 assert_eq!(
668 graph.parser_facts.sass.module_use_edges[0].namespace_kind,
669 "alias"
670 );
671 assert_eq!(
672 graph.parser_facts.sass.variable_ref_names,
673 vec!["brand".to_string()]
674 );
675 assert_eq!(
676 graph.selector_reference_engine.style_path,
677 Some("/tmp/Component.module.scss".to_string())
678 );
679 assert_eq!(
680 graph.source_input_evidence.reference_site_identity.status,
681 "ready"
682 );
683 Ok(())
684 }
685
686 #[test]
687 fn collects_design_token_workspace_declarations_from_source_through_bridge() {
688 let declarations = collect_omena_bridge_design_token_workspace_declarations_from_source(
689 "/tmp/tokens.module.scss",
690 r#":root { --brand: red; } .button { --local: blue; color: var(--brand); }"#,
691 );
692
693 assert_eq!(
694 declarations
695 .iter()
696 .map(|declaration| declaration.name.as_str())
697 .collect::<Vec<_>>(),
698 vec!["--brand", "--local"]
699 );
700 assert!(
701 declarations
702 .iter()
703 .all(|declaration| declaration.file_path == "/tmp/tokens.module.scss")
704 );
705 assert_eq!(declarations[0].source_order, 0);
706 assert_eq!(declarations[1].source_order, 1);
707 }
708
709 #[test]
710 fn owns_selector_reference_engine_without_changing_host_product() {
711 let bridge_references = summarize_omena_bridge_selector_reference_engine(
712 &sample_engine_input(),
713 Some("/tmp/Component.module.scss"),
714 );
715 let semantic_references = omena_semantic::summarize_selector_reference_engine(
716 &sample_engine_input(),
717 Some("/tmp/Component.module.scss"),
718 );
719
720 assert_eq!(
721 bridge_references.product,
722 "omena-semantic.selector-references"
723 );
724 assert_eq!(bridge_references.product, semantic_references.product);
725 assert_eq!(bridge_references.style_path, semantic_references.style_path);
726 assert_eq!(
727 bridge_references.selector_count,
728 semantic_references.selector_count
729 );
730 assert_eq!(
731 bridge_references.referenced_selector_count,
732 semantic_references.referenced_selector_count
733 );
734 assert_eq!(
735 bridge_references.total_reference_sites,
736 semantic_references.total_reference_sites
737 );
738 assert_eq!(
739 bridge_references.selectors[0].canonical_id,
740 semantic_references.selectors[0].canonical_id
741 );
742 assert_eq!(
743 bridge_references.selectors[0].editable_direct_reference_count,
744 semantic_references.selectors[0].editable_direct_reference_count
745 );
746 }
747
748 #[test]
749 fn owns_source_input_evidence_without_changing_host_product() {
750 let bridge_evidence = summarize_omena_bridge_source_input_evidence(&sample_engine_input());
751 let semantic_evidence =
752 omena_semantic::summarize_source_input_evidence(&sample_engine_input());
753
754 assert_bridge_source_input_evidence_matches_semantic(&bridge_evidence, &semantic_evidence);
755 }
756
757 #[test]
758 fn owns_source_backed_promotion_evidence_without_changing_host_product() -> Result<(), String> {
759 let boundary = omena_semantic::summarize_omena_parser_style_semantic_boundary_from_source(
760 "/tmp/Component.module.scss",
761 ".button { color: red; }",
762 );
763 let input = sample_engine_input();
764 let bridge_evidence = summarize_omena_bridge_promotion_evidence_with_source_input(
765 &boundary.parser_facts,
766 &boundary.semantic_facts,
767 &input,
768 );
769 let semantic_evidence =
770 omena_semantic::summarize_semantic_promotion_evidence_with_source_input(
771 &boundary.parser_facts,
772 &boundary.semantic_facts,
773 &input,
774 );
775
776 assert_bridge_promotion_evidence_matches_semantic(&bridge_evidence, &semantic_evidence);
777 Ok(())
778 }
779
780 #[test]
781 fn owns_graph_assembly_without_changing_host_product() -> Result<(), String> {
782 let bridge_graph = summarize_omena_bridge_style_semantic_graph_from_source(
783 "/tmp/Component.module.scss",
784 ".button { color: red; }",
785 &sample_engine_input(),
786 )
787 .ok_or_else(|| "bridge should parse SCSS module source".to_string())?;
788 let semantic_graph = omena_semantic::summarize_style_semantic_graph_from_source(
789 "/tmp/Component.module.scss",
790 ".button { color: red; }",
791 &sample_engine_input(),
792 )
793 .ok_or_else(|| "semantic should parse SCSS module source".to_string())?;
794
795 assert_eq!(bridge_graph.product, "omena-semantic.style-semantic-graph");
796 assert_eq!(bridge_graph.product, semantic_graph.product);
797 assert_eq!(bridge_graph.language, semantic_graph.language);
798 assert_eq!(
799 bridge_graph.selector_reference_engine.product,
800 semantic_graph.selector_reference_engine.product
801 );
802 assert_eq!(
803 bridge_graph.selector_reference_engine.selector_count,
804 semantic_graph.selector_reference_engine.selector_count
805 );
806 assert_eq!(
807 bridge_graph.selector_reference_engine.total_reference_sites,
808 semantic_graph
809 .selector_reference_engine
810 .total_reference_sites
811 );
812 assert_bridge_source_input_evidence_matches_semantic(
813 &bridge_graph.source_input_evidence,
814 &semantic_graph.source_input_evidence,
815 );
816 assert_eq!(
817 bridge_graph.design_token_semantics,
818 semantic_graph.design_token_semantics
819 );
820 assert_bridge_promotion_evidence_matches_semantic(
821 &bridge_graph.promotion_evidence,
822 &semantic_graph.promotion_evidence,
823 );
824 Ok(())
825 }
826
827 fn assert_bridge_promotion_evidence_matches_semantic(
828 bridge: &super::SemanticPromotionEvidenceSummaryV0,
829 semantic: &omena_semantic::SemanticPromotionEvidenceSummaryV0,
830 ) {
831 assert_eq!(bridge.schema_version, semantic.schema_version);
832 assert_eq!(bridge.product, semantic.product);
833 assert_eq!(bridge.blocking_gaps, semantic.blocking_gaps);
834 assert_eq!(bridge.next_priorities, semantic.next_priorities);
835 assert_eq!(bridge.items.len(), semantic.items.len());
836
837 for (bridge_item, semantic_item) in bridge.items.iter().zip(&semantic.items) {
838 assert_eq!(bridge_item.evidence, semantic_item.evidence);
839 assert_eq!(bridge_item.status, semantic_item.status);
840 assert_eq!(bridge_item.provider, semantic_item.provider);
841 assert_eq!(bridge_item.observed_count, semantic_item.observed_count);
842 assert_eq!(bridge_item.reason, semantic_item.reason);
843 }
844 }
845
846 fn assert_bridge_source_input_evidence_matches_semantic(
847 bridge: &super::SourceInputPromotionEvidenceSummaryV0,
848 semantic: &omena_semantic::SourceInputPromotionEvidenceSummaryV0,
849 ) {
850 assert_eq!(bridge.schema_version, semantic.schema_version);
851 assert_eq!(bridge.product, semantic.product);
852 assert_eq!(bridge.input_version, semantic.input_version);
853 assert_eq!(
854 bridge.reference_site_identity.status,
855 semantic.reference_site_identity.status
856 );
857 assert_eq!(
858 bridge.reference_site_identity.selector_count,
859 semantic.reference_site_identity.selector_count
860 );
861 assert_eq!(
862 bridge.reference_site_identity.reference_site_count,
863 semantic.reference_site_identity.reference_site_count
864 );
865 assert_eq!(
866 bridge.reference_site_identity.direct_reference_site_count,
867 semantic.reference_site_identity.direct_reference_site_count
868 );
869 assert_eq!(
870 bridge.reference_site_identity.expanded_reference_site_count,
871 semantic
872 .reference_site_identity
873 .expanded_reference_site_count
874 );
875 assert_eq!(
876 bridge
877 .reference_site_identity
878 .style_dependency_reference_site_count,
879 semantic
880 .reference_site_identity
881 .style_dependency_reference_site_count
882 );
883 assert_eq!(
884 bridge.reference_site_identity.editable_direct_site_count,
885 semantic.reference_site_identity.editable_direct_site_count
886 );
887 assert_eq!(
888 bridge.reference_site_identity.reference_kind_counts,
889 semantic.reference_site_identity.reference_kind_counts
890 );
891 assert_eq!(
892 bridge.certainty_reason.status,
893 semantic.certainty_reason.status
894 );
895 assert_eq!(
896 bridge.certainty_reason.expression_count,
897 semantic.certainty_reason.expression_count
898 );
899 assert_eq!(
900 bridge.certainty_reason.exact_count,
901 semantic.certainty_reason.exact_count
902 );
903 assert_eq!(
904 bridge.certainty_reason.inferred_count,
905 semantic.certainty_reason.inferred_count
906 );
907 assert_eq!(
908 bridge.certainty_reason.possible_count,
909 semantic.certainty_reason.possible_count
910 );
911 assert_eq!(
912 bridge.certainty_reason.missing_reason_count,
913 semantic.certainty_reason.missing_reason_count
914 );
915 assert_eq!(
916 bridge.certainty_reason.reason_counts,
917 semantic.certainty_reason.reason_counts
918 );
919 assert_eq!(
920 bridge.certainty_reason.shape_kind_counts,
921 semantic.certainty_reason.shape_kind_counts
922 );
923 assert_eq!(
924 bridge.certainty_reason.shape_label_counts,
925 semantic.certainty_reason.shape_label_counts
926 );
927 assert_eq!(bridge.binding_origin.status, semantic.binding_origin.status);
928 assert_eq!(
929 bridge.binding_origin.expression_count,
930 semantic.binding_origin.expression_count
931 );
932 assert_eq!(
933 bridge.binding_origin.direct_class_name_count,
934 semantic.binding_origin.direct_class_name_count
935 );
936 assert_eq!(
937 bridge.binding_origin.root_binding_count,
938 semantic.binding_origin.root_binding_count
939 );
940 assert_eq!(
941 bridge.binding_origin.access_path_count,
942 semantic.binding_origin.access_path_count
943 );
944 assert_eq!(
945 bridge.binding_origin.access_path_segment_count,
946 semantic.binding_origin.access_path_segment_count
947 );
948 assert_eq!(
949 bridge.binding_origin.expression_kind_counts,
950 semantic.binding_origin.expression_kind_counts
951 );
952 assert_eq!(
953 bridge.style_module_edge.status,
954 semantic.style_module_edge.status
955 );
956 assert_eq!(
957 bridge.style_module_edge.source_style_edge_count,
958 semantic.style_module_edge.source_style_edge_count
959 );
960 assert_eq!(
961 bridge.style_module_edge.distinct_style_module_count,
962 semantic.style_module_edge.distinct_style_module_count
963 );
964 assert_eq!(
965 bridge.style_module_edge.missing_style_document_edge_count,
966 semantic.style_module_edge.missing_style_document_edge_count
967 );
968 assert_eq!(
969 bridge.style_module_edge.composed_edge_count,
970 semantic.style_module_edge.composed_edge_count
971 );
972 assert_eq!(
973 bridge.style_module_edge.imported_composed_edge_count,
974 semantic.style_module_edge.imported_composed_edge_count
975 );
976 assert_eq!(
977 bridge.style_module_edge.global_composed_edge_count,
978 semantic.style_module_edge.global_composed_edge_count
979 );
980 assert_eq!(
981 bridge.value_domain_explanation.status,
982 semantic.value_domain_explanation.status
983 );
984 assert_eq!(
985 bridge.value_domain_explanation.expression_count,
986 semantic.value_domain_explanation.expression_count
987 );
988 assert_eq!(
989 bridge.value_domain_explanation.exact_expression_count,
990 semantic.value_domain_explanation.exact_expression_count
991 );
992 assert_eq!(
993 bridge
994 .value_domain_explanation
995 .finite_value_expression_count,
996 semantic
997 .value_domain_explanation
998 .finite_value_expression_count
999 );
1000 assert_eq!(
1001 bridge.value_domain_explanation.constrained_expression_count,
1002 semantic
1003 .value_domain_explanation
1004 .constrained_expression_count
1005 );
1006 assert_eq!(
1007 bridge.value_domain_explanation.unknown_expression_count,
1008 semantic.value_domain_explanation.unknown_expression_count
1009 );
1010 assert_eq!(
1011 bridge.value_domain_explanation.finite_value_count,
1012 semantic.value_domain_explanation.finite_value_count
1013 );
1014 assert_eq!(
1015 bridge.value_domain_explanation.derivation_count,
1016 semantic.value_domain_explanation.derivation_count
1017 );
1018 assert_eq!(
1019 bridge.value_domain_explanation.derivation_step_count,
1020 semantic.value_domain_explanation.derivation_step_count
1021 );
1022 assert_eq!(
1023 bridge.value_domain_explanation.value_domain_kind_counts,
1024 semantic.value_domain_explanation.value_domain_kind_counts
1025 );
1026 assert_eq!(
1027 bridge.value_domain_explanation.constraint_kind_counts,
1028 semantic.value_domain_explanation.constraint_kind_counts
1029 );
1030 assert_eq!(
1031 bridge.value_domain_explanation.derivation_product_counts,
1032 semantic.value_domain_explanation.derivation_product_counts
1033 );
1034 assert_eq!(
1035 bridge
1036 .value_domain_explanation
1037 .derivation_reduced_kind_counts,
1038 semantic
1039 .value_domain_explanation
1040 .derivation_reduced_kind_counts
1041 );
1042 assert_eq!(
1043 bridge.value_domain_explanation.derivation_operation_counts,
1044 semantic
1045 .value_domain_explanation
1046 .derivation_operation_counts
1047 );
1048 assert_eq!(bridge.blocking_gaps, semantic.blocking_gaps);
1049 assert_eq!(bridge.next_priorities, semantic.next_priorities);
1050 }
1051
1052 fn sample_engine_input() -> EngineInputV2 {
1053 EngineInputV2 {
1054 version: "2".to_string(),
1055 sources: vec![SourceAnalysisInputV2 {
1056 document: SourceDocumentV2 {
1057 class_expressions: vec![ClassExpressionInputV2 {
1058 id: "expr-literal".to_string(),
1059 kind: "literal".to_string(),
1060 scss_module_path: "/tmp/Component.module.scss".to_string(),
1061 range: range(4, 12, 4, 18),
1062 class_name: Some("button".to_string()),
1063 root_binding_decl_id: None,
1064 access_path: None,
1065 }],
1066 },
1067 }],
1068 styles: vec![StyleAnalysisInputV2 {
1069 file_path: "/tmp/Component.module.scss".to_string(),
1070 source: None,
1071 document: StyleDocumentV2 {
1072 selectors: vec![StyleSelectorV2 {
1073 name: "button".to_string(),
1074 view_kind: "canonical".to_string(),
1075 canonical_name: Some("button".to_string()),
1076 range: range(0, 1, 0, 7),
1077 nested_safety: Some("flat".to_string()),
1078 composes: None,
1079 bem_suffix: None,
1080 }],
1081 },
1082 }],
1083 type_facts: vec![TypeFactEntryV2 {
1084 file_path: "/tmp/Component.tsx".to_string(),
1085 expression_id: "expr-literal".to_string(),
1086 facts: StringTypeFactsV2 {
1087 kind: "exact".to_string(),
1088 constraint_kind: None,
1089 values: Some(vec!["button".to_string()]),
1090 prefix: None,
1091 suffix: None,
1092 min_len: None,
1093 max_len: None,
1094 char_must: None,
1095 char_may: None,
1096 may_include_other_chars: None,
1097 provenance: None,
1098 },
1099 control_flow_graph: None,
1100 }],
1101 }
1102 }
1103
1104 fn range(
1105 start_line: usize,
1106 start_character: usize,
1107 end_line: usize,
1108 end_character: usize,
1109 ) -> RangeV2 {
1110 RangeV2 {
1111 start: PositionV2 {
1112 line: start_line,
1113 character: start_character,
1114 },
1115 end: PositionV2 {
1116 line: end_line,
1117 character: end_character,
1118 },
1119 }
1120 }
1121}