@shapeshift-labs/frontier-lang-compiler 0.2.24 → 0.2.25
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 +3 -1
- package/bench/smoke.mjs +19 -0
- package/dist/index.d.ts +91 -1
- package/dist/index.js +238 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -229,10 +229,12 @@ const changeSet = diffNativeSources({
|
|
|
229
229
|
|
|
230
230
|
console.log(changeSet.changedSymbols[0]?.changeKind); // "modified"
|
|
231
231
|
console.log(changeSet.changedRegions[0]?.conflictKey); // semantic ownership key
|
|
232
|
+
console.log(changeSet.changedRegions[0]?.metadata.changedRegionProjection.reviewRequired); // true
|
|
233
|
+
console.log(changeSet.metadata.changedRegionProjectionSummary.autoMergeClaims); // 0
|
|
232
234
|
console.log(changeSet.mergeCandidate.readiness); // merge-admission classification
|
|
233
235
|
```
|
|
234
236
|
|
|
235
|
-
Use `diffNativeSourceImports` when the worker or runner already produced `importNativeSource` results. Body-only edits that the lightweight scanner cannot anchor to a symbol are still reported as file-level changed regions instead of being silently treated as safe.
|
|
237
|
+
Use `diffNativeSourceImports` when the worker or runner already produced `importNativeSource` results. Changed regions include a `metadata.changedRegionProjection` envelope with before/after source hashes, source-map links, ownership keys, readiness, and `autoMergeClaim: false` so swarm admission tools can score or port patches without treating semantic metadata as proof. Body-only edits that the lightweight scanner cannot anchor to a symbol are still reported as file-level changed regions instead of being silently treated as safe.
|
|
236
238
|
|
|
237
239
|
Compile native source imports through the same reader/IR/writer facade that swarms use for sidecar evidence. Same-language targets preserve exact source when hashes match; cross-language targets emit declaration stubs until a real adapter provides stronger evidence:
|
|
238
240
|
|
package/bench/smoke.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
createProjectionTargetLossMatrix,
|
|
8
8
|
createNativeSourcePreservation,
|
|
9
9
|
createSemanticImportSidecar,
|
|
10
|
+
diffNativeSources,
|
|
10
11
|
importExternalSemanticIndex,
|
|
11
12
|
importNativeSource,
|
|
12
13
|
projectNativeImportToSource,
|
|
@@ -165,6 +166,20 @@ const regionScanDurationMs = performance.now() - regionScanStart;
|
|
|
165
166
|
const regionScanSymbols = regionScanImports.reduce((sum, entry) => sum + entry.imported.semanticIndex.symbols.length, 0);
|
|
166
167
|
const regionScanOwnershipRegions = regionScanImports.reduce((sum, entry) => sum + entry.sidecar.ownershipRegions.length, 0);
|
|
167
168
|
|
|
169
|
+
const changeProjectionStart = performance.now();
|
|
170
|
+
const changeProjectionSets = [];
|
|
171
|
+
for (let index = 0; index < 80; index += 1) {
|
|
172
|
+
changeProjectionSets.push(diffNativeSources({
|
|
173
|
+
language: 'javascript',
|
|
174
|
+
sourcePath: `src/change-projection-${index}.js`,
|
|
175
|
+
beforeSourceText: `export function changeProjection${index}() { return ${index}; }\n`,
|
|
176
|
+
afterSourceText: `export function changeProjection${index}() { return ${index + 1}; }\nexport const changeProjectionFlag${index} = true;\n`
|
|
177
|
+
}));
|
|
178
|
+
}
|
|
179
|
+
const changeProjectionDurationMs = performance.now() - changeProjectionStart;
|
|
180
|
+
const changedRegionProjections = changeProjectionSets.reduce((sum, changeSet) => sum + changeSet.metadata.changedRegionProjectionSummary.withProjection, 0);
|
|
181
|
+
const changedRegionProjectionSourceMapLinks = changeProjectionSets.reduce((sum, changeSet) => sum + changeSet.metadata.changedRegionProjectionSummary.sourceMapLinks, 0);
|
|
182
|
+
|
|
168
183
|
const externalSemanticStart = performance.now();
|
|
169
184
|
const externalSemanticImports = [];
|
|
170
185
|
for (let index = 0; index < 100; index += 1) {
|
|
@@ -242,6 +257,10 @@ console.log(JSON.stringify({
|
|
|
242
257
|
regionScanSymbols,
|
|
243
258
|
regionScanOwnershipRegions,
|
|
244
259
|
regionScanDurationMs: Number(regionScanDurationMs.toFixed(2)),
|
|
260
|
+
changeProjectionSets: changeProjectionSets.length,
|
|
261
|
+
changedRegionProjections,
|
|
262
|
+
changedRegionProjectionSourceMapLinks,
|
|
263
|
+
changeProjectionDurationMs: Number(changeProjectionDurationMs.toFixed(2)),
|
|
245
264
|
externalSemanticImports: externalSemanticImports.length,
|
|
246
265
|
externalSemanticSymbols,
|
|
247
266
|
externalSemanticMappings,
|
package/dist/index.d.ts
CHANGED
|
@@ -786,6 +786,91 @@ export interface SemanticImportSidecarOptions {
|
|
|
786
786
|
|
|
787
787
|
export type NativeSourceChangeKind = 'added' | 'removed' | 'modified' | 'unchanged';
|
|
788
788
|
|
|
789
|
+
export interface NativeSourceChangeProjectionEndpoint {
|
|
790
|
+
readonly side: 'before' | 'after';
|
|
791
|
+
readonly importId?: string;
|
|
792
|
+
readonly sidecarId?: string;
|
|
793
|
+
readonly nativeSourceId?: string;
|
|
794
|
+
readonly nativeAstId?: string;
|
|
795
|
+
readonly semanticIndexId?: string;
|
|
796
|
+
readonly universalAstId?: string;
|
|
797
|
+
readonly sourcePath?: string;
|
|
798
|
+
readonly sourceHash?: string;
|
|
799
|
+
readonly sourcePreservationId?: string;
|
|
800
|
+
readonly exactSourceAvailable: boolean;
|
|
801
|
+
readonly ownershipRegionId?: string;
|
|
802
|
+
readonly ownershipKey?: string;
|
|
803
|
+
readonly ownershipRegionKind?: NativeImportRegionTaxonomyKind;
|
|
804
|
+
readonly sourceSpan?: SourceSpan;
|
|
805
|
+
readonly sourceMapIds: readonly string[];
|
|
806
|
+
readonly sourceMapMappingIds: readonly string[];
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
export interface NativeSourceChangeProjectionSourceMapLink {
|
|
810
|
+
readonly id: string;
|
|
811
|
+
readonly side: 'before' | 'after';
|
|
812
|
+
readonly sourceMapId?: string;
|
|
813
|
+
readonly sourceMapMappingId?: string;
|
|
814
|
+
readonly sourcePath?: string;
|
|
815
|
+
readonly sourceHash?: string;
|
|
816
|
+
readonly targetPath?: string;
|
|
817
|
+
readonly targetHash?: string;
|
|
818
|
+
readonly semanticSymbolId?: string;
|
|
819
|
+
readonly semanticOccurrenceId?: string;
|
|
820
|
+
readonly semanticNodeId?: string;
|
|
821
|
+
readonly nativeSourceId?: string;
|
|
822
|
+
readonly nativeAstNodeId?: string;
|
|
823
|
+
readonly precision?: string;
|
|
824
|
+
readonly sourceSpan?: SourceSpan;
|
|
825
|
+
readonly generatedSpan?: SourceMapMappingRecord['generatedSpan'];
|
|
826
|
+
readonly ownershipRegionId?: string;
|
|
827
|
+
readonly ownershipRegionKey?: string;
|
|
828
|
+
readonly ownershipRegionKind?: NativeImportRegionTaxonomyKind;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
export interface NativeSourceChangeProjectionMetadata {
|
|
832
|
+
readonly schema: 'frontier.lang.changedRegionProjection.v1';
|
|
833
|
+
readonly id: string;
|
|
834
|
+
readonly reviewRequired: true;
|
|
835
|
+
readonly autoMergeClaim: false;
|
|
836
|
+
readonly changeKind: NativeSourceChangeKind;
|
|
837
|
+
readonly language?: FrontierSourceLanguage | string;
|
|
838
|
+
readonly sourcePath?: string;
|
|
839
|
+
readonly conflictKey: string;
|
|
840
|
+
readonly region: {
|
|
841
|
+
readonly id?: string;
|
|
842
|
+
readonly key?: string;
|
|
843
|
+
readonly kind?: NativeImportRegionTaxonomyKind;
|
|
844
|
+
readonly granularity?: string;
|
|
845
|
+
readonly precision?: string;
|
|
846
|
+
readonly sourceSpan?: SourceSpan;
|
|
847
|
+
readonly nativeAstNodeId?: string;
|
|
848
|
+
readonly symbolId?: string;
|
|
849
|
+
readonly symbolName?: string;
|
|
850
|
+
readonly symbolKind?: string;
|
|
851
|
+
};
|
|
852
|
+
readonly before?: NativeSourceChangeProjectionEndpoint;
|
|
853
|
+
readonly after?: NativeSourceChangeProjectionEndpoint;
|
|
854
|
+
readonly sourceMapLinks: readonly NativeSourceChangeProjectionSourceMapLink[];
|
|
855
|
+
readonly admission: {
|
|
856
|
+
readonly readiness: SemanticMergeReadiness;
|
|
857
|
+
readonly action: 'review-addition' | 'review-removal' | 'review-file' | 'review-port' | 'rerun-or-human-port' | string;
|
|
858
|
+
readonly reasons: readonly string[];
|
|
859
|
+
readonly conflictKeys: readonly string[];
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
export interface NativeSourceChangeProjectionSummary {
|
|
864
|
+
readonly schema: 'frontier.lang.changedRegionProjectionSummary.v1';
|
|
865
|
+
readonly total: number;
|
|
866
|
+
readonly withProjection: number;
|
|
867
|
+
readonly reviewRequired: number;
|
|
868
|
+
readonly autoMergeClaims: number;
|
|
869
|
+
readonly sourceMapLinks: number;
|
|
870
|
+
readonly byAction: Readonly<Record<string, number>>;
|
|
871
|
+
readonly byRegionKind: Readonly<Record<string, number>>;
|
|
872
|
+
}
|
|
873
|
+
|
|
789
874
|
export interface NativeSourceChangeSymbol {
|
|
790
875
|
readonly changeKind: NativeSourceChangeKind;
|
|
791
876
|
readonly key: string;
|
|
@@ -813,6 +898,9 @@ export interface NativeSourceChangeSymbol {
|
|
|
813
898
|
export interface NativeSourceChangeRegion extends SemanticImportOwnershipRegion {
|
|
814
899
|
readonly changeKind: NativeSourceChangeKind;
|
|
815
900
|
readonly conflictKey: string;
|
|
901
|
+
readonly metadata?: SemanticImportOwnershipRegion['metadata'] & {
|
|
902
|
+
readonly changedRegionProjection?: NativeSourceChangeProjectionMetadata;
|
|
903
|
+
};
|
|
816
904
|
}
|
|
817
905
|
|
|
818
906
|
export interface NativeSourceChangeSummary {
|
|
@@ -875,7 +963,9 @@ export interface NativeSourceChangeSet {
|
|
|
875
963
|
readonly semanticIndex?: SemanticIndexRecord;
|
|
876
964
|
readonly losses: readonly NativeAstLossRecord[];
|
|
877
965
|
readonly summary: NativeSourceChangeSummary;
|
|
878
|
-
readonly metadata?: Record<string, unknown
|
|
966
|
+
readonly metadata?: Record<string, unknown> & {
|
|
967
|
+
readonly changedRegionProjectionSummary?: NativeSourceChangeProjectionSummary;
|
|
968
|
+
};
|
|
879
969
|
}
|
|
880
970
|
|
|
881
971
|
export type NativeImporterAdapterExactness =
|
package/dist/index.js
CHANGED
|
@@ -3158,6 +3158,25 @@ export function diffNativeSourceImports(input) {
|
|
|
3158
3158
|
if (sourceChanged && changedSymbols.length === 0 && changedRegions.length === 0) {
|
|
3159
3159
|
changedRegions = [fileLevelNativeChangeRegion({ language, sourcePath, beforeHash, afterHash, before, after })];
|
|
3160
3160
|
}
|
|
3161
|
+
const readiness = maxSemanticMergeReadiness(
|
|
3162
|
+
maxSemanticMergeReadiness(nativeImportReadiness(before), nativeImportReadiness(after)),
|
|
3163
|
+
sourceChanged && changedSymbols.length === 0 ? 'needs-review' : 'ready'
|
|
3164
|
+
);
|
|
3165
|
+
const reasons = nativeSourceChangeReasons({ before, after, beforeHash, afterHash, changedSymbols, changedRegions, readiness });
|
|
3166
|
+
changedRegions = attachNativeChangeRegionProjectionMetadata(changedRegions, {
|
|
3167
|
+
before,
|
|
3168
|
+
after,
|
|
3169
|
+
beforeSidecar,
|
|
3170
|
+
afterSidecar,
|
|
3171
|
+
changedSymbols,
|
|
3172
|
+
language,
|
|
3173
|
+
sourcePath,
|
|
3174
|
+
beforeHash,
|
|
3175
|
+
afterHash,
|
|
3176
|
+
readiness,
|
|
3177
|
+
reasons
|
|
3178
|
+
});
|
|
3179
|
+
const changedRegionProjectionSummary = summarizeNativeChangedRegionProjections(changedRegions);
|
|
3161
3180
|
const evidence = [{
|
|
3162
3181
|
id: input.evidenceId ?? `evidence_${idPart}_native_source_diff`,
|
|
3163
3182
|
kind: 'import',
|
|
@@ -3172,14 +3191,10 @@ export function diffNativeSourceImports(input) {
|
|
|
3172
3191
|
sourceChanged,
|
|
3173
3192
|
addedSymbols: changedSymbols.filter((symbol) => symbol.changeKind === 'added').length,
|
|
3174
3193
|
removedSymbols: changedSymbols.filter((symbol) => symbol.changeKind === 'removed').length,
|
|
3175
|
-
modifiedSymbols: changedSymbols.filter((symbol) => symbol.changeKind === 'modified').length
|
|
3194
|
+
modifiedSymbols: changedSymbols.filter((symbol) => symbol.changeKind === 'modified').length,
|
|
3195
|
+
changedRegionProjectionSummary
|
|
3176
3196
|
}
|
|
3177
3197
|
}];
|
|
3178
|
-
const readiness = maxSemanticMergeReadiness(
|
|
3179
|
-
maxSemanticMergeReadiness(nativeImportReadiness(before), nativeImportReadiness(after)),
|
|
3180
|
-
sourceChanged && changedSymbols.length === 0 ? 'needs-review' : 'ready'
|
|
3181
|
-
);
|
|
3182
|
-
const reasons = nativeSourceChangeReasons({ before, after, beforeHash, afterHash, changedSymbols, changedRegions, readiness });
|
|
3183
3198
|
const conflictKeys = uniqueStrings([
|
|
3184
3199
|
...changedSymbols.map((symbol) => symbol.conflictKey),
|
|
3185
3200
|
...changedRegions.map((region) => region.conflictKey ?? region.key ?? region.id),
|
|
@@ -3230,7 +3245,8 @@ export function diffNativeSourceImports(input) {
|
|
|
3230
3245
|
beforeImportId: before?.id,
|
|
3231
3246
|
afterImportId: after?.id,
|
|
3232
3247
|
sourceChanged,
|
|
3233
|
-
changeSummary: nativeSourceChangeSummary(changedSymbols, changedRegions, sourceChanged)
|
|
3248
|
+
changeSummary: nativeSourceChangeSummary(changedSymbols, changedRegions, sourceChanged),
|
|
3249
|
+
changedRegionProjectionSummary
|
|
3234
3250
|
}
|
|
3235
3251
|
});
|
|
3236
3252
|
return {
|
|
@@ -3259,6 +3275,7 @@ export function diffNativeSourceImports(input) {
|
|
|
3259
3275
|
afterSidecarId: afterSidecar?.id,
|
|
3260
3276
|
beforeImportContract: before?.metadata?.importResultContract,
|
|
3261
3277
|
afterImportContract: after?.metadata?.importResultContract,
|
|
3278
|
+
changedRegionProjectionSummary,
|
|
3262
3279
|
...input.metadata
|
|
3263
3280
|
}
|
|
3264
3281
|
};
|
|
@@ -3404,6 +3421,199 @@ function fileLevelNativeChangeRegion(input) {
|
|
|
3404
3421
|
};
|
|
3405
3422
|
}
|
|
3406
3423
|
|
|
3424
|
+
function attachNativeChangeRegionProjectionMetadata(regions, context) {
|
|
3425
|
+
return (regions ?? []).map((region) => {
|
|
3426
|
+
const projection = nativeChangedRegionProjectionMetadata(region, context);
|
|
3427
|
+
return {
|
|
3428
|
+
...region,
|
|
3429
|
+
metadata: {
|
|
3430
|
+
...(region.metadata ?? {}),
|
|
3431
|
+
changedRegionProjection: projection
|
|
3432
|
+
}
|
|
3433
|
+
};
|
|
3434
|
+
});
|
|
3435
|
+
}
|
|
3436
|
+
|
|
3437
|
+
function nativeChangedRegionProjectionMetadata(region, context) {
|
|
3438
|
+
const beforeRegion = findSemanticImportRegion(context.beforeSidecar, region);
|
|
3439
|
+
const afterRegion = findSemanticImportRegion(context.afterSidecar, region);
|
|
3440
|
+
const regionSymbols = (context.changedSymbols ?? []).filter((symbol) => nativeChangeSymbolTouchesRegion(symbol, region));
|
|
3441
|
+
const sourceMapLinks = uniqueRecordsById([
|
|
3442
|
+
...nativeChangeProjectionSourceMapLinks(context.before, 'before', beforeRegion ?? region, regionSymbols),
|
|
3443
|
+
...nativeChangeProjectionSourceMapLinks(context.after, 'after', afterRegion ?? region, regionSymbols)
|
|
3444
|
+
]).slice(0, 24);
|
|
3445
|
+
const action = nativeChangedRegionProjectionAction(region, context.readiness);
|
|
3446
|
+
const conflictKeys = uniqueStrings([
|
|
3447
|
+
region.conflictKey,
|
|
3448
|
+
region.key ? `region:${region.key}` : undefined,
|
|
3449
|
+
region.id ? `region:${region.id}` : undefined,
|
|
3450
|
+
...regionSymbols.map((symbol) => symbol.conflictKey)
|
|
3451
|
+
].filter(Boolean));
|
|
3452
|
+
return {
|
|
3453
|
+
schema: 'frontier.lang.changedRegionProjection.v1',
|
|
3454
|
+
id: `changed_region_projection_${idFragment(region.conflictKey ?? region.key ?? region.id)}`,
|
|
3455
|
+
reviewRequired: true,
|
|
3456
|
+
autoMergeClaim: false,
|
|
3457
|
+
changeKind: region.changeKind,
|
|
3458
|
+
language: region.language ?? context.language,
|
|
3459
|
+
sourcePath: region.sourcePath ?? context.sourcePath,
|
|
3460
|
+
conflictKey: region.conflictKey,
|
|
3461
|
+
region: {
|
|
3462
|
+
id: region.id,
|
|
3463
|
+
key: region.key,
|
|
3464
|
+
kind: region.regionKind,
|
|
3465
|
+
granularity: region.granularity,
|
|
3466
|
+
precision: region.precision,
|
|
3467
|
+
sourceSpan: region.sourceSpan,
|
|
3468
|
+
nativeAstNodeId: region.nativeAstNodeId,
|
|
3469
|
+
symbolId: region.symbolId,
|
|
3470
|
+
symbolName: region.symbolName,
|
|
3471
|
+
symbolKind: region.symbolKind
|
|
3472
|
+
},
|
|
3473
|
+
before: nativeChangeProjectionEndpoint(context.before, context.beforeSidecar, beforeRegion ?? (region.changeKind === 'added' ? undefined : region), 'before'),
|
|
3474
|
+
after: nativeChangeProjectionEndpoint(context.after, context.afterSidecar, afterRegion ?? (region.changeKind === 'removed' ? undefined : region), 'after'),
|
|
3475
|
+
sourceMapLinks,
|
|
3476
|
+
admission: {
|
|
3477
|
+
readiness: context.readiness,
|
|
3478
|
+
action,
|
|
3479
|
+
reasons: context.reasons ?? [],
|
|
3480
|
+
conflictKeys
|
|
3481
|
+
}
|
|
3482
|
+
};
|
|
3483
|
+
}
|
|
3484
|
+
|
|
3485
|
+
function findSemanticImportRegion(sidecar, region) {
|
|
3486
|
+
return (sidecar?.ownershipRegions ?? []).find((candidate) => (
|
|
3487
|
+
(region.id && candidate.id === region.id) ||
|
|
3488
|
+
(region.key && candidate.key === region.key)
|
|
3489
|
+
));
|
|
3490
|
+
}
|
|
3491
|
+
|
|
3492
|
+
function nativeChangeProjectionEndpoint(imported, sidecar, region, side) {
|
|
3493
|
+
if (!imported && !region) return undefined;
|
|
3494
|
+
const preservation = nativeImportSourcePreservationRecord(imported);
|
|
3495
|
+
const sourceMaps = imported?.sourceMaps ?? imported?.universalAst?.sourceMaps ?? [];
|
|
3496
|
+
const regionMappings = sourceMaps
|
|
3497
|
+
.flatMap((sourceMap) => (sourceMap?.mappings ?? []).map((mapping) => ({ sourceMap, mapping })))
|
|
3498
|
+
.filter(({ mapping }) => nativeChangeMappingTouchesRegion(mapping, region, []));
|
|
3499
|
+
return {
|
|
3500
|
+
side,
|
|
3501
|
+
importId: imported?.id,
|
|
3502
|
+
sidecarId: sidecar?.id,
|
|
3503
|
+
nativeSourceId: imported?.nativeSource?.id,
|
|
3504
|
+
nativeAstId: imported?.nativeAst?.id,
|
|
3505
|
+
semanticIndexId: imported?.semanticIndex?.id,
|
|
3506
|
+
universalAstId: imported?.universalAst?.id,
|
|
3507
|
+
sourcePath: imported?.sourcePath ?? region?.sourcePath,
|
|
3508
|
+
sourceHash: imported?.nativeSource?.sourceHash ?? imported?.nativeAst?.sourceHash ?? region?.sourceHash,
|
|
3509
|
+
sourcePreservationId: preservation?.id,
|
|
3510
|
+
exactSourceAvailable: preservation?.summary?.exactSourceAvailable === true,
|
|
3511
|
+
ownershipRegionId: region?.id,
|
|
3512
|
+
ownershipKey: region?.key,
|
|
3513
|
+
ownershipRegionKind: region?.regionKind,
|
|
3514
|
+
sourceSpan: region?.sourceSpan,
|
|
3515
|
+
sourceMapIds: sourceMaps.map((sourceMap) => sourceMap?.id).filter(Boolean),
|
|
3516
|
+
sourceMapMappingIds: regionMappings.map(({ mapping }) => mapping?.id).filter(Boolean)
|
|
3517
|
+
};
|
|
3518
|
+
}
|
|
3519
|
+
|
|
3520
|
+
function nativeChangeProjectionSourceMapLinks(imported, side, region, symbols) {
|
|
3521
|
+
if (!imported) return [];
|
|
3522
|
+
const sourceMaps = imported.sourceMaps ?? imported.universalAst?.sourceMaps ?? [];
|
|
3523
|
+
const links = [];
|
|
3524
|
+
for (const sourceMap of sourceMaps) {
|
|
3525
|
+
for (const mapping of sourceMap?.mappings ?? []) {
|
|
3526
|
+
if (!nativeChangeMappingTouchesRegion(mapping, region, symbols)) continue;
|
|
3527
|
+
links.push({
|
|
3528
|
+
id: `${side}:${sourceMap.id}:${mapping.id}`,
|
|
3529
|
+
side,
|
|
3530
|
+
sourceMapId: sourceMap.id,
|
|
3531
|
+
sourceMapMappingId: mapping.id,
|
|
3532
|
+
sourcePath: mapping.sourceSpan?.path ?? sourceMap.sourcePath ?? imported.sourcePath,
|
|
3533
|
+
sourceHash: sourceMap.sourceHash ?? imported.nativeSource?.sourceHash ?? imported.nativeAst?.sourceHash,
|
|
3534
|
+
targetPath: mapping.generatedSpan?.targetPath ?? sourceMap.targetPath,
|
|
3535
|
+
targetHash: mapping.generatedSpan?.targetHash ?? sourceMap.targetHash,
|
|
3536
|
+
semanticSymbolId: mapping.semanticSymbolId,
|
|
3537
|
+
semanticOccurrenceId: mapping.semanticOccurrenceId,
|
|
3538
|
+
semanticNodeId: mapping.semanticNodeId,
|
|
3539
|
+
nativeSourceId: mapping.nativeSourceId,
|
|
3540
|
+
nativeAstNodeId: mapping.nativeAstNodeId,
|
|
3541
|
+
precision: mapping.precision,
|
|
3542
|
+
sourceSpan: mapping.sourceSpan,
|
|
3543
|
+
generatedSpan: mapping.generatedSpan,
|
|
3544
|
+
ownershipRegionId: mapping.ownershipRegionId,
|
|
3545
|
+
ownershipRegionKey: mapping.ownershipRegionKey,
|
|
3546
|
+
ownershipRegionKind: mapping.ownershipRegionKind
|
|
3547
|
+
});
|
|
3548
|
+
}
|
|
3549
|
+
}
|
|
3550
|
+
return links;
|
|
3551
|
+
}
|
|
3552
|
+
|
|
3553
|
+
function nativeChangeMappingTouchesRegion(mapping, region, symbols) {
|
|
3554
|
+
if (!mapping || !region) return false;
|
|
3555
|
+
const symbolIds = new Set((symbols ?? []).map((symbol) => symbol.id).filter(Boolean));
|
|
3556
|
+
const occurrenceIds = new Set((symbols ?? []).map((symbol) => symbol.semanticOccurrenceId).filter(Boolean));
|
|
3557
|
+
const mappingIds = new Set((symbols ?? []).map((symbol) => symbol.sourceMapMappingId).filter(Boolean));
|
|
3558
|
+
if (mappingIds.has(mapping.id)) return true;
|
|
3559
|
+
if (region.id && mapping.ownershipRegionId === region.id) return true;
|
|
3560
|
+
if (region.key && mapping.ownershipRegionKey === region.key) return true;
|
|
3561
|
+
if (region.nativeAstNodeId && mapping.nativeAstNodeId === region.nativeAstNodeId) return true;
|
|
3562
|
+
if (symbolIds.has(mapping.semanticSymbolId)) return true;
|
|
3563
|
+
if (occurrenceIds.has(mapping.semanticOccurrenceId)) return true;
|
|
3564
|
+
if (region.granularity === 'file') {
|
|
3565
|
+
return !region.sourcePath || sourceSpanPathMatches(mapping.sourceSpan, region.sourcePath);
|
|
3566
|
+
}
|
|
3567
|
+
return false;
|
|
3568
|
+
}
|
|
3569
|
+
|
|
3570
|
+
function sourceSpanPathMatches(span, sourcePath) {
|
|
3571
|
+
if (!span || !sourcePath) return false;
|
|
3572
|
+
return span.path === sourcePath || span.sourceId === sourcePath;
|
|
3573
|
+
}
|
|
3574
|
+
|
|
3575
|
+
function nativeChangeSymbolTouchesRegion(symbol, region) {
|
|
3576
|
+
return Boolean(symbol && region && (
|
|
3577
|
+
(region.id && symbol.ownershipRegionId === region.id) ||
|
|
3578
|
+
(region.key && (
|
|
3579
|
+
symbol.ownershipKey === region.key ||
|
|
3580
|
+
symbol.beforeOwnershipKey === region.key ||
|
|
3581
|
+
symbol.afterOwnershipKey === region.key
|
|
3582
|
+
))
|
|
3583
|
+
));
|
|
3584
|
+
}
|
|
3585
|
+
|
|
3586
|
+
function nativeChangedRegionProjectionAction(region, readiness) {
|
|
3587
|
+
if (readiness === 'blocked') return 'rerun-or-human-port';
|
|
3588
|
+
if (region.changeKind === 'added') return 'review-addition';
|
|
3589
|
+
if (region.changeKind === 'removed') return 'review-removal';
|
|
3590
|
+
if (region.granularity === 'file') return 'review-file';
|
|
3591
|
+
return 'review-port';
|
|
3592
|
+
}
|
|
3593
|
+
|
|
3594
|
+
function nativeImportSourcePreservationRecord(imported) {
|
|
3595
|
+
return imported?.metadata?.sourcePreservation
|
|
3596
|
+
?? imported?.nativeSource?.metadata?.sourcePreservation
|
|
3597
|
+
?? imported?.nativeAst?.metadata?.sourcePreservation
|
|
3598
|
+
?? imported?.universalAst?.metadata?.sourcePreservation;
|
|
3599
|
+
}
|
|
3600
|
+
|
|
3601
|
+
function summarizeNativeChangedRegionProjections(regions) {
|
|
3602
|
+
const projections = (regions ?? [])
|
|
3603
|
+
.map((region) => region?.metadata?.changedRegionProjection)
|
|
3604
|
+
.filter(Boolean);
|
|
3605
|
+
return {
|
|
3606
|
+
schema: 'frontier.lang.changedRegionProjectionSummary.v1',
|
|
3607
|
+
total: regions?.length ?? 0,
|
|
3608
|
+
withProjection: projections.length,
|
|
3609
|
+
reviewRequired: projections.filter((projection) => projection.reviewRequired === true).length,
|
|
3610
|
+
autoMergeClaims: projections.filter((projection) => projection.autoMergeClaim === true).length,
|
|
3611
|
+
sourceMapLinks: projections.reduce((sum, projection) => sum + (projection.sourceMapLinks?.length ?? 0), 0),
|
|
3612
|
+
byAction: countBy(projections.map((projection) => projection.admission?.action ?? 'unknown')),
|
|
3613
|
+
byRegionKind: countBy(projections.map((projection) => projection.region?.kind ?? 'unknown'))
|
|
3614
|
+
};
|
|
3615
|
+
}
|
|
3616
|
+
|
|
3407
3617
|
function nativeImportReadiness(imported) {
|
|
3408
3618
|
return imported?.metadata?.semanticMergeReadiness
|
|
3409
3619
|
?? imported?.metadata?.nativeImportLossSummary?.semanticMergeReadiness
|
|
@@ -3467,11 +3677,31 @@ function nativeChangeSpans(changedSymbols, changedRegions, input) {
|
|
|
3467
3677
|
symbolId: region.symbolId,
|
|
3468
3678
|
span: region.sourceSpan,
|
|
3469
3679
|
conflictKey: region.conflictKey ?? `region:${region.key ?? region.id}`,
|
|
3470
|
-
metadata: {
|
|
3680
|
+
metadata: {
|
|
3681
|
+
changeKind: region.changeKind,
|
|
3682
|
+
regionKind: region.regionKind,
|
|
3683
|
+
granularity: region.granularity,
|
|
3684
|
+
...(region.metadata?.changedRegionProjection ? {
|
|
3685
|
+
changedRegionProjection: nativeChangedRegionProjectionSpanMetadata(region.metadata.changedRegionProjection)
|
|
3686
|
+
} : {})
|
|
3687
|
+
}
|
|
3471
3688
|
}));
|
|
3472
3689
|
return uniqueRecordsById([...symbolSpans, ...regionSpans]);
|
|
3473
3690
|
}
|
|
3474
3691
|
|
|
3692
|
+
function nativeChangedRegionProjectionSpanMetadata(projection) {
|
|
3693
|
+
return {
|
|
3694
|
+
schema: projection.schema,
|
|
3695
|
+
id: projection.id,
|
|
3696
|
+
reviewRequired: projection.reviewRequired,
|
|
3697
|
+
autoMergeClaim: projection.autoMergeClaim,
|
|
3698
|
+
beforeSourceHash: projection.before?.sourceHash,
|
|
3699
|
+
afterSourceHash: projection.after?.sourceHash,
|
|
3700
|
+
sourceMapLinks: projection.sourceMapLinks?.length ?? 0,
|
|
3701
|
+
admission: projection.admission
|
|
3702
|
+
};
|
|
3703
|
+
}
|
|
3704
|
+
|
|
3475
3705
|
function nativeSourceChangeSummary(changedSymbols, changedRegions, sourceChanged) {
|
|
3476
3706
|
return {
|
|
3477
3707
|
sourceChanged,
|
package/package.json
CHANGED