@shapeshift-labs/frontier-lang-compiler 0.2.102 → 0.2.104
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/README.md +13 -0
- package/dist/declarations/bidirectional-target-change-source-edit.d.ts +30 -0
- package/dist/declarations/bidirectional-target-change.d.ts +10 -0
- package/dist/declarations/js-ts-safe-member-merge.d.ts +58 -0
- package/dist/declarations/js-ts-safe-merge.d.ts +120 -0
- package/dist/declarations/js-ts-semantic-conflict-sidecars.d.ts +235 -0
- package/dist/declarations/js-ts-semantic-merge-contracts.d.ts +287 -0
- package/dist/declarations/js-ts-semantic-merge.d.ts +4 -0
- package/dist/declarations/native-import-losses.d.ts +3 -0
- package/dist/declarations/native-project-admission-semantic-evidence.d.ts +34 -0
- package/dist/declarations/native-project-admission.d.ts +6 -10
- package/dist/declarations/semantic-edit-replay-diagnostics.d.ts +12 -0
- package/dist/declarations/semantic-edit-script.d.ts +10 -4
- package/dist/declarations/semantic-patch-bundle-index.d.ts +45 -0
- package/dist/declarations/semantic-patch-bundle-overlaps.d.ts +1 -0
- package/dist/declarations/semantic-patch-bundle.d.ts +6 -4
- package/dist/declarations/semantic-sidecar-example.d.ts +18 -0
- package/dist/declarations/semantic-transform-identity.d.ts +3 -0
- package/dist/declarations/source-preservation.d.ts +72 -0
- package/dist/declarations/universal-capability.d.ts +4 -0
- package/dist/declarations/universal-conversion-artifacts.d.ts +61 -1
- package/dist/declarations/universal-conversion-compact-counts.d.ts +51 -0
- package/dist/declarations/universal-conversion-plan.d.ts +6 -1
- package/dist/declarations/universal-representation-coverage.d.ts +90 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/internal/index-impl/bidirectionalExactSourceBackprojection.js +199 -0
- package/dist/internal/index-impl/bidirectionalSameLanguageSourceProjection.js +112 -0
- package/dist/internal/index-impl/bidirectionalSourceEditProjection.js +319 -0
- package/dist/internal/index-impl/bidirectionalSourceEditProjectionArtifacts.js +67 -0
- package/dist/internal/index-impl/bidirectionalTargetChangeRecordInternals.js +17 -5
- package/dist/internal/index-impl/bidirectionalTargetRoundtripEvidence.js +58 -20
- package/dist/internal/index-impl/createBidirectionalTargetChangeRecord.js +60 -7
- package/dist/internal/index-impl/createLightweightNativeImport.js +1 -0
- package/dist/internal/index-impl/createNativeSourcePreservation.js +28 -2
- package/dist/internal/index-impl/createProjectImportAdmissionRecord.js +14 -2
- package/dist/internal/index-impl/diffNativeSymbols.js +82 -1
- package/dist/internal/index-impl/nativeChangeProjectionSourceMapLinks.js +2 -0
- package/dist/internal/index-impl/projectImportAdmissionImportEvidence.js +1 -1
- package/dist/internal/index-impl/projectImportAdmissionSemanticWarnings.js +178 -0
- package/dist/internal/index-impl/projectImportAdmissionSummaries.js +22 -3
- package/dist/internal/index-impl/projectSemanticEditScriptToSource.js +54 -69
- package/dist/internal/index-impl/replaySemanticEditLineEndings.js +34 -0
- package/dist/internal/index-impl/replaySemanticEditProjection.js +78 -78
- package/dist/internal/index-impl/semanticEditBundleAdmission.js +7 -3
- package/dist/internal/index-impl/semanticEditBundleIndex.js +47 -1
- package/dist/internal/index-impl/semanticEditExplicitSourceReplacement.js +40 -0
- package/dist/internal/index-impl/semanticEditImportProjection.js +53 -0
- package/dist/internal/index-impl/semanticEditOperationCoverage.js +33 -3
- package/dist/internal/index-impl/semanticEditProjectionRecord.js +108 -0
- package/dist/internal/index-impl/semanticEditReplayAnchors.js +63 -0
- package/dist/internal/index-impl/semanticEditReplayDiagnostics.js +39 -0
- package/dist/internal/index-impl/semanticEditReplaySourceReplacement.js +85 -0
- package/dist/internal/index-impl/semanticEditScripts.js +4 -0
- package/dist/internal/index-impl/semanticEditSourceRanges.js +32 -0
- package/dist/internal/index-impl/semanticIndexFromNativeDeclarations.js +1 -0
- package/dist/internal/index-impl/semanticPatchBundleAdmission.js +92 -9
- package/dist/internal/index-impl/semanticPatchBundleOverlaps.js +33 -16
- package/dist/internal/index-impl/semanticPatchBundleRecords.js +16 -0
- package/dist/internal/index-impl/semanticPatchBundleSourceRecords.js +2 -0
- package/dist/internal/index-impl/semanticSidecarQuality.js +111 -0
- package/dist/internal/index-impl/semanticSourceEditDedupe.js +69 -9
- package/dist/internal/index-impl/semanticTransformIdentityRecords.js +85 -9
- package/dist/js-ts-safe-member-merge-result.js +158 -0
- package/dist/js-ts-safe-member-merge.js +202 -0
- package/dist/js-ts-safe-merge-analyze.js +279 -0
- package/dist/js-ts-safe-merge-constants.js +50 -0
- package/dist/js-ts-safe-merge-context.js +118 -0
- package/dist/js-ts-safe-merge-ledger-validation.js +92 -0
- package/dist/js-ts-safe-merge-ledger.js +85 -0
- package/dist/js-ts-safe-merge-parse-declarations.js +210 -0
- package/dist/js-ts-safe-merge-parse-statements.js +155 -0
- package/dist/js-ts-safe-merge-plan.js +190 -0
- package/dist/js-ts-safe-merge.js +175 -0
- package/dist/js-ts-semantic-conflict-sidecar-constants.js +77 -0
- package/dist/js-ts-semantic-conflict-sidecar-detectors.js +195 -0
- package/dist/js-ts-semantic-conflict-sidecar-normalize.js +203 -0
- package/dist/js-ts-semantic-conflict-sidecar-utils.js +190 -0
- package/dist/js-ts-semantic-conflict-sidecars.js +81 -0
- package/dist/js-ts-semantic-merge-contract-helpers.js +128 -0
- package/dist/js-ts-semantic-merge-contracts.js +217 -0
- package/dist/js-ts-semantic-merge-member-containers.js +100 -0
- package/dist/js-ts-semantic-merge-member-keys.js +142 -0
- package/dist/js-ts-semantic-merge-member-segments.js +185 -0
- package/dist/js-ts-semantic-merge-member-source.js +64 -0
- package/dist/js-ts-semantic-merge-member-utils.js +18 -0
- package/dist/js-ts-semantic-merge-parse.js +15 -0
- package/dist/js-ts-semantic-merge.js +21 -0
- package/dist/lightweight-dependency-effects.js +51 -0
- package/dist/lightweight-dependency-language.js +12 -1
- package/dist/lightweight-dependency-relations.js +14 -27
- package/dist/native-region-scanner-core.js +33 -1
- package/dist/native-region-scanner-csharp.js +151 -0
- package/dist/native-region-scanner-dart.js +91 -0
- package/dist/native-region-scanner-dynamic.js +21 -151
- package/dist/native-region-scanner-functional.js +40 -13
- package/dist/native-region-scanner-java.js +97 -0
- package/dist/native-region-scanner-js-class.js +100 -0
- package/dist/native-region-scanner-js-helpers.js +28 -86
- package/dist/native-region-scanner-js-imports.js +121 -1
- package/dist/native-region-scanner-js-nested.js +96 -8
- package/dist/native-region-scanner-js-structure.js +27 -0
- package/dist/native-region-scanner-js-types.js +99 -0
- package/dist/native-region-scanner-js.js +70 -118
- package/dist/native-region-scanner-kotlin.js +94 -0
- package/dist/native-region-scanner-main.js +15 -181
- package/dist/native-region-scanner-php.js +80 -0
- package/dist/native-region-scanner-python.js +62 -0
- package/dist/native-region-scanner-ruby.js +72 -0
- package/dist/native-region-scanner-scala.js +91 -0
- package/dist/native-region-scanner-spans.js +74 -0
- package/dist/native-region-scanner-swift.js +155 -0
- package/dist/native-region-scanner.js +14 -10
- package/dist/native-source-ledger-helpers.js +195 -0
- package/dist/native-source-ledger.js +306 -0
- package/dist/native-source-preservation-scanner.js +4 -0
- package/dist/semantic-import-callsite-regions.js +136 -0
- package/dist/semantic-import-effect-regions.js +283 -0
- package/dist/semantic-import-regions.js +11 -2
- package/dist/semantic-import-sidecar-entry.js +16 -2
- package/dist/semantic-import-sidecar-types.d.ts +2 -0
- package/dist/semantic-sidecar-example.js +68 -0
- package/dist/universal-capability-matrix.js +23 -0
- package/dist/universal-conversion-artifact-query.js +79 -2
- package/dist/universal-conversion-artifact-semantic-edit.js +103 -0
- package/dist/universal-conversion-artifact-summary.js +33 -1
- package/dist/universal-conversion-artifacts.js +13 -48
- package/dist/universal-conversion-plan-scoring.js +21 -1
- package/dist/universal-conversion-plan-summary.js +30 -0
- package/dist/universal-conversion-plan.js +25 -9
- package/dist/universal-conversion-route-metadata.js +96 -0
- package/dist/universal-conversion-route-operations.js +7 -0
- package/dist/universal-representation-coverage.js +193 -0
- package/package.json +1 -1
|
@@ -2,21 +2,25 @@ import { normalizeSemanticMergeReadiness, uniqueStrings } from '../../native-imp
|
|
|
2
2
|
|
|
3
3
|
export function createSemanticPatchBundleAdmission(input = {}, context = {}) {
|
|
4
4
|
const transformAdmission = semanticTransformAdmission(context);
|
|
5
|
-
const semanticEditAdmission =
|
|
5
|
+
const semanticEditAdmission = semanticEditAdmissionWithReplayRequirement(
|
|
6
|
+
context.semanticEditAdmission ?? { status: 'none', action: 'none', readiness: 'needs-review', reasonCodes: [] }
|
|
7
|
+
);
|
|
6
8
|
const evidenceAdmission = autoMergeEvidenceAdmission(context, { transformAdmission, semanticEditAdmission });
|
|
7
9
|
const fallbackReadiness = fallbackAdmissionReadiness(transformAdmission, semanticEditAdmission, evidenceAdmission, context.readiness);
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
+
const requestedReadiness = normalizeSemanticMergeReadiness(input.readiness) ?? input.readiness;
|
|
11
|
+
const inputReadiness = fallbackReadiness === 'blocked' ? 'blocked' : requestedReadiness ?? fallbackReadiness;
|
|
12
|
+
const positiveApply = !hasSkipReadyAction(semanticEditAdmission) && hasPositiveApplyAction(transformAdmission, semanticEditAdmission);
|
|
13
|
+
const readiness = positiveApply && evidenceAdmission.action !== 'admit'
|
|
10
14
|
? evidenceAdmission.readiness
|
|
11
15
|
: inputReadiness;
|
|
12
16
|
const computedStatus = admissionStatusForReadiness(readiness, transformAdmission, semanticEditAdmission, evidenceAdmission);
|
|
13
|
-
const status = input.status
|
|
17
|
+
const status = safePatchBundleStatus(input.status, computedStatus);
|
|
14
18
|
const computedAutoApplyCandidate = status === 'admitted' &&
|
|
15
|
-
|
|
19
|
+
positiveApply &&
|
|
16
20
|
evidenceAdmission.action === 'admit';
|
|
17
21
|
const autoApplyCandidate = input.autoApplyCandidate === true ? computedAutoApplyCandidate : input.autoApplyCandidate ?? computedAutoApplyCandidate;
|
|
18
22
|
const admittedWithoutPositiveProof = status === 'admitted' &&
|
|
19
|
-
|
|
23
|
+
positiveApply &&
|
|
20
24
|
evidenceAdmission.action !== 'admit';
|
|
21
25
|
return compactRecord({
|
|
22
26
|
status,
|
|
@@ -35,7 +39,7 @@ export function createSemanticPatchBundleAdmission(input = {}, context = {}) {
|
|
|
35
39
|
...strings(semanticEditAdmission.reasonCodes),
|
|
36
40
|
...strings(evidenceAdmission.reasonCodes)
|
|
37
41
|
].filter(Boolean)),
|
|
38
|
-
conflictKeys: uniqueStrings([...strings(input.conflictKeys), ...context.conflictKeys]),
|
|
42
|
+
conflictKeys: uniqueStrings([...strings(input.conflictKeys), ...strings(context.conflictKeys)]),
|
|
39
43
|
admittedAt: input.admittedAt,
|
|
40
44
|
reviewerId: input.reviewerId,
|
|
41
45
|
evidenceIds: uniqueStrings([...strings(input.evidenceIds), ...strings(transformAdmission.evidenceIds), ...strings(evidenceAdmission.evidenceIds)]),
|
|
@@ -70,10 +74,15 @@ function semanticTransformAdmission(context) {
|
|
|
70
74
|
transformKeys: strings(index.semanticTransformKeys),
|
|
71
75
|
contentHashes: strings(index.semanticTransformContentHashes),
|
|
72
76
|
projectionIdentityHashes: strings(index.projectionIdentityHashes),
|
|
77
|
+
baseHashes: strings(index.transformBaseHashes),
|
|
78
|
+
targetHashes: strings(index.transformTargetHashes),
|
|
73
79
|
sourceLanguages: strings(index.transformSourceLanguages),
|
|
74
80
|
targetLanguages: strings(index.transformTargetLanguages),
|
|
75
81
|
sourcePaths: strings(index.transformSourcePaths),
|
|
76
82
|
targetPaths: strings(index.transformTargetPaths),
|
|
83
|
+
sourceMapIds: strings(index.transformSourceMapIds),
|
|
84
|
+
sourceMapLinkIds: strings(index.transformSourceMapLinkIds),
|
|
85
|
+
sourceMapMappingIds: strings(index.transformSourceMapMappingIds),
|
|
77
86
|
evidenceIds: strings(index.semanticTransformEvidenceIds)
|
|
78
87
|
});
|
|
79
88
|
}
|
|
@@ -106,8 +115,12 @@ function autoMergeEvidenceAdmission(context, admissions) {
|
|
|
106
115
|
...array(context.source?.semanticPatch?.evidence),
|
|
107
116
|
...array(context.mergeCandidate?.evidence)
|
|
108
117
|
]);
|
|
109
|
-
const
|
|
110
|
-
|
|
118
|
+
const skipReady = hasSkipReadyAction(admissions.semanticEditAdmission);
|
|
119
|
+
const positiveApply = !skipReady &&
|
|
120
|
+
hasPositiveApplyAttempt(admissions.transformAdmission, admissions.semanticEditAdmission);
|
|
121
|
+
if (!positiveApply) return skipReady
|
|
122
|
+
? skipEvidenceAdmission(evidence)
|
|
123
|
+
: { status: 'none', action: 'none', readiness: 'needs-review', reasonCodes: [], evidenceIds: evidenceIds(evidence) };
|
|
111
124
|
const summary = summarizeAutoMergeEvidence(evidence);
|
|
112
125
|
const blocked = summary.failed > 0 || summary.conflict > 0;
|
|
113
126
|
const ready = !blocked && summary.stale === 0 && summary.passed > 0;
|
|
@@ -125,6 +138,23 @@ function autoMergeEvidenceAdmission(context, admissions) {
|
|
|
125
138
|
});
|
|
126
139
|
}
|
|
127
140
|
|
|
141
|
+
function skipEvidenceAdmission(evidence) {
|
|
142
|
+
const summary = summarizeAutoMergeEvidence(evidence);
|
|
143
|
+
const blocked = summary.failed > 0 || summary.conflict > 0;
|
|
144
|
+
const status = blocked ? 'blocked' : summary.stale > 0 ? 'stale' : summary.passed > 0 ? 'ready' : 'none';
|
|
145
|
+
return compactRecord({
|
|
146
|
+
status,
|
|
147
|
+
action: blocked ? 'block' : status === 'stale' ? 'rerun-semantic-import' : status === 'ready' ? 'skip' : 'none',
|
|
148
|
+
readiness: blocked ? 'blocked' : status === 'ready' ? 'ready' : 'needs-review',
|
|
149
|
+
reasonCodes: status === 'none' ? [] : autoMergeEvidenceReasonCodes(summary, status),
|
|
150
|
+
evidenceIds: summary.evidenceIds,
|
|
151
|
+
passed: summary.passed,
|
|
152
|
+
failed: summary.failed,
|
|
153
|
+
conflict: summary.conflict,
|
|
154
|
+
stale: summary.stale
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
128
158
|
function summarizeAutoMergeEvidence(evidence) {
|
|
129
159
|
const testLike = evidence.filter(isAutoMergeTestEvidence);
|
|
130
160
|
const failed = testLike.filter((record) => evidenceStatus(record, ['failed', 'failure', 'error', 'blocked', 'rejected']));
|
|
@@ -155,6 +185,7 @@ function fallbackAdmissionReadiness(transformAdmission, semanticEditAdmission, e
|
|
|
155
185
|
if ([transformAdmission.readiness, semanticEditAdmission.readiness, evidenceAdmission.readiness].includes('blocked')) return 'blocked';
|
|
156
186
|
if (hasSkipReadyAction(semanticEditAdmission)) return 'ready';
|
|
157
187
|
if (hasPositiveApplyAction(transformAdmission, semanticEditAdmission)) return evidenceAdmission.action === 'admit' ? 'ready' : evidenceAdmission.readiness;
|
|
188
|
+
if (semanticEditAdmission.action === 'review' || semanticEditAdmission.status === 'needs-review') return 'needs-review';
|
|
158
189
|
return fallback;
|
|
159
190
|
}
|
|
160
191
|
|
|
@@ -164,6 +195,12 @@ function admissionStatusForReadiness(readiness, transformAdmission, semanticEdit
|
|
|
164
195
|
return readiness === 'needs-review' ? 'needs-review' : 'proposed';
|
|
165
196
|
}
|
|
166
197
|
|
|
198
|
+
function safePatchBundleStatus(requested, computed) {
|
|
199
|
+
if (computed === 'blocked' && requested !== 'rejected') return 'blocked';
|
|
200
|
+
if (requested === 'admitted' && computed !== 'admitted') return computed;
|
|
201
|
+
return requested ?? computed;
|
|
202
|
+
}
|
|
203
|
+
|
|
167
204
|
function hasAdmissibleReadyAction(transformAdmission, semanticEditAdmission, evidenceAdmission) {
|
|
168
205
|
return hasSkipReadyAction(semanticEditAdmission) ||
|
|
169
206
|
(hasPositiveApplyAction(transformAdmission, semanticEditAdmission) && evidenceAdmission.action === 'admit');
|
|
@@ -183,6 +220,51 @@ function hasSkipReadyAction(semanticEditAdmission) {
|
|
|
183
220
|
return semanticEditAdmission.action === 'skip' && semanticEditAdmission.readiness === 'ready' && semanticEditAdmission.reviewRequired === false;
|
|
184
221
|
}
|
|
185
222
|
|
|
223
|
+
function semanticEditAdmissionWithReplayRequirement(admission) {
|
|
224
|
+
if (!requiresSemanticEditReplay(admission) || hasAcceptedCleanSemanticEditReplay(admission)) return admission;
|
|
225
|
+
return compactRecord({
|
|
226
|
+
...admission,
|
|
227
|
+
status: 'needs-review',
|
|
228
|
+
action: 'review',
|
|
229
|
+
readiness: 'needs-review',
|
|
230
|
+
reviewRequired: true,
|
|
231
|
+
autoApplyCandidate: false,
|
|
232
|
+
reasonCodes: uniqueStrings([
|
|
233
|
+
...strings(admission.reasonCodes).filter((reason) => reason !== 'semantic-edit-positive-auto-merge-proof'),
|
|
234
|
+
...semanticEditReplayRequirementReasonCodes(admission)
|
|
235
|
+
])
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function requiresSemanticEditReplay(admission) {
|
|
240
|
+
return admission.action === 'admit' ||
|
|
241
|
+
admission.autoApplyCandidate === true ||
|
|
242
|
+
admission.status === 'ready' ||
|
|
243
|
+
strings(admission.reasonCodes).includes('semantic-edit-positive-auto-merge-proof');
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function hasAcceptedCleanSemanticEditReplay(admission) {
|
|
247
|
+
const summary = admission.summary ?? {};
|
|
248
|
+
const acceptedClean = count(summary.acceptedClean);
|
|
249
|
+
const alreadyApplied = count(summary.alreadyApplied);
|
|
250
|
+
const replays = count(summary.replays);
|
|
251
|
+
return acceptedClean > 0 && replays > 0 && acceptedClean + alreadyApplied === replays;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function semanticEditReplayRequirementReasonCodes(admission) {
|
|
255
|
+
const summary = admission.summary ?? {};
|
|
256
|
+
const scripts = count(summary.scripts);
|
|
257
|
+
const projections = count(summary.projections);
|
|
258
|
+
const replays = count(summary.replays);
|
|
259
|
+
const acceptedClean = count(summary.acceptedClean);
|
|
260
|
+
return [
|
|
261
|
+
scripts > 0 && projections === 0 ? 'semantic-edit-projection-missing' : undefined,
|
|
262
|
+
(scripts > 0 || projections > 0) && replays === 0 ? 'semantic-edit-replay-missing' : undefined,
|
|
263
|
+
replays > 0 && acceptedClean === 0 ? 'semantic-edit-replay-accepted-clean-missing' : undefined,
|
|
264
|
+
'semantic-edit-replay-required'
|
|
265
|
+
].filter(Boolean);
|
|
266
|
+
}
|
|
267
|
+
|
|
186
268
|
function hasCrossLanguageTransform(index) {
|
|
187
269
|
const source = new Set(strings(index.transformSourceLanguages));
|
|
188
270
|
return strings(index.transformTargetLanguages).some((target) => !source.has(target));
|
|
@@ -211,6 +293,7 @@ function uniqueEvidenceRecords(records) {
|
|
|
211
293
|
}
|
|
212
294
|
|
|
213
295
|
function evidenceIds(evidence) { return uniqueStrings(evidence.map((record) => record.id)); }
|
|
296
|
+
function count(value) { const number = Number(value ?? 0); return Number.isFinite(number) ? number : 0; }
|
|
214
297
|
function array(value) { if (value === undefined || value === null) return []; return Array.isArray(value) ? value : [value]; }
|
|
215
298
|
function strings(value) { return array(value).map((entry) => String(entry ?? '')).filter(Boolean); }
|
|
216
299
|
function compactRecord(value) { return Object.fromEntries(Object.entries(value ?? {}).filter(([, entry]) => entry !== undefined && (!Array.isArray(entry) || entry.length > 0))); }
|
|
@@ -65,7 +65,8 @@ export function compareSemanticPatchBundleRecords(left={},right={},options={}){
|
|
|
65
65
|
semanticSignals:shared.semanticEditKeys.length+shared.semanticIdentityHashes.length+shared.sourceIdentityHashes.length+shared.semanticTransformIdentityHashes.length+shared.projectionIdentityHashes.length,
|
|
66
66
|
sourceSignals:shared.regionKeys.length+shared.conflictKeys.length+shared.sourcePaths.length+shared.semanticEditReplayCurrentHashes.length,
|
|
67
67
|
baseHashMismatch:admission.reasonCodes.includes('base-hash-mismatch'),
|
|
68
|
-
targetHashMismatch:admission.reasonCodes.includes('target-hash-mismatch')
|
|
68
|
+
targetHashMismatch:admission.reasonCodes.includes('target-hash-mismatch'),
|
|
69
|
+
replayOutputHashMismatch:admission.reasonCodes.includes('replay-output-hash-mismatch')
|
|
69
70
|
},
|
|
70
71
|
metadata:compactRecord(options.metadata)
|
|
71
72
|
};
|
|
@@ -110,21 +111,32 @@ function sharedIndex(left,right,options){
|
|
|
110
111
|
baseHashes:intersect(left.baseHashes,right.baseHashes),
|
|
111
112
|
targetHashes:intersect(left.targetHashes,right.targetHashes)
|
|
112
113
|
};
|
|
113
|
-
const
|
|
114
|
-
const
|
|
115
|
-
return{
|
|
114
|
+
const semanticKeyIndependent=hasDisjointSemanticEditScope(left,right,shared);
|
|
115
|
+
const scopedShared={
|
|
116
116
|
...shared,
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
117
|
+
sourcePaths:semanticKeyIndependent?[]:shared.sourcePaths
|
|
118
|
+
};
|
|
119
|
+
const scopedEdit=hasSharedEditScope(scopedShared);
|
|
120
|
+
const scopedSource=hasSharedSourceScope(scopedShared);
|
|
121
|
+
return{
|
|
122
|
+
...scopedShared,
|
|
123
|
+
operationContentHashes:scopedEdit?scopedShared.operationContentHashes:[],
|
|
124
|
+
editContentHashes:scopedEdit?scopedShared.editContentHashes:[],
|
|
125
|
+
semanticEditKeys:scopedSource?scopedShared.semanticEditKeys:[],
|
|
126
|
+
semanticIdentityHashes:scopedSource?scopedShared.semanticIdentityHashes:[],
|
|
127
|
+
semanticEditReplayCurrentHashes:scopedSource?scopedShared.semanticEditReplayCurrentHashes:[],
|
|
128
|
+
semanticEditReplayOutputHashes:scopedEdit?scopedShared.semanticEditReplayOutputHashes:[],
|
|
129
|
+
semanticTransformContentHashes:scopedShared.projectionIdentityHashes.length?scopedShared.semanticTransformContentHashes:[],
|
|
130
|
+
semanticTransformIdentityHashes:scopedShared.projectionIdentityHashes.length?scopedShared.semanticTransformIdentityHashes:[]
|
|
125
131
|
};
|
|
126
132
|
}
|
|
127
133
|
|
|
134
|
+
function hasDisjointSemanticEditScope(left,right,shared){
|
|
135
|
+
return Boolean(shared.sourcePaths.length&&left.semanticEditKeys.length&&right.semanticEditKeys.length
|
|
136
|
+
&&shared.semanticEditKeys.length===0&&shared.regionKeys.length===0&&shared.conflictKeys.length===0
|
|
137
|
+
&&shared.semanticIdentityHashes.length===0&&shared.sourceIdentityHashes.length===0);
|
|
138
|
+
}
|
|
139
|
+
|
|
128
140
|
function hasSharedEditScope(shared){
|
|
129
141
|
return Boolean(shared.regionKeys.length||shared.conflictKeys.length||shared.sourceIdentityHashes.length
|
|
130
142
|
||(shared.sourcePaths.length&&(shared.semanticEditKeys.length||shared.semanticIdentityHashes.length)));
|
|
@@ -135,7 +147,10 @@ function hasSharedSourceScope(shared){
|
|
|
135
147
|
}
|
|
136
148
|
|
|
137
149
|
function overlapAdmission(shared,{leftIndex,rightIndex,options}){
|
|
138
|
-
const
|
|
150
|
+
const baseHashMismatch=disjointNonEmpty(leftIndex.baseHashes,rightIndex.baseHashes);
|
|
151
|
+
const targetHashMismatch=disjointNonEmpty(leftIndex.targetHashes,rightIndex.targetHashes);
|
|
152
|
+
const replayOutputHashMismatch=disjointNonEmpty(leftIndex.semanticEditReplayOutputHashes,rightIndex.semanticEditReplayOutputHashes);
|
|
153
|
+
const hashMismatch=baseHashMismatch||targetHashMismatch||replayOutputHashMismatch;
|
|
139
154
|
const sourceRelated=shared.sourcePaths.length||shared.regionKeys.length||shared.conflictKeys.length||shared.sourceIdentityHashes.length;
|
|
140
155
|
const editContent=shared.operationContentHashes.length||shared.editContentHashes.length||shared.semanticEditReplayOutputHashes.length;
|
|
141
156
|
const transformContent=shared.semanticTransformContentHashes.length&&shared.projectionIdentityHashes.length;
|
|
@@ -158,8 +173,9 @@ function overlapAdmission(shared,{leftIndex,rightIndex,options}){
|
|
|
158
173
|
shared.regionKeys.length?'same-region-key':undefined,
|
|
159
174
|
shared.conflictKeys.length?'same-conflict-key':undefined,
|
|
160
175
|
shared.sourcePaths.length?'same-source-path':undefined,
|
|
161
|
-
status!=='independent'&&
|
|
162
|
-
status!=='independent'&&
|
|
176
|
+
status!=='independent'&&baseHashMismatch?'base-hash-mismatch':undefined,
|
|
177
|
+
status!=='independent'&&targetHashMismatch?'target-hash-mismatch':undefined,
|
|
178
|
+
status!=='independent'&&replayOutputHashMismatch?'replay-output-hash-mismatch':undefined
|
|
163
179
|
]);
|
|
164
180
|
return{
|
|
165
181
|
status,
|
|
@@ -223,7 +239,8 @@ function matchesOverlap(overlap,query){
|
|
|
223
239
|
function overlapScore(status,shared,reasonCodes){
|
|
224
240
|
const base=status==='duplicate'?100:status==='semantic-overlap'?75:status==='source-overlap'?35:0;
|
|
225
241
|
const sharedBonus=Math.min(20,countShared(shared));
|
|
226
|
-
const stalePenalty=reasonCodes.includes('base-hash-mismatch')||reasonCodes.includes('target-hash-mismatch')
|
|
242
|
+
const stalePenalty=reasonCodes.includes('base-hash-mismatch')||reasonCodes.includes('target-hash-mismatch')
|
|
243
|
+
||reasonCodes.includes('replay-output-hash-mismatch')?15:0;
|
|
227
244
|
return Math.max(0,base+sharedBonus-stalePenalty);
|
|
228
245
|
}
|
|
229
246
|
|
|
@@ -141,11 +141,13 @@ function recordIndex(parts){
|
|
|
141
141
|
semanticEditReplayIds:editIndex.semanticEditReplayIds,
|
|
142
142
|
semanticEditReplayStatuses:editIndex.semanticEditReplayStatuses,
|
|
143
143
|
semanticEditReplayActions:editIndex.semanticEditReplayActions,
|
|
144
|
+
semanticEditReplayReasonCodes:editIndex.semanticEditReplayReasonCodes,
|
|
144
145
|
semanticEditAdmissionStatuses:uniqueStrings([editAdmission.status]),
|
|
145
146
|
semanticEditAdmissionActions:uniqueStrings([editAdmission.action]),
|
|
146
147
|
semanticEditAdmissionReadinesses:uniqueStrings([editAdmission.readiness]),
|
|
147
148
|
semanticEditReplayCurrentHashes:editIndex.semanticEditReplayCurrentHashes,
|
|
148
149
|
semanticEditReplayOutputHashes:editIndex.semanticEditReplayOutputHashes,
|
|
150
|
+
sourceBackprojectionModes:editIndex.sourceBackprojectionModes,
|
|
149
151
|
semanticEditKeys:editIndex.semanticEditKeys,
|
|
150
152
|
semanticIdentityHashes:editIndex.semanticIdentityHashes,
|
|
151
153
|
sourceIdentityHashes:editIndex.sourceIdentityHashes,
|
|
@@ -156,12 +158,18 @@ function recordIndex(parts){
|
|
|
156
158
|
semanticTransformIdentityHashes:semanticTransformIndex.semanticTransformIdentityHashes,
|
|
157
159
|
semanticTransformContentHashes:semanticTransformIndex.semanticTransformContentHashes,
|
|
158
160
|
projectionIdentityHashes:semanticTransformIndex.projectionIdentityHashes,
|
|
161
|
+
transformBaseHashes:semanticTransformIndex.transformBaseHashes,
|
|
162
|
+
transformTargetHashes:semanticTransformIndex.transformTargetHashes,
|
|
159
163
|
semanticTransformReadinesses:semanticTransformIndex.semanticTransformReadinesses,
|
|
160
164
|
semanticTransformEvidenceIds:semanticTransformIndex.semanticTransformEvidenceIds,
|
|
161
165
|
transformSourceLanguages:semanticTransformIndex.transformSourceLanguages,
|
|
162
166
|
transformTargetLanguages:semanticTransformIndex.transformTargetLanguages,
|
|
163
167
|
transformSourcePaths:semanticTransformIndex.transformSourcePaths,
|
|
164
168
|
transformTargetPaths:semanticTransformIndex.transformTargetPaths,
|
|
169
|
+
transformCrossLanguages:semanticTransformIndex.transformCrossLanguages,
|
|
170
|
+
transformSourceMapIds:semanticTransformIndex.transformSourceMapIds,
|
|
171
|
+
transformSourceMapLinkIds:semanticTransformIndex.transformSourceMapLinkIds,
|
|
172
|
+
transformSourceMapMappingIds:semanticTransformIndex.transformSourceMapMappingIds,
|
|
165
173
|
targetPortabilityStatuses:uniqueStrings([parts.targetPortability?.status]),
|
|
166
174
|
targetPortabilityActions:uniqueStrings([parts.targetPortability?.action]),
|
|
167
175
|
targetPortabilityReasonCodes:uniqueStrings(parts.targetPortability?.reasonCodes),
|
|
@@ -202,11 +210,13 @@ function matchesRecord(record,query){
|
|
|
202
210
|
&&matchAny(queryValues(query.semanticEditReplayId,query.semanticEditReplayIds),index.semanticEditReplayIds)
|
|
203
211
|
&&matchAny(queryValues(query.semanticEditReplayStatus,query.semanticEditReplayStatuses),index.semanticEditReplayStatuses)
|
|
204
212
|
&&matchAny(queryValues(query.semanticEditReplayAction,query.semanticEditReplayActions),index.semanticEditReplayActions)
|
|
213
|
+
&&matchAny(queryValues(query.semanticEditReplayReasonCode,query.semanticEditReplayReasonCodes),index.semanticEditReplayReasonCodes)
|
|
205
214
|
&&matchAny(queryValues(query.semanticEditAdmissionStatus,query.semanticEditAdmissionStatuses),index.semanticEditAdmissionStatuses)
|
|
206
215
|
&&matchAny(queryValues(query.semanticEditAdmissionAction,query.semanticEditAdmissionActions),index.semanticEditAdmissionActions)
|
|
207
216
|
&&matchAny(queryValues(query.semanticEditAdmissionReadiness,query.semanticEditAdmissionReadinesses),index.semanticEditAdmissionReadinesses)
|
|
208
217
|
&&matchAny(queryValues(query.semanticEditReplayCurrentHash,query.semanticEditReplayCurrentHashes),index.semanticEditReplayCurrentHashes)
|
|
209
218
|
&&matchAny(queryValues(query.semanticEditReplayOutputHash,query.semanticEditReplayOutputHashes),index.semanticEditReplayOutputHashes)
|
|
219
|
+
&&matchAny(queryValues(query.sourceBackprojectionMode,query.sourceBackprojectionModes),index.sourceBackprojectionModes)
|
|
210
220
|
&&matchAny(queryValues(query.semanticEditKey,query.semanticEditKeys),index.semanticEditKeys)
|
|
211
221
|
&&matchAny(queryValues(query.semanticIdentityHash,query.semanticIdentityHashes),index.semanticIdentityHashes)
|
|
212
222
|
&&matchAny(queryValues(query.sourceIdentityHash,query.sourceIdentityHashes),index.sourceIdentityHashes)
|
|
@@ -217,12 +227,18 @@ function matchesRecord(record,query){
|
|
|
217
227
|
&&matchAny(queryValues(query.semanticTransformIdentityHash,query.semanticTransformIdentityHashes),index.semanticTransformIdentityHashes)
|
|
218
228
|
&&matchAny(queryValues(query.semanticTransformContentHash,query.semanticTransformContentHashes),index.semanticTransformContentHashes)
|
|
219
229
|
&&matchAny(queryValues(query.projectionIdentityHash,query.projectionIdentityHashes),index.projectionIdentityHashes)
|
|
230
|
+
&&matchAny(queryValues(query.transformBaseHash,query.transformBaseHashes),index.transformBaseHashes)
|
|
231
|
+
&&matchAny(queryValues(query.transformTargetHash,query.transformTargetHashes),index.transformTargetHashes)
|
|
220
232
|
&&matchAny(queryValues(query.semanticTransformReadiness,query.semanticTransformReadinesses),index.semanticTransformReadinesses)
|
|
221
233
|
&&matchAny(queryValues(query.semanticTransformEvidenceId,query.semanticTransformEvidenceIds),index.semanticTransformEvidenceIds)
|
|
222
234
|
&&matchAny(queryValues(query.transformSourceLanguage,query.transformSourceLanguages),index.transformSourceLanguages)
|
|
223
235
|
&&matchAny(queryValues(query.transformTargetLanguage,query.transformTargetLanguages),index.transformTargetLanguages)
|
|
224
236
|
&&matchAny(queryValues(query.transformSourcePath,query.transformSourcePaths),index.transformSourcePaths)
|
|
225
237
|
&&matchAny(queryValues(query.transformTargetPath,query.transformTargetPaths),index.transformTargetPaths)
|
|
238
|
+
&&matchAny(queryValues(query.transformCrossLanguage,query.transformCrossLanguages),index.transformCrossLanguages)
|
|
239
|
+
&&matchAny(queryValues(query.transformSourceMapId,query.transformSourceMapIds),index.transformSourceMapIds)
|
|
240
|
+
&&matchAny(queryValues(query.transformSourceMapLinkId,query.transformSourceMapLinkIds),index.transformSourceMapLinkIds)
|
|
241
|
+
&&matchAny(queryValues(query.transformSourceMapMappingId,query.transformSourceMapMappingIds),index.transformSourceMapMappingIds)
|
|
226
242
|
&&matchAny(queryValues(query.targetPortabilityStatus,query.targetPortabilityStatuses),index.targetPortabilityStatuses)
|
|
227
243
|
&&matchAny(queryValues(query.targetPortabilityAction,query.targetPortabilityActions),index.targetPortabilityActions)
|
|
228
244
|
&&matchAny(queryValues(query.targetPortabilityReasonCode,query.targetPortabilityReasonCodes),index.targetPortabilityReasonCodes)
|
|
@@ -102,6 +102,8 @@ export function normalizeSourceMapLinks(links) {
|
|
|
102
102
|
precision: link.precision,
|
|
103
103
|
sourceSpan: link.sourceSpan,
|
|
104
104
|
generatedSpan: link.generatedSpan,
|
|
105
|
+
sourceReplacementText: link.sourceReplacementText,
|
|
106
|
+
sourceReplacementTextHash: link.sourceReplacementTextHash,
|
|
105
107
|
regionKey: link.ownershipRegionKey,
|
|
106
108
|
regionKind: link.ownershipRegionKind
|
|
107
109
|
}));
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { uniqueStrings } from '../../native-import-utils.js';
|
|
2
|
+
|
|
3
|
+
function summarizeSemanticSidecarQuality(sources) {
|
|
4
|
+
const records = uniqueSemanticSidecarQualityRecords(array(sources).flatMap(semanticSidecarQualityRecords));
|
|
5
|
+
const warningCodes = uniqueStrings(records.flatMap(sidecarQualityWarningCodes));
|
|
6
|
+
const zeroRecordWarningCodes = uniqueStrings(records.flatMap(sidecarQualityZeroRecordWarningCodes));
|
|
7
|
+
return {
|
|
8
|
+
records: records.length,
|
|
9
|
+
symbols: records.reduce((sum, record) => sum + sidecarQualityCount(record, 'symbolCount', 'symbols'), 0),
|
|
10
|
+
ownershipRegions: records.reduce((sum, record) => sum + sidecarQualityCount(record, 'ownershipRegionCount', 'ownershipRegions'), 0),
|
|
11
|
+
patchHints: records.reduce((sum, record) => sum + sidecarQualityCount(record, 'patchHintCount', 'patchHints'), 0),
|
|
12
|
+
warnings: records.reduce((sum, record) => sum + sidecarQualityWarningCount(record), 0),
|
|
13
|
+
zeroRecordWarnings: zeroRecordWarningCodes.length,
|
|
14
|
+
warningCodes,
|
|
15
|
+
zeroRecordWarningCodes
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function semanticSidecarQualityRecords(source) {
|
|
20
|
+
if (!source || typeof source !== 'object') return [];
|
|
21
|
+
return [
|
|
22
|
+
source.semanticSidecarQuality,
|
|
23
|
+
source.sidecarQuality,
|
|
24
|
+
source.semanticSidecar?.quality,
|
|
25
|
+
source.sidecar?.quality,
|
|
26
|
+
source.semanticSidecarAdmission,
|
|
27
|
+
source.sidecarAdmission,
|
|
28
|
+
source.semanticSidecar?.admission,
|
|
29
|
+
source.sidecar?.admission,
|
|
30
|
+
source.metadata?.semanticSidecarQuality,
|
|
31
|
+
source.metadata?.sidecarQuality,
|
|
32
|
+
source.metadata?.semanticSidecarAdmission,
|
|
33
|
+
source.metadata?.sidecarAdmission
|
|
34
|
+
].filter(looksLikeSemanticSidecarQuality);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function looksLikeSemanticSidecarQuality(value) {
|
|
38
|
+
return value && typeof value === 'object' && (
|
|
39
|
+
value.schema === 'frontier.lang.semanticSidecarQuality.v1' ||
|
|
40
|
+
value.schema === 'frontier.lang.semanticSidecarAdmission.v1' ||
|
|
41
|
+
value.imported !== undefined ||
|
|
42
|
+
value.eligible !== undefined ||
|
|
43
|
+
value.expectedSatisfied !== undefined ||
|
|
44
|
+
value.warningCount !== undefined ||
|
|
45
|
+
value.emptyEvidenceWarnings !== undefined ||
|
|
46
|
+
value.proofSummary !== undefined ||
|
|
47
|
+
value.counts !== undefined
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function uniqueSemanticSidecarQualityRecords(records) {
|
|
52
|
+
const seen = new Set();
|
|
53
|
+
const result = [];
|
|
54
|
+
for (const record of records) {
|
|
55
|
+
const key = record.id ?? JSON.stringify({
|
|
56
|
+
schema: record.schema,
|
|
57
|
+
symbols: sidecarQualityCount(record, 'symbolCount', 'symbols'),
|
|
58
|
+
ownershipRegions: sidecarQualityCount(record, 'ownershipRegionCount', 'ownershipRegions'),
|
|
59
|
+
patchHints: sidecarQualityCount(record, 'patchHintCount', 'patchHints'),
|
|
60
|
+
warningCodes: sidecarQualityWarningCodes(record)
|
|
61
|
+
});
|
|
62
|
+
if (seen.has(key)) continue;
|
|
63
|
+
seen.add(key);
|
|
64
|
+
result.push(record);
|
|
65
|
+
}
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function sidecarQualityCount(record, field, countsField) {
|
|
70
|
+
for (const value of [record?.[field], record?.counts?.[countsField]]) {
|
|
71
|
+
const count = Number(value ?? 0);
|
|
72
|
+
if (Number.isFinite(count) && count > 0) return count;
|
|
73
|
+
}
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function sidecarQualityWarningCount(record) {
|
|
78
|
+
const count = Number(record?.warningCount ?? 0);
|
|
79
|
+
if (Number.isFinite(count) && count > 0) return count;
|
|
80
|
+
return sidecarQualityWarningCodes(record).length;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function sidecarQualityWarningCodes(record) {
|
|
84
|
+
return uniqueStrings([
|
|
85
|
+
...array(record?.warnings).map((warning) => warning?.code ?? warning?.reasonCode),
|
|
86
|
+
...array(record?.emptyEvidenceWarnings).map((warning) => warning?.code ?? warning?.reasonCode),
|
|
87
|
+
...strings(record?.expectedMissingReasonCodes),
|
|
88
|
+
...strings(record?.reasonCodes)
|
|
89
|
+
].filter(Boolean));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function sidecarQualityZeroRecordWarningCodes(record) {
|
|
93
|
+
return sidecarQualityWarningCodes(record).filter(isZeroRecordWarningCode);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function isZeroRecordWarningCode(code) {
|
|
97
|
+
return [
|
|
98
|
+
'empty-evidence',
|
|
99
|
+
'empty-semantic-index',
|
|
100
|
+
'expected-semantic-import-empty',
|
|
101
|
+
'expected-semantic-import-missing',
|
|
102
|
+
'missing-imports',
|
|
103
|
+
'missing-ownership-regions',
|
|
104
|
+
'missing-patch-hints'
|
|
105
|
+
].includes(code);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function array(value) { if (value === undefined || value === null) return []; return Array.isArray(value) ? value : [value]; }
|
|
109
|
+
function strings(value) { return array(value).map((entry) => String(entry ?? '')).filter(Boolean); }
|
|
110
|
+
|
|
111
|
+
export { summarizeSemanticSidecarQuality };
|
|
@@ -8,11 +8,18 @@ export function applySourceEdits(sourceText, edits) {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export function dedupeSourceEdits(edits) {
|
|
11
|
-
const exact =
|
|
12
|
-
const
|
|
11
|
+
const exact = dedupeExactEdits(edits);
|
|
12
|
+
const noops = removeNoopReplacements(exact.edits);
|
|
13
|
+
const coveredDeletes = removeContainedDeletionEdits(noops.edits);
|
|
14
|
+
const covered = removeCoveredContainerReplacements(coveredDeletes.edits);
|
|
13
15
|
return {
|
|
14
16
|
edits: covered.edits,
|
|
15
|
-
skippedOperationIds: [
|
|
17
|
+
skippedOperationIds: [
|
|
18
|
+
...exact.skippedOperationIds,
|
|
19
|
+
...noops.skippedOperationIds,
|
|
20
|
+
...coveredDeletes.skippedOperationIds,
|
|
21
|
+
...covered.skippedOperationIds
|
|
22
|
+
]
|
|
16
23
|
};
|
|
17
24
|
}
|
|
18
25
|
|
|
@@ -27,7 +34,7 @@ export function validateSourceEdits(edits) {
|
|
|
27
34
|
return uniqueStrings(reasons);
|
|
28
35
|
}
|
|
29
36
|
|
|
30
|
-
function
|
|
37
|
+
function dedupeExactEdits(edits) {
|
|
31
38
|
const seen = new Map();
|
|
32
39
|
const result = [];
|
|
33
40
|
const skippedOperationIds = [];
|
|
@@ -43,6 +50,19 @@ function dedupeExactInsertions(edits) {
|
|
|
43
50
|
return { edits: result, skippedOperationIds };
|
|
44
51
|
}
|
|
45
52
|
|
|
53
|
+
function removeNoopReplacements(edits) {
|
|
54
|
+
const skippedOperationIds = [];
|
|
55
|
+
const result = [];
|
|
56
|
+
for (const edit of edits) {
|
|
57
|
+
if (edit.editKind === 'replace' && !edit.alreadyApplied && edit.current === edit.replacement) {
|
|
58
|
+
skippedOperationIds.push(edit.operationId);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
result.push(edit);
|
|
62
|
+
}
|
|
63
|
+
return { edits: result, skippedOperationIds };
|
|
64
|
+
}
|
|
65
|
+
|
|
46
66
|
function removeCoveredContainerReplacements(edits) {
|
|
47
67
|
const skippedOperationIds = [];
|
|
48
68
|
const result = [];
|
|
@@ -56,6 +76,31 @@ function removeCoveredContainerReplacements(edits) {
|
|
|
56
76
|
return { edits: result, skippedOperationIds };
|
|
57
77
|
}
|
|
58
78
|
|
|
79
|
+
function removeContainedDeletionEdits(edits) {
|
|
80
|
+
const skippedOperationIds = [];
|
|
81
|
+
const result = [];
|
|
82
|
+
for (const edit of edits) {
|
|
83
|
+
if (deleteCoveredByLargerDelete(edit, edits)) {
|
|
84
|
+
skippedOperationIds.push(edit.operationId);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
result.push(edit);
|
|
88
|
+
}
|
|
89
|
+
return { edits: result, skippedOperationIds };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function deleteCoveredByLargerDelete(edit, edits) {
|
|
93
|
+
return edit.editKind === 'delete' && !edit.alreadyApplied && edits.some((candidate) => (
|
|
94
|
+
candidate !== edit &&
|
|
95
|
+
candidate.editKind === 'delete' &&
|
|
96
|
+
!candidate.alreadyApplied &&
|
|
97
|
+
sameSourcePath(candidate, edit) &&
|
|
98
|
+
candidate.start <= edit.start &&
|
|
99
|
+
edit.end <= candidate.end &&
|
|
100
|
+
(candidate.start !== edit.start || candidate.end !== edit.end)
|
|
101
|
+
));
|
|
102
|
+
}
|
|
103
|
+
|
|
59
104
|
function containerReplacementCoveredByInsertions(edit, edits) {
|
|
60
105
|
if (edit.editKind !== 'replace' || edit.alreadyApplied) return false;
|
|
61
106
|
const insertions = containedInsertions(edit, edits);
|
|
@@ -76,15 +121,30 @@ function containedInsertions(container, edits) {
|
|
|
76
121
|
.sort((left, right) => left.start - right.start || (left.order ?? 0) - (right.order ?? 0));
|
|
77
122
|
}
|
|
78
123
|
|
|
124
|
+
function sameSourcePath(left, right) {
|
|
125
|
+
const leftPath = left.targetSourcePath ?? left.sourcePath;
|
|
126
|
+
const rightPath = right.targetSourcePath ?? right.sourcePath;
|
|
127
|
+
return !leftPath || !rightPath || leftPath === rightPath;
|
|
128
|
+
}
|
|
129
|
+
|
|
79
130
|
function duplicateEditKey(edit) {
|
|
80
|
-
if (edit.
|
|
131
|
+
if (edit.alreadyApplied) return undefined;
|
|
132
|
+
if (edit.editKind === 'insert') {
|
|
133
|
+
return [
|
|
134
|
+
'insert',
|
|
135
|
+
edit.start,
|
|
136
|
+
edit.end,
|
|
137
|
+
edit.insertion?.mode,
|
|
138
|
+
edit.insertion?.anchorKey,
|
|
139
|
+
hashSemanticValue(edit.replacementSpanText ?? edit.replacement)
|
|
140
|
+
].join(':');
|
|
141
|
+
}
|
|
81
142
|
return [
|
|
82
|
-
|
|
143
|
+
edit.editKind,
|
|
83
144
|
edit.start,
|
|
84
145
|
edit.end,
|
|
85
|
-
edit.
|
|
86
|
-
edit.
|
|
87
|
-
hashSemanticValue(edit.replacementSpanText ?? edit.replacement)
|
|
146
|
+
hashSemanticValue(edit.current),
|
|
147
|
+
hashSemanticValue(edit.replacement)
|
|
88
148
|
].join(':');
|
|
89
149
|
}
|
|
90
150
|
|