@shapeshift-labs/frontier-lang-compiler 0.2.160 → 0.2.162
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.
- package/dist/declarations/js-ts-project-merge-summary.d.ts +1 -1
- package/dist/internal/index-impl/projectSymbolGraphCompilerAdvancedTypeMetadata.js +142 -0
- package/dist/internal/index-impl/projectSymbolGraphCssModuleUtils.js +56 -1
- package/dist/internal/index-impl/projectSymbolGraphJsxPropValues.js +137 -0
- package/dist/internal/index-impl/projectSymbolGraphModuleResolution.js +1 -1
- package/dist/internal/index-impl/projectSymbolGraphPackageConditions.js +11 -14
- package/dist/internal/index-impl/projectSymbolGraphPackageRuntimeConditions.js +22 -0
- package/dist/internal/index-impl/projectSymbolGraphScopeUseDefLexical.js +11 -19
- package/dist/js-ts-safe-project-merge-admission.js +10 -0
- package/dist/js-ts-safe-project-merge-evidence-routing.js +30 -2
- package/dist/js-ts-safe-project-merge-graph-delta-compiler-conflicts.js +7 -0
- package/dist/js-ts-safe-project-merge-html-css-summary.js +28 -0
- package/dist/native-source-preservation-scanner.js +10 -0
- package/dist/semantic-import-runtime-dynamic-import-evidence.js +141 -0
- package/dist/semantic-import-runtime-order-evidence.js +5 -4
- package/package.json +2 -2
|
@@ -5,7 +5,7 @@ export interface JsTsProjectSafeMergeSummary {
|
|
|
5
5
|
readonly files: number; readonly mergedFiles: number; readonly blockedFiles: number; readonly outputFiles: number;
|
|
6
6
|
readonly htmlFiles:number; readonly cssFiles:number; readonly htmlCssFiles:number; readonly htmlMergedFiles:number; readonly cssMergedFiles:number; readonly htmlCssMergedFiles:number; readonly htmlBlockedFiles:number; readonly cssBlockedFiles:number; readonly htmlCssBlockedFiles:number; readonly htmlCssBrowserRuntimeProofs:number;
|
|
7
7
|
readonly htmlParserEvidenceFiles:number; readonly cssParserEvidenceFiles:number; readonly htmlCssParserEvidenceFiles:number; readonly htmlParserEvidenceFailedFiles:number; readonly cssParserEvidenceFailedFiles:number; readonly htmlCssParserEvidenceFailedFiles:number;
|
|
8
|
-
readonly htmlIdentityEvidenceFiles:number; readonly cssSelectorTargetEvidenceFiles:number; readonly htmlCssStructuralTargetEvidenceFiles:number; readonly htmlIdentityEvidenceFailedFiles:number; readonly cssSelectorTargetConflictFiles:number; readonly htmlCssStructuralTargetEvidenceFailedFiles:number;
|
|
8
|
+
readonly htmlIdentityEvidenceFiles:number; readonly cssSelectorTargetEvidenceFiles:number; readonly htmlCssStructuralTargetEvidenceFiles:number; readonly htmlIdentityEvidenceFailedFiles:number; readonly cssSelectorTargetConflictFiles:number; readonly htmlCssStructuralTargetEvidenceFailedFiles:number; readonly cssSelectorTargetRebasedFiles:number;
|
|
9
9
|
readonly projectGraphConflicts: number; readonly projectGraphDeltaEvidenceIncluded: number; readonly outputProjectGraphConflicts:number; readonly projectGraphCssModuleUseSiteConflicts:number; readonly projectGraphDeltaConflicts: number; readonly projectGraphLimitConflicts: number; readonly projectGraphPublicContractConflicts: number; readonly projectGraphSourceSpanConflicts: number;
|
|
10
10
|
readonly projectGraphCompilerTypeConflicts: number; readonly projectGraphRuntimeRegionConflicts: number; readonly projectGraphScopeUseDefConflicts: number; readonly projectGraphJsxPropConflicts: number; readonly projectGraphJsxRenderRiskConflicts: number; readonly projectGraphReExportIdentityConflicts: number; readonly projectGraphModuleDeclarationShapeConflicts: number; readonly projectGraphExportAssignmentShapeConflicts: number;
|
|
11
11
|
readonly projectGraphImportAttributeConflicts: number; readonly projectGraphImportTargetConflicts: number; readonly outputDiagnostics: number; readonly outputDiagnosticConflicts: number; readonly outputDiagnosticErrors: number; readonly outputDiagnosticWarnings: number; readonly outputDeclarations: number; readonly outputDeclarationBytes: number; readonly outputDeclarationConflicts: number; readonly outputDeclarationDiagnosticErrors: number; readonly outputQualityGates: number; readonly outputQualityGateConflicts: number;
|
|
@@ -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);
|
|
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,6 +38,145 @@ 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 AdvancedTypeProofShapeSpecs = [
|
|
44
|
+
proofShapeSpec('conditional-type', 'conditionalTypeCount', [
|
|
45
|
+
proofField('nodeText', 'compiler-conditional-type-node-texts'),
|
|
46
|
+
proofField('typeText', 'compiler-conditional-type-type-texts'),
|
|
47
|
+
proofField('checkTypeText', 'compiler-conditional-type-check-type-texts'),
|
|
48
|
+
proofField('extendsTypeText', 'compiler-conditional-type-extends-type-texts'),
|
|
49
|
+
proofField('trueTypeText', 'compiler-conditional-type-true-type-texts'),
|
|
50
|
+
proofField('falseTypeText', 'compiler-conditional-type-false-type-texts')
|
|
51
|
+
]),
|
|
52
|
+
proofShapeSpec('mapped-type', 'mappedTypeCount', [
|
|
53
|
+
proofField('nodeText', 'compiler-mapped-type-node-texts'),
|
|
54
|
+
proofField('typeText', 'compiler-mapped-type-type-texts'),
|
|
55
|
+
proofField('mappedConstraintTypeText', 'compiler-mapped-type-constraint-type-texts'),
|
|
56
|
+
proofField('mappedValueTypeText', 'compiler-mapped-type-value-type-texts')
|
|
57
|
+
]),
|
|
58
|
+
proofShapeSpec('indexed-access-type', 'indexedAccessTypeCount', [
|
|
59
|
+
proofField('nodeText', 'compiler-indexed-access-type-node-texts'),
|
|
60
|
+
proofField('typeText', 'compiler-indexed-access-type-type-texts'),
|
|
61
|
+
proofField('objectTypeText', 'compiler-indexed-access-type-object-type-texts'),
|
|
62
|
+
proofField('indexTypeText', 'compiler-indexed-access-type-index-type-texts')
|
|
63
|
+
]),
|
|
64
|
+
proofShapeSpec('keyof-type-operator', 'keyofTypeOperatorCount', [
|
|
65
|
+
proofField('nodeText', 'compiler-keyof-type-operator-node-texts'),
|
|
66
|
+
proofField('typeText', 'compiler-keyof-type-operator-type-texts'),
|
|
67
|
+
proofField('keyofTargetTypeText', 'compiler-keyof-type-operator-target-type-texts')
|
|
68
|
+
]),
|
|
69
|
+
proofShapeSpec('template-literal-type', 'templateLiteralTypeCount', [
|
|
70
|
+
proofField('nodeText', 'compiler-template-literal-type-node-texts'),
|
|
71
|
+
proofField('typeText', 'compiler-template-literal-type-type-texts'),
|
|
72
|
+
proofField('templateHeadText', 'compiler-template-literal-type-head-texts'),
|
|
73
|
+
proofField('templateSpanTexts', 'compiler-template-literal-type-span-texts'),
|
|
74
|
+
proofField('templateSpanTypeTexts', 'compiler-template-literal-type-span-type-texts'),
|
|
75
|
+
proofField('templateLiteralTexts', 'compiler-template-literal-type-literal-texts')
|
|
76
|
+
]),
|
|
77
|
+
proofShapeSpec('infer-type', 'inferTypeCount', [
|
|
78
|
+
proofField('nodeText', 'compiler-infer-type-node-texts'),
|
|
79
|
+
proofField('typeText', 'compiler-infer-type-type-texts'),
|
|
80
|
+
proofField('typeParameterText', 'compiler-infer-type-type-parameter-texts'),
|
|
81
|
+
proofField('typeParameterName', 'compiler-infer-type-type-parameter-names')
|
|
82
|
+
]),
|
|
83
|
+
proofShapeSpec('union-type', 'unionTypeCount', [
|
|
84
|
+
proofField('nodeText', 'compiler-union-type-node-texts'),
|
|
85
|
+
proofField('typeText', 'compiler-union-type-type-texts'),
|
|
86
|
+
proofField('memberTypeTexts', 'compiler-union-type-member-type-texts')
|
|
87
|
+
]),
|
|
88
|
+
proofShapeSpec('intersection-type', 'intersectionTypeCount', [
|
|
89
|
+
proofField('nodeText', 'compiler-intersection-type-node-texts'),
|
|
90
|
+
proofField('typeText', 'compiler-intersection-type-type-texts'),
|
|
91
|
+
proofField('memberTypeTexts', 'compiler-intersection-type-member-type-texts')
|
|
92
|
+
]),
|
|
93
|
+
proofShapeSpec('tuple-type', 'tupleTypeCount', [
|
|
94
|
+
proofField('nodeText', 'compiler-tuple-type-node-texts'),
|
|
95
|
+
proofField('typeText', 'compiler-tuple-type-type-texts'),
|
|
96
|
+
proofField('tupleElementTexts', 'compiler-tuple-type-element-texts'),
|
|
97
|
+
proofField('tupleElementTypeTexts', 'compiler-tuple-type-element-type-texts')
|
|
98
|
+
])
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
function advancedTypeProofRequirement(advancedTypeShapes, counts) {
|
|
102
|
+
if (!counts.advancedTypeShapeCount) return {};
|
|
103
|
+
const requiredSignals = advancedTypeRequiredProofSignals(counts);
|
|
104
|
+
const missingSignals = missingAdvancedTypeProofSignals(advancedTypeShapes, counts);
|
|
105
|
+
const unsupportedSignals = unsupportedAdvancedTypeProofSignals(counts);
|
|
106
|
+
const status = unsupportedSignals.length
|
|
107
|
+
? 'requires-review'
|
|
108
|
+
: missingSignals.length ? 'missing-compiler-evidence' : 'requires-type-equivalence-proof';
|
|
109
|
+
const requirement = compactRecord({
|
|
110
|
+
kind: AdvancedTypeProofRequirementKind,
|
|
111
|
+
requiredEvidence: AdvancedTypeProofRequiredEvidence,
|
|
112
|
+
status,
|
|
113
|
+
requiredSignals,
|
|
114
|
+
missingSignals: nonEmptyArray(missingSignals),
|
|
115
|
+
unsupportedSignals: nonEmptyArray(unsupportedSignals),
|
|
116
|
+
advancedTypeShapeCount: counts.advancedTypeShapeCount,
|
|
117
|
+
advancedTypeShapeKinds: nonEmptyArray(uniqueStrings(advancedTypeShapes.map((shape) => shape.kind))),
|
|
118
|
+
conditionalTypeCount: counts.conditionalTypeCount || undefined,
|
|
119
|
+
mappedTypeCount: counts.mappedTypeCount || undefined,
|
|
120
|
+
indexedAccessTypeCount: counts.indexedAccessTypeCount || undefined,
|
|
121
|
+
keyofTypeOperatorCount: counts.keyofTypeOperatorCount || undefined,
|
|
122
|
+
templateLiteralTypeCount: counts.templateLiteralTypeCount || undefined,
|
|
123
|
+
inferTypeCount: counts.inferTypeCount || undefined,
|
|
124
|
+
unionTypeCount: counts.unionTypeCount || undefined,
|
|
125
|
+
intersectionTypeCount: counts.intersectionTypeCount || undefined,
|
|
126
|
+
tupleTypeCount: counts.tupleTypeCount || undefined,
|
|
127
|
+
autoMergeClaim: false,
|
|
128
|
+
semanticEquivalenceClaim: false
|
|
129
|
+
});
|
|
130
|
+
return {
|
|
131
|
+
requirement,
|
|
132
|
+
missingProof: status === 'requires-type-equivalence-proof' ? undefined : compactRecord({
|
|
133
|
+
kind: AdvancedTypeProofRequirementKind,
|
|
134
|
+
requiredEvidence: AdvancedTypeProofRequiredEvidence,
|
|
135
|
+
status,
|
|
136
|
+
reasonCode: status === 'missing-compiler-evidence'
|
|
137
|
+
? 'typescript-public-api-advanced-type-shape-proof-missing'
|
|
138
|
+
: 'typescript-public-api-advanced-type-shape-proof-requires-review',
|
|
139
|
+
missingSignals: nonEmptyArray(missingSignals),
|
|
140
|
+
unsupportedSignals: nonEmptyArray(unsupportedSignals),
|
|
141
|
+
autoMergeClaim: false,
|
|
142
|
+
semanticEquivalenceClaim: false
|
|
143
|
+
})
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function advancedTypeRequiredProofSignals(counts) {
|
|
148
|
+
return uniqueStrings(AdvancedTypeProofShapeSpecs.flatMap((spec) => (
|
|
149
|
+
counts[spec.countKey] > 0 ? [countSignal(spec.kind), ...spec.fields.map((field) => field.signal)] : []
|
|
150
|
+
)));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function missingAdvancedTypeProofSignals(advancedTypeShapes, counts) {
|
|
154
|
+
return uniqueStrings(AdvancedTypeProofShapeSpecs.flatMap((spec) => {
|
|
155
|
+
const count = counts[spec.countKey] || 0;
|
|
156
|
+
if (!count) return [];
|
|
157
|
+
const shapes = advancedTypeShapes.filter((shape) => shape?.kind === spec.kind);
|
|
158
|
+
const missing = [];
|
|
159
|
+
if (shapes.length !== count) missing.push(countSignal(spec.kind));
|
|
160
|
+
for (const field of spec.fields) {
|
|
161
|
+
if (shapes.some((shape) => fieldMissing(shape?.[field.key]))) missing.push(field.signal);
|
|
162
|
+
}
|
|
163
|
+
return missing;
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function unsupportedAdvancedTypeProofSignals(counts) {
|
|
168
|
+
const knownShapeCount = AdvancedTypeProofShapeSpecs.reduce((sum, spec) => sum + (counts[spec.countKey] || 0), 0);
|
|
169
|
+
return counts.advancedTypeShapeCount > knownShapeCount ? ['compiler-unknown-advanced-type-shape'] : [];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function fieldMissing(value) {
|
|
173
|
+
if (Array.isArray(value)) return !value.length || value.some((item) => item === undefined || item === null);
|
|
174
|
+
return value === undefined || value === null;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function proofShapeSpec(kind, countKey, fields) { return { kind, countKey, fields }; }
|
|
178
|
+
function proofField(key, signal) { return { key, signal }; }
|
|
179
|
+
function countSignal(kind) { return `compiler-${kind}-count`; }
|
|
38
180
|
function countKind(records, kind) { return records.filter((record) => record.kind === kind).length; }
|
|
39
181
|
function arrayValue(value) { return Array.isArray(value) ? value : []; }
|
|
40
182
|
function compactRecord(record) { return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined)); }
|
|
@@ -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
|
|
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
|
}
|
|
@@ -119,9 +119,145 @@ function staticLiteralKind(text) {
|
|
|
119
119
|
if (value === 'undefined') return 'undefined';
|
|
120
120
|
if (/^[-]?(?:0|[1-9]\d*)(?:\.\d+)?$/.test(value)) return 'number';
|
|
121
121
|
if (quotedLiteralText(value)) return 'string';
|
|
122
|
+
return staticStructuredLiteralKind(value);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function staticStructuredLiteralKind(text) {
|
|
126
|
+
const parsed = parseStaticLiteralExpression(text);
|
|
127
|
+
return parsed && ['object-literal', 'array-literal', 'template-string'].includes(parsed.kind)
|
|
128
|
+
? parsed.kind
|
|
129
|
+
: undefined;
|
|
130
|
+
}
|
|
131
|
+
|
|
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';
|
|
122
234
|
return undefined;
|
|
123
235
|
}
|
|
124
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
|
+
|
|
125
261
|
function staticPropReference(text) {
|
|
126
262
|
const value = normalizedText(text);
|
|
127
263
|
if (!/^(?:this|[A-Za-z_$][\w$]*)(?:\s*\.\s*[A-Za-z_$][\w$]*)*$/.test(value)) return undefined;
|
|
@@ -133,6 +269,7 @@ function staticPropReference(text) {
|
|
|
133
269
|
function jsxPropValueDynamicBlockerReasonCode(text) {
|
|
134
270
|
const value = normalizedText(text);
|
|
135
271
|
if (/\[[\s\S]*\]/.test(value)) return 'jsx-render-prop-value-computed-reference-unsupported';
|
|
272
|
+
if (/^`[\s\S]*\$\{[\s\S]*`$/.test(value)) return 'jsx-render-prop-value-template-interpolation-unsupported';
|
|
136
273
|
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
274
|
if (/\?\./.test(value)) return 'jsx-render-prop-value-optional-reference-unsupported';
|
|
138
275
|
return 'jsx-render-prop-value-expression-unsupported';
|
|
@@ -295,7 +295,7 @@ function packageSpecifierInfo(moduleSpecifier) {
|
|
|
295
295
|
|
|
296
296
|
function packageResolutionFields(candidate, packageInfo) {
|
|
297
297
|
if (!candidate.packageName && candidate.kind !== 'package') return {};
|
|
298
|
-
return { packageName: candidate.packageName ?? packageInfo?.packageName, packageSubpath: candidate.packageSubpath ?? packageInfo?.packageSubpath, packageExportKey: candidate.packageExportKey, packageExportCondition: candidate.packageExportCondition, packageExportTarget: candidate.packageExportTarget, packageImportKey: candidate.packageImportKey, packageImportCondition: candidate.packageImportCondition, packageImportTarget: candidate.packageImportTarget, packageRuntimeCondition: candidate.packageRuntimeCondition, packageRuntimeConditionEvidenceSource: candidate.packageRuntimeConditionEvidenceSource, packageRuntimeConditionEdgeKind: candidate.packageRuntimeConditionEdgeKind, packageRuntimeConditionCandidates: candidate.packageRuntimeConditionCandidates, packageRuntimeConditionReasonCode: candidate.packageRuntimeConditionReasonCode, packageEnvironmentCondition: candidate.packageEnvironmentCondition, packageEnvironmentConditionEvidenceSource: candidate.packageEnvironmentConditionEvidenceSource, packageEnvironmentConditionCandidates: candidate.packageEnvironmentConditionCandidates, packageEnvironmentConditionReasonCode: candidate.packageEnvironmentConditionReasonCode, packageType: candidate.packageType, packageWorkspaceRootAmbiguous: candidate.packageWorkspaceRootAmbiguous, packageWorkspaceRoots: candidate.packageWorkspaceRoots, packageResolutionReasonCode: candidate.packageResolutionReasonCode };
|
|
298
|
+
return { packageName: candidate.packageName ?? packageInfo?.packageName, packageSubpath: candidate.packageSubpath ?? packageInfo?.packageSubpath, packageExportKey: candidate.packageExportKey, packageExportCondition: candidate.packageExportCondition, packageExportTarget: candidate.packageExportTarget, packageImportKey: candidate.packageImportKey, packageImportCondition: candidate.packageImportCondition, packageImportTarget: candidate.packageImportTarget, packageRuntimeCondition: candidate.packageRuntimeCondition, packageRuntimeConditionEvidenceSource: candidate.packageRuntimeConditionEvidenceSource, packageRuntimeConditionEdgeKind: candidate.packageRuntimeConditionEdgeKind, packageRuntimeConditionCandidates: candidate.packageRuntimeConditionCandidates, packageRuntimeConditionExcludedConditions: candidate.packageRuntimeConditionExcludedConditions, packageRuntimeConditionReasonCode: candidate.packageRuntimeConditionReasonCode, packageEnvironmentCondition: candidate.packageEnvironmentCondition, packageEnvironmentConditionEvidenceSource: candidate.packageEnvironmentConditionEvidenceSource, packageEnvironmentConditionCandidates: candidate.packageEnvironmentConditionCandidates, packageEnvironmentConditionReasonCode: candidate.packageEnvironmentConditionReasonCode, packageType: candidate.packageType, packageWorkspaceRootAmbiguous: candidate.packageWorkspaceRootAmbiguous, packageWorkspaceRoots: candidate.packageWorkspaceRoots, packageResolutionReasonCode: candidate.packageResolutionReasonCode };
|
|
299
299
|
}
|
|
300
300
|
|
|
301
301
|
function environmentAmbiguityFields(ambiguity) { return { packageEnvironmentConditionCandidates: ambiguity.split('|'), packageEnvironmentConditionReasonCode: 'package-environment-condition-ambiguous-missing' }; }
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { runtimeAdmittedConditions, runtimeConditionRecord } from './projectSymbolGraphPackageRuntimeConditions.js';
|
|
2
|
+
|
|
1
3
|
const EnvironmentPackageConditions = Object.freeze([
|
|
2
4
|
'browser',
|
|
3
5
|
'node',
|
|
@@ -30,7 +32,10 @@ function exportMapMatch(exportsValue, subpath) {
|
|
|
30
32
|
|
|
31
33
|
function packageConditions(moduleResolution = {}, sourcePath, packageContext, edgeMetadata) {
|
|
32
34
|
return prioritizeConditions(
|
|
33
|
-
|
|
35
|
+
runtimeAdmittedConditions(
|
|
36
|
+
moduleResolution.packageExportConditions ?? moduleResolution.conditions ?? ['types', 'import', 'module', 'require', 'default'],
|
|
37
|
+
packageRuntimeConditionEvidence(moduleResolution, sourcePath, packageContext, edgeMetadata).packageRuntimeCondition
|
|
38
|
+
),
|
|
34
39
|
packageConditionPreferences(sourcePath, moduleResolution, packageContext, edgeMetadata)
|
|
35
40
|
);
|
|
36
41
|
}
|
|
@@ -78,8 +83,8 @@ function packageRuntimeConditionEvidence(moduleResolution = {}, sourcePath, pack
|
|
|
78
83
|
}
|
|
79
84
|
const hostAmbiguity = edgeCondition ? undefined : packageRuntimeHostConditionAmbiguity(edgeMetadata, packageType);
|
|
80
85
|
if (hostAmbiguity) return hostAmbiguity;
|
|
81
|
-
if (extensionCondition) return { packageRuntimeCondition: extensionCondition, packageRuntimeConditionEvidenceSource: 'source-extension', packageType };
|
|
82
|
-
if (packageTypeCondition) return { packageRuntimeCondition: packageTypeCondition, packageRuntimeConditionEvidenceSource: 'package-type', packageType };
|
|
86
|
+
if (extensionCondition) return runtimeConditionRecord({ packageRuntimeCondition: extensionCondition, packageRuntimeConditionEvidenceSource: 'source-extension', packageType });
|
|
87
|
+
if (packageTypeCondition) return runtimeConditionRecord({ packageRuntimeCondition: packageTypeCondition, packageRuntimeConditionEvidenceSource: 'package-type', packageType });
|
|
83
88
|
return {};
|
|
84
89
|
}
|
|
85
90
|
|
|
@@ -178,14 +183,14 @@ function packageRuntimeHostConditionAmbiguity(edgeMetadata = {}, packageType) {
|
|
|
178
183
|
}
|
|
179
184
|
|
|
180
185
|
function edgeCondition(packageRuntimeCondition, packageRuntimeConditionEdgeKind, packageRuntimeConditionReasonCode, preferred, conflictsWithSource) {
|
|
181
|
-
return {
|
|
186
|
+
return runtimeConditionRecord({
|
|
182
187
|
packageRuntimeCondition,
|
|
183
188
|
packageRuntimeConditionEvidenceSource: 'edge-kind',
|
|
184
189
|
packageRuntimeConditionEdgeKind,
|
|
185
190
|
packageRuntimeConditionReasonCode,
|
|
186
191
|
preferred,
|
|
187
192
|
conflictsWithSource
|
|
188
|
-
};
|
|
193
|
+
});
|
|
189
194
|
}
|
|
190
195
|
|
|
191
196
|
function staticImportKind(importKind) {
|
|
@@ -303,12 +308,4 @@ function pathInsideRoot(sourcePath, root) {
|
|
|
303
308
|
return sourcePath === root || sourcePath.startsWith(`${root}/`);
|
|
304
309
|
}
|
|
305
310
|
|
|
306
|
-
export {
|
|
307
|
-
exportMapMatch,
|
|
308
|
-
exportTargetsForValue,
|
|
309
|
-
packageConditions,
|
|
310
|
-
packageEnvironmentConditionAmbiguity,
|
|
311
|
-
packageEnvironmentConditionEvidence,
|
|
312
|
-
packageRuntimeConditionAmbiguity,
|
|
313
|
-
packageRuntimeConditionEvidence
|
|
314
|
-
};
|
|
311
|
+
export { exportMapMatch, exportTargetsForValue, packageConditions, packageEnvironmentConditionAmbiguity, packageEnvironmentConditionEvidence, packageRuntimeConditionAmbiguity, packageRuntimeConditionEvidence };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
function runtimeAdmittedConditions(conditions, runtimeCondition) {
|
|
2
|
+
const entries = Array.isArray(conditions) ? conditions : [conditions];
|
|
3
|
+
const excluded = new Set(runtimeExcludedConditions(runtimeCondition));
|
|
4
|
+
return excluded.size ? entries.filter((entry) => !excluded.has(String(entry))) : entries;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function runtimeConditionRecord(record) {
|
|
8
|
+
return compactRecord({
|
|
9
|
+
...record,
|
|
10
|
+
packageRuntimeConditionExcludedConditions: runtimeExcludedConditions(record.packageRuntimeCondition)
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function runtimeExcludedConditions(runtimeCondition) {
|
|
15
|
+
if (runtimeCondition === 'import') return ['require'];
|
|
16
|
+
if (runtimeCondition === 'require') return ['import', 'module'];
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function compactRecord(record) { return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined)); }
|
|
21
|
+
|
|
22
|
+
export { runtimeAdmittedConditions, runtimeConditionRecord };
|
|
@@ -8,6 +8,7 @@ import { nearestPublicOwnerForOffset } from './projectSymbolGraphScopeUseDefOwne
|
|
|
8
8
|
import { readStaticMemberLiteral } from './staticMemberLiteral.js';
|
|
9
9
|
|
|
10
10
|
const jsTsKeywords = new Set('abstract as async await break case catch class const continue debugger declare default delete do else enum export extends false finally for from function if implements import in infer instanceof interface keyof let module namespace new null of package private protected public readonly return satisfies static super switch this throw true try type typeof undefined unique unknown var void while with yield'.split(' '));
|
|
11
|
+
const namespaceComputedMemberDynamicUnsupportedReason = 'lexical-scope-namespace-computed-member-dynamic-unsupported', namespaceComputedMemberUnresolvedReason = 'lexical-scope-namespace-computed-member-unresolved';
|
|
11
12
|
|
|
12
13
|
function lexicalScopeRecordsForImport(sourceText, context) {
|
|
13
14
|
const masked = maskNonCode(sourceText);
|
|
@@ -230,15 +231,17 @@ function namespacePropertyAccess(code, token, binding, context) {
|
|
|
230
231
|
|
|
231
232
|
function namespaceComputedPropertyAccess(sourceText, code, tokenStart, open) {
|
|
232
233
|
const close = findMatchingBracket(code, open);
|
|
233
|
-
if (close === -1) return blockedNamespaceComputedPropertyAccess();
|
|
234
|
+
if (close === -1) return blockedNamespaceComputedPropertyAccess(undefined, [namespaceComputedMemberUnresolvedReason]);
|
|
234
235
|
const writeOperation = namespaceMemberWriteOperation(code, tokenStart, close + 1);
|
|
235
236
|
let index = open + 1;
|
|
236
237
|
while (index < close && /\s/.test(sourceText[index])) index += 1;
|
|
238
|
+
if (index >= close) return blockedNamespaceComputedPropertyAccess(writeOperation, [namespaceComputedMemberUnresolvedReason]);
|
|
237
239
|
const literal = readStaticMemberLiteral(sourceText, index, close);
|
|
238
|
-
if (!literal) return blockedNamespaceComputedPropertyAccess(writeOperation);
|
|
240
|
+
if (!literal) return blockedNamespaceComputedPropertyAccess(writeOperation, [namespaceComputedMemberDynamicUnsupportedReason]);
|
|
239
241
|
let afterLiteral = literal.end + 1;
|
|
240
242
|
while (afterLiteral < close && /\s/.test(sourceText[afterLiteral])) afterLiteral += 1;
|
|
241
|
-
if (afterLiteral !== close
|
|
243
|
+
if (afterLiteral !== close) return blockedNamespaceComputedPropertyAccess(writeOperation, [namespaceComputedMemberDynamicUnsupportedReason]);
|
|
244
|
+
if (!identifierRegExp.test(literal.value)) return blockedNamespaceComputedPropertyAccess(writeOperation);
|
|
242
245
|
if (writeOperation) {
|
|
243
246
|
return blockedNamespaceMemberWrite('namespace-computed-property-write', {
|
|
244
247
|
memberName: literal.value,
|
|
@@ -252,31 +255,18 @@ function namespaceComputedPropertyAccess(sourceText, code, tokenStart, open) {
|
|
|
252
255
|
return { referenceKind: 'namespace-computed-property-read', memberName: literal.value, memberStart: literal.start, memberEnd: literal.end, memberComputed: true, memberLiteralKind: literal.literalKind };
|
|
253
256
|
}
|
|
254
257
|
|
|
255
|
-
function blockedNamespaceComputedPropertyAccess(writeOperation) {
|
|
258
|
+
function blockedNamespaceComputedPropertyAccess(writeOperation, reasonCodes = []) {
|
|
256
259
|
return {
|
|
257
260
|
referenceKind: writeOperation ? 'namespace-computed-property-write' : 'namespace-computed-property-read',
|
|
258
261
|
memberComputed: true,
|
|
259
262
|
writeOperation,
|
|
260
263
|
status: 'blocked',
|
|
261
|
-
reasonCodes: [
|
|
262
|
-
LexicalUseDefReasonCodes.namespaceComputedMemberUnsupported,
|
|
263
|
-
...(writeOperation ? [LexicalUseDefReasonCodes.namespaceMemberWriteUnsupported] : [])
|
|
264
|
-
]
|
|
264
|
+
reasonCodes: uniqueReasonCodes([LexicalUseDefReasonCodes.namespaceComputedMemberUnsupported, ...reasonCodes, ...(writeOperation ? [LexicalUseDefReasonCodes.namespaceMemberWriteUnsupported] : [])])
|
|
265
265
|
};
|
|
266
266
|
}
|
|
267
267
|
|
|
268
268
|
function blockedNamespaceMemberWrite(referenceKind, fields = {}) {
|
|
269
|
-
return {
|
|
270
|
-
referenceKind,
|
|
271
|
-
memberName: fields.memberName,
|
|
272
|
-
memberStart: fields.memberStart,
|
|
273
|
-
memberEnd: fields.memberEnd,
|
|
274
|
-
memberComputed: fields.memberComputed,
|
|
275
|
-
memberLiteralKind: fields.memberLiteralKind,
|
|
276
|
-
status: 'blocked',
|
|
277
|
-
reasonCodes: [LexicalUseDefReasonCodes.namespaceMemberWriteUnsupported],
|
|
278
|
-
writeOperation: fields.writeOperation
|
|
279
|
-
};
|
|
269
|
+
return { referenceKind, memberName: fields.memberName, memberStart: fields.memberStart, memberEnd: fields.memberEnd, memberComputed: fields.memberComputed, memberLiteralKind: fields.memberLiteralKind, status: 'blocked', reasonCodes: [LexicalUseDefReasonCodes.namespaceMemberWriteUnsupported], writeOperation: fields.writeOperation };
|
|
280
270
|
}
|
|
281
271
|
|
|
282
272
|
function namespaceMemberWriteOperation(code, tokenStart, accessEnd) {
|
|
@@ -317,4 +307,6 @@ function findMatchingBracket(code, open) {
|
|
|
317
307
|
return -1;
|
|
318
308
|
}
|
|
319
309
|
|
|
310
|
+
function uniqueReasonCodes(reasonCodes) { return [...new Set(reasonCodes.filter(Boolean))]; }
|
|
311
|
+
|
|
320
312
|
export { lexicalScopeRecordsForImport };
|
|
@@ -80,10 +80,18 @@ function exactBranchProjectSemanticEditAdmission(options) {
|
|
|
80
80
|
if (requireOtherBranchUnchanged && !otherProjectBranchUnchanged(file, classification.branch, { requireBase: requireBaseForOtherBranchUnchanged })) return undefined;
|
|
81
81
|
}
|
|
82
82
|
const outputHash = hashProjectSourceText(branchText);
|
|
83
|
+
const admissionOutcome = 'safe';
|
|
84
|
+
const admissionOutcomeReasonCode = exactMergedOutput && allowExistingExactOutput
|
|
85
|
+
? 'existing-exact-branch-output'
|
|
86
|
+
: typeof branchText === 'string'
|
|
87
|
+
? 'exact-branch-output-other-branch-unchanged'
|
|
88
|
+
: 'exact-branch-deletion-other-branch-unchanged';
|
|
83
89
|
const admission = {
|
|
84
90
|
id: safeProjectEvidenceId(`${classification.details?.conflictKey ?? classification.code}_${file.sourcePath}`),
|
|
85
91
|
kind: admissionKind,
|
|
86
92
|
status: 'passed',
|
|
93
|
+
admissionOutcome,
|
|
94
|
+
admissionOutcomeReasonCode,
|
|
87
95
|
branch: classification.branch,
|
|
88
96
|
...(admissionFields(classification) ?? {}),
|
|
89
97
|
sourcePath: file.sourcePath,
|
|
@@ -94,6 +102,8 @@ function exactBranchProjectSemanticEditAdmission(options) {
|
|
|
94
102
|
...(details(classification) ?? {}),
|
|
95
103
|
sourcePath: file.sourcePath,
|
|
96
104
|
outputHash,
|
|
105
|
+
admissionOutcome,
|
|
106
|
+
admissionOutcomeReasonCode,
|
|
97
107
|
exactBranchOutput: true,
|
|
98
108
|
deletedOutput: typeof branchText !== 'string' || undefined,
|
|
99
109
|
autoMergeClaim: false,
|
|
@@ -21,7 +21,7 @@ function fileAdmissionEvidenceRecords(files = []) {
|
|
|
21
21
|
return files.flatMap((file) => [
|
|
22
22
|
...recordArraysWithSuffix(file.summary, 'AdmissionEvidence'),
|
|
23
23
|
...recordArraysWithSuffix(file.metadata, 'Admissions')
|
|
24
|
-
]);
|
|
24
|
+
].map(admissionEvidenceRecordWithOutcome));
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
function recordArraysWithSuffix(record, suffix) {
|
|
@@ -32,7 +32,35 @@ function recordArraysWithSuffix(record, suffix) {
|
|
|
32
32
|
.filter((value) => value?.kind && value?.id);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function admissionEvidenceRecordWithOutcome(record) {
|
|
36
|
+
const admissionOutcome = admissionEvidenceOutcome(record);
|
|
37
|
+
return compactRecord({
|
|
38
|
+
...record,
|
|
39
|
+
admissionOutcome,
|
|
40
|
+
admissionOutcomeReasonCode: admissionEvidenceOutcomeReasonCode(record, admissionOutcome)
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function admissionEvidenceOutcome(record) {
|
|
45
|
+
if (['safe', 'review', 'blocked'].includes(record?.admissionOutcome)) return record.admissionOutcome;
|
|
46
|
+
const routeStatus = record?.admissionRoute?.status;
|
|
47
|
+
if (record?.status === 'passed' && (!routeStatus || routeStatus === 'passed')) return 'safe';
|
|
48
|
+
if (record?.status === 'failed' || routeStatus === 'failed' || routeStatus === 'blocked') return 'blocked';
|
|
49
|
+
return 'review';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function admissionEvidenceOutcomeReasonCode(record, admissionOutcome) {
|
|
53
|
+
if (typeof record?.admissionOutcomeReasonCode === 'string' && record.admissionOutcomeReasonCode.length > 0) return record.admissionOutcomeReasonCode;
|
|
54
|
+
const routeReasonCode = record?.admissionRoute?.reasonCodes?.[0];
|
|
55
|
+
if (typeof record?.details?.reasonCode === 'string' && record.details.reasonCode.length > 0) return record.details.reasonCode;
|
|
56
|
+
if (typeof routeReasonCode === 'string' && routeReasonCode.length > 0) return routeReasonCode;
|
|
57
|
+
if (admissionOutcome === 'safe' && record?.details?.exactBranchOutput === true) return 'passed-exact-branch-output';
|
|
58
|
+
if (admissionOutcome === 'safe') return 'passed-admission-evidence';
|
|
59
|
+
if (admissionOutcome === 'blocked') return 'failed-admission-evidence';
|
|
60
|
+
return 'review-admission-evidence';
|
|
61
|
+
}
|
|
62
|
+
|
|
35
63
|
function isPlainObject(value) { return Boolean(value && typeof value === 'object' && !Array.isArray(value)); }
|
|
36
64
|
function compactRecord(record) { return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined)); }
|
|
37
65
|
|
|
38
|
-
export { failedEvidenceMissingItems, fileAdmissionEvidenceRecords };
|
|
66
|
+
export { admissionEvidenceOutcome, failedEvidenceMissingItems, fileAdmissionEvidenceRecords };
|
|
@@ -117,6 +117,8 @@ function missingSharedCompilerTypeEquivalenceEvidence(workerRecord, headRecord)
|
|
|
117
117
|
enumMemberCount: record.enumMemberCount,
|
|
118
118
|
enumComputedMemberCount: record.enumComputedMemberCount,
|
|
119
119
|
typeEquivalenceEnumRuntimeShapeHash: record.typeEquivalenceEnumRuntimeShapeHash,
|
|
120
|
+
advancedTypeProofRequirement: record.advancedTypeProofRequirement,
|
|
121
|
+
advancedTypeMissingProof: record.advancedTypeMissingProof,
|
|
120
122
|
typeEquivalenceSignatureSetHash: record.typeEquivalenceSignatureSetHash,
|
|
121
123
|
typeEquivalenceCallSignatureSetHash: record.typeEquivalenceCallSignatureSetHash, typeEquivalenceConstructSignatureSetHash: record.typeEquivalenceConstructSignatureSetHash,
|
|
122
124
|
typeEquivalenceTypeParameterSetHash: record.typeEquivalenceTypeParameterSetHash,
|
|
@@ -169,9 +171,14 @@ function hasPassedCompilerTypeEquivalenceProof(record) {
|
|
|
169
171
|
];
|
|
170
172
|
return Boolean(record?.typeEquivalenceStatus === 'compiler-backed-equivalent'
|
|
171
173
|
&& record?.typeEquivalenceProof?.status === 'passed'
|
|
174
|
+
&& !hasMissingAdvancedTypeProof(record)
|
|
172
175
|
&& requiredHashes.every(([required, hash]) => !required || hash)
|
|
173
176
|
&& record?.apiSignatureHash);
|
|
174
177
|
}
|
|
178
|
+
function hasMissingAdvancedTypeProof(record) {
|
|
179
|
+
const status = record?.advancedTypeMissingProof?.status ?? record?.advancedTypeProofRequirement?.status;
|
|
180
|
+
return status === 'missing-compiler-evidence' || status === 'requires-review';
|
|
181
|
+
}
|
|
175
182
|
function recordsByIdentityKey(records, identityKey) { const result = new Map(); for (const record of records ?? []) { const key = identityKey(record); if (!key || result.has(key)) continue; result.set(key, record); } return result; }
|
|
176
183
|
function optionalFingerprint(record, fingerprint) { return record ? fingerprint(record) : undefined; }
|
|
177
184
|
function stableKey(parts) { const values = parts.map((part) => part === undefined || part === null ? '' : String(part)); return values.some(Boolean) ? values.join('#') : undefined; }
|
|
@@ -7,7 +7,11 @@ function htmlCssProjectSummary(files) {
|
|
|
7
7
|
htmlParserEvidenceFiles: htmlFiles.filter(hasHtmlParserEvidence).length, cssParserEvidenceFiles: cssFiles.filter(hasCssParserEvidence).length, htmlCssParserEvidenceFiles: htmlCssFiles.filter((file) => hasHtmlParserEvidence(file) || hasCssParserEvidence(file)).length,
|
|
8
8
|
htmlParserEvidenceFailedFiles: htmlFiles.filter(hasParserEvidenceFailure).length, cssParserEvidenceFailedFiles: cssFiles.filter(hasParserEvidenceFailure).length, htmlCssParserEvidenceFailedFiles: htmlCssFiles.filter(hasParserEvidenceFailure).length,
|
|
9
9
|
htmlIdentityEvidenceFiles: htmlFiles.filter(hasHtmlIdentityEvidence).length, cssSelectorTargetEvidenceFiles: cssFiles.filter(hasCssSelectorTargetEvidence).length, htmlCssStructuralTargetEvidenceFiles: htmlCssFiles.filter((file) => hasHtmlIdentityEvidence(file) || hasCssSelectorTargetEvidence(file)).length,
|
|
10
|
+
htmlExplicitIdentityEvidenceFiles: htmlFiles.filter(hasHtmlExplicitIdentityEvidence).length, htmlPathOnlyIdentityResidualFiles: htmlFiles.filter(hasHtmlPathOnlyIdentityResidual).length,
|
|
11
|
+
htmlRuntimeBoundaryEvidenceFiles: htmlFiles.filter(hasHtmlRuntimeBoundaryEvidence).length, htmlFrameworkBoundaryEvidenceFiles: htmlFiles.filter(hasHtmlFrameworkBoundaryEvidence).length, htmlProofGapBlockedFiles: htmlFiles.filter(hasHtmlProofGapBlockedConflict).length,
|
|
10
12
|
htmlIdentityEvidenceFailedFiles: htmlFiles.filter(hasHtmlIdentityEvidenceFailure).length, cssSelectorTargetConflictFiles: cssFiles.filter(hasCssSelectorTargetConflict).length, htmlCssStructuralTargetEvidenceFailedFiles: htmlCssFiles.filter((file) => hasHtmlIdentityEvidenceFailure(file) || hasCssSelectorTargetConflict(file)).length,
|
|
13
|
+
cssSelectorTargetRebasedFiles: cssFiles.filter(hasCssSelectorTargetRebase).length,
|
|
14
|
+
cssScopedCascadeFiles: cssFiles.filter(hasCssScopedCascadeScope).length, cssScopedCascadeEvidenceFiles: cssFiles.filter(hasCssScopedCascadeEvidence).length, cssScopedCascadeBlockedFiles: cssFiles.filter(hasCssScopedCascadeMissingProof).length,
|
|
11
15
|
htmlCssBrowserRuntimeProofs: htmlCssFiles.filter(hasBrowserRuntimeProof).length
|
|
12
16
|
};
|
|
13
17
|
}
|
|
@@ -30,6 +34,13 @@ function hasHtmlIdentityEvidence(file) {
|
|
|
30
34
|
const evidence = file?.result?.identityEvidence;
|
|
31
35
|
return evidence?.parserBackedStructuralSpans === true && evidence.structuralAddressability === true;
|
|
32
36
|
}
|
|
37
|
+
function hasHtmlExplicitIdentityEvidence(file) {
|
|
38
|
+
const evidence = file?.result?.identityEvidence;
|
|
39
|
+
return hasHtmlIdentityEvidence(file) && evidence.explicitIdentityAvailable === true;
|
|
40
|
+
}
|
|
41
|
+
function hasHtmlPathOnlyIdentityResidual(file) { return (file?.result?.identityEvidence?.pathOnlyIdentityElements ?? 0) > 0; }
|
|
42
|
+
function hasHtmlRuntimeBoundaryEvidence(file) { return (file?.result?.identityEvidence?.runtimeBoundaryElements ?? 0) > 0; }
|
|
43
|
+
function hasHtmlFrameworkBoundaryEvidence(file) { return (file?.result?.identityEvidence?.frameworkBoundaryElements ?? 0) > 0; }
|
|
33
44
|
function hasHtmlIdentityEvidenceFailure(file) {
|
|
34
45
|
const evidence = file?.result?.identityEvidence;
|
|
35
46
|
return Boolean(evidence) && (evidence.parserBackedStructuralSpans !== true || evidence.structuralAddressability !== true);
|
|
@@ -41,9 +52,26 @@ function hasCssSelectorTargetEvidence(file) {
|
|
|
41
52
|
function hasCssSelectorTargetConflict(file) {
|
|
42
53
|
return (file?.result?.conflicts ?? file?.conflicts ?? []).some((conflict) => conflict.code === 'css-selector-target-conflict');
|
|
43
54
|
}
|
|
55
|
+
function hasHtmlProofGapBlockedConflict(file) {
|
|
56
|
+
return (file?.result?.conflicts ?? file?.conflicts ?? []).some((conflict) => conflict.code === 'html-proof-gap-blocked');
|
|
57
|
+
}
|
|
58
|
+
function hasCssSelectorTargetRebase(file) { return (file?.result?.selectorTargetEvidence?.rebasedChangeCount ?? 0) > 0; }
|
|
59
|
+
function hasCssScopedCascadeScope(file) { return cssScopedRuleCount(file) > 0; }
|
|
60
|
+
function hasCssScopedCascadeEvidence(file) {
|
|
61
|
+
return hasCssScopedCascadeScope(file) && file?.result?.parserEvidence?.scopedCascadeGraphHashPresent === true;
|
|
62
|
+
}
|
|
63
|
+
function hasCssScopedCascadeMissingProof(file) {
|
|
64
|
+
return hasCssScopedCascadeScope(file) && (file?.result?.conflicts ?? file?.conflicts ?? []).some((conflict) => ScopedCascadeMissingProofReasonCodes.has(conflict?.details?.reasonCode));
|
|
65
|
+
}
|
|
66
|
+
function cssScopedRuleCount(file) {
|
|
67
|
+
const sides = Object.values(file?.result?.selectorTargetEvidence?.sides ?? {});
|
|
68
|
+
return sides.reduce((count, side) => Math.max(count, side?.scopedRuleCount ?? 0), 0);
|
|
69
|
+
}
|
|
44
70
|
function hasBrowserRuntimeProof(file) {
|
|
45
71
|
const admission = file?.result?.admission ?? file?.admission ?? {};
|
|
46
72
|
return admission.browserRuntimeEquivalenceClaim === true || admission.browserCascadeEquivalenceClaim === true || admission.browserRenderEquivalenceClaim === true;
|
|
47
73
|
}
|
|
48
74
|
|
|
75
|
+
const ScopedCascadeMissingProofReasonCodes = new Set(['css-scoped-cascade-equivalence-unproved', 'css-media-cascade-scope-unproved', 'css-supports-cascade-scope-unproved', 'css-container-cascade-scope-unproved', 'css-layer-cascade-scope-unproved', 'css-scope-cascade-scope-unproved']);
|
|
76
|
+
|
|
49
77
|
export { htmlCssProjectSummary };
|
|
@@ -57,6 +57,16 @@ function scanPreservedSourceTokens(sourceText, input) {
|
|
|
57
57
|
push(trivia, 'whitespace', text, start);
|
|
58
58
|
continue;
|
|
59
59
|
}
|
|
60
|
+
if (offset === 0 && char === '#' && next === '!') {
|
|
61
|
+
let text = '';
|
|
62
|
+
while (offset < sourceText.length && sourceText[offset] !== '\n' && sourceText[offset] !== '\r') {
|
|
63
|
+
text += sourceText[offset];
|
|
64
|
+
offset += 1;
|
|
65
|
+
column += 1;
|
|
66
|
+
}
|
|
67
|
+
push(trivia, 'shebang', text, start);
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
60
70
|
if (char === '/' && next === '/') {
|
|
61
71
|
let text = '';
|
|
62
72
|
while (offset < sourceText.length && sourceText[offset] !== '\n' && sourceText[offset] !== '\r') {
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
function dynamicImportEvidenceRecords(line, start, end) {
|
|
2
|
+
const expression = String(line ?? '');
|
|
3
|
+
const records = [];
|
|
4
|
+
for (const call of dynamicImportCalls(expression)) {
|
|
5
|
+
if (!rangesOverlap(start, end, call.start, call.end) && !rangesOverlap(start, end, call.argumentStart, call.argumentEnd)) continue;
|
|
6
|
+
const specifier = normalizeOrderEvidenceText(call.argumentText);
|
|
7
|
+
const specifierKind = dynamicImportSpecifierKind(specifier, call.closed);
|
|
8
|
+
const staticSpecifier = dynamicImportStaticSpecifierEvidence(specifier, specifierKind);
|
|
9
|
+
records.push(compactRecord({
|
|
10
|
+
kind: 'dynamic-import',
|
|
11
|
+
ordinal: records.length + 1,
|
|
12
|
+
text: normalizeOrderEvidenceText(call.text),
|
|
13
|
+
specifierText: specifier,
|
|
14
|
+
specifierKind,
|
|
15
|
+
dynamicImportStaticSpecifierEvidence: staticSpecifier,
|
|
16
|
+
dynamicImportRuntimeResolutionClaim: false,
|
|
17
|
+
dynamicImportResolutionProofRequired: !staticSpecifier,
|
|
18
|
+
runtimeEquivalenceClaim: false
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
return records;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function dynamicImportCalls(expression) {
|
|
25
|
+
const text = String(expression ?? '');
|
|
26
|
+
const records = [];
|
|
27
|
+
let quote;
|
|
28
|
+
let escaped = false;
|
|
29
|
+
for (let index = 0; index < text.length; index += 1) {
|
|
30
|
+
const char = text[index];
|
|
31
|
+
if (quote) {
|
|
32
|
+
if (escaped) escaped = false;
|
|
33
|
+
else if (char === '\\') escaped = true;
|
|
34
|
+
else if (char === quote) quote = undefined;
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (char === '\'' || char === '"' || char === '`') { quote = char; continue; }
|
|
38
|
+
const match = dynamicImportAt(text, index);
|
|
39
|
+
if (!match) continue;
|
|
40
|
+
records.push(match);
|
|
41
|
+
index = Math.max(index, match.end - 1);
|
|
42
|
+
}
|
|
43
|
+
return records;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function dynamicImportAt(text, index) {
|
|
47
|
+
if (text.slice(index, index + 6) !== 'import' || isIdentifierPart(text[index - 1]) || isIdentifierPart(text[index + 6])) return undefined;
|
|
48
|
+
let cursor = index + 6;
|
|
49
|
+
while (/\s/.test(text[cursor] ?? '')) cursor += 1;
|
|
50
|
+
if (text[cursor] !== '(') return undefined;
|
|
51
|
+
const close = matchingParenIndex(text, cursor);
|
|
52
|
+
const end = close === undefined ? statementEnd(text, cursor) : close + 1;
|
|
53
|
+
return {
|
|
54
|
+
start: index,
|
|
55
|
+
text: text.slice(index, end),
|
|
56
|
+
argumentText: firstCallArgumentText(text, cursor + 1, close ?? end),
|
|
57
|
+
argumentStart: cursor + 1,
|
|
58
|
+
argumentEnd: close ?? end,
|
|
59
|
+
end,
|
|
60
|
+
closed: close !== undefined
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function firstCallArgumentText(text, start, end) {
|
|
65
|
+
let depth = 0;
|
|
66
|
+
let quote;
|
|
67
|
+
let escaped = false;
|
|
68
|
+
for (let index = start; index < end; index += 1) {
|
|
69
|
+
const char = text[index];
|
|
70
|
+
if (quote) {
|
|
71
|
+
if (escaped) escaped = false;
|
|
72
|
+
else if (char === '\\') escaped = true;
|
|
73
|
+
else if (char === quote) quote = undefined;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
if (char === '\'' || char === '"' || char === '`') { quote = char; continue; }
|
|
77
|
+
if (char === '(' || char === '[' || char === '{') depth += 1;
|
|
78
|
+
else if (char === ')' || char === ']' || char === '}') depth = Math.max(0, depth - 1);
|
|
79
|
+
else if (char === ',' && depth === 0) return text.slice(start, index);
|
|
80
|
+
}
|
|
81
|
+
return text.slice(start, end);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
function dynamicImportSpecifierKind(specifierText, closed) {
|
|
85
|
+
const text = String(specifierText ?? '').trim();
|
|
86
|
+
if (!closed || !text) return 'unparsed';
|
|
87
|
+
if (isStaticStringLiteral(text) || isStaticTemplateLiteral(text)) return 'literal';
|
|
88
|
+
if (text.startsWith('`')) return 'template';
|
|
89
|
+
if (/^[A-Za-z_$][\w$]*$/.test(text)) return 'identifier';
|
|
90
|
+
if (/^[A-Za-z_$][\w$]*(?:(?:\.|\?\.)[A-Za-z_$][\w$]*|\[[^\]]+\])+$/.test(text)) return 'member';
|
|
91
|
+
if (/\?/.test(text) && /:/.test(text)) return 'conditional';
|
|
92
|
+
if (/[+\-*/%]|\|\||&&|\?\?/.test(text)) return 'binary';
|
|
93
|
+
if (/\)\s*$/.test(text)) return 'call';
|
|
94
|
+
return 'expression';
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function dynamicImportStaticSpecifierEvidence(specifierText, specifierKind) {
|
|
98
|
+
if (specifierKind !== 'literal') return false;
|
|
99
|
+
return isStaticStringLiteral(specifierText) || isStaticTemplateLiteral(specifierText);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function dynamicImportSignatureEvidence(record) {
|
|
103
|
+
return compactRecord({
|
|
104
|
+
specifierKind: record?.specifierKind,
|
|
105
|
+
specifierText: record?.specifierText,
|
|
106
|
+
dynamicImportStaticSpecifierEvidence: record?.dynamicImportStaticSpecifierEvidence,
|
|
107
|
+
dynamicImportRuntimeResolutionClaim: record?.dynamicImportRuntimeResolutionClaim,
|
|
108
|
+
dynamicImportResolutionProofRequired: record?.dynamicImportResolutionProofRequired,
|
|
109
|
+
runtimeEquivalenceClaim: record?.runtimeEquivalenceClaim
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function matchingParenIndex(line, open) {
|
|
114
|
+
if (open < 0) return undefined;
|
|
115
|
+
let depth = 0;
|
|
116
|
+
let quote;
|
|
117
|
+
let escaped = false;
|
|
118
|
+
for (let index = open; index < line.length; index += 1) {
|
|
119
|
+
const char = line[index];
|
|
120
|
+
if (quote) {
|
|
121
|
+
if (escaped) escaped = false;
|
|
122
|
+
else if (char === '\\') escaped = true;
|
|
123
|
+
else if (char === quote) quote = undefined;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (char === '\'' || char === '"' || char === '`') { quote = char; continue; }
|
|
127
|
+
if (char === '(') depth += 1;
|
|
128
|
+
else if (char === ')' && --depth === 0) return index;
|
|
129
|
+
}
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function rangesOverlap(leftStart, leftEnd, rightStart, rightEnd) { return Math.max(leftStart, rightStart) < Math.min(leftEnd, rightEnd); }
|
|
134
|
+
function normalizeOrderEvidenceText(value) { return String(value ?? '').replace(/\s+/g, ' ').trim(); }
|
|
135
|
+
function isStaticStringLiteral(value) { const text = String(value ?? '').trim(), quote = text[0]; return (quote === '\'' || quote === '"') && text.endsWith(quote); }
|
|
136
|
+
function isStaticTemplateLiteral(value) { const text = String(value ?? '').trim(); return text.startsWith('`') && text.endsWith('`') && !text.includes('${'); }
|
|
137
|
+
function isIdentifierPart(char) { return /[A-Za-z0-9_$]/.test(char ?? ''); }
|
|
138
|
+
function statementEnd(line, start) { const semicolon = line.indexOf(';', start); return semicolon === -1 ? line.length : semicolon + 1; }
|
|
139
|
+
function compactRecord(record) { return Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined && (!Array.isArray(value) || value.length > 0))); }
|
|
140
|
+
|
|
141
|
+
export { dynamicImportEvidenceRecords, dynamicImportSignatureEvidence };
|
|
@@ -9,6 +9,7 @@ import { reachabilityOrderEvidence } from './semantic-import-runtime-reachabilit
|
|
|
9
9
|
import { throwOrderEvidenceRecords } from './semantic-import-runtime-throw-evidence.js';
|
|
10
10
|
import { promiseCombinatorEvidenceRecords } from './semantic-import-runtime-promise-combinator-evidence.js';
|
|
11
11
|
import { promiseChainEvidenceRecords } from './semantic-import-runtime-promise-chain-evidence.js';
|
|
12
|
+
import { dynamicImportEvidenceRecords, dynamicImportSignatureEvidence } from './semantic-import-runtime-dynamic-import-evidence.js';
|
|
12
13
|
function semanticFactOrderInfo(groups) {
|
|
13
14
|
const bySubject = new Map();
|
|
14
15
|
const info = new Map();
|
|
@@ -61,6 +62,7 @@ function semanticFactRuntimeOrderEvidence(sourceText, group, fact, spanInfo, ord
|
|
|
61
62
|
sameLineAwaitOrder: sameLineEvidence.awaitOrder,
|
|
62
63
|
sameLineOptionalChain: sameLineEvidence.optionalChain,
|
|
63
64
|
sameLineConditionalExpression: sameLineEvidence.conditionalExpression,
|
|
65
|
+
sameLineDynamicImport: sameLineEvidence.dynamicImport,
|
|
64
66
|
sameLinePromiseCombinator: sameLineEvidence.promiseCombinator,
|
|
65
67
|
sameLinePromiseChain: sameLineEvidence.promiseChain,
|
|
66
68
|
sameLineThrow: sameLineEvidence.throw,
|
|
@@ -85,6 +87,7 @@ function semanticFactRuntimeOrderSignatureEvidence(evidence) {
|
|
|
85
87
|
sameLineAwaitOrder: evidence?.sameLineAwaitOrder,
|
|
86
88
|
sameLineOptionalChain: evidence?.sameLineOptionalChain,
|
|
87
89
|
sameLineConditionalExpression: evidence?.sameLineConditionalExpression,
|
|
90
|
+
sameLineDynamicImport: evidence?.sameLineDynamicImport?.map(dynamicImportSignatureEvidence),
|
|
88
91
|
sameLinePromiseCombinator: evidence?.sameLinePromiseCombinator,
|
|
89
92
|
sameLinePromiseChain: evidence?.sameLinePromiseChain,
|
|
90
93
|
sameLineThrow: evidence?.sameLineThrow,
|
|
@@ -100,7 +103,7 @@ function sameLineRuntimeOrderEvidence(line, start, end) {
|
|
|
100
103
|
const prefix = String(line ?? '').slice(0, start);
|
|
101
104
|
const controlFlow = controlHeadEvidenceRecords(prefix), shortCircuit = shortCircuitEvidenceRecords(prefix), awaitOrder = awaitOrderEvidenceRecords(prefix);
|
|
102
105
|
const optionalChain = optionalChainEvidenceRecords(line, start, end), conditionalExpression = conditionalExpressionEvidenceRecords(line, start, end);
|
|
103
|
-
const promiseCombinator = promiseCombinatorEvidenceRecords(line, start, end), promiseChain = promiseChainEvidenceRecords(line, start, end), throwOrder = throwOrderEvidenceRecords(line, start, end);
|
|
106
|
+
const dynamicImport = dynamicImportEvidenceRecords(line, start, end), promiseCombinator = promiseCombinatorEvidenceRecords(line, start, end), promiseChain = promiseChainEvidenceRecords(line, start, end), throwOrder = throwOrderEvidenceRecords(line, start, end);
|
|
104
107
|
return {
|
|
105
108
|
controlFlow: controlFlow.length ? controlFlow : undefined,
|
|
106
109
|
shortCircuit: shortCircuit.length ? shortCircuit : undefined,
|
|
@@ -108,6 +111,7 @@ function sameLineRuntimeOrderEvidence(line, start, end) {
|
|
|
108
111
|
awaitOrder: awaitOrder.length ? awaitOrder : undefined,
|
|
109
112
|
optionalChain: optionalChain.length ? optionalChain : undefined,
|
|
110
113
|
conditionalExpression: conditionalExpression.length ? conditionalExpression : undefined,
|
|
114
|
+
dynamicImport: dynamicImport.length ? dynamicImport : undefined,
|
|
111
115
|
promiseCombinator: promiseCombinator.length ? promiseCombinator : undefined,
|
|
112
116
|
promiseChain: promiseChain.length ? promiseChain : undefined,
|
|
113
117
|
throw: throwOrder.length ? true : /\bthrow\b/.test(prefix) || undefined,
|
|
@@ -126,7 +130,6 @@ function controlFlowOrderEvidence(line, lineNumber, group) {
|
|
|
126
130
|
loop: records.filter((record) => record.kind === 'loop')
|
|
127
131
|
};
|
|
128
132
|
}
|
|
129
|
-
|
|
130
133
|
function optionalChainEvidenceRecords(line, start, end) {
|
|
131
134
|
const expression = String(line ?? '').slice(Math.max(0, start), Math.max(start, end));
|
|
132
135
|
const matches = [...expression.matchAll(/\?\.(?:\s*\(|\s*[A-Za-z_$][\w$]*|\s*\[)/g)];
|
|
@@ -136,7 +139,6 @@ function optionalChainEvidenceRecords(line, start, end) {
|
|
|
136
139
|
text: normalizeOrderEvidenceText(expression.slice(Math.max(0, match.index - 24), match.index + match[0].length + 24))
|
|
137
140
|
}));
|
|
138
141
|
}
|
|
139
|
-
|
|
140
142
|
function awaitOrderEvidenceRecords(prefix) {
|
|
141
143
|
const text = String(prefix ?? '');
|
|
142
144
|
const tokens = awaitTokenIndexes(text);
|
|
@@ -164,7 +166,6 @@ function awaitTokenIndexes(text) {
|
|
|
164
166
|
}
|
|
165
167
|
return indexes;
|
|
166
168
|
}
|
|
167
|
-
|
|
168
169
|
function shortCircuitEvidenceRecords(prefix) {
|
|
169
170
|
const text = String(prefix ?? '');
|
|
170
171
|
const operators = shortCircuitOperators(text);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapeshift-labs/frontier-lang-compiler",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.162",
|
|
4
4
|
"description": "Compiler facade for Frontier Lang source documents and language projection adapters.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -63,7 +63,7 @@
|
|
|
63
63
|
"dependencies": {
|
|
64
64
|
"@shapeshift-labs/frontier-lang-c": "0.2.9",
|
|
65
65
|
"@shapeshift-labs/frontier-lang-checker": "0.3.8",
|
|
66
|
-
"@shapeshift-labs/frontier-lang-css": "^0.1.
|
|
66
|
+
"@shapeshift-labs/frontier-lang-css": "^0.1.9",
|
|
67
67
|
"@shapeshift-labs/frontier-lang-html": "^0.1.6",
|
|
68
68
|
"@shapeshift-labs/frontier-lang-javascript": "0.2.9",
|
|
69
69
|
"@shapeshift-labs/frontier-lang-kernel": "0.3.12",
|