@shapeshift-labs/frontier-lang-compiler 0.2.161 → 0.2.163

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/internal/index-impl/moduleHostResourceImportMetadata.js +47 -0
  2. package/dist/internal/index-impl/projectSymbolGraphCompilerAdvancedTypeMetadata.js +215 -1
  3. package/dist/internal/index-impl/projectSymbolGraphCompilerFacts.js +1 -1
  4. package/dist/internal/index-impl/projectSymbolGraphCssModuleUtils.js +56 -1
  5. package/dist/internal/index-impl/projectSymbolGraphCssModules.js +48 -4
  6. package/dist/internal/index-impl/projectSymbolGraphJsxPropRecordFields.js +91 -0
  7. package/dist/internal/index-impl/projectSymbolGraphJsxPropValues.js +35 -7
  8. package/dist/internal/index-impl/projectSymbolGraphJsxRecords.js +4 -31
  9. package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturnCollectionHelpers.js +201 -0
  10. package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturnCollections.js +210 -0
  11. package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturns.js +12 -5
  12. package/dist/internal/index-impl/projectSymbolGraphJsxSpreadPropValues.js +196 -0
  13. package/dist/internal/index-impl/projectSymbolGraphJsxStaticLiterals.js +207 -0
  14. package/dist/internal/index-impl/projectSymbolGraphModuleResolution.js +12 -14
  15. package/dist/internal/index-impl/projectSymbolGraphPackageConditions.js +33 -31
  16. package/dist/internal/index-impl/projectSymbolGraphPackageRuntimeConditions.js +22 -0
  17. package/dist/internal/index-impl/projectSymbolGraphScopeUseDefLexical.js +11 -19
  18. package/dist/internal/index-impl/syntaxModuleDeclarationEntries.js +27 -1
  19. package/dist/js-ts-safe-project-merge-admission.js +10 -0
  20. package/dist/js-ts-safe-project-merge-evidence-routing.js +30 -2
  21. package/dist/js-ts-safe-project-merge-graph-delta-compiler-conflicts.js +7 -0
  22. package/dist/js-ts-safe-project-merge-html-css-matrix.js +7 -2
  23. package/dist/js-ts-safe-project-merge-html-css-summary.js +110 -2
  24. package/dist/js-ts-safe-project-merge-html-css.js +137 -3
  25. package/dist/js-ts-safe-project-merge-jsx-graph-conflict-details.js +9 -0
  26. package/dist/js-ts-safe-project-merge.js +3 -0
  27. package/dist/native-source-preservation-scanner.js +10 -0
  28. package/dist/semantic-import-runtime-dynamic-import-evidence.js +141 -0
  29. package/dist/semantic-import-runtime-order-evidence.js +5 -4
  30. package/package.json +1 -1
@@ -0,0 +1,47 @@
1
+ import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
2
+
3
+ const HOST_RESOURCE_IMPORT_KINDS = Object.freeze({
4
+ 'css-import': 'css',
5
+ 'css-module-import': 'css-module',
6
+ 'html-import': 'html'
7
+ });
8
+
9
+ export function moduleHostResourceImportMetadata(moduleSpecifier, options = {}) {
10
+ const hostDependencyKind = moduleHostResourceImportKind(moduleSpecifier);
11
+ if (!hostDependencyKind) return {};
12
+ const hostDependencyBase = options.hostDependencyBase ?? 'module-import';
13
+ const hostDependencyExpressionText = options.expressionText ?? String(moduleSpecifier);
14
+ return {
15
+ hostDependency: true,
16
+ hostDependencyKind,
17
+ hostDependencyBase,
18
+ hostDependencyExpressionText,
19
+ hostDependencyExpressionHash: hashSemanticValue({
20
+ kind: hostDependencyKind,
21
+ moduleSpecifier,
22
+ base: hostDependencyBase,
23
+ expressionText: hostDependencyExpressionText
24
+ }),
25
+ hostDependencyStaticSpecifierEvidence: true,
26
+ hostDependencyRuntimeResolutionClaim: false,
27
+ hostDependencyResolutionProofRequired: true
28
+ };
29
+ }
30
+
31
+ export function moduleHostResourceImportKind(moduleSpecifier) {
32
+ const path = resourcePath(moduleSpecifier);
33
+ if (!path) return undefined;
34
+ if (/\.module\.css$/i.test(path)) return 'css-module-import';
35
+ if (/\.css$/i.test(path)) return 'css-import';
36
+ if (/\.html?$/i.test(path)) return 'html-import';
37
+ return undefined;
38
+ }
39
+
40
+ export function hostResourceImportDependencyKind(hostDependencyKind) {
41
+ return HOST_RESOURCE_IMPORT_KINDS[hostDependencyKind];
42
+ }
43
+
44
+ function resourcePath(moduleSpecifier) {
45
+ const path = String(moduleSpecifier ?? '').split(/[?#]/, 1)[0];
46
+ return path || undefined;
47
+ }
@@ -1,4 +1,4 @@
1
- function compilerAdvancedTypeMetadata(value) {
1
+ function compilerAdvancedTypeMetadata(value, source = {}) {
2
2
  const advancedTypeShapes = arrayValue(value.advancedTypeShapes);
3
3
  const typeReferenceTargets = arrayValue(value.typeReferenceTargets);
4
4
  const counts = {
@@ -14,11 +14,14 @@ function compilerAdvancedTypeMetadata(value) {
14
14
  intersectionTypeCount: numberValue(value.intersectionTypeCount) ?? countKind(advancedTypeShapes, 'intersection-type'),
15
15
  tupleTypeCount: numberValue(value.tupleTypeCount) ?? countKind(advancedTypeShapes, 'tuple-type')
16
16
  };
17
+ const proofRequirement = advancedTypeProofRequirement(advancedTypeShapes, counts, source);
17
18
  return {
18
19
  counts,
19
20
  record: compactRecord({
20
21
  advancedTypeShapeCount: counts.advancedTypeShapeCount || undefined,
21
22
  advancedTypeShapeKinds: value.advancedTypeShapeKinds ?? nonEmptyArray(uniqueStrings(advancedTypeShapes.map((shape) => shape.kind))),
23
+ advancedTypeProofRequirement: proofRequirement.requirement,
24
+ advancedTypeMissingProof: proofRequirement.missingProof,
22
25
  typeReferenceTargetCount: counts.typeReferenceTargetCount || undefined,
23
26
  conditionalTypeCount: counts.conditionalTypeCount || undefined,
24
27
  mappedTypeCount: counts.mappedTypeCount || undefined,
@@ -35,11 +38,222 @@ function compilerAdvancedTypeMetadata(value) {
35
38
  };
36
39
  }
37
40
 
41
+ const AdvancedTypeProofRequirementKind = 'typescript-checker-public-api-advanced-type-shape-equivalence';
42
+ const AdvancedTypeProofRequiredEvidence = 'typescript-checker-public-api-type-equivalence';
43
+ const AdvancedTypeSourcePathSignal = 'compiler-public-api-advanced-type-source-path';
44
+ const AdvancedTypeSourceHashSignal = 'compiler-public-api-advanced-type-source-hash';
45
+ const AdvancedTypeSourcePathStaleSignal = 'compiler-public-api-advanced-type-source-path-stale';
46
+ const AdvancedTypeSourceHashStaleSignal = 'compiler-public-api-advanced-type-source-hash-stale';
47
+ const AdvancedTypeClaimBearingSignal = 'compiler-advanced-type-shape-claim-bearing';
48
+ const AdvancedTypeProofShapeSpecs = [
49
+ proofShapeSpec('conditional-type', 'conditionalTypeCount', [
50
+ proofField('nodeText', 'compiler-conditional-type-node-texts'),
51
+ proofField('typeText', 'compiler-conditional-type-type-texts'),
52
+ proofField('checkTypeText', 'compiler-conditional-type-check-type-texts'),
53
+ proofField('extendsTypeText', 'compiler-conditional-type-extends-type-texts'),
54
+ proofField('trueTypeText', 'compiler-conditional-type-true-type-texts'),
55
+ proofField('falseTypeText', 'compiler-conditional-type-false-type-texts')
56
+ ]),
57
+ proofShapeSpec('mapped-type', 'mappedTypeCount', [
58
+ proofField('nodeText', 'compiler-mapped-type-node-texts'),
59
+ proofField('typeText', 'compiler-mapped-type-type-texts'),
60
+ proofField('mappedConstraintTypeText', 'compiler-mapped-type-constraint-type-texts'),
61
+ proofField('mappedValueTypeText', 'compiler-mapped-type-value-type-texts')
62
+ ]),
63
+ proofShapeSpec('indexed-access-type', 'indexedAccessTypeCount', [
64
+ proofField('nodeText', 'compiler-indexed-access-type-node-texts'),
65
+ proofField('typeText', 'compiler-indexed-access-type-type-texts'),
66
+ proofField('objectTypeText', 'compiler-indexed-access-type-object-type-texts'),
67
+ proofField('indexTypeText', 'compiler-indexed-access-type-index-type-texts')
68
+ ]),
69
+ proofShapeSpec('keyof-type-operator', 'keyofTypeOperatorCount', [
70
+ proofField('nodeText', 'compiler-keyof-type-operator-node-texts'),
71
+ proofField('typeText', 'compiler-keyof-type-operator-type-texts'),
72
+ proofField('keyofTargetTypeText', 'compiler-keyof-type-operator-target-type-texts')
73
+ ]),
74
+ proofShapeSpec('template-literal-type', 'templateLiteralTypeCount', [
75
+ proofField('nodeText', 'compiler-template-literal-type-node-texts'),
76
+ proofField('typeText', 'compiler-template-literal-type-type-texts'),
77
+ proofField('templateHeadText', 'compiler-template-literal-type-head-texts'),
78
+ proofField('templateSpanTexts', 'compiler-template-literal-type-span-texts'),
79
+ proofField('templateSpanTypeTexts', 'compiler-template-literal-type-span-type-texts'),
80
+ proofField('templateLiteralTexts', 'compiler-template-literal-type-literal-texts')
81
+ ]),
82
+ proofShapeSpec('infer-type', 'inferTypeCount', [
83
+ proofField('nodeText', 'compiler-infer-type-node-texts'),
84
+ proofField('typeText', 'compiler-infer-type-type-texts'),
85
+ proofField('typeParameterText', 'compiler-infer-type-type-parameter-texts'),
86
+ proofField('typeParameterName', 'compiler-infer-type-type-parameter-names')
87
+ ]),
88
+ proofShapeSpec('union-type', 'unionTypeCount', [
89
+ proofField('nodeText', 'compiler-union-type-node-texts'),
90
+ proofField('typeText', 'compiler-union-type-type-texts'),
91
+ proofField('memberTypeTexts', 'compiler-union-type-member-type-texts')
92
+ ]),
93
+ proofShapeSpec('intersection-type', 'intersectionTypeCount', [
94
+ proofField('nodeText', 'compiler-intersection-type-node-texts'),
95
+ proofField('typeText', 'compiler-intersection-type-type-texts'),
96
+ proofField('memberTypeTexts', 'compiler-intersection-type-member-type-texts')
97
+ ]),
98
+ proofShapeSpec('tuple-type', 'tupleTypeCount', [
99
+ proofField('nodeText', 'compiler-tuple-type-node-texts'),
100
+ proofField('typeText', 'compiler-tuple-type-type-texts'),
101
+ proofField('tupleElementTexts', 'compiler-tuple-type-element-texts'),
102
+ proofField('tupleElementTypeTexts', 'compiler-tuple-type-element-type-texts')
103
+ ])
104
+ ];
105
+
106
+ function advancedTypeProofRequirement(advancedTypeShapes, counts, source = {}) {
107
+ if (!counts.advancedTypeShapeCount) return {};
108
+ const sourceBinding = advancedTypeSourceBinding(source);
109
+ const requiredSignals = advancedTypeRequiredProofSignals(counts, sourceBinding);
110
+ const missingSignals = uniqueStrings([
111
+ ...missingAdvancedTypeProofSignals(advancedTypeShapes, counts),
112
+ ...missingAdvancedTypeSourceBindingSignals(sourceBinding)
113
+ ]);
114
+ const unsupportedSignals = unsupportedAdvancedTypeProofSignals(advancedTypeShapes, counts, sourceBinding);
115
+ const status = unsupportedSignals.length
116
+ ? 'requires-review'
117
+ : missingSignals.length ? 'missing-compiler-evidence' : 'requires-type-equivalence-proof';
118
+ const requirement = compactRecord({
119
+ kind: AdvancedTypeProofRequirementKind,
120
+ requiredEvidence: AdvancedTypeProofRequiredEvidence,
121
+ status,
122
+ requiredSignals,
123
+ missingSignals: nonEmptyArray(missingSignals),
124
+ unsupportedSignals: nonEmptyArray(unsupportedSignals),
125
+ advancedTypeShapeCount: counts.advancedTypeShapeCount,
126
+ advancedTypeShapeKinds: nonEmptyArray(uniqueStrings(advancedTypeShapes.map((shape) => shape.kind))),
127
+ conditionalTypeCount: counts.conditionalTypeCount || undefined,
128
+ mappedTypeCount: counts.mappedTypeCount || undefined,
129
+ indexedAccessTypeCount: counts.indexedAccessTypeCount || undefined,
130
+ keyofTypeOperatorCount: counts.keyofTypeOperatorCount || undefined,
131
+ templateLiteralTypeCount: counts.templateLiteralTypeCount || undefined,
132
+ inferTypeCount: counts.inferTypeCount || undefined,
133
+ unionTypeCount: counts.unionTypeCount || undefined,
134
+ intersectionTypeCount: counts.intersectionTypeCount || undefined,
135
+ tupleTypeCount: counts.tupleTypeCount || undefined,
136
+ sourcePath: sourceBinding.sourcePath,
137
+ sourceHash: sourceBinding.sourceHash,
138
+ sourceBound: sourceBinding.required ? sourceBinding.bound : undefined,
139
+ autoMergeClaim: false,
140
+ semanticEquivalenceClaim: false
141
+ });
142
+ return {
143
+ requirement,
144
+ missingProof: status === 'requires-type-equivalence-proof' ? undefined : compactRecord({
145
+ kind: AdvancedTypeProofRequirementKind,
146
+ requiredEvidence: AdvancedTypeProofRequiredEvidence,
147
+ status,
148
+ reasonCode: status === 'missing-compiler-evidence'
149
+ ? 'typescript-public-api-advanced-type-shape-proof-missing'
150
+ : 'typescript-public-api-advanced-type-shape-proof-requires-review',
151
+ missingSignals: nonEmptyArray(missingSignals),
152
+ unsupportedSignals: nonEmptyArray(unsupportedSignals),
153
+ autoMergeClaim: false,
154
+ semanticEquivalenceClaim: false
155
+ })
156
+ };
157
+ }
158
+
159
+ function advancedTypeRequiredProofSignals(counts, sourceBinding) {
160
+ const shapeSignals = AdvancedTypeProofShapeSpecs.flatMap((spec) => (
161
+ counts[spec.countKey] > 0 ? [countSignal(spec.kind), ...spec.fields.map((field) => field.signal)] : []
162
+ ));
163
+ return uniqueStrings([
164
+ ...shapeSignals,
165
+ ...(sourceBinding.required ? [AdvancedTypeSourcePathSignal, AdvancedTypeSourceHashSignal] : [])
166
+ ]);
167
+ }
168
+
169
+ function missingAdvancedTypeProofSignals(advancedTypeShapes, counts) {
170
+ return uniqueStrings(AdvancedTypeProofShapeSpecs.flatMap((spec) => {
171
+ const count = counts[spec.countKey] || 0;
172
+ if (!count) return [];
173
+ const shapes = advancedTypeShapes.filter((shape) => shape?.kind === spec.kind);
174
+ const missing = [];
175
+ if (shapes.length !== count) missing.push(countSignal(spec.kind));
176
+ for (const field of spec.fields) {
177
+ if (shapes.some((shape) => fieldMissing(shape?.[field.key]))) missing.push(field.signal);
178
+ }
179
+ return missing;
180
+ }));
181
+ }
182
+
183
+ function missingAdvancedTypeSourceBindingSignals(sourceBinding) {
184
+ if (!sourceBinding.required) return [];
185
+ return [
186
+ sourceBinding.sourcePath ? undefined : AdvancedTypeSourcePathSignal,
187
+ sourceBinding.sourceHash ? undefined : AdvancedTypeSourceHashSignal
188
+ ].filter(Boolean);
189
+ }
190
+
191
+ function unsupportedAdvancedTypeProofSignals(advancedTypeShapes, counts, sourceBinding) {
192
+ const knownShapeCount = AdvancedTypeProofShapeSpecs.reduce((sum, spec) => sum + (counts[spec.countKey] || 0), 0);
193
+ return [
194
+ counts.advancedTypeShapeCount > knownShapeCount ? 'compiler-unknown-advanced-type-shape' : undefined,
195
+ ...staleAdvancedTypeSourceBindingSignals(advancedTypeShapes, sourceBinding),
196
+ hasClaimBearingAdvancedTypeShape(advancedTypeShapes) ? AdvancedTypeClaimBearingSignal : undefined
197
+ ].filter(Boolean);
198
+ }
199
+
200
+ function staleAdvancedTypeSourceBindingSignals(advancedTypeShapes, sourceBinding) {
201
+ if (!sourceBinding.required) return [];
202
+ const stalePath = sourceBinding.sourcePath
203
+ && advancedTypeShapes.some((shape) => nonBlankString(shape?.sourcePath) && shape.sourcePath !== sourceBinding.sourcePath);
204
+ const staleHash = sourceBinding.sourceHash
205
+ && advancedTypeShapes.some((shape) => nonBlankString(shape?.sourceHash) && shape.sourceHash !== sourceBinding.sourceHash);
206
+ return [
207
+ stalePath ? AdvancedTypeSourcePathStaleSignal : undefined,
208
+ staleHash ? AdvancedTypeSourceHashStaleSignal : undefined
209
+ ].filter(Boolean);
210
+ }
211
+
212
+ function hasClaimBearingAdvancedTypeShape(advancedTypeShapes) {
213
+ return advancedTypeShapes.some((shape) => [
214
+ shape?.proofClaim,
215
+ shape?.autoMergeClaim,
216
+ shape?.semanticEquivalenceClaim,
217
+ shape?.runtimeEquivalenceClaim,
218
+ shape?.proof?.proofClaim,
219
+ shape?.proof?.autoMergeClaim,
220
+ shape?.proof?.semanticEquivalenceClaim,
221
+ shape?.proof?.runtimeEquivalenceClaim
222
+ ].some((value) => value === true));
223
+ }
224
+
225
+ function advancedTypeSourceBinding(source) {
226
+ const required = source?.publicContract === true;
227
+ const sourcePath = nonBlankString(source?.sourcePath) ? source.sourcePath : undefined;
228
+ const sourceHash = nonBlankString(source?.sourceHash) ? source.sourceHash : undefined;
229
+ return {
230
+ required,
231
+ sourcePath,
232
+ sourceHash,
233
+ bound: !required || Boolean(sourcePath && sourceHash)
234
+ };
235
+ }
236
+
237
+ function fieldMissing(value) {
238
+ if (Array.isArray(value)) return !value.length || value.some(arrayFieldEntryMissing);
239
+ if (typeof value === 'string') return value.trim().length === 0;
240
+ return value === undefined || value === null;
241
+ }
242
+
243
+ function arrayFieldEntryMissing(value) {
244
+ if (Array.isArray(value)) return !value.length || value.some(arrayFieldEntryMissing);
245
+ return value === undefined || value === null;
246
+ }
247
+
248
+ function proofShapeSpec(kind, countKey, fields) { return { kind, countKey, fields }; }
249
+ function proofField(key, signal) { return { key, signal }; }
250
+ function countSignal(kind) { return `compiler-${kind}-count`; }
38
251
  function countKind(records, kind) { return records.filter((record) => record.kind === kind).length; }
39
252
  function arrayValue(value) { return Array.isArray(value) ? value : []; }
40
253
  function compactRecord(record) { return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined)); }
41
254
  function numberValue(value) { return Number.isFinite(value) ? value : undefined; }
42
255
  function nonEmptyArray(value) { return Array.isArray(value) && value.length ? value : undefined; }
256
+ function nonBlankString(value) { return typeof value === 'string' && value.trim().length > 0; }
43
257
  function uniqueStrings(values) { return [...new Set(values.filter((value) => typeof value === 'string' && value.length > 0))]; }
44
258
 
45
259
  export { compilerAdvancedTypeMetadata };
@@ -69,7 +69,7 @@ function compilerTypeRecord(fact, symbol, document, publicSymbolIds, compilerSym
69
69
  const indexSignatureReadonlyCount = numberValue(value.indexSignatureReadonlyCount) ?? compilerIndexSignatureReadonlyCount(value.indexSignatures);
70
70
  const constructorSignatureCount = numberValue(value.constructorSignatureCount) ?? arrayLength(value.constructorSignatures);
71
71
  const classHeritageCount = numberValue(value.classHeritageCount) ?? arrayLength(value.classHeritage);
72
- const advancedType = compilerAdvancedTypeMetadata(value);
72
+ const advancedType = compilerAdvancedTypeMetadata(value, sourceBinding);
73
73
  const enumShape = compilerEnumShapeMetadata(value);
74
74
  const typeInferenceSyntax = compilerTypeInferenceSyntaxMetadata(value, sourceBinding);
75
75
  const classMemberShape = compilerClassMemberShapeMetadata(value, sourceBinding);
@@ -19,10 +19,11 @@ function cssModuleSourceRecord(imported) {
19
19
  );
20
20
  const sourceText = nativeImportSourceText(imported);
21
21
  const inferredEvidence = suppliedEvidence ? undefined : inferCssModuleEvidence(sourceText, sourcePath, metadata, nativeMetadata, astMetadata);
22
+ const cssModuleEvidence = normalizeCssModuleEvidence(suppliedEvidence ?? inferredEvidence);
22
23
  return compactRecord({
23
24
  sourcePath,
24
25
  sourceHash: imported?.nativeSource?.sourceHash ?? imported?.metadata?.sourceHash,
25
- cssModuleEvidence: suppliedEvidence ?? inferredEvidence,
26
+ cssModuleEvidence,
26
27
  cssModuleEvidenceSource: suppliedEvidence ? 'supplied' : inferredEvidence ? 'inferred-source' : undefined,
27
28
  bundlerTransformHash: firstString(metadata.bundlerTransformHash, nativeMetadata.bundlerTransformHash, astMetadata.bundlerTransformHash),
28
29
  sourceMapProofHash: firstString(metadata.sourceMapProofHash, nativeMetadata.sourceMapProofHash, astMetadata.sourceMapProofHash)
@@ -134,6 +135,48 @@ function semanticSpanForHash(span) {
134
135
  return span ? { path: span.path, start: span.start, end: span.end, startLine: span.startLine, startColumn: span.startColumn, endLine: span.endLine, endColumn: span.endColumn } : undefined;
135
136
  }
136
137
 
138
+ function normalizeCssModuleEvidence(evidence) {
139
+ if (!evidence || typeof evidence !== 'object' || Array.isArray(evidence)) return undefined;
140
+ const icssExportNames = cssModuleIcssExportNames(evidence);
141
+ const exportNames = uniqueSortedStrings([
142
+ ...cssModuleEvidenceExportNames(evidence),
143
+ ...(evidence.icssGraphHash ? icssExportNames : [])
144
+ ]);
145
+ return compactRecord({
146
+ ...evidence,
147
+ icssExportNames: icssExportNames.length ? icssExportNames : undefined,
148
+ exportNames: exportNames.length ? exportNames : evidence.exportNames
149
+ });
150
+ }
151
+
152
+ function cssModuleEvidenceExportNames(evidence) {
153
+ return uniqueSortedStrings([
154
+ ...arrayValue(evidence?.exportNames),
155
+ ...arrayValue(evidence?.localClassNames),
156
+ ...arrayValue(evidence?.classNames),
157
+ ...cssModuleExportRecordNames(evidence?.exports),
158
+ ...objectKeys(evidence?.exports),
159
+ ...objectKeys(evidence?.generatedClassNameMap),
160
+ ...objectKeys(evidence?.classMap)
161
+ ]);
162
+ }
163
+
164
+ function cssModuleIcssExportNames(evidence) {
165
+ return uniqueSortedStrings([
166
+ ...arrayValue(evidence?.icssExportNames),
167
+ ...cssModuleExportRecordNames(evidence?.icssExports),
168
+ ...objectKeys(evidence?.icssExports),
169
+ ...cssModuleExportRecordNames(evidence?.icss?.exports),
170
+ ...objectKeys(evidence?.icss?.exports)
171
+ ]);
172
+ }
173
+
174
+ function cssModuleExportRecordNames(value) {
175
+ return Array.isArray(value)
176
+ ? value.map((entry) => entry?.name ?? entry?.localName ?? entry?.exportedName).filter(Boolean)
177
+ : [];
178
+ }
179
+
137
180
  function compactRecord(record) {
138
181
  return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));
139
182
  }
@@ -150,6 +193,18 @@ function objectValue(value) {
150
193
  return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
151
194
  }
152
195
 
196
+ function arrayValue(value) {
197
+ return Array.isArray(value) ? value : [];
198
+ }
199
+
200
+ function objectKeys(value) {
201
+ return Object.keys(objectValue(value));
202
+ }
203
+
204
+ function uniqueSortedStrings(values) {
205
+ return [...new Set(values.filter((value) => typeof value === 'string' && value.length > 0))].sort();
206
+ }
207
+
153
208
  function firstObject(...values) {
154
209
  return values.find((value) => value && typeof value === 'object' && !Array.isArray(value));
155
210
  }
@@ -37,10 +37,13 @@ function createProjectCssModuleGraphRecords(semanticIndex, imports, importEdges,
37
37
  const namedImportBlockers = importBindings
38
38
  .filter((binding) => binding.importKind === 'named')
39
39
  .map((binding) => cssModuleNamedExportBlocker(binding));
40
- const missingTransformBlockers = importBindings
41
- .filter((binding) => hasUseSite(binding, lexicalUseSites) || hasUseSite(binding, jsxUseSites))
42
- .flatMap((binding) => cssModuleTransformBlockers(binding));
43
40
  const cssModuleUseSites = uniqueRecords([...jsxUseSites, ...lexicalUseSites], cssModuleUseSiteKey);
41
+ const usedImportBindings = importBindings
42
+ .filter((binding) => hasUseSite(binding, cssModuleUseSites));
43
+ const missingTransformBlockers = usedImportBindings
44
+ .flatMap((binding) => cssModuleTransformBlockers(binding));
45
+ const missingDependencyGraphBlockers = usedImportBindings
46
+ .flatMap((binding) => cssModuleDependencyGraphBlockers(binding, cssSourcesByPath));
44
47
  const bindingsById = new Map(importBindings.map((binding) => [binding.id, binding]));
45
48
  const missingExportBlockers = cssModuleMissingExportBlockers(bindingsById, cssModuleUseSites);
46
49
  const cssModuleUseSiteBlockers = uniqueRecords([
@@ -48,7 +51,8 @@ function createProjectCssModuleGraphRecords(semanticIndex, imports, importEdges,
48
51
  ...jsxBlockers,
49
52
  ...namedImportBlockers,
50
53
  ...missingExportBlockers,
51
- ...missingTransformBlockers
54
+ ...missingTransformBlockers,
55
+ ...missingDependencyGraphBlockers
52
56
  ], cssModuleBlockerKey);
53
57
  return {
54
58
  cssModuleImportBindings: importBindings,
@@ -75,6 +79,46 @@ function cssModuleNamedExportBlocker(binding) {
75
79
  });
76
80
  }
77
81
 
82
+ function cssModuleDependencyGraphBlockers(binding, cssSourcesByPath) {
83
+ const cssModuleEvidence = cssSourcesByPath.get(binding.cssModuleSourcePath)?.cssModuleEvidence;
84
+ const blockers = [];
85
+ if (requiresCssModuleCompositionGraph(cssModuleEvidence) && !binding.cssModuleCompositionGraphHash) {
86
+ blockers.push(cssModuleBindingBlocker(binding, {
87
+ reasonCode: 'css-module-composition-resolution-unproved',
88
+ expressionText: binding.localName
89
+ }));
90
+ }
91
+ if (requiresIcssGraph(cssModuleEvidence) && !binding.icssGraphHash) {
92
+ blockers.push(cssModuleBindingBlocker(binding, {
93
+ reasonCode: 'css-module-icss-graph-unproved',
94
+ expressionText: binding.localName
95
+ }));
96
+ }
97
+ return blockers;
98
+ }
99
+
100
+ function requiresCssModuleCompositionGraph(cssModuleEvidence) {
101
+ return hasCssModuleProofGap(cssModuleEvidence, 'css-module-composition-resolution-unproved')
102
+ || hasRecords(cssModuleEvidence?.compositions);
103
+ }
104
+
105
+ function requiresIcssGraph(cssModuleEvidence) {
106
+ return hasCssModuleProofGap(cssModuleEvidence, 'css-module-icss-graph-unproved')
107
+ || hasRecords(cssModuleEvidence?.icssImports)
108
+ || hasRecords(cssModuleEvidence?.icssExports)
109
+ || hasRecords(cssModuleEvidence?.icss?.imports)
110
+ || hasRecords(cssModuleEvidence?.icss?.exports);
111
+ }
112
+
113
+ function hasCssModuleProofGap(cssModuleEvidence, code) {
114
+ return (cssModuleEvidence?.proofGaps ?? []).some((gap) => gap?.code === code);
115
+ }
116
+
117
+ function hasRecords(value) {
118
+ if (Array.isArray(value)) return value.length > 0;
119
+ return value && typeof value === 'object' ? Object.keys(value).length > 0 : false;
120
+ }
121
+
78
122
  function hasUseSite(binding, useSites) {
79
123
  return useSites.some((site) => site.cssModuleImportBindingId === binding.id);
80
124
  }
@@ -0,0 +1,91 @@
1
+ function jsxPropValueRecordFields(valueEvidence) {
2
+ return {
3
+ propValueProofStatus: valueEvidence?.proofStatus,
4
+ propValueReasonCode: valueEvidence?.reasonCode,
5
+ propValueKind: valueEvidence?.valueKind,
6
+ propValueText: valueEvidence?.valueText,
7
+ propValueExpressionText: valueEvidence?.expressionText,
8
+ propValueReferenceRoot: valueEvidence?.referenceRoot,
9
+ propValueReferencePath: valueEvidence?.referencePath,
10
+ propValueDynamicText: valueEvidence?.dynamicText,
11
+ propValueOptionalReference: valueEvidence?.optionalReference,
12
+ propValueOptionalReferenceSegments: valueEvidence?.optionalReferenceSegments,
13
+ propValueOptionalReferenceSegmentIndexes: valueEvidence?.optionalReferenceSegmentIndexes,
14
+ propValueOptionalNullishBoundaryCount: valueEvidence?.optionalNullishBoundaryCount,
15
+ propValueClaimScope: valueEvidence?.claimScope,
16
+ propValueRenderEquivalenceClaim: valueEvidence?.renderEquivalenceClaim,
17
+ propValueStaticSpreadSourceKind: valueEvidence?.staticSpreadSourceKind,
18
+ propValueStaticSpreadSourceName: valueEvidence?.staticSpreadSourceName,
19
+ propValueStaticSpreadPropEntries: valueEvidence?.staticSpreadPropEntries,
20
+ propValueStaticSpreadPropNames: valueEvidence?.staticSpreadPropNames,
21
+ propValueStaticSpreadPropCount: valueEvidence?.staticSpreadPropCount,
22
+ propValueStaticSpreadEffectivePropEntries: valueEvidence?.staticSpreadEffectivePropEntries,
23
+ propValueStaticSpreadEffectivePropNames: valueEvidence?.staticSpreadEffectivePropNames,
24
+ propValueStaticSpreadExplicitOverridePropNames: valueEvidence?.staticSpreadExplicitOverridePropNames,
25
+ propValueStaticSpreadOverridesExplicitPropNames: valueEvidence?.staticSpreadOverridesExplicitPropNames,
26
+ propValueStaticSpreadDuplicatePropNames: valueEvidence?.staticSpreadDuplicatePropNames,
27
+ propValueStaticSpreadPrecedenceStatus: valueEvidence?.staticSpreadPrecedenceStatus,
28
+ propValueDynamicBlockerReasonCode: valueEvidence?.dynamicBlockerReasonCode,
29
+ propValueExpressionHash: valueEvidence?.expressionHash,
30
+ propValueSignatureHash: valueEvidence?.signatureHash
31
+ };
32
+ }
33
+
34
+ function jsxPropComponentFlowRecordFields(flow) {
35
+ return {
36
+ componentPropRenderFlowStatus: flow?.status,
37
+ componentPropRenderFlowReasonCode: flow?.reasonCode,
38
+ componentPropRenderFlowClaim: flow?.claim,
39
+ componentPropRenderFlowClaimScope: flow?.claimScope,
40
+ componentPropRenderFlowRenderEquivalenceClaim: flow?.renderEquivalenceClaim,
41
+ componentPropRenderFlowScope: flow?.scope,
42
+ componentPropRenderFlowTargetName: flow?.targetName,
43
+ componentPropRenderFlowTargetKind: flow?.targetKind,
44
+ componentPropRenderFlowTargetOwnerName: flow?.targetOwnerName,
45
+ componentPropRenderFlowTargetOwnerCount: flow?.targetOwnerCount,
46
+ componentPropRenderFlowTargetSourcePath: flow?.targetSourcePath,
47
+ componentPropRenderFlowTargetLookupStatus: flow?.targetLookupStatus,
48
+ componentPropRenderFlowTargetLookupScope: flow?.targetLookupScope,
49
+ componentPropRenderFlowImportEdgeId: flow?.importEdgeId,
50
+ componentPropRenderFlowImportKind: flow?.importKind,
51
+ componentPropRenderFlowImportedName: flow?.importedName,
52
+ componentPropRenderFlowLocalName: flow?.localName,
53
+ componentPropRenderFlowTargetExportName: flow?.targetExportName,
54
+ ...jsxPropComponentFlowReExportFields(flow),
55
+ ...jsxPropComponentFlowMemberFields(flow),
56
+ componentPropRenderFlowComponentPropName: flow?.componentPropName,
57
+ componentPropRenderFlowRenderedTagName: flow?.renderedTagName,
58
+ componentPropRenderFlowRenderedPropName: flow?.renderedPropName,
59
+ componentPropRenderFlowPassthroughExpressionText: flow?.passthroughExpressionText,
60
+ componentPropRenderFlowBindingKind: flow?.bindingKind,
61
+ componentPropRenderFlowReturnOrdinal: flow?.returnOrdinal,
62
+ componentPropRenderFlowDynamicBlockerReasonCode: flow?.dynamicBlockerReasonCode,
63
+ componentPropRenderFlowTargetSignatureHash: flow?.targetSignatureHash,
64
+ componentPropRenderFlowSignatureHash: flow?.signatureHash
65
+ };
66
+ }
67
+
68
+ function jsxPropComponentFlowReExportFields(flow) {
69
+ return {
70
+ componentPropRenderFlowReExportEdgeId: flow?.reExportEdgeId,
71
+ componentPropRenderFlowReExportSourcePath: flow?.reExportSourcePath,
72
+ componentPropRenderFlowReExportExportedName: flow?.reExportExportedName,
73
+ componentPropRenderFlowReExportLocalName: flow?.reExportLocalName,
74
+ componentPropRenderFlowReExportTargetSourcePath: flow?.reExportTargetSourcePath,
75
+ componentPropRenderFlowReExportKind: flow?.reExportKind,
76
+ componentPropRenderFlowReExportIdentityId: flow?.reExportIdentityId,
77
+ componentPropRenderFlowTargetLookupHash: flow?.targetLookupHash
78
+ };
79
+ }
80
+
81
+ function jsxPropComponentFlowMemberFields(flow) {
82
+ return {
83
+ componentPropRenderFlowMemberObjectName: flow?.memberObjectName,
84
+ componentPropRenderFlowMemberPropertyName: flow?.memberPropertyName,
85
+ componentPropRenderFlowMemberLocalName: flow?.memberLocalName,
86
+ componentPropRenderFlowMemberBindingKind: flow?.memberBindingKind,
87
+ componentPropRenderFlowMemberBindingHash: flow?.memberBindingHash
88
+ };
89
+ }
90
+
91
+ export { jsxPropComponentFlowRecordFields, jsxPropValueRecordFields };
@@ -1,13 +1,13 @@
1
1
  import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
2
2
  import { isJsxSpreadAttribute } from '../../js-ts-safe-merge-jsx-attribute-parser.js';
3
+ import { jsxSpreadPropValueEvidence } from './projectSymbolGraphJsxSpreadPropValues.js';
4
+ import { parseStaticLiteralExpression } from './projectSymbolGraphJsxStaticLiterals.js';
3
5
  import { staticOptionalMemberReference } from './staticOptionalMemberReference.js';
4
6
 
5
- function jsxPropValueEvidence(tag, attribute) {
6
- if (isJsxSpreadAttribute(attribute)) return undefined;
7
- const assignedValueText = jsxAssignedPropValueText(attribute);
8
- const evidence = assignedValueText === undefined
9
- ? staticPropValueEvidence('boolean-shorthand', 'true', 'true')
10
- : jsxAssignedPropValueEvidence(assignedValueText);
7
+ function jsxPropValueEvidence(tag, attribute, context = {}) {
8
+ const evidence = isJsxSpreadAttribute(attribute)
9
+ ? jsxSpreadPropValueEvidence(tag, attribute, context)
10
+ : jsxNonSpreadPropValueEvidence(attribute);
11
11
  return compactRecord({
12
12
  ...evidence,
13
13
  expressionHash: hashSemanticValue({
@@ -34,12 +34,32 @@ function jsxPropValueEvidence(tag, attribute) {
34
34
  optionalReferenceSegments: evidence.optionalReferenceSegments,
35
35
  optionalReferenceSegmentIndexes: evidence.optionalReferenceSegmentIndexes,
36
36
  optionalNullishBoundaryCount: evidence.optionalNullishBoundaryCount,
37
+ claimScope: evidence.claimScope,
38
+ renderEquivalenceClaim: evidence.renderEquivalenceClaim,
39
+ staticSpreadSourceKind: evidence.staticSpreadSourceKind,
40
+ staticSpreadSourceName: evidence.staticSpreadSourceName,
41
+ staticSpreadPropEntries: evidence.staticSpreadPropEntries,
42
+ staticSpreadPropNames: evidence.staticSpreadPropNames,
43
+ staticSpreadPropCount: evidence.staticSpreadPropCount,
44
+ staticSpreadEffectivePropEntries: evidence.staticSpreadEffectivePropEntries,
45
+ staticSpreadEffectivePropNames: evidence.staticSpreadEffectivePropNames,
46
+ staticSpreadExplicitOverridePropNames: evidence.staticSpreadExplicitOverridePropNames,
47
+ staticSpreadOverridesExplicitPropNames: evidence.staticSpreadOverridesExplicitPropNames,
48
+ staticSpreadDuplicatePropNames: evidence.staticSpreadDuplicatePropNames,
49
+ staticSpreadPrecedenceStatus: evidence.staticSpreadPrecedenceStatus,
37
50
  dynamicText: evidence.dynamicText,
38
51
  dynamicBlockerReasonCode: evidence.dynamicBlockerReasonCode
39
52
  })
40
53
  });
41
54
  }
42
55
 
56
+ function jsxNonSpreadPropValueEvidence(attribute) {
57
+ const assignedValueText = jsxAssignedPropValueText(attribute);
58
+ return assignedValueText === undefined
59
+ ? staticPropValueEvidence('boolean-shorthand', 'true', 'true')
60
+ : jsxAssignedPropValueEvidence(assignedValueText);
61
+ }
62
+
43
63
  function jsxAssignedPropValueText(attribute) {
44
64
  const match = /^[A-Za-z_$][\w$:-]*\s*=\s*([\s\S]*)$/.exec(String(attribute?.text ?? '').trim());
45
65
  return match ? normalizedText(match[1]) : undefined;
@@ -119,7 +139,14 @@ function staticLiteralKind(text) {
119
139
  if (value === 'undefined') return 'undefined';
120
140
  if (/^[-]?(?:0|[1-9]\d*)(?:\.\d+)?$/.test(value)) return 'number';
121
141
  if (quotedLiteralText(value)) return 'string';
122
- return undefined;
142
+ return staticStructuredLiteralKind(value);
143
+ }
144
+
145
+ function staticStructuredLiteralKind(text) {
146
+ const parsed = parseStaticLiteralExpression(text);
147
+ return parsed && ['object-literal', 'array-literal', 'template-string'].includes(parsed.kind)
148
+ ? parsed.kind
149
+ : undefined;
123
150
  }
124
151
 
125
152
  function staticPropReference(text) {
@@ -133,6 +160,7 @@ function staticPropReference(text) {
133
160
  function jsxPropValueDynamicBlockerReasonCode(text) {
134
161
  const value = normalizedText(text);
135
162
  if (/\[[\s\S]*\]/.test(value)) return 'jsx-render-prop-value-computed-reference-unsupported';
163
+ if (/^`[\s\S]*\$\{[\s\S]*`$/.test(value)) return 'jsx-render-prop-value-template-interpolation-unsupported';
136
164
  if (/\?\.\s*\(/.test(value) || /\b[A-Za-z_$][\w$]*(?:\s*(?:\.|\?\.)\s*[A-Za-z_$][\w$]*)*\s*\(/.test(value)) return 'jsx-render-prop-value-call-expression-unsupported';
137
165
  if (/\?\./.test(value)) return 'jsx-render-prop-value-optional-reference-unsupported';
138
166
  return 'jsx-render-prop-value-expression-unsupported';