@shapeshift-labs/frontier-lang-compiler 0.2.103 → 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/semantic-edit-replay-diagnostics.d.ts +12 -0
- package/dist/declarations/semantic-edit-script.d.ts +7 -4
- package/dist/declarations/semantic-patch-bundle-index.d.ts +45 -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/diffNativeSymbols.js +3 -3
- package/dist/internal/index-impl/nativeChangeProjectionSourceMapLinks.js +2 -0
- package/dist/internal/index-impl/projectSemanticEditScriptToSource.js +43 -8
- package/dist/internal/index-impl/replaySemanticEditLineEndings.js +34 -0
- package/dist/internal/index-impl/replaySemanticEditProjection.js +39 -19
- 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/semanticEditOperationCoverage.js +33 -3
- package/dist/internal/index-impl/semanticEditProjectionRecord.js +29 -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 +27 -0
- package/dist/internal/index-impl/semanticIndexFromNativeDeclarations.js +1 -0
- package/dist/internal/index-impl/semanticPatchBundleAdmission.js +41 -7
- 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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { uniqueStrings } from '../../native-import-utils.js';
|
|
2
|
+
import { summarizeSemanticSidecarQuality } from './semanticSidecarQuality.js';
|
|
2
3
|
|
|
3
4
|
export function semanticEditRecordIndex(scripts, projections, replays, source = {}) {
|
|
4
5
|
const operations = scripts.flatMap((script) => array(script.operations));
|
|
@@ -6,6 +7,8 @@ export function semanticEditRecordIndex(scripts, projections, replays, source =
|
|
|
6
7
|
const replayEdits = replays.flatMap((replay) => array(replay.edits));
|
|
7
8
|
const index = source.index ?? {};
|
|
8
9
|
const summary = source.metadata?.semanticEditSummary ?? {};
|
|
10
|
+
const sidecarQuality = summarizeSemanticSidecarQuality([source, ...scripts, ...projections, ...replays]);
|
|
11
|
+
const priorSidecarQuality = summary.semanticSidecarQuality ?? {};
|
|
9
12
|
return {
|
|
10
13
|
semanticEditScriptIds: uniqueStrings([...strings(source.semanticEditScriptIds), ...strings(source.semanticEditScriptId), ...strings(index.semanticEditScriptIds), ...strings(summary.scriptIds), ...scripts.map((script) => script.id), ...replays.map((replay) => replay.scriptId)]),
|
|
11
14
|
semanticEditProjectionIds: uniqueStrings([...strings(source.semanticEditProjectionIds), ...strings(source.semanticEditProjectionId), ...strings(index.semanticEditProjectionIds), ...strings(summary.projectionIds), ...projections.map((projection) => projection.id), ...replays.map((replay) => replay.projectionId)]),
|
|
@@ -15,8 +18,10 @@ export function semanticEditRecordIndex(scripts, projections, replays, source =
|
|
|
15
18
|
semanticEditReplayEditCount: replayEdits.length,
|
|
16
19
|
semanticEditReplayStatuses: uniqueStrings([...strings(source.semanticEditReplayStatuses), ...strings(index.semanticEditReplayStatuses), ...strings(summary.replayStatuses), ...replays.map((replay) => replay.status)]),
|
|
17
20
|
semanticEditReplayActions: uniqueStrings([...strings(source.semanticEditReplayActions), ...strings(index.semanticEditReplayActions), ...strings(summary.replayActions), ...replays.map((replay) => replay.admission?.action)]),
|
|
21
|
+
semanticEditReplayReasonCodes: uniqueStrings([...strings(source.semanticEditReplayReasonCodes), ...strings(index.semanticEditReplayReasonCodes), ...strings(summary.replayReasonCodes), ...replays.flatMap(replayReasonCodes)]),
|
|
18
22
|
semanticEditReplayCurrentHashes: uniqueStrings([...strings(source.semanticEditReplayCurrentHashes), ...strings(index.semanticEditReplayCurrentHashes), ...strings(summary.replayCurrentHashes), ...strings(summary.semanticEditReplayCurrentHashes), ...replays.map((replay) => replay.currentHash)]),
|
|
19
23
|
semanticEditReplayOutputHashes: uniqueStrings([...strings(source.semanticEditReplayOutputHashes), ...strings(index.semanticEditReplayOutputHashes), ...strings(summary.replayOutputHashes), ...strings(summary.semanticEditReplayOutputHashes), ...replays.map((replay) => replay.outputHash)]),
|
|
24
|
+
sourceBackprojectionModes: uniqueStrings([...strings(source.sourceBackprojectionModes), ...strings(index.sourceBackprojectionModes), ...strings(summary.sourceBackprojectionModes), ...scripts.flatMap(scriptBackprojectionModes), ...projections.map((projection) => projection.metadata?.sourceBackprojectionMode), ...replays.map((replay) => replay.metadata?.sourceBackprojectionMode)]),
|
|
20
25
|
semanticEditKeys: uniqueStrings([...strings(source.semanticEditKeys), ...strings(index.semanticEditKeys), ...strings(summary.semanticEditKeys), ...operations.map((operation) => operation.semanticKey), ...edits.map((edit) => edit.semanticKey), ...replayEdits.map((edit) => edit.semanticKey)]),
|
|
21
26
|
semanticIdentityHashes: uniqueStrings([...strings(source.semanticIdentityHashes), ...strings(index.semanticIdentityHashes), ...strings(summary.semanticIdentityHashes), ...operations.map((operation) => operation.semanticIdentityHash), ...edits.map((edit) => edit.semanticIdentityHash), ...replayEdits.map((edit) => edit.semanticIdentityHash)]),
|
|
22
27
|
sourceIdentityHashes: uniqueStrings([...strings(source.sourceIdentityHashes), ...strings(index.sourceIdentityHashes), ...strings(summary.sourceIdentityHashes), ...operations.map((operation) => operation.sourceIdentityHash), ...edits.map((edit) => edit.sourceIdentityHash), ...replayEdits.map((edit) => edit.sourceIdentityHash)]),
|
|
@@ -24,7 +29,15 @@ export function semanticEditRecordIndex(scripts, projections, replays, source =
|
|
|
24
29
|
editContentHashes: uniqueStrings([...strings(source.editContentHashes), ...strings(index.editContentHashes), ...strings(summary.editContentHashes), ...edits.map((edit) => edit.editContentHash), ...replayEdits.map((edit) => edit.editContentHash)]),
|
|
25
30
|
anchorKeys: uniqueStrings([...strings(source.anchorKeys), ...strings(index.anchorKeys), ...strings(summary.anchorKeys), ...operations.map((operation) => operation.anchor?.key), ...edits.map((edit) => edit.anchorKey), ...replayEdits.map((edit) => edit.anchorKey)]),
|
|
26
31
|
conflictKeys: uniqueStrings([...strings(source.conflictKeys), ...strings(index.conflictKeys), ...strings(summary.conflictKeys), ...operations.map((operation) => operation.anchor?.conflictKey), ...edits.map((edit) => edit.conflictKey), ...replayEdits.map((edit) => edit.conflictKey)]),
|
|
27
|
-
projectedSourcePaths: uniqueStrings([...strings(source.projectedSourcePaths), ...strings(index.projectedSourcePaths), ...strings(summary.projectedSourcePaths), ...projections.map((projection) => projection.sourcePath), ...edits.flatMap((edit) => [edit.sourcePath, edit.targetSourcePath]), ...replays.map((replay) => replay.sourcePath), ...replayEdits.map((edit) => edit.sourcePath)])
|
|
32
|
+
projectedSourcePaths: uniqueStrings([...strings(source.projectedSourcePaths), ...strings(index.projectedSourcePaths), ...strings(summary.projectedSourcePaths), ...projections.map((projection) => projection.sourcePath), ...edits.flatMap((edit) => [edit.sourcePath, edit.targetSourcePath]), ...replays.map((replay) => replay.sourcePath), ...replayEdits.map((edit) => edit.sourcePath)]),
|
|
33
|
+
semanticEditSidecarQualityRecords: maxCount(sidecarQuality.records, source.semanticEditSidecarQualityRecords, index.semanticEditSidecarQualityRecords, priorSidecarQuality.records),
|
|
34
|
+
semanticEditSidecarSymbolCount: maxCount(sidecarQuality.symbols, source.semanticEditSidecarSymbolCount, index.semanticEditSidecarSymbolCount, priorSidecarQuality.symbols),
|
|
35
|
+
semanticEditSidecarOwnershipRegionCount: maxCount(sidecarQuality.ownershipRegions, source.semanticEditSidecarOwnershipRegionCount, index.semanticEditSidecarOwnershipRegionCount, priorSidecarQuality.ownershipRegions),
|
|
36
|
+
semanticEditSidecarPatchHintCount: maxCount(sidecarQuality.patchHints, source.semanticEditSidecarPatchHintCount, index.semanticEditSidecarPatchHintCount, priorSidecarQuality.patchHints),
|
|
37
|
+
semanticEditSidecarWarningCount: maxCount(sidecarQuality.warnings, source.semanticEditSidecarWarningCount, index.semanticEditSidecarWarningCount, priorSidecarQuality.warnings),
|
|
38
|
+
semanticEditSidecarZeroRecordWarningCount: maxCount(sidecarQuality.zeroRecordWarnings, source.semanticEditSidecarZeroRecordWarningCount, index.semanticEditSidecarZeroRecordWarningCount, priorSidecarQuality.zeroRecordWarnings),
|
|
39
|
+
semanticEditSidecarWarningCodes: uniqueStrings([...strings(source.semanticEditSidecarWarningCodes), ...strings(index.semanticEditSidecarWarningCodes), ...strings(priorSidecarQuality.warningCodes), ...sidecarQuality.warningCodes]),
|
|
40
|
+
semanticEditSidecarZeroRecordWarningCodes: uniqueStrings([...strings(source.semanticEditSidecarZeroRecordWarningCodes), ...strings(index.semanticEditSidecarZeroRecordWarningCodes), ...strings(priorSidecarQuality.zeroRecordWarningCodes), ...sidecarQuality.zeroRecordWarningCodes])
|
|
28
41
|
};
|
|
29
42
|
}
|
|
30
43
|
|
|
@@ -36,8 +49,10 @@ export function semanticEditSummary(index) {
|
|
|
36
49
|
replayIds: index.semanticEditReplayIds,
|
|
37
50
|
replayStatuses: index.semanticEditReplayStatuses,
|
|
38
51
|
replayActions: index.semanticEditReplayActions,
|
|
52
|
+
replayReasonCodes: index.semanticEditReplayReasonCodes,
|
|
39
53
|
replayCurrentHashes: index.semanticEditReplayCurrentHashes,
|
|
40
54
|
replayOutputHashes: index.semanticEditReplayOutputHashes,
|
|
55
|
+
sourceBackprojectionModes: index.sourceBackprojectionModes,
|
|
41
56
|
semanticEditKeys: index.semanticEditKeys,
|
|
42
57
|
semanticIdentityHashes: index.semanticIdentityHashes,
|
|
43
58
|
sourceIdentityHashes: index.sourceIdentityHashes,
|
|
@@ -46,6 +61,16 @@ export function semanticEditSummary(index) {
|
|
|
46
61
|
anchorKeys: index.anchorKeys,
|
|
47
62
|
conflictKeys: index.conflictKeys,
|
|
48
63
|
projectedSourcePaths: index.projectedSourcePaths,
|
|
64
|
+
semanticSidecarQuality: {
|
|
65
|
+
records: index.semanticEditSidecarQualityRecords,
|
|
66
|
+
symbols: index.semanticEditSidecarSymbolCount,
|
|
67
|
+
ownershipRegions: index.semanticEditSidecarOwnershipRegionCount,
|
|
68
|
+
patchHints: index.semanticEditSidecarPatchHintCount,
|
|
69
|
+
warnings: index.semanticEditSidecarWarningCount,
|
|
70
|
+
zeroRecordWarnings: index.semanticEditSidecarZeroRecordWarningCount,
|
|
71
|
+
warningCodes: index.semanticEditSidecarWarningCodes,
|
|
72
|
+
zeroRecordWarningCodes: index.semanticEditSidecarZeroRecordWarningCodes
|
|
73
|
+
},
|
|
49
74
|
replayEditCount: index.semanticEditReplayEditCount
|
|
50
75
|
});
|
|
51
76
|
}
|
|
@@ -57,6 +82,27 @@ function replayOperationIds(replays) {
|
|
|
57
82
|
...array(replay.edits).map((edit) => edit.operationId)
|
|
58
83
|
]);
|
|
59
84
|
}
|
|
85
|
+
function replayReasonCodes(replay) {
|
|
86
|
+
return [
|
|
87
|
+
...array(replay.admission?.reasonCodes),
|
|
88
|
+
...array(replay.summary?.reasonCodes),
|
|
89
|
+
...array(replay.diagnostics).flatMap((diagnostic) => array(diagnostic.reasonCodes)),
|
|
90
|
+
...array(replay.edits).flatMap((edit) => array(edit.reasonCodes))
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
function scriptBackprojectionModes(script) {
|
|
94
|
+
return [
|
|
95
|
+
script.metadata?.sourceBackprojectionMode,
|
|
96
|
+
script.metadata?.sourceProjectionHint?.sourceBackprojectionMode,
|
|
97
|
+
...array(script.operations).map((operation) => operation.metadata?.sourceBackprojection?.mode)
|
|
98
|
+
];
|
|
99
|
+
}
|
|
100
|
+
function maxCount(...values) {
|
|
101
|
+
return Math.max(0, ...values.map((value) => {
|
|
102
|
+
const count = Number(value ?? 0);
|
|
103
|
+
return Number.isFinite(count) ? count : 0;
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
60
106
|
function array(value) { if (value === undefined || value === null) return []; return Array.isArray(value) ? value : [value]; }
|
|
61
107
|
function strings(value) { return array(value).map((entry) => String(entry ?? '')).filter(Boolean); }
|
|
62
108
|
function compactRecord(value) { return Object.fromEntries(Object.entries(value ?? {}).filter(([, entry]) => entry !== undefined && (!Array.isArray(entry) || entry.length > 0))); }
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
|
|
2
|
+
import { spanOffsets } from './semanticEditSourceRanges.js';
|
|
3
|
+
|
|
4
|
+
export function explicitSourceReplacementEditForOperation(operation, identity, headSourceText, order) {
|
|
5
|
+
const backprojection = operation.metadata?.sourceBackprojection;
|
|
6
|
+
if (backprojection?.mode !== 'cross-language-explicit-source-replacement') return undefined;
|
|
7
|
+
const replacement = backprojection.sourceReplacementText;
|
|
8
|
+
const range = spanOffsets(headSourceText, backprojection.sourceEditSpan ?? operation.spans?.head ?? operation.spans?.base);
|
|
9
|
+
const anchorRange = spanOffsets(headSourceText, operation.anchor?.sourceSpan);
|
|
10
|
+
const reasons = [];
|
|
11
|
+
if (typeof replacement !== 'string') reasons.push(`source-replacement-text-missing:${operation.id}`);
|
|
12
|
+
if (!range) reasons.push(`head-span-not-resolvable:${operation.id}`);
|
|
13
|
+
if (reasons.length) return { ok: false, reasonCodes: reasons };
|
|
14
|
+
const current = headSourceText.slice(range.start, range.end);
|
|
15
|
+
const currentHash = hashSemanticValue(current);
|
|
16
|
+
const replacementHash = hashSemanticValue(replacement);
|
|
17
|
+
const expectedCurrentHash = backprojection.sourceEditTextHash ?? operation.hashes?.headTextHash ?? operation.hashes?.baseTextHash;
|
|
18
|
+
if (expectedCurrentHash && currentHash !== expectedCurrentHash) reasons.push(`head-span-hash-mismatch:${operation.id}`);
|
|
19
|
+
if (backprojection.sourceReplacementTextHash && replacementHash !== backprojection.sourceReplacementTextHash) {
|
|
20
|
+
reasons.push(`source-replacement-text-hash-mismatch:${operation.id}`);
|
|
21
|
+
}
|
|
22
|
+
if (reasons.length) return { ok: false, reasonCodes: reasons };
|
|
23
|
+
return {
|
|
24
|
+
ok: true,
|
|
25
|
+
value: {
|
|
26
|
+
operationId: operation.id,
|
|
27
|
+
order,
|
|
28
|
+
...identity,
|
|
29
|
+
editKind: 'replace',
|
|
30
|
+
sourceRangeKind: 'cross-language-explicit-source-replacement',
|
|
31
|
+
start: range.start,
|
|
32
|
+
end: range.end,
|
|
33
|
+
headAnchorStart: anchorRange?.start,
|
|
34
|
+
headAnchorEnd: anchorRange?.end,
|
|
35
|
+
replacement,
|
|
36
|
+
replacementSpanText: replacement,
|
|
37
|
+
current
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -7,14 +7,16 @@ export function markCoveredSemanticEditOperations(operations, context) {
|
|
|
7
7
|
worker: nativeImportSourceText(context.worker)
|
|
8
8
|
};
|
|
9
9
|
return (operations ?? []).map((operation) => {
|
|
10
|
-
const
|
|
10
|
+
const childCoverage = coveredByChildOperations(operation, operations, sourceText);
|
|
11
|
+
const parentCoverage = childCoverage.length ? [] : coveredByParentOperations(operation, operations, sourceText);
|
|
12
|
+
const coveredBy = childCoverage.length ? childCoverage : parentCoverage;
|
|
11
13
|
if (!coveredBy.length) return operation;
|
|
12
14
|
return {
|
|
13
15
|
...operation,
|
|
14
16
|
status: 'covered',
|
|
15
17
|
readiness: 'ready',
|
|
16
18
|
confidence: Math.max(operation.confidence ?? 0, 0.82),
|
|
17
|
-
reasonCodes: uniqueStrings([...(operation.reasonCodes ?? []),
|
|
19
|
+
reasonCodes: uniqueStrings([...(operation.reasonCodes ?? []), coverageReason(childCoverage)]),
|
|
18
20
|
evidenceIds: uniqueStrings(operation.evidenceIds ?? []),
|
|
19
21
|
metadata: {
|
|
20
22
|
...(operation.metadata ?? {}),
|
|
@@ -24,6 +26,10 @@ export function markCoveredSemanticEditOperations(operations, context) {
|
|
|
24
26
|
});
|
|
25
27
|
}
|
|
26
28
|
|
|
29
|
+
function coverageReason(childCoverage) {
|
|
30
|
+
return childCoverage.length ? 'container-covered-by-child-edits' : 'child-covered-by-container-edit';
|
|
31
|
+
}
|
|
32
|
+
|
|
27
33
|
function coveredByChildOperations(container, operations, sourceText) {
|
|
28
34
|
if (!isCoverableContainer(container)) return [];
|
|
29
35
|
const containerBase = spanOffsets(sourceText.base, container.spans?.base);
|
|
@@ -43,7 +49,31 @@ function isCoverableContainer(operation) {
|
|
|
43
49
|
if (operation.changeKind !== 'modified') return false;
|
|
44
50
|
if (!operation.spans?.base || !operation.spans?.worker) return false;
|
|
45
51
|
const kind = String(operation.anchor?.regionKind ?? operation.regionKind ?? '');
|
|
46
|
-
return
|
|
52
|
+
return ['type', 'config', 'content', 'route', 'property', 'controlFlow', 'effect', 'mutation'].includes(kind);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function coveredByParentOperations(child, operations, sourceText) {
|
|
56
|
+
if (child.changeKind !== 'added' && child.changeKind !== 'removed') return [];
|
|
57
|
+
if (!isSemanticFactRegion(child)) return [];
|
|
58
|
+
const side = child.changeKind === 'removed' ? 'base' : 'worker';
|
|
59
|
+
const childRange = spanOffsets(sourceText[side], child.spans?.[side]);
|
|
60
|
+
if (!childRange) return [];
|
|
61
|
+
return (operations ?? []).filter((parent) => parent.id !== child.id
|
|
62
|
+
&& parent.changeKind === child.changeKind
|
|
63
|
+
&& ['portable', 'already-applied'].includes(parent.status)
|
|
64
|
+
&& parent.anchor?.regionKind === 'body'
|
|
65
|
+
&& sameSourcePath(parent, child)
|
|
66
|
+
&& contained(childRange, spanOffsets(sourceText[side], parent.spans?.[side])));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function isSemanticFactRegion(operation) {
|
|
70
|
+
return ['controlFlow', 'effect', 'mutation', 'call'].includes(String(operation.anchor?.regionKind ?? ''));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function sameSourcePath(left, right) {
|
|
74
|
+
const leftPath = left.anchor?.sourcePath ?? left.insertion?.sourcePath;
|
|
75
|
+
const rightPath = right.anchor?.sourcePath ?? right.insertion?.sourcePath;
|
|
76
|
+
return !leftPath || !rightPath || leftPath === rightPath;
|
|
47
77
|
}
|
|
48
78
|
|
|
49
79
|
function childEdit(operation, sourceText, containerBase) {
|
|
@@ -6,6 +6,7 @@ export function projectionEditRecord(edit) {
|
|
|
6
6
|
const replacementTextHash = hashSemanticValue(edit.replacement);
|
|
7
7
|
const replacementSpanText = edit.replacementSpanText ?? edit.replacement;
|
|
8
8
|
const identity = semanticEditIdentityFields(edit);
|
|
9
|
+
const sourceIdentity = sourceIdentityAnchorFields(edit);
|
|
9
10
|
return compactRecord({
|
|
10
11
|
operationId: edit.operationId,
|
|
11
12
|
status: edit.alreadyApplied ? 'already-applied' : 'applied',
|
|
@@ -26,9 +27,14 @@ export function projectionEditRecord(edit) {
|
|
|
26
27
|
symbolName: edit.symbolName,
|
|
27
28
|
symbolKind: edit.symbolKind,
|
|
28
29
|
...identity,
|
|
30
|
+
...sourceIdentity,
|
|
29
31
|
operationContentHash: edit.operationContentHash,
|
|
30
32
|
editContentHash: hashSemanticValue(compactRecord({
|
|
31
33
|
semanticIdentityHash: identity.semanticIdentityHash,
|
|
34
|
+
sourceIdentityHash: identity.sourceIdentityHash,
|
|
35
|
+
sourceIdentityStatus: sourceIdentity.sourceIdentityStatus,
|
|
36
|
+
sourceIdentityAnchorKey: sourceIdentity.sourceIdentityAnchorKey,
|
|
37
|
+
targetIdentityAnchorKey: sourceIdentity.targetIdentityAnchorKey,
|
|
32
38
|
sourceRangeKind: edit.sourceRangeKind,
|
|
33
39
|
deletedTextHash,
|
|
34
40
|
replacementTextHash,
|
|
@@ -48,6 +54,7 @@ export function projectionEditRecord(edit) {
|
|
|
48
54
|
replacementBytes: edit.replacement.length,
|
|
49
55
|
deletedTextHash,
|
|
50
56
|
replacementTextHash,
|
|
57
|
+
deletedText: deletedTextForEdit(edit),
|
|
51
58
|
deletedTextLineEndingStableHash: lineEndingStableTextHash(edit.current),
|
|
52
59
|
replacementTextLineEndingStableHash: lineEndingStableTextHash(edit.replacement),
|
|
53
60
|
anchorDeletedTextHash: edit.anchorDeletedTextHash,
|
|
@@ -63,6 +70,28 @@ export function projectionEditRecord(edit) {
|
|
|
63
70
|
});
|
|
64
71
|
}
|
|
65
72
|
|
|
73
|
+
function deletedTextForEdit(edit) {
|
|
74
|
+
return edit.sourceRangeKind === 'cross-language-explicit-source-replacement' ? edit.current : undefined;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function sourceIdentityAnchorFields(edit) {
|
|
78
|
+
const sourceIdentityAnchorKey = edit.sourceIdentityAnchorKey ?? edit.anchorKey;
|
|
79
|
+
const targetIdentityAnchorKey = edit.targetIdentityAnchorKey ?? edit.targetAnchorKey ?? sourceIdentityAnchorKey;
|
|
80
|
+
const sourceIdentitySourcePath = edit.sourceIdentitySourcePath ?? edit.originalSourcePath ?? edit.sourcePath;
|
|
81
|
+
const targetIdentitySourcePath = edit.targetIdentitySourcePath ?? edit.targetSourcePath ?? edit.sourcePath;
|
|
82
|
+
const moved = Boolean(
|
|
83
|
+
(sourceIdentityAnchorKey && targetIdentityAnchorKey && sourceIdentityAnchorKey !== targetIdentityAnchorKey)
|
|
84
|
+
|| (sourceIdentitySourcePath && targetIdentitySourcePath && sourceIdentitySourcePath !== targetIdentitySourcePath)
|
|
85
|
+
);
|
|
86
|
+
return compactRecord({
|
|
87
|
+
sourceIdentityStatus: edit.sourceIdentityStatus ?? (moved ? 'moved-source' : 'same-source'),
|
|
88
|
+
sourceIdentityAnchorKey,
|
|
89
|
+
targetIdentityAnchorKey,
|
|
90
|
+
sourceIdentitySourcePath,
|
|
91
|
+
targetIdentitySourcePath
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
66
95
|
function lineEndingStableTextHash(value) {
|
|
67
96
|
const normalized = lineEndingStableText(value);
|
|
68
97
|
return normalized === undefined ? undefined : hashSemanticValue(normalized);
|
|
@@ -8,6 +8,7 @@ export function replayEditDiagnostics(edit, status, range, reasonCodes, sourceTe
|
|
|
8
8
|
status,
|
|
9
9
|
operationId: edit.operationId,
|
|
10
10
|
sourcePath: edit.targetSourcePath ?? edit.sourcePath,
|
|
11
|
+
...sourceIdentityDiagnosticContext(edit),
|
|
11
12
|
symbolName: edit.targetSymbolName ?? edit.symbolName,
|
|
12
13
|
symbolKind: edit.targetSymbolKind ?? edit.symbolKind,
|
|
13
14
|
editKind: edit.editKind,
|
|
@@ -64,6 +65,7 @@ function appendOverlapDiagnostic(overlapDiagnostics, edit, code, operationIds) {
|
|
|
64
65
|
status: 'conflict',
|
|
65
66
|
operationId: edit.operationId,
|
|
66
67
|
sourcePath: edit.sourcePath,
|
|
68
|
+
...sourceIdentityDiagnosticContext(edit),
|
|
67
69
|
symbolName: edit.symbolName,
|
|
68
70
|
symbolKind: edit.symbolKind,
|
|
69
71
|
editKind: edit.editKind,
|
|
@@ -93,6 +95,18 @@ function replayDiagnostic(code, context) {
|
|
|
93
95
|
status: context.status,
|
|
94
96
|
operationId: context.operationId,
|
|
95
97
|
sourcePath: context.sourcePath,
|
|
98
|
+
originalSourcePath: context.originalSourcePath,
|
|
99
|
+
targetSourcePath: context.targetSourcePath,
|
|
100
|
+
anchorKey: context.anchorKey,
|
|
101
|
+
targetAnchorKey: context.targetAnchorKey,
|
|
102
|
+
sourceIdentityStatus: context.sourceIdentityStatus,
|
|
103
|
+
sourceIdentityAnchorKey: context.sourceIdentityAnchorKey,
|
|
104
|
+
targetIdentityAnchorKey: context.targetIdentityAnchorKey,
|
|
105
|
+
sourceIdentitySourcePath: context.sourceIdentitySourcePath,
|
|
106
|
+
targetIdentitySourcePath: context.targetIdentitySourcePath,
|
|
107
|
+
semanticIdentityHash: context.semanticIdentityHash,
|
|
108
|
+
sourceIdentityHash: context.sourceIdentityHash,
|
|
109
|
+
editContentHash: context.editContentHash,
|
|
96
110
|
symbolName: context.symbolName,
|
|
97
111
|
symbolKind: context.symbolKind,
|
|
98
112
|
editKind: context.editKind,
|
|
@@ -105,6 +119,31 @@ function replayDiagnostic(code, context) {
|
|
|
105
119
|
});
|
|
106
120
|
}
|
|
107
121
|
|
|
122
|
+
function sourceIdentityDiagnosticContext(edit) {
|
|
123
|
+
const sourceIdentityAnchorKey = edit.sourceIdentityAnchorKey ?? edit.anchorKey;
|
|
124
|
+
const targetIdentityAnchorKey = edit.targetIdentityAnchorKey ?? edit.targetAnchorKey ?? sourceIdentityAnchorKey;
|
|
125
|
+
const sourceIdentitySourcePath = edit.sourceIdentitySourcePath ?? edit.originalSourcePath ?? edit.sourcePath;
|
|
126
|
+
const targetIdentitySourcePath = edit.targetIdentitySourcePath ?? edit.targetSourcePath ?? edit.sourcePath;
|
|
127
|
+
const moved = Boolean(
|
|
128
|
+
(sourceIdentityAnchorKey && targetIdentityAnchorKey && sourceIdentityAnchorKey !== targetIdentityAnchorKey)
|
|
129
|
+
|| (sourceIdentitySourcePath && targetIdentitySourcePath && sourceIdentitySourcePath !== targetIdentitySourcePath)
|
|
130
|
+
);
|
|
131
|
+
return compactRecord({
|
|
132
|
+
originalSourcePath: edit.originalSourcePath,
|
|
133
|
+
targetSourcePath: edit.targetSourcePath,
|
|
134
|
+
anchorKey: edit.anchorKey,
|
|
135
|
+
targetAnchorKey: edit.targetAnchorKey,
|
|
136
|
+
sourceIdentityStatus: edit.sourceIdentityStatus ?? (moved ? 'moved-source' : 'same-source'),
|
|
137
|
+
sourceIdentityAnchorKey,
|
|
138
|
+
targetIdentityAnchorKey,
|
|
139
|
+
sourceIdentitySourcePath,
|
|
140
|
+
targetIdentitySourcePath,
|
|
141
|
+
semanticIdentityHash: edit.semanticIdentityHash,
|
|
142
|
+
sourceIdentityHash: edit.sourceIdentityHash,
|
|
143
|
+
editContentHash: edit.editContentHash
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
108
147
|
function replayDiagnosticCategory(code, status) {
|
|
109
148
|
if (code.includes('overlap')) return 'overlap';
|
|
110
149
|
if (code.startsWith('missing-current-source') || code.startsWith('missing-head-source') || code.startsWith('missing-worker-source')) return 'missing-source';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export function explicitSourceReplacementReplayRange(edit, symbolRange, sourceText) {
|
|
2
|
+
if (edit.sourceRangeKind !== 'cross-language-explicit-source-replacement' || !symbolRange || typeof sourceText !== 'string') {
|
|
3
|
+
return undefined;
|
|
4
|
+
}
|
|
5
|
+
const deleted = uniqueTextRange(sourceText, symbolRange, edit.deletedText, 'deleted-text');
|
|
6
|
+
if (deleted.status === 'matched') return deleted;
|
|
7
|
+
const replacement = uniqueTextRange(sourceText, symbolRange, edit.replacementText, 'replacement-text');
|
|
8
|
+
if (replacement.status === 'matched') return replacement;
|
|
9
|
+
const relative = relativeAnchorRange(edit, symbolRange);
|
|
10
|
+
return {
|
|
11
|
+
...relative,
|
|
12
|
+
conflictReasonCodes: [deleted.reasonCode, replacement.reasonCode].filter(Boolean)
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function uniqueTextRange(sourceText, symbolRange, needle, label) {
|
|
17
|
+
if (typeof needle !== 'string' || needle.length === 0) {
|
|
18
|
+
return { status: 'missing', reasonCode: `current-symbol-explicit-source-replacement-${label}-missing` };
|
|
19
|
+
}
|
|
20
|
+
const symbolText = sourceText.slice(symbolRange.start, symbolRange.end);
|
|
21
|
+
const matches = [];
|
|
22
|
+
for (let index = symbolText.indexOf(needle); index >= 0; index = symbolText.indexOf(needle, index + 1)) {
|
|
23
|
+
const start = symbolRange.start + index;
|
|
24
|
+
if (isCodeOffset(sourceText, start)) matches.push(start);
|
|
25
|
+
}
|
|
26
|
+
if (matches.length !== 1) {
|
|
27
|
+
return { status: matches.length ? 'ambiguous' : 'missing', reasonCode: `current-symbol-explicit-source-replacement-${label}-${matches.length ? 'ambiguous' : 'missing'}` };
|
|
28
|
+
}
|
|
29
|
+
const first = matches[0] - symbolRange.start;
|
|
30
|
+
return {
|
|
31
|
+
status: 'matched',
|
|
32
|
+
range: { start: symbolRange.start + first, end: symbolRange.start + first + needle.length },
|
|
33
|
+
reasonCode: `current-symbol-explicit-source-replacement-${label}`
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function isCodeOffset(sourceText, offset) {
|
|
38
|
+
let state = 'code';
|
|
39
|
+
for (let index = 0; index < offset; index += 1) {
|
|
40
|
+
const char = sourceText[index];
|
|
41
|
+
const next = sourceText[index + 1];
|
|
42
|
+
if (state === 'line-comment') {
|
|
43
|
+
if (char === '\n' || char === '\r') state = 'code';
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
if (state === 'block-comment') {
|
|
47
|
+
if (char === '*' && next === '/') {
|
|
48
|
+
index += 1;
|
|
49
|
+
state = 'code';
|
|
50
|
+
}
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (state === 'single' || state === 'double' || state === 'template') {
|
|
54
|
+
if (char === '\\') {
|
|
55
|
+
index += 1;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if ((state === 'single' && char === "'") || (state === 'double' && char === '"') || (state === 'template' && char === '`')) state = 'code';
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (char === '/' && next === '/') {
|
|
62
|
+
index += 1;
|
|
63
|
+
state = 'line-comment';
|
|
64
|
+
} else if (char === '#') {
|
|
65
|
+
state = 'line-comment';
|
|
66
|
+
} else if (char === '/' && next === '*') {
|
|
67
|
+
index += 1;
|
|
68
|
+
state = 'block-comment';
|
|
69
|
+
} else if (char === "'") state = 'single';
|
|
70
|
+
else if (char === '"') state = 'double';
|
|
71
|
+
else if (char === '`') state = 'template';
|
|
72
|
+
}
|
|
73
|
+
return state === 'code';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function relativeAnchorRange(edit, symbolRange) {
|
|
77
|
+
if (!Number.isFinite(edit.headAnchorStart) || !Number.isFinite(edit.headAnchorEnd)) return undefined;
|
|
78
|
+
if (!Number.isFinite(edit.headStart) || !Number.isFinite(edit.headEnd)) return undefined;
|
|
79
|
+
const offset = edit.headStart - edit.headAnchorStart;
|
|
80
|
+
const length = edit.headEnd - edit.headStart;
|
|
81
|
+
if (offset < 0 || length < 0) return undefined;
|
|
82
|
+
const range = { start: symbolRange.start + offset, end: symbolRange.start + offset + length };
|
|
83
|
+
if (range.start < symbolRange.start || range.end > symbolRange.end) return undefined;
|
|
84
|
+
return { range, reasonCode: 'current-symbol-explicit-source-replacement-relative-offset' };
|
|
85
|
+
}
|
|
@@ -226,6 +226,10 @@ function semanticEditOperationKind(region) {
|
|
|
226
226
|
if (kind === 'import') return `${prefix}Import`;
|
|
227
227
|
if (kind === 'type') return `${prefix}TypeDeclaration`;
|
|
228
228
|
if (kind === 'property') return `${prefix}Property`;
|
|
229
|
+
if (kind === 'call') return `${prefix}Callsite`;
|
|
230
|
+
if (kind === 'controlFlow') return `${prefix}ControlFlow`;
|
|
231
|
+
if (kind === 'effect') return `${prefix}Effect`;
|
|
232
|
+
if (kind === 'mutation') return `${prefix}Mutation`;
|
|
229
233
|
return `${prefix}Region`;
|
|
230
234
|
}
|
|
231
235
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { hashSemanticValue } from '@shapeshift-labs/frontier-lang-kernel';
|
|
2
2
|
|
|
3
|
+
const nestedBodyCoveredKinds = new Set(['export', 'call', 'controlFlow', 'effect', 'mutation']);
|
|
4
|
+
|
|
3
5
|
export function projectionCoveredContainerOperationIds(operations, workerSourceText) {
|
|
4
6
|
if (typeof workerSourceText !== 'string') return new Set();
|
|
5
7
|
const result = new Set();
|
|
@@ -7,6 +9,9 @@ export function projectionCoveredContainerOperationIds(operations, workerSourceT
|
|
|
7
9
|
if (!isProjectionCoverableContainer(operation)) continue;
|
|
8
10
|
if (workerContainerCoveredByInsertedChildren(operation, operations, workerSourceText)) result.add(operation.id);
|
|
9
11
|
}
|
|
12
|
+
for (const operation of operations ?? []) {
|
|
13
|
+
if (operationCoveredByBody(operation, operations, workerSourceText)) result.add(operation.id);
|
|
14
|
+
}
|
|
10
15
|
return result;
|
|
11
16
|
}
|
|
12
17
|
|
|
@@ -111,6 +116,28 @@ function workerContainerCoveredByInsertedChildren(container, operations, workerS
|
|
|
111
116
|
return hashSemanticValue(stripped) === container.hashes.baseTextHash;
|
|
112
117
|
}
|
|
113
118
|
|
|
119
|
+
function operationCoveredByBody(operation, operations, workerSourceText) {
|
|
120
|
+
const kind = operation.anchor?.regionKind;
|
|
121
|
+
if (!nestedBodyCoveredKinds.has(kind)) return false;
|
|
122
|
+
if (!['added', 'modified'].includes(operation.changeKind)) return false;
|
|
123
|
+
const range = spanOffsets(workerSourceText, operation.spans?.worker);
|
|
124
|
+
if (!range) return false;
|
|
125
|
+
return (operations ?? []).some((candidate) => (
|
|
126
|
+
candidate.id !== operation.id
|
|
127
|
+
&& ['portable', 'already-applied'].includes(candidate.status)
|
|
128
|
+
&& candidate.anchor?.regionKind === 'body'
|
|
129
|
+
&& (kind !== 'export' || candidate.anchor?.symbolName === operation.anchor?.symbolName)
|
|
130
|
+
&& sameOperationSourcePath(candidate, operation)
|
|
131
|
+
&& containedRange(range, spanOffsets(workerSourceText, candidate.spans?.worker))
|
|
132
|
+
));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function sameOperationSourcePath(left, right) {
|
|
136
|
+
const leftPath = left.anchor?.sourcePath ?? left.insertion?.sourcePath;
|
|
137
|
+
const rightPath = right.anchor?.sourcePath ?? right.insertion?.sourcePath;
|
|
138
|
+
return !leftPath || !rightPath || leftPath === rightPath;
|
|
139
|
+
}
|
|
140
|
+
|
|
114
141
|
function containedRange(inner, outer) {
|
|
115
142
|
return Boolean(inner && outer && outer.start <= inner.start && inner.end <= outer.end);
|
|
116
143
|
}
|
|
@@ -35,6 +35,7 @@ export function semanticIndexFromNativeDeclarations(declarations, input, options
|
|
|
35
35
|
signatureHash: hashSemanticValue([input.language, declaration.nativeNode.kind, declaration.name, declaration.nativeNode.fields ?? {}]),
|
|
36
36
|
definitionSpan: declaration.nativeNode.span,
|
|
37
37
|
metadata: {
|
|
38
|
+
...declaration.nativeNode.metadata,
|
|
38
39
|
ownershipRegionId: ownershipRegion.id,
|
|
39
40
|
ownershipRegionKey: ownershipRegion.key,
|
|
40
41
|
ownershipRegionKind: ownershipRegion.regionKind
|
|
@@ -7,18 +7,20 @@ export function createSemanticPatchBundleAdmission(input = {}, context = {}) {
|
|
|
7
7
|
);
|
|
8
8
|
const evidenceAdmission = autoMergeEvidenceAdmission(context, { transformAdmission, semanticEditAdmission });
|
|
9
9
|
const fallbackReadiness = fallbackAdmissionReadiness(transformAdmission, semanticEditAdmission, evidenceAdmission, context.readiness);
|
|
10
|
-
const
|
|
11
|
-
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'
|
|
12
14
|
? evidenceAdmission.readiness
|
|
13
15
|
: inputReadiness;
|
|
14
16
|
const computedStatus = admissionStatusForReadiness(readiness, transformAdmission, semanticEditAdmission, evidenceAdmission);
|
|
15
|
-
const status = input.status
|
|
17
|
+
const status = safePatchBundleStatus(input.status, computedStatus);
|
|
16
18
|
const computedAutoApplyCandidate = status === 'admitted' &&
|
|
17
|
-
|
|
19
|
+
positiveApply &&
|
|
18
20
|
evidenceAdmission.action === 'admit';
|
|
19
21
|
const autoApplyCandidate = input.autoApplyCandidate === true ? computedAutoApplyCandidate : input.autoApplyCandidate ?? computedAutoApplyCandidate;
|
|
20
22
|
const admittedWithoutPositiveProof = status === 'admitted' &&
|
|
21
|
-
|
|
23
|
+
positiveApply &&
|
|
22
24
|
evidenceAdmission.action !== 'admit';
|
|
23
25
|
return compactRecord({
|
|
24
26
|
status,
|
|
@@ -72,10 +74,15 @@ function semanticTransformAdmission(context) {
|
|
|
72
74
|
transformKeys: strings(index.semanticTransformKeys),
|
|
73
75
|
contentHashes: strings(index.semanticTransformContentHashes),
|
|
74
76
|
projectionIdentityHashes: strings(index.projectionIdentityHashes),
|
|
77
|
+
baseHashes: strings(index.transformBaseHashes),
|
|
78
|
+
targetHashes: strings(index.transformTargetHashes),
|
|
75
79
|
sourceLanguages: strings(index.transformSourceLanguages),
|
|
76
80
|
targetLanguages: strings(index.transformTargetLanguages),
|
|
77
81
|
sourcePaths: strings(index.transformSourcePaths),
|
|
78
82
|
targetPaths: strings(index.transformTargetPaths),
|
|
83
|
+
sourceMapIds: strings(index.transformSourceMapIds),
|
|
84
|
+
sourceMapLinkIds: strings(index.transformSourceMapLinkIds),
|
|
85
|
+
sourceMapMappingIds: strings(index.transformSourceMapMappingIds),
|
|
79
86
|
evidenceIds: strings(index.semanticTransformEvidenceIds)
|
|
80
87
|
});
|
|
81
88
|
}
|
|
@@ -108,8 +115,12 @@ function autoMergeEvidenceAdmission(context, admissions) {
|
|
|
108
115
|
...array(context.source?.semanticPatch?.evidence),
|
|
109
116
|
...array(context.mergeCandidate?.evidence)
|
|
110
117
|
]);
|
|
111
|
-
const
|
|
112
|
-
|
|
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) };
|
|
113
124
|
const summary = summarizeAutoMergeEvidence(evidence);
|
|
114
125
|
const blocked = summary.failed > 0 || summary.conflict > 0;
|
|
115
126
|
const ready = !blocked && summary.stale === 0 && summary.passed > 0;
|
|
@@ -127,6 +138,23 @@ function autoMergeEvidenceAdmission(context, admissions) {
|
|
|
127
138
|
});
|
|
128
139
|
}
|
|
129
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
|
+
|
|
130
158
|
function summarizeAutoMergeEvidence(evidence) {
|
|
131
159
|
const testLike = evidence.filter(isAutoMergeTestEvidence);
|
|
132
160
|
const failed = testLike.filter((record) => evidenceStatus(record, ['failed', 'failure', 'error', 'blocked', 'rejected']));
|
|
@@ -167,6 +195,12 @@ function admissionStatusForReadiness(readiness, transformAdmission, semanticEdit
|
|
|
167
195
|
return readiness === 'needs-review' ? 'needs-review' : 'proposed';
|
|
168
196
|
}
|
|
169
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
|
+
|
|
170
204
|
function hasAdmissibleReadyAction(transformAdmission, semanticEditAdmission, evidenceAdmission) {
|
|
171
205
|
return hasSkipReadyAction(semanticEditAdmission) ||
|
|
172
206
|
(hasPositiveApplyAction(transformAdmission, semanticEditAdmission) && evidenceAdmission.action === 'admit');
|
|
@@ -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)
|