@shapeshift-labs/frontier-lang-compiler 0.2.162 → 0.2.164

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 (24) hide show
  1. package/dist/internal/index-impl/moduleHostResourceImportMetadata.js +47 -0
  2. package/dist/internal/index-impl/projectSymbolGraphCompilerAdvancedTypeMetadata.js +84 -12
  3. package/dist/internal/index-impl/projectSymbolGraphCompilerFacts.js +1 -1
  4. package/dist/internal/index-impl/projectSymbolGraphCssModules.js +48 -4
  5. package/dist/internal/index-impl/projectSymbolGraphJsxPropRecordFields.js +91 -0
  6. package/dist/internal/index-impl/projectSymbolGraphJsxPropValues.js +26 -135
  7. package/dist/internal/index-impl/projectSymbolGraphJsxRecords.js +4 -31
  8. package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturnCollectionHelpers.js +201 -0
  9. package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturnCollections.js +210 -0
  10. package/dist/internal/index-impl/projectSymbolGraphJsxRenderReturns.js +12 -5
  11. package/dist/internal/index-impl/projectSymbolGraphJsxSpreadPropValues.js +196 -0
  12. package/dist/internal/index-impl/projectSymbolGraphJsxStaticLiterals.js +207 -0
  13. package/dist/internal/index-impl/projectSymbolGraphModuleResolution.js +12 -14
  14. package/dist/internal/index-impl/projectSymbolGraphPackageConditions.js +22 -17
  15. package/dist/internal/index-impl/syntaxModuleDeclarationEntries.js +27 -1
  16. package/dist/js-ts-safe-project-merge-html-css-matrix.js +7 -2
  17. package/dist/js-ts-safe-project-merge-html-css-summary.js +90 -8
  18. package/dist/js-ts-safe-project-merge-html-css.js +137 -3
  19. package/dist/js-ts-safe-project-merge-jsx-graph-conflict-details.js +9 -0
  20. package/dist/js-ts-safe-project-merge-missing-evidence.js +12 -12
  21. package/dist/js-ts-safe-project-merge-source-text-candidate.js +68 -0
  22. package/dist/js-ts-safe-project-merge-summary.js +8 -11
  23. package/dist/js-ts-safe-project-merge.js +3 -0
  24. 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,7 +14,7 @@ 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);
17
+ const proofRequirement = advancedTypeProofRequirement(advancedTypeShapes, counts, source);
18
18
  return {
19
19
  counts,
20
20
  record: compactRecord({
@@ -40,6 +40,11 @@ function compilerAdvancedTypeMetadata(value) {
40
40
 
41
41
  const AdvancedTypeProofRequirementKind = 'typescript-checker-public-api-advanced-type-shape-equivalence';
42
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';
43
48
  const AdvancedTypeProofShapeSpecs = [
44
49
  proofShapeSpec('conditional-type', 'conditionalTypeCount', [
45
50
  proofField('nodeText', 'compiler-conditional-type-node-texts'),
@@ -98,11 +103,15 @@ const AdvancedTypeProofShapeSpecs = [
98
103
  ])
99
104
  ];
100
105
 
101
- function advancedTypeProofRequirement(advancedTypeShapes, counts) {
106
+ function advancedTypeProofRequirement(advancedTypeShapes, counts, source = {}) {
102
107
  if (!counts.advancedTypeShapeCount) return {};
103
- const requiredSignals = advancedTypeRequiredProofSignals(counts);
104
- const missingSignals = missingAdvancedTypeProofSignals(advancedTypeShapes, counts);
105
- const unsupportedSignals = unsupportedAdvancedTypeProofSignals(counts);
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);
106
115
  const status = unsupportedSignals.length
107
116
  ? 'requires-review'
108
117
  : missingSignals.length ? 'missing-compiler-evidence' : 'requires-type-equivalence-proof';
@@ -124,6 +133,9 @@ function advancedTypeProofRequirement(advancedTypeShapes, counts) {
124
133
  unionTypeCount: counts.unionTypeCount || undefined,
125
134
  intersectionTypeCount: counts.intersectionTypeCount || undefined,
126
135
  tupleTypeCount: counts.tupleTypeCount || undefined,
136
+ sourcePath: sourceBinding.sourcePath,
137
+ sourceHash: sourceBinding.sourceHash,
138
+ sourceBound: sourceBinding.required ? sourceBinding.bound : undefined,
127
139
  autoMergeClaim: false,
128
140
  semanticEquivalenceClaim: false
129
141
  });
@@ -144,10 +156,14 @@ function advancedTypeProofRequirement(advancedTypeShapes, counts) {
144
156
  };
145
157
  }
146
158
 
147
- function advancedTypeRequiredProofSignals(counts) {
148
- return uniqueStrings(AdvancedTypeProofShapeSpecs.flatMap((spec) => (
159
+ function advancedTypeRequiredProofSignals(counts, sourceBinding) {
160
+ const shapeSignals = AdvancedTypeProofShapeSpecs.flatMap((spec) => (
149
161
  counts[spec.countKey] > 0 ? [countSignal(spec.kind), ...spec.fields.map((field) => field.signal)] : []
150
- )));
162
+ ));
163
+ return uniqueStrings([
164
+ ...shapeSignals,
165
+ ...(sourceBinding.required ? [AdvancedTypeSourcePathSignal, AdvancedTypeSourceHashSignal] : [])
166
+ ]);
151
167
  }
152
168
 
153
169
  function missingAdvancedTypeProofSignals(advancedTypeShapes, counts) {
@@ -164,13 +180,68 @@ function missingAdvancedTypeProofSignals(advancedTypeShapes, counts) {
164
180
  }));
165
181
  }
166
182
 
167
- function unsupportedAdvancedTypeProofSignals(counts) {
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) {
168
192
  const knownShapeCount = AdvancedTypeProofShapeSpecs.reduce((sum, spec) => sum + (counts[spec.countKey] || 0), 0);
169
- return counts.advancedTypeShapeCount > knownShapeCount ? ['compiler-unknown-advanced-type-shape'] : [];
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
+ };
170
235
  }
171
236
 
172
237
  function fieldMissing(value) {
173
- if (Array.isArray(value)) return !value.length || value.some((item) => item === undefined || item === null);
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);
174
245
  return value === undefined || value === null;
175
246
  }
176
247
 
@@ -182,6 +253,7 @@ function arrayValue(value) { return Array.isArray(value) ? value : []; }
182
253
  function compactRecord(record) { return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined)); }
183
254
  function numberValue(value) { return Number.isFinite(value) ? value : undefined; }
184
255
  function nonEmptyArray(value) { return Array.isArray(value) && value.length ? value : undefined; }
256
+ function nonBlankString(value) { return typeof value === 'string' && value.trim().length > 0; }
185
257
  function uniqueStrings(values) { return [...new Set(values.filter((value) => typeof value === 'string' && value.length > 0))]; }
186
258
 
187
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);
@@ -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;
@@ -129,135 +149,6 @@ function staticStructuredLiteralKind(text) {
129
149
  : undefined;
130
150
  }
131
151
 
132
- function parseStaticLiteralExpression(text) {
133
- const state = { text: String(text ?? ''), index: 0 };
134
- const parsed = parseStaticLiteralValue(state);
135
- skipWhitespace(state);
136
- return parsed && state.index === state.text.length ? parsed : undefined;
137
- }
138
-
139
- function parseStaticLiteralValue(state) {
140
- skipWhitespace(state);
141
- const char = state.text[state.index];
142
- if (char === '"' || char === "'") return parseQuotedStaticString(state) ? { kind: 'string' } : undefined;
143
- if (char === '`') return parseStaticTemplateString(state) ? { kind: 'template-string' } : undefined;
144
- if (char === '{') return parseStaticObjectLiteral(state) ? { kind: 'object-literal' } : undefined;
145
- if (char === '[') return parseStaticArrayLiteral(state) ? { kind: 'array-literal' } : undefined;
146
- const primitive = parseStaticPrimitiveToken(state);
147
- return primitive ? { kind: primitive } : undefined;
148
- }
149
-
150
- function parseStaticObjectLiteral(state) {
151
- state.index += 1;
152
- skipWhitespace(state);
153
- if (consumeChar(state, '}')) return true;
154
- while (state.index < state.text.length) {
155
- if (state.text.startsWith('...', state.index) || state.text[state.index] === '[') return false;
156
- if (!parseStaticObjectKey(state)) return false;
157
- skipWhitespace(state);
158
- if (!consumeChar(state, ':')) return false;
159
- if (!parseStaticLiteralValue(state)) return false;
160
- skipWhitespace(state);
161
- if (consumeChar(state, '}')) return true;
162
- if (!consumeChar(state, ',')) return false;
163
- skipWhitespace(state);
164
- if (consumeChar(state, '}')) return true;
165
- }
166
- return false;
167
- }
168
-
169
- function parseStaticArrayLiteral(state) {
170
- state.index += 1;
171
- skipWhitespace(state);
172
- if (consumeChar(state, ']')) return true;
173
- while (state.index < state.text.length) {
174
- if (state.text.startsWith('...', state.index) || state.text[state.index] === ',') return false;
175
- if (!parseStaticLiteralValue(state)) return false;
176
- skipWhitespace(state);
177
- if (consumeChar(state, ']')) return true;
178
- if (!consumeChar(state, ',')) return false;
179
- skipWhitespace(state);
180
- if (consumeChar(state, ']')) return true;
181
- }
182
- return false;
183
- }
184
-
185
- function parseStaticObjectKey(state) {
186
- skipWhitespace(state);
187
- const char = state.text[state.index];
188
- if (char === '"' || char === "'") return parseQuotedStaticString(state);
189
- const numberStart = state.index;
190
- if (parseStaticNumberToken(state)) return true;
191
- state.index = numberStart;
192
- return Boolean(parseIdentifierToken(state));
193
- }
194
-
195
- function parseQuotedStaticString(state) {
196
- const quote = state.text[state.index];
197
- if (quote !== '"' && quote !== "'") return false;
198
- state.index += 1;
199
- while (state.index < state.text.length) {
200
- const char = state.text[state.index];
201
- if (char === '\\') {
202
- state.index += 2;
203
- continue;
204
- }
205
- state.index += 1;
206
- if (char === quote) return true;
207
- }
208
- return false;
209
- }
210
-
211
- function parseStaticTemplateString(state) {
212
- if (state.text[state.index] !== '`') return false;
213
- state.index += 1;
214
- while (state.index < state.text.length) {
215
- const char = state.text[state.index];
216
- if (char === '\\') {
217
- state.index += 2;
218
- continue;
219
- }
220
- if (char === '$' && state.text[state.index + 1] === '{') return false;
221
- state.index += 1;
222
- if (char === '`') return true;
223
- }
224
- return false;
225
- }
226
-
227
- function parseStaticPrimitiveToken(state) {
228
- const number = parseStaticNumberToken(state);
229
- if (number) return 'number';
230
- const identifier = parseIdentifierToken(state);
231
- if (['true', 'false'].includes(identifier)) return 'boolean';
232
- if (identifier === 'null') return 'null';
233
- if (identifier === 'undefined') return 'undefined';
234
- return undefined;
235
- }
236
-
237
- function parseStaticNumberToken(state) {
238
- const match = /^[-]?(?:0|[1-9]\d*)(?:\.\d+)?/.exec(state.text.slice(state.index));
239
- if (!match) return undefined;
240
- state.index += match[0].length;
241
- return match[0];
242
- }
243
-
244
- function parseIdentifierToken(state) {
245
- const match = /^[A-Za-z_$][\w$]*/.exec(state.text.slice(state.index));
246
- if (!match) return undefined;
247
- state.index += match[0].length;
248
- return match[0];
249
- }
250
-
251
- function consumeChar(state, char) {
252
- if (state.text[state.index] !== char) return false;
253
- state.index += 1;
254
- return true;
255
- }
256
-
257
- function skipWhitespace(state) {
258
- while (/\s/.test(state.text[state.index] ?? '')) state.index += 1;
259
- }
260
-
261
152
  function staticPropReference(text) {
262
153
  const value = normalizedText(text);
263
154
  if (!/^(?:this|[A-Za-z_$][\w$]*)(?:\s*\.\s*[A-Za-z_$][\w$]*)*$/.test(value)) return undefined;
@@ -11,6 +11,7 @@ import { jsxImportedComponentOwnerIndexes, jsxImportedMemberComponentOwnerIndexe
11
11
  import { jsxSameFileMemberComponentObjectIndex, jsxSameFileMemberComponentOwnerIndex } from './projectSymbolGraphJsxMemberComponents.js';
12
12
  import { jsxProviderFlowAncestorMap, jsxProviderFlowRecords } from './projectSymbolGraphJsxProviderFlows.js';
13
13
  import { jsxComponentPropRenderFlowBoundary, jsxComponentPropRenderFlowRecords } from './projectSymbolGraphJsxPropFlows.js';
14
+ import { jsxPropComponentFlowRecordFields, jsxPropValueRecordFields } from './projectSymbolGraphJsxPropRecordFields.js';
14
15
  import { jsxPropValueEvidence } from './projectSymbolGraphJsxPropValues.js';
15
16
  import { lineColumnForOffset } from './lineColumnForOffset.js';
16
17
 
@@ -112,7 +113,7 @@ function jsxElementRecord(tag, index, context) {
112
113
  function jsxPropRecordsForTag(tag, index, element, context) {
113
114
  return tag.attributes.map((attribute, attrIndex) => {
114
115
  const sourceSpan = sourceSpanForRange(context, attribute.start, attribute.end);
115
- const valueEvidence = jsxPropValueEvidence(tag, attribute);
116
+ const valueEvidence = jsxPropValueEvidence(tag, attribute, context);
116
117
  const componentPropRenderFlow = jsxComponentPropRenderFlowBoundary(tag, attribute, valueEvidence, { componentOwners: context.componentOwners, componentMemberOwners: context.componentMemberOwners, sourcePath: context.sourcePath, sourceText: context.sourceText });
117
118
  return compactRecord({
118
119
  id: `jsx_prop_${idFragment(context.sourcePath)}_${index + 1}_${attrIndex + 1}`,
@@ -122,36 +123,8 @@ function jsxPropRecordsForTag(tag, index, element, context) {
122
123
  propKind: propKind(attribute), keyProp: attribute.name === 'key' || undefined,
123
124
  spread: isJsxSpreadAttribute(attribute) || undefined, spreadOrdinal: attribute.spreadOrdinal,
124
125
  spreadExpressionHash: spreadExpressionHash(attribute),
125
- propValueProofStatus: valueEvidence?.proofStatus, propValueReasonCode: valueEvidence?.reasonCode,
126
- propValueKind: valueEvidence?.valueKind, propValueText: valueEvidence?.valueText,
127
- propValueExpressionText: valueEvidence?.expressionText, propValueReferenceRoot: valueEvidence?.referenceRoot,
128
- propValueReferencePath: valueEvidence?.referencePath, propValueDynamicText: valueEvidence?.dynamicText,
129
- propValueOptionalReference: valueEvidence?.optionalReference, propValueOptionalReferenceSegments: valueEvidence?.optionalReferenceSegments,
130
- propValueOptionalReferenceSegmentIndexes: valueEvidence?.optionalReferenceSegmentIndexes, propValueOptionalNullishBoundaryCount: valueEvidence?.optionalNullishBoundaryCount,
131
- propValueDynamicBlockerReasonCode: valueEvidence?.dynamicBlockerReasonCode,
132
- propValueExpressionHash: valueEvidence?.expressionHash, propValueSignatureHash: valueEvidence?.signatureHash,
133
- componentPropRenderFlowStatus: componentPropRenderFlow?.status, componentPropRenderFlowReasonCode: componentPropRenderFlow?.reasonCode,
134
- componentPropRenderFlowClaim: componentPropRenderFlow?.claim, componentPropRenderFlowClaimScope: componentPropRenderFlow?.claimScope,
135
- componentPropRenderFlowRenderEquivalenceClaim: componentPropRenderFlow?.renderEquivalenceClaim,
136
- componentPropRenderFlowScope: componentPropRenderFlow?.scope,
137
- componentPropRenderFlowTargetName: componentPropRenderFlow?.targetName,
138
- componentPropRenderFlowTargetKind: componentPropRenderFlow?.targetKind,
139
- componentPropRenderFlowTargetOwnerName: componentPropRenderFlow?.targetOwnerName,
140
- componentPropRenderFlowTargetOwnerCount: componentPropRenderFlow?.targetOwnerCount,
141
- componentPropRenderFlowTargetSourcePath: componentPropRenderFlow?.targetSourcePath,
142
- componentPropRenderFlowTargetLookupStatus: componentPropRenderFlow?.targetLookupStatus, componentPropRenderFlowTargetLookupScope: componentPropRenderFlow?.targetLookupScope,
143
- componentPropRenderFlowImportEdgeId: componentPropRenderFlow?.importEdgeId, componentPropRenderFlowImportKind: componentPropRenderFlow?.importKind, componentPropRenderFlowImportedName: componentPropRenderFlow?.importedName, componentPropRenderFlowLocalName: componentPropRenderFlow?.localName, componentPropRenderFlowTargetExportName: componentPropRenderFlow?.targetExportName,
144
- componentPropRenderFlowReExportEdgeId: componentPropRenderFlow?.reExportEdgeId, componentPropRenderFlowReExportSourcePath: componentPropRenderFlow?.reExportSourcePath, componentPropRenderFlowReExportExportedName: componentPropRenderFlow?.reExportExportedName, componentPropRenderFlowReExportLocalName: componentPropRenderFlow?.reExportLocalName, componentPropRenderFlowReExportTargetSourcePath: componentPropRenderFlow?.reExportTargetSourcePath, componentPropRenderFlowReExportKind: componentPropRenderFlow?.reExportKind, componentPropRenderFlowReExportIdentityId: componentPropRenderFlow?.reExportIdentityId, componentPropRenderFlowTargetLookupHash: componentPropRenderFlow?.targetLookupHash,
145
- componentPropRenderFlowMemberObjectName: componentPropRenderFlow?.memberObjectName, componentPropRenderFlowMemberPropertyName: componentPropRenderFlow?.memberPropertyName, componentPropRenderFlowMemberLocalName: componentPropRenderFlow?.memberLocalName, componentPropRenderFlowMemberBindingKind: componentPropRenderFlow?.memberBindingKind, componentPropRenderFlowMemberBindingHash: componentPropRenderFlow?.memberBindingHash,
146
- componentPropRenderFlowComponentPropName: componentPropRenderFlow?.componentPropName,
147
- componentPropRenderFlowRenderedTagName: componentPropRenderFlow?.renderedTagName,
148
- componentPropRenderFlowRenderedPropName: componentPropRenderFlow?.renderedPropName,
149
- componentPropRenderFlowPassthroughExpressionText: componentPropRenderFlow?.passthroughExpressionText,
150
- componentPropRenderFlowBindingKind: componentPropRenderFlow?.bindingKind,
151
- componentPropRenderFlowReturnOrdinal: componentPropRenderFlow?.returnOrdinal,
152
- componentPropRenderFlowDynamicBlockerReasonCode: componentPropRenderFlow?.dynamicBlockerReasonCode,
153
- componentPropRenderFlowTargetSignatureHash: componentPropRenderFlow?.targetSignatureHash,
154
- componentPropRenderFlowSignatureHash: componentPropRenderFlow?.signatureHash,
126
+ ...jsxPropValueRecordFields(valueEvidence),
127
+ ...jsxPropComponentFlowRecordFields(componentPropRenderFlow),
155
128
  publicContract: element.publicContract, publicOwnerName: element.publicOwnerName,
156
129
  signatureHash: hashSemanticValue({
157
130
  kind: 'frontier.lang.projectJsxPropSignature', tagName: tag.tagName, tagKey: tag.key,