@shapeshift-labs/frontier-lang-compiler 0.2.10 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +247 -0
- package/dist/index.js +728 -15
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -112,11 +112,23 @@ export type NativeImportKnownLossKind =
|
|
|
112
112
|
| 'parserDiagnostic'
|
|
113
113
|
| 'unsupportedSyntax'
|
|
114
114
|
| 'unsupportedSemantic'
|
|
115
|
+
| 'unverifiedNativeAst'
|
|
115
116
|
| 'partialSemanticIndex'
|
|
116
117
|
| 'sourceMapApproximation'
|
|
117
118
|
| 'targetProjectionLoss'
|
|
118
119
|
| string;
|
|
119
120
|
|
|
121
|
+
export type NativeImportRegionTaxonomyKind =
|
|
122
|
+
| 'symbol'
|
|
123
|
+
| 'declaration'
|
|
124
|
+
| 'import'
|
|
125
|
+
| 'body'
|
|
126
|
+
| 'call'
|
|
127
|
+
| 'type'
|
|
128
|
+
| 'effect'
|
|
129
|
+
| 'generatedOutput'
|
|
130
|
+
| string;
|
|
131
|
+
|
|
120
132
|
export interface NativeImportLossSummaryOptions {
|
|
121
133
|
readonly exactAst?: boolean;
|
|
122
134
|
readonly evidence?: readonly EvidenceRecord[];
|
|
@@ -216,6 +228,167 @@ export interface NativeImportCoverageMatrixOptions {
|
|
|
216
228
|
readonly generatedAt?: number;
|
|
217
229
|
}
|
|
218
230
|
|
|
231
|
+
export interface NativeImportContractSource {
|
|
232
|
+
readonly id: string;
|
|
233
|
+
readonly language?: FrontierSourceLanguage | string;
|
|
234
|
+
readonly sourcePath?: string;
|
|
235
|
+
readonly sourceHash?: string;
|
|
236
|
+
readonly parser?: string;
|
|
237
|
+
readonly nativeSourceId?: string;
|
|
238
|
+
readonly nativeAstId?: string;
|
|
239
|
+
readonly semanticIndexId?: string;
|
|
240
|
+
readonly universalAstId?: string;
|
|
241
|
+
readonly patchId?: string;
|
|
242
|
+
readonly sourceMapIds: readonly string[];
|
|
243
|
+
readonly sourceMapMappings: number;
|
|
244
|
+
readonly symbolCount: number;
|
|
245
|
+
readonly lossCount: number;
|
|
246
|
+
readonly evidenceCount: number;
|
|
247
|
+
readonly readiness?: SemanticMergeReadiness;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
export interface NativeImportSourcePreservationRecordSummary {
|
|
251
|
+
readonly id?: string;
|
|
252
|
+
readonly language?: FrontierSourceLanguage | string;
|
|
253
|
+
readonly sourcePath?: string;
|
|
254
|
+
readonly sourceHash?: string;
|
|
255
|
+
readonly sourceBytes?: number;
|
|
256
|
+
readonly lineCount?: number;
|
|
257
|
+
readonly newline?: string;
|
|
258
|
+
readonly encoding?: string;
|
|
259
|
+
readonly exactSourceAvailable: boolean;
|
|
260
|
+
readonly tokens: number;
|
|
261
|
+
readonly trivia: number;
|
|
262
|
+
readonly directives: number;
|
|
263
|
+
readonly comments: number;
|
|
264
|
+
readonly whitespace: number;
|
|
265
|
+
readonly truncated: boolean;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export interface NativeImportSourcePreservationContract {
|
|
269
|
+
readonly total: number;
|
|
270
|
+
readonly ids: readonly string[];
|
|
271
|
+
readonly sourcePaths: readonly string[];
|
|
272
|
+
readonly sourceHashes: readonly string[];
|
|
273
|
+
readonly exactSourceAvailable: number;
|
|
274
|
+
readonly sourceBytes: number;
|
|
275
|
+
readonly lineCount: number;
|
|
276
|
+
readonly tokens: number;
|
|
277
|
+
readonly trivia: number;
|
|
278
|
+
readonly directives: number;
|
|
279
|
+
readonly comments: number;
|
|
280
|
+
readonly whitespace: number;
|
|
281
|
+
readonly truncated: boolean;
|
|
282
|
+
readonly records: readonly NativeImportSourcePreservationRecordSummary[];
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
export interface NativeImportAdapterCoverageRecordSummary {
|
|
286
|
+
readonly adapterId?: string;
|
|
287
|
+
readonly adapterVersion?: string;
|
|
288
|
+
readonly parser?: string;
|
|
289
|
+
readonly capabilities: readonly string[];
|
|
290
|
+
readonly supportedExtensions: readonly string[];
|
|
291
|
+
readonly exactness?: NativeImporterAdapterExactness;
|
|
292
|
+
readonly exactAst: boolean;
|
|
293
|
+
readonly tokens: boolean;
|
|
294
|
+
readonly trivia: boolean;
|
|
295
|
+
readonly diagnostics: boolean;
|
|
296
|
+
readonly sourceRanges: boolean;
|
|
297
|
+
readonly generatedRanges: boolean;
|
|
298
|
+
readonly semanticCoverage?: NativeImporterAdapterSemanticCoverage;
|
|
299
|
+
readonly observed?: NativeImporterAdapterCoverageObserved;
|
|
300
|
+
readonly notes: readonly string[];
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
export interface NativeImportAdapterCoverageContract {
|
|
304
|
+
readonly total: number;
|
|
305
|
+
readonly adapterIds: readonly string[];
|
|
306
|
+
readonly parsers: readonly string[];
|
|
307
|
+
readonly exactness: readonly string[];
|
|
308
|
+
readonly exactAst: number;
|
|
309
|
+
readonly tokens: number;
|
|
310
|
+
readonly trivia: number;
|
|
311
|
+
readonly diagnostics: number;
|
|
312
|
+
readonly sourceRanges: number;
|
|
313
|
+
readonly generatedRanges: number;
|
|
314
|
+
readonly semanticCoverageLevels: readonly string[];
|
|
315
|
+
readonly observed: NativeImporterAdapterCoverageObserved;
|
|
316
|
+
readonly records: readonly NativeImportAdapterCoverageRecordSummary[];
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
export interface NativeImportRegionSummary {
|
|
320
|
+
readonly total: number;
|
|
321
|
+
readonly ids: readonly string[];
|
|
322
|
+
readonly keys: readonly string[];
|
|
323
|
+
readonly sourcePaths: readonly string[];
|
|
324
|
+
readonly byKind: Readonly<Record<string, number>>;
|
|
325
|
+
readonly byGranularity: Readonly<Record<string, number>>;
|
|
326
|
+
readonly byPrecision: Readonly<Record<string, number>>;
|
|
327
|
+
readonly byLanguage: Readonly<Record<string, number>>;
|
|
328
|
+
readonly symbolIds: readonly string[];
|
|
329
|
+
readonly taxonomy: SemanticImportRegionTaxonomySummary;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export interface NativeImportSourceMapSummary {
|
|
333
|
+
readonly total: number;
|
|
334
|
+
readonly ids: readonly string[];
|
|
335
|
+
readonly mappingCount: number;
|
|
336
|
+
readonly sourcePaths: readonly string[];
|
|
337
|
+
readonly targetPaths: readonly string[];
|
|
338
|
+
readonly byPrecision: Readonly<Record<string, number>>;
|
|
339
|
+
readonly sourceRangeMappings: number;
|
|
340
|
+
readonly generatedRangeMappings: number;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
export interface NativeImportReadinessContract {
|
|
344
|
+
readonly semanticMergeReadiness: SemanticMergeReadiness;
|
|
345
|
+
readonly severityReadiness: SemanticMergeReadiness;
|
|
346
|
+
readonly reasons: readonly string[];
|
|
347
|
+
readonly failedEvidenceIds: readonly string[];
|
|
348
|
+
readonly blockingLossIds: readonly string[];
|
|
349
|
+
readonly reviewLossIds: readonly string[];
|
|
350
|
+
readonly informationalLossIds: readonly string[];
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export interface NativeImportResultContract {
|
|
354
|
+
readonly kind: 'frontier.lang.nativeImportResultContract';
|
|
355
|
+
readonly version: 1;
|
|
356
|
+
readonly importResultId?: string;
|
|
357
|
+
readonly language?: FrontierSourceLanguage | 'mixed' | string;
|
|
358
|
+
readonly sourcePath?: string;
|
|
359
|
+
readonly sourceHash?: string;
|
|
360
|
+
readonly sourceCount: number;
|
|
361
|
+
readonly sources: readonly NativeImportContractSource[];
|
|
362
|
+
readonly ids: {
|
|
363
|
+
readonly nativeSourceId?: string;
|
|
364
|
+
readonly nativeAstId?: string;
|
|
365
|
+
readonly semanticIndexId?: string;
|
|
366
|
+
readonly universalAstId?: string;
|
|
367
|
+
readonly patchId?: string;
|
|
368
|
+
readonly sourceMapIds: readonly string[];
|
|
369
|
+
readonly semanticSidecarIds: readonly string[];
|
|
370
|
+
};
|
|
371
|
+
readonly sourcePreservation: NativeImportSourcePreservationContract;
|
|
372
|
+
readonly adapterCoverage: NativeImportAdapterCoverageContract;
|
|
373
|
+
readonly lossSummary: NativeImportLossSummary;
|
|
374
|
+
readonly regions: NativeImportRegionSummary;
|
|
375
|
+
readonly sourceMaps: NativeImportSourceMapSummary;
|
|
376
|
+
readonly readiness: NativeImportReadinessContract;
|
|
377
|
+
readonly evidence: {
|
|
378
|
+
readonly total: number;
|
|
379
|
+
readonly failed: readonly string[];
|
|
380
|
+
readonly ids: readonly string[];
|
|
381
|
+
};
|
|
382
|
+
readonly metadata: Record<string, unknown>;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export interface NativeImportResultContractOptions extends SemanticImportSidecarOptions {
|
|
386
|
+
readonly lossSummary?: NativeImportLossSummary;
|
|
387
|
+
readonly semanticSidecarIds?: readonly string[] | string;
|
|
388
|
+
readonly sidecarIds?: readonly string[] | string;
|
|
389
|
+
readonly sidecarId?: string;
|
|
390
|
+
}
|
|
391
|
+
|
|
219
392
|
export type NativeSourceTokenKind =
|
|
220
393
|
| 'identifier'
|
|
221
394
|
| 'keyword'
|
|
@@ -295,8 +468,10 @@ export interface CreateNativeSourcePreservationOptions {
|
|
|
295
468
|
export interface SemanticImportOwnershipRegion {
|
|
296
469
|
readonly id: string;
|
|
297
470
|
readonly key: string;
|
|
471
|
+
readonly regionKind?: NativeImportRegionTaxonomyKind;
|
|
298
472
|
readonly granularity: 'symbol' | string;
|
|
299
473
|
readonly language?: FrontierSourceLanguage | string;
|
|
474
|
+
readonly documentId?: string;
|
|
300
475
|
readonly sourcePath?: string;
|
|
301
476
|
readonly sourceHash?: string;
|
|
302
477
|
readonly symbolId?: string;
|
|
@@ -306,6 +481,7 @@ export interface SemanticImportOwnershipRegion {
|
|
|
306
481
|
readonly sourceSpan?: SourceSpan;
|
|
307
482
|
readonly precision?: 'exact' | 'declaration' | 'line' | 'estimated' | 'unknown' | string;
|
|
308
483
|
readonly mergePolicy?: string;
|
|
484
|
+
readonly metadata?: Record<string, unknown>;
|
|
309
485
|
}
|
|
310
486
|
|
|
311
487
|
export interface SemanticImportSidecarSymbol {
|
|
@@ -320,9 +496,18 @@ export interface SemanticImportSidecarSymbol {
|
|
|
320
496
|
readonly signatureHash?: string;
|
|
321
497
|
readonly ownershipRegionId: string;
|
|
322
498
|
readonly ownershipKey: string;
|
|
499
|
+
readonly ownershipRegionKind?: NativeImportRegionTaxonomyKind;
|
|
323
500
|
readonly readiness: SemanticMergeReadiness;
|
|
324
501
|
}
|
|
325
502
|
|
|
503
|
+
export interface SemanticImportRegionTaxonomySummary {
|
|
504
|
+
readonly kinds: readonly NativeImportRegionTaxonomyKind[];
|
|
505
|
+
readonly presentKinds: readonly NativeImportRegionTaxonomyKind[];
|
|
506
|
+
readonly byKind: Readonly<Record<string, number>>;
|
|
507
|
+
readonly keys: readonly string[];
|
|
508
|
+
readonly keysByKind: Readonly<Record<string, readonly string[]>>;
|
|
509
|
+
}
|
|
510
|
+
|
|
326
511
|
export interface SemanticImportPatchHint {
|
|
327
512
|
readonly id: string;
|
|
328
513
|
readonly kind: 'source-region-patch' | string;
|
|
@@ -356,6 +541,7 @@ export interface SemanticImportSidecarImportEntry {
|
|
|
356
541
|
readonly sourceMapMappingCount: number;
|
|
357
542
|
readonly readiness: SemanticMergeReadiness;
|
|
358
543
|
readonly emptySemanticIndex: boolean;
|
|
544
|
+
readonly regionTaxonomy?: SemanticImportRegionTaxonomySummary;
|
|
359
545
|
}
|
|
360
546
|
|
|
361
547
|
export interface SemanticImportSidecar {
|
|
@@ -389,6 +575,7 @@ export interface SemanticImportSidecar {
|
|
|
389
575
|
readonly blockingLossIds: readonly string[];
|
|
390
576
|
readonly reviewLossIds: readonly string[];
|
|
391
577
|
};
|
|
578
|
+
readonly regionTaxonomy: SemanticImportRegionTaxonomySummary;
|
|
392
579
|
readonly evidence: {
|
|
393
580
|
readonly total: number;
|
|
394
581
|
readonly failed: readonly string[];
|
|
@@ -398,6 +585,7 @@ export interface SemanticImportSidecar {
|
|
|
398
585
|
readonly imports: number;
|
|
399
586
|
readonly symbols: number;
|
|
400
587
|
readonly ownershipRegions: number;
|
|
588
|
+
readonly regionKinds: number;
|
|
401
589
|
readonly sourceMapMappings: number;
|
|
402
590
|
readonly readiness: SemanticMergeReadiness;
|
|
403
591
|
readonly emptySemanticIndex: boolean;
|
|
@@ -511,6 +699,7 @@ export interface ImportNativeSourceOptions {
|
|
|
511
699
|
readonly sourceMaps?: readonly SourceMapRecord[];
|
|
512
700
|
readonly universalAstId?: string;
|
|
513
701
|
readonly universalAstMetadata?: Record<string, unknown>;
|
|
702
|
+
readonly exactAst?: boolean;
|
|
514
703
|
readonly metadata?: Record<string, unknown>;
|
|
515
704
|
}
|
|
516
705
|
|
|
@@ -724,9 +913,65 @@ export interface NativeSourceProjectionResult {
|
|
|
724
913
|
readonly metadata: Record<string, unknown>;
|
|
725
914
|
}
|
|
726
915
|
|
|
916
|
+
export type NativeImportRoundtripReadinessStatus =
|
|
917
|
+
| 'exact'
|
|
918
|
+
| 'preserved-source'
|
|
919
|
+
| 'stub-only'
|
|
920
|
+
| 'blocked'
|
|
921
|
+
| 'needs-review';
|
|
922
|
+
|
|
923
|
+
export interface NativeImportRoundtripReadinessOptions extends ProjectNativeImportToSourceOptions {
|
|
924
|
+
readonly projection?: NativeSourceProjectionResult;
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
export interface NativeImportRoundtripReadinessClassification {
|
|
928
|
+
readonly kind: 'frontier.lang.nativeImportRoundtripReadiness';
|
|
929
|
+
readonly version: 1;
|
|
930
|
+
readonly status: NativeImportRoundtripReadinessStatus;
|
|
931
|
+
readonly semanticMergeReadiness: SemanticMergeReadiness;
|
|
932
|
+
readonly reasons: readonly string[];
|
|
933
|
+
readonly importReadiness: NativeImportReadinessClassification;
|
|
934
|
+
readonly projectionReadiness: NativeImportReadinessClassification;
|
|
935
|
+
readonly projectionMode: NativeSourceProjectionMode;
|
|
936
|
+
readonly checks: {
|
|
937
|
+
readonly nativeImport: {
|
|
938
|
+
readonly imports: number;
|
|
939
|
+
readonly exactAst: boolean;
|
|
940
|
+
readonly losses: number;
|
|
941
|
+
readonly readiness: SemanticMergeReadiness;
|
|
942
|
+
};
|
|
943
|
+
readonly universalAst: {
|
|
944
|
+
readonly present: boolean;
|
|
945
|
+
readonly valid: boolean;
|
|
946
|
+
readonly issues: readonly string[];
|
|
947
|
+
readonly nativeSources: number;
|
|
948
|
+
readonly semanticSymbols: number;
|
|
949
|
+
readonly sourceMaps: number;
|
|
950
|
+
readonly sourceMapMappings: number;
|
|
951
|
+
};
|
|
952
|
+
readonly projectedSource: {
|
|
953
|
+
readonly mode: NativeSourceProjectionMode;
|
|
954
|
+
readonly outputHash: string;
|
|
955
|
+
readonly expectedSourceHash?: string;
|
|
956
|
+
readonly sourceHashVerified: boolean;
|
|
957
|
+
readonly declarations: number;
|
|
958
|
+
readonly losses: number;
|
|
959
|
+
readonly readiness: SemanticMergeReadiness;
|
|
960
|
+
};
|
|
961
|
+
};
|
|
962
|
+
readonly evidence: {
|
|
963
|
+
readonly importEvidenceIds: readonly string[];
|
|
964
|
+
readonly projectionEvidenceIds: readonly string[];
|
|
965
|
+
readonly failedEvidenceIds: readonly string[];
|
|
966
|
+
};
|
|
967
|
+
readonly metadata: Record<string, unknown>;
|
|
968
|
+
}
|
|
969
|
+
|
|
727
970
|
export declare const FrontierCompileTargets: readonly FrontierCompileTarget[];
|
|
971
|
+
export declare const NativeImportRoundtripReadinessStatuses: readonly NativeImportRoundtripReadinessStatus[];
|
|
728
972
|
export declare const NativeImportTaxonomyKinds: readonly NativeImportTaxonomyKind[];
|
|
729
973
|
export declare const NativeImportLossKinds: readonly NativeImportKnownLossKind[];
|
|
974
|
+
export declare const NativeImportRegionTaxonomyKinds: readonly NativeImportRegionTaxonomyKind[];
|
|
730
975
|
export declare const NativeImportReadinessBySeverity: Readonly<Record<NativeImportLossSummary['highestSeverity'], SemanticMergeReadiness>>;
|
|
731
976
|
export declare const NativeImportLanguageProfiles: readonly NativeImportLanguageProfile[];
|
|
732
977
|
export declare function normalizeCompileTarget(target?: string): FrontierCompileTarget;
|
|
@@ -737,9 +982,11 @@ export declare function renderTargetAst(ast: FrontierTargetAst, target?: Frontie
|
|
|
737
982
|
export declare function resolveCapabilityAdapters(document: FrontierLangDocument, target?: FrontierCompileOptions['target'], options?: { readonly platform?: string }): readonly CapabilityResolution[];
|
|
738
983
|
export declare function summarizeNativeImportLosses(losses?: readonly NativeAstLossRecord[], options?: NativeImportLossSummaryOptions): NativeImportLossSummary;
|
|
739
984
|
export declare function classifyNativeImportReadiness(losses?: readonly NativeAstLossRecord[], options?: NativeImportLossSummaryOptions): NativeImportReadinessClassification;
|
|
985
|
+
export declare function classifyNativeImportRoundtripReadiness(importResult: NativeSourceImportResult | NativeProjectImportResult, options?: NativeImportRoundtripReadinessOptions): NativeImportRoundtripReadinessClassification;
|
|
740
986
|
export declare function createNativeImportCoverageMatrix(options?: NativeImportCoverageMatrixOptions): NativeImportCoverageMatrix;
|
|
741
987
|
export declare function createNativeSourcePreservation(options: CreateNativeSourcePreservationOptions): NativeSourcePreservation;
|
|
742
988
|
export declare function createSemanticImportSidecar(importResult: NativeSourceImportResult | NativeProjectImportResult, options?: SemanticImportSidecarOptions): SemanticImportSidecar;
|
|
989
|
+
export declare function createNativeImportResultContract(importResult: NativeSourceImportResult | NativeProjectImportResult, options?: NativeImportResultContractOptions): NativeImportResultContract;
|
|
743
990
|
export declare function createEstreeNativeImporterAdapter(options?: JavaScriptNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
744
991
|
export declare function createBabelNativeImporterAdapter(options?: JavaScriptNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
745
992
|
export declare function createTypeScriptCompilerNativeImporterAdapter(options?: TypeScriptCompilerNativeImporterAdapterOptions): NativeImporterAdapter;
|
package/dist/index.js
CHANGED
|
@@ -67,6 +67,14 @@ const semanticMergeReadinessRank = Object.freeze({
|
|
|
67
67
|
blocked: 3
|
|
68
68
|
});
|
|
69
69
|
|
|
70
|
+
export const NativeImportRoundtripReadinessStatuses = Object.freeze([
|
|
71
|
+
'exact',
|
|
72
|
+
'preserved-source',
|
|
73
|
+
'stub-only',
|
|
74
|
+
'blocked',
|
|
75
|
+
'needs-review'
|
|
76
|
+
]);
|
|
77
|
+
|
|
70
78
|
export const NativeImportTaxonomyKinds = Object.freeze([
|
|
71
79
|
'exactAstImport',
|
|
72
80
|
'declarationsOnly',
|
|
@@ -106,6 +114,7 @@ export const NativeImportLossKinds = Object.freeze([
|
|
|
106
114
|
'parserDiagnostic',
|
|
107
115
|
'unsupportedSyntax',
|
|
108
116
|
'unsupportedSemantic',
|
|
117
|
+
'unverifiedNativeAst',
|
|
109
118
|
'partialSemanticIndex',
|
|
110
119
|
'sourceMapApproximation',
|
|
111
120
|
'targetProjectionLoss'
|
|
@@ -118,6 +127,17 @@ export const NativeImportReadinessBySeverity = Object.freeze({
|
|
|
118
127
|
error: 'blocked'
|
|
119
128
|
});
|
|
120
129
|
|
|
130
|
+
export const NativeImportRegionTaxonomyKinds = Object.freeze([
|
|
131
|
+
'symbol',
|
|
132
|
+
'declaration',
|
|
133
|
+
'import',
|
|
134
|
+
'body',
|
|
135
|
+
'call',
|
|
136
|
+
'type',
|
|
137
|
+
'effect',
|
|
138
|
+
'generatedOutput'
|
|
139
|
+
]);
|
|
140
|
+
|
|
121
141
|
export const NativeImportLanguageProfiles = Object.freeze([
|
|
122
142
|
nativeImportLanguageProfile('javascript', {
|
|
123
143
|
aliases: ['js', 'mjs', 'cjs', 'jsx'],
|
|
@@ -327,6 +347,134 @@ export function classifyNativeImportReadiness(losses = [], options = {}) {
|
|
|
327
347
|
};
|
|
328
348
|
}
|
|
329
349
|
|
|
350
|
+
export function classifyNativeImportRoundtripReadiness(importResult, options = {}) {
|
|
351
|
+
if (!importResult || typeof importResult !== 'object') {
|
|
352
|
+
throw new Error('classifyNativeImportRoundtripReadiness requires a native import result');
|
|
353
|
+
}
|
|
354
|
+
const imports = nativeImportEntries(importResult);
|
|
355
|
+
const importLosses = uniqueByLossId([
|
|
356
|
+
...(importResult.losses ?? []),
|
|
357
|
+
...imports.flatMap((imported) => imported?.losses ?? [])
|
|
358
|
+
]);
|
|
359
|
+
const importEvidence = uniqueByEvidenceId([
|
|
360
|
+
...(importResult.evidence ?? []),
|
|
361
|
+
...imports.flatMap((imported) => imported?.evidence ?? [])
|
|
362
|
+
]);
|
|
363
|
+
const exactAst = imports.length > 0 && imports.every((imported) => nativeImportHasExactAstCoverage(imported));
|
|
364
|
+
const importReadiness = classifyNativeImportReadiness(importLosses, {
|
|
365
|
+
exactAst,
|
|
366
|
+
evidence: importEvidence,
|
|
367
|
+
parser: nativeImportRoundtripParser(importResult, imports),
|
|
368
|
+
scanKind: importResult.metadata?.nativeImportLossSummary?.scanKind,
|
|
369
|
+
semanticStatus: importResult.metadata?.semanticStatus ?? importResult.universalAst?.metadata?.semanticStatus
|
|
370
|
+
});
|
|
371
|
+
const projection = options.projection ?? projectNativeImportToSource(importResult, options);
|
|
372
|
+
const projectionReadiness = projection.readiness ?? classifyNativeImportReadiness(projection.losses ?? [], {
|
|
373
|
+
evidence: projection.evidence,
|
|
374
|
+
parser: projection.metadata?.nativeImportLossSummary?.parser,
|
|
375
|
+
scanKind: 'native-source-projection'
|
|
376
|
+
});
|
|
377
|
+
const universalAst = importResult.universalAst;
|
|
378
|
+
const universalAstIssues = universalAst
|
|
379
|
+
? validateUniversalAstEnvelope(universalAst)
|
|
380
|
+
: ['missing-universal-ast'];
|
|
381
|
+
const universalAstNativeSources = universalAst?.nativeSources?.length ?? importResult.nativeSources?.length ?? (importResult.nativeSource ? 1 : 0);
|
|
382
|
+
const semanticIndex = importResult.semanticIndex ?? universalAst?.semanticIndex;
|
|
383
|
+
const semanticSymbols = semanticIndex?.symbols?.length ?? 0;
|
|
384
|
+
const sourceMaps = importResult.sourceMaps ?? universalAst?.sourceMaps ?? [];
|
|
385
|
+
const sourceMapMappings = sourceMaps.reduce((sum, sourceMap) => sum + (sourceMap?.mappings?.length ?? 0), 0);
|
|
386
|
+
const projectionMatchesSourceHash = Boolean(projection.sourceHash && projection.outputHash === projection.sourceHash);
|
|
387
|
+
const preservedSource = projection.mode === 'preserved-source';
|
|
388
|
+
const failedEvidenceIds = uniqueStrings([
|
|
389
|
+
...importEvidence.filter((record) => record?.status === 'failed').map((record) => record.id),
|
|
390
|
+
...(projection.evidence ?? []).filter((record) => record?.status === 'failed').map((record) => record.id)
|
|
391
|
+
]);
|
|
392
|
+
const blockingReasons = [
|
|
393
|
+
...(importReadiness.readiness === 'blocked' ? importReadiness.reasons : []),
|
|
394
|
+
...(projectionReadiness.readiness === 'blocked' ? projectionReadiness.reasons : []),
|
|
395
|
+
...(failedEvidenceIds.length ? [`Failed evidence prevents native roundtrip readiness: ${failedEvidenceIds.join(', ')}`] : []),
|
|
396
|
+
...(universalAstIssues.length ? [`Universal AST validation failed: ${universalAstIssues.join('; ')}`] : [])
|
|
397
|
+
];
|
|
398
|
+
const reviewReasons = [
|
|
399
|
+
...(semanticSymbols === 0 ? ['Universal AST semantic index has no symbols for source projection review.'] : []),
|
|
400
|
+
...(sourceMapMappings === 0 ? ['Universal AST has no native source-map mappings for roundtrip review.'] : []),
|
|
401
|
+
...(preservedSource && !projectionMatchesSourceHash ? ['Projected source was preserved without a verified import source hash match.'] : []),
|
|
402
|
+
...importReadiness.reasons.filter((reason) => importReadiness.readiness !== 'ready' || !exactAst),
|
|
403
|
+
...projectionReadiness.reasons.filter((reason) => projectionReadiness.readiness !== 'ready')
|
|
404
|
+
];
|
|
405
|
+
let status;
|
|
406
|
+
if (blockingReasons.length) {
|
|
407
|
+
status = 'blocked';
|
|
408
|
+
} else if (projection.mode === 'native-source-stubs') {
|
|
409
|
+
status = 'stub-only';
|
|
410
|
+
} else if (reviewReasons.some((reason) => reason.startsWith('Universal AST')) || (preservedSource && !projectionMatchesSourceHash)) {
|
|
411
|
+
status = 'needs-review';
|
|
412
|
+
} else if (exactAst && preservedSource && projectionMatchesSourceHash && projectionReadiness.readiness === 'ready') {
|
|
413
|
+
status = 'exact';
|
|
414
|
+
} else if (preservedSource && projectionMatchesSourceHash) {
|
|
415
|
+
status = 'preserved-source';
|
|
416
|
+
} else {
|
|
417
|
+
status = 'needs-review';
|
|
418
|
+
}
|
|
419
|
+
const reasons = nativeImportRoundtripReasons(status, {
|
|
420
|
+
blockingReasons,
|
|
421
|
+
reviewReasons,
|
|
422
|
+
projection,
|
|
423
|
+
importReadiness,
|
|
424
|
+
projectionReadiness
|
|
425
|
+
});
|
|
426
|
+
return {
|
|
427
|
+
kind: 'frontier.lang.nativeImportRoundtripReadiness',
|
|
428
|
+
version: 1,
|
|
429
|
+
status,
|
|
430
|
+
semanticMergeReadiness: maxSemanticMergeReadiness(importReadiness.readiness, projectionReadiness.readiness),
|
|
431
|
+
reasons,
|
|
432
|
+
importReadiness,
|
|
433
|
+
projectionReadiness,
|
|
434
|
+
projectionMode: projection.mode,
|
|
435
|
+
checks: {
|
|
436
|
+
nativeImport: {
|
|
437
|
+
imports: imports.length,
|
|
438
|
+
exactAst,
|
|
439
|
+
losses: importReadiness.summary.total,
|
|
440
|
+
readiness: importReadiness.readiness
|
|
441
|
+
},
|
|
442
|
+
universalAst: {
|
|
443
|
+
present: Boolean(universalAst),
|
|
444
|
+
valid: universalAstIssues.length === 0,
|
|
445
|
+
issues: universalAstIssues,
|
|
446
|
+
nativeSources: universalAstNativeSources,
|
|
447
|
+
semanticSymbols,
|
|
448
|
+
sourceMaps: sourceMaps.length,
|
|
449
|
+
sourceMapMappings
|
|
450
|
+
},
|
|
451
|
+
projectedSource: {
|
|
452
|
+
mode: projection.mode,
|
|
453
|
+
outputHash: projection.outputHash,
|
|
454
|
+
expectedSourceHash: projection.sourceHash,
|
|
455
|
+
sourceHashVerified: projectionMatchesSourceHash,
|
|
456
|
+
declarations: projection.declarations?.length ?? 0,
|
|
457
|
+
losses: projection.lossSummary?.total ?? projection.losses?.length ?? 0,
|
|
458
|
+
readiness: projectionReadiness.readiness
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
evidence: {
|
|
462
|
+
importEvidenceIds: importEvidence.map((record) => record.id).filter(Boolean),
|
|
463
|
+
projectionEvidenceIds: (projection.evidence ?? []).map((record) => record.id).filter(Boolean),
|
|
464
|
+
failedEvidenceIds
|
|
465
|
+
},
|
|
466
|
+
metadata: {
|
|
467
|
+
nativeImportId: importResult.id,
|
|
468
|
+
universalAstId: universalAst?.id,
|
|
469
|
+
projectionId: projection.id,
|
|
470
|
+
sourcePath: projection.sourcePath ?? importResult.sourcePath,
|
|
471
|
+
language: projection.language ?? importResult.language,
|
|
472
|
+
sourcePreservationId: projection.metadata?.sourcePreservationId,
|
|
473
|
+
...options.metadata
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
|
|
330
478
|
export function createNativeImportCoverageMatrix(input = {}) {
|
|
331
479
|
const imports = input.imports ?? [];
|
|
332
480
|
const adapters = input.adapters ?? [];
|
|
@@ -446,6 +594,7 @@ export function createSemanticImportSidecar(importResult, options = {}) {
|
|
|
446
594
|
const evidence = uniqueRecordsById(imports.flatMap((imported) => imported?.evidence ?? []));
|
|
447
595
|
const mergeCandidates = imports.flatMap((imported) => imported?.mergeCandidates ?? []);
|
|
448
596
|
const lossSummary = summarizeNativeImportLosses(losses, { evidence });
|
|
597
|
+
const regionTaxonomy = summarizeSemanticImportRegionTaxonomy(ownershipRegions);
|
|
449
598
|
const readiness = mergeCandidates.reduce(
|
|
450
599
|
(current, candidate) => maxSemanticMergeReadiness(current, candidate.readiness),
|
|
451
600
|
lossSummary.semanticMergeReadiness
|
|
@@ -482,6 +631,7 @@ export function createSemanticImportSidecar(importResult, options = {}) {
|
|
|
482
631
|
blockingLossIds: lossSummary.blockingLossIds,
|
|
483
632
|
reviewLossIds: lossSummary.reviewLossIds
|
|
484
633
|
},
|
|
634
|
+
regionTaxonomy,
|
|
485
635
|
evidence: {
|
|
486
636
|
total: evidence.length,
|
|
487
637
|
failed: evidence.filter((record) => record.status === 'failed').map((record) => record.id),
|
|
@@ -491,6 +641,7 @@ export function createSemanticImportSidecar(importResult, options = {}) {
|
|
|
491
641
|
imports: imports.length,
|
|
492
642
|
symbols: symbols.length,
|
|
493
643
|
ownershipRegions: ownershipRegions.length,
|
|
644
|
+
regionKinds: regionTaxonomy.presentKinds.length,
|
|
494
645
|
sourceMapMappings: sourceMapMappings.length,
|
|
495
646
|
readiness,
|
|
496
647
|
emptySemanticIndex: symbols.length === 0
|
|
@@ -502,6 +653,83 @@ export function createSemanticImportSidecar(importResult, options = {}) {
|
|
|
502
653
|
};
|
|
503
654
|
}
|
|
504
655
|
|
|
656
|
+
export function createNativeImportResultContract(importResult, options = {}) {
|
|
657
|
+
if (!importResult || typeof importResult !== 'object') {
|
|
658
|
+
throw new Error('createNativeImportResultContract requires a native import result');
|
|
659
|
+
}
|
|
660
|
+
const imports = nativeImportEntries(importResult);
|
|
661
|
+
const evidence = uniqueByEvidenceId([
|
|
662
|
+
...(importResult.evidence ?? []),
|
|
663
|
+
...imports.flatMap((imported) => imported?.evidence ?? [])
|
|
664
|
+
]);
|
|
665
|
+
const losses = uniqueByLossId([
|
|
666
|
+
...(importResult.losses ?? []),
|
|
667
|
+
...imports.flatMap((imported) => imported?.losses ?? imported?.nativeAst?.losses ?? [])
|
|
668
|
+
]);
|
|
669
|
+
const sourceMaps = collectImportSourceMaps(importResult, imports);
|
|
670
|
+
const regionSummary = summarizeImportRegions(importResult, imports, options);
|
|
671
|
+
const sourceMapSummary = summarizeImportSourceMaps(sourceMaps);
|
|
672
|
+
const sourcePreservation = summarizeImportSourcePreservation(importResult, imports);
|
|
673
|
+
const adapterCoverage = summarizeImportAdapterCoverage(importResult, imports);
|
|
674
|
+
const primary = imports[0] ?? importResult;
|
|
675
|
+
const nativeSource = importResult.nativeSource ?? importResult.nativeSources?.[0] ?? primary?.nativeSource;
|
|
676
|
+
const nativeAst = importResult.nativeAst ?? nativeSource?.ast ?? primary?.nativeAst ?? primary?.nativeSource?.ast;
|
|
677
|
+
const semanticIndex = importResult.semanticIndex ?? importResult.universalAst?.semanticIndex ?? primary?.semanticIndex ?? primary?.universalAst?.semanticIndex;
|
|
678
|
+
const lossSummary = options.lossSummary ?? importResult.metadata?.nativeImportLossSummary ?? summarizeNativeImportLosses(losses, {
|
|
679
|
+
evidence,
|
|
680
|
+
parser: nativeAst?.parser,
|
|
681
|
+
scanKind: importResult.metadata?.scanKind,
|
|
682
|
+
semanticStatus: importResult.metadata?.semanticStatus ?? importResult.universalAst?.metadata?.semanticStatus
|
|
683
|
+
});
|
|
684
|
+
const mergeCandidates = [
|
|
685
|
+
...(importResult.mergeCandidates ?? []),
|
|
686
|
+
...imports.flatMap((imported) => imported?.mergeCandidates ?? [])
|
|
687
|
+
];
|
|
688
|
+
const readiness = summarizeImportContractReadiness(importResult, mergeCandidates, lossSummary);
|
|
689
|
+
const defaultSidecarId = defaultSemanticImportSidecarId(importResult, imports);
|
|
690
|
+
return {
|
|
691
|
+
kind: 'frontier.lang.nativeImportResultContract',
|
|
692
|
+
version: 1,
|
|
693
|
+
importResultId: importResult.id,
|
|
694
|
+
language: importResult.language ?? (imports.length === 1 ? imports[0]?.language : 'mixed'),
|
|
695
|
+
sourcePath: importResult.sourcePath ?? primary?.sourcePath ?? nativeSource?.sourcePath ?? nativeAst?.sourcePath,
|
|
696
|
+
sourceHash: nativeSource?.sourceHash ?? nativeAst?.sourceHash,
|
|
697
|
+
sourceCount: imports.length,
|
|
698
|
+
sources: imports.map((imported, index) => compactImportContractSource(imported, index)),
|
|
699
|
+
ids: {
|
|
700
|
+
nativeSourceId: nativeSource?.id,
|
|
701
|
+
nativeAstId: nativeAst?.id,
|
|
702
|
+
semanticIndexId: semanticIndex?.id,
|
|
703
|
+
universalAstId: importResult.universalAst?.id ?? primary?.universalAst?.id,
|
|
704
|
+
patchId: importResult.patch?.id,
|
|
705
|
+
sourceMapIds: sourceMapSummary.ids,
|
|
706
|
+
semanticSidecarIds: uniqueStrings([
|
|
707
|
+
...normalizeStringList(options.semanticSidecarIds ?? options.sidecarIds ?? options.sidecarId),
|
|
708
|
+
defaultSidecarId
|
|
709
|
+
])
|
|
710
|
+
},
|
|
711
|
+
sourcePreservation,
|
|
712
|
+
adapterCoverage,
|
|
713
|
+
lossSummary,
|
|
714
|
+
regions: regionSummary,
|
|
715
|
+
sourceMaps: sourceMapSummary,
|
|
716
|
+
readiness,
|
|
717
|
+
evidence: {
|
|
718
|
+
total: evidence.length,
|
|
719
|
+
failed: evidence.filter((record) => record?.status === 'failed').map((record) => record.id).filter(Boolean),
|
|
720
|
+
ids: evidence.map((record) => record.id).filter(Boolean)
|
|
721
|
+
},
|
|
722
|
+
metadata: {
|
|
723
|
+
parser: nativeAst?.parser,
|
|
724
|
+
semanticStatus: importResult.metadata?.semanticStatus ?? importResult.universalAst?.metadata?.semanticStatus,
|
|
725
|
+
projectRoot: importResult.projectRoot,
|
|
726
|
+
defaultSemanticSidecarId: defaultSidecarId,
|
|
727
|
+
note: 'Contract summarizes import-result evidence for merge admission; it does not upgrade lightweight scans into exact semantic imports.',
|
|
728
|
+
...options.metadata
|
|
729
|
+
}
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
|
|
505
733
|
export function createEstreeNativeImporterAdapter(options = {}) {
|
|
506
734
|
return createJavaScriptSyntaxImporterAdapter({
|
|
507
735
|
id: 'frontier.estree-native-importer',
|
|
@@ -917,7 +1145,17 @@ export function importNativeSource(input) {
|
|
|
917
1145
|
const frontierNodeIds = input.frontierNodeIds ?? input.semanticNodes?.map((node) => node.id) ?? [];
|
|
918
1146
|
const semanticNodes = input.semanticNodes ?? [];
|
|
919
1147
|
const semanticStatus = input.semanticStatus ?? (semanticNodes.length ? 'mapped' : 'native-only');
|
|
920
|
-
const
|
|
1148
|
+
const nativeAstExact = hasNativeExactAstEvidence(input, nativeAst, lightweight);
|
|
1149
|
+
const baseLosses = normalizeNativeLossRecords(input.losses ?? nativeAst.losses ?? lightweight?.losses ?? []);
|
|
1150
|
+
const losses = normalizeNativeLossRecords([
|
|
1151
|
+
...baseLosses,
|
|
1152
|
+
...unverifiedNativeAstLosses(input, nativeAst, {
|
|
1153
|
+
importIdPart,
|
|
1154
|
+
exactAst: nativeAstExact,
|
|
1155
|
+
hasLosses: baseLosses.length > 0,
|
|
1156
|
+
lightweight
|
|
1157
|
+
})
|
|
1158
|
+
]);
|
|
921
1159
|
const nativeSource = nativeSourceNode({
|
|
922
1160
|
id: input.nativeSourceId ?? `native_source_${importIdPart}`,
|
|
923
1161
|
name: input.name ?? sourcePath?.split(/[\\/]/).filter(Boolean).at(-1) ?? `${language}NativeSource`,
|
|
@@ -978,7 +1216,7 @@ export function importNativeSource(input) {
|
|
|
978
1216
|
}
|
|
979
1217
|
}];
|
|
980
1218
|
const lossSummary = summarizeNativeImportLosses(losses, {
|
|
981
|
-
exactAst:
|
|
1219
|
+
exactAst: nativeAstExact,
|
|
982
1220
|
evidence: baseEvidence,
|
|
983
1221
|
parser: nativeAst.parser,
|
|
984
1222
|
scanKind: lightweight?.metadata?.scanKind,
|
|
@@ -1164,7 +1402,8 @@ function createLightweightNativeImport(input) {
|
|
|
1164
1402
|
metadata: {
|
|
1165
1403
|
...declaration.metadata,
|
|
1166
1404
|
ownershipRegionId: ownershipRegion.id,
|
|
1167
|
-
ownershipRegionKey: ownershipRegion.key
|
|
1405
|
+
ownershipRegionKey: ownershipRegion.key,
|
|
1406
|
+
ownershipRegionKind: ownershipRegion.regionKind
|
|
1168
1407
|
}
|
|
1169
1408
|
};
|
|
1170
1409
|
if (declaration.symbolId) {
|
|
@@ -1180,7 +1419,8 @@ function createLightweightNativeImport(input) {
|
|
|
1180
1419
|
definitionSpan: declaration.span,
|
|
1181
1420
|
metadata: {
|
|
1182
1421
|
ownershipRegionId: ownershipRegion.id,
|
|
1183
|
-
ownershipRegionKey: ownershipRegion.key
|
|
1422
|
+
ownershipRegionKey: ownershipRegion.key,
|
|
1423
|
+
ownershipRegionKind: ownershipRegion.regionKind
|
|
1184
1424
|
}
|
|
1185
1425
|
});
|
|
1186
1426
|
occurrences.push({
|
|
@@ -1207,6 +1447,15 @@ function createLightweightNativeImport(input) {
|
|
|
1207
1447
|
predicate: 'semanticOwnershipRegion',
|
|
1208
1448
|
subjectId: declaration.symbolId,
|
|
1209
1449
|
value: ownershipRegion
|
|
1450
|
+
}, {
|
|
1451
|
+
id: `fact_${idFragment(declaration.nodeId)}_ownership_region_taxonomy`,
|
|
1452
|
+
predicate: 'semanticOwnershipRegionTaxonomy',
|
|
1453
|
+
subjectId: declaration.symbolId,
|
|
1454
|
+
value: {
|
|
1455
|
+
regionKind: ownershipRegion.regionKind,
|
|
1456
|
+
granularity: ownershipRegion.granularity,
|
|
1457
|
+
key: ownershipRegion.key
|
|
1458
|
+
}
|
|
1210
1459
|
});
|
|
1211
1460
|
mappings.push({
|
|
1212
1461
|
id: `map_${idFragment(declaration.nodeId)}`,
|
|
@@ -1217,6 +1466,8 @@ function createLightweightNativeImport(input) {
|
|
|
1217
1466
|
evidenceIds: [evidenceId],
|
|
1218
1467
|
lossIds: declaration.loss ? [declaration.loss.id] : [],
|
|
1219
1468
|
ownershipRegionId: ownershipRegion.id,
|
|
1469
|
+
ownershipRegionKey: ownershipRegion.key,
|
|
1470
|
+
ownershipRegionKind: ownershipRegion.regionKind,
|
|
1220
1471
|
precision: 'declaration'
|
|
1221
1472
|
});
|
|
1222
1473
|
}
|
|
@@ -2827,6 +3078,9 @@ function inferSourceMapMappings(input) {
|
|
|
2827
3078
|
sourceSpan: occurrence.span ?? nativeNode?.span,
|
|
2828
3079
|
evidenceIds,
|
|
2829
3080
|
lossIds: lossIdsForNativeNode(input.losses ?? nativeAst?.losses ?? [], occurrence.nativeAstNodeId),
|
|
3081
|
+
ownershipRegionId: symbol?.metadata?.ownershipRegionId,
|
|
3082
|
+
ownershipRegionKey: symbol?.metadata?.ownershipRegionKey,
|
|
3083
|
+
ownershipRegionKind: symbol?.metadata?.ownershipRegionKind,
|
|
2830
3084
|
precision: occurrence.span || nativeNode?.span ? 'declaration' : 'unknown'
|
|
2831
3085
|
};
|
|
2832
3086
|
});
|
|
@@ -2896,6 +3150,9 @@ function normalizeSourceMapMappings(mappings, context) {
|
|
|
2896
3150
|
target,
|
|
2897
3151
|
evidenceIds: normalizeReferenceIds(mapping.evidenceIds, evidenceIds),
|
|
2898
3152
|
lossIds: normalizeReferenceIds(mapping.lossIds, lossIdsForNativeNode(context.losses ?? nativeAst?.losses ?? [], nativeAstNodeId)),
|
|
3153
|
+
ownershipRegionId: mapping.ownershipRegionId ?? symbol?.metadata?.ownershipRegionId,
|
|
3154
|
+
ownershipRegionKey: mapping.ownershipRegionKey ?? symbol?.metadata?.ownershipRegionKey,
|
|
3155
|
+
ownershipRegionKind: mapping.ownershipRegionKind ?? symbol?.metadata?.ownershipRegionKind,
|
|
2899
3156
|
precision: normalizeSourceMapPrecision(mapping.precision, sourceSpan, generatedSpan)
|
|
2900
3157
|
};
|
|
2901
3158
|
return {
|
|
@@ -3106,7 +3363,7 @@ function nativeImportCategoryForLossKind(kind) {
|
|
|
3106
3363
|
if (kind === 'sourcePreservation' || kind === 'commentsTrivia' || kind === 'nonRoundTrippable') return 'sourcePreservation';
|
|
3107
3364
|
if (kind === 'parserDiagnostic') return 'parserDiagnostics';
|
|
3108
3365
|
if (kind === 'unsupportedSyntax' || kind === 'unsupportedSemantic') return 'unsupportedSyntax';
|
|
3109
|
-
if (kind === 'partialSemanticIndex') return 'partialSemanticIndex';
|
|
3366
|
+
if (kind === 'partialSemanticIndex' || kind === 'unverifiedNativeAst') return 'partialSemanticIndex';
|
|
3110
3367
|
if (kind === 'sourceMapApproximation') return 'sourceMapApproximation';
|
|
3111
3368
|
if (kind === 'targetProjectionLoss') return 'targetProjectionLoss';
|
|
3112
3369
|
return String(kind ?? 'opaqueNative');
|
|
@@ -3238,9 +3495,12 @@ function semanticImportSidecarEntry(imported, index, options) {
|
|
|
3238
3495
|
signatureHash: symbol.signatureHash,
|
|
3239
3496
|
ownershipRegionId: region.id,
|
|
3240
3497
|
ownershipKey: region.key,
|
|
3498
|
+
ownershipRegionKind: region.regionKind,
|
|
3241
3499
|
readiness: imported?.metadata?.semanticMergeReadiness ?? imported?.mergeCandidates?.[0]?.readiness ?? 'needs-review'
|
|
3242
3500
|
});
|
|
3243
3501
|
}
|
|
3502
|
+
const ownershipRegions = uniqueRecordsById(regions);
|
|
3503
|
+
const regionTaxonomy = summarizeSemanticImportRegionTaxonomy(ownershipRegions);
|
|
3244
3504
|
return {
|
|
3245
3505
|
id: imported?.id ?? `import_${index + 1}`,
|
|
3246
3506
|
language: imported?.language,
|
|
@@ -3256,8 +3516,9 @@ function semanticImportSidecarEntry(imported, index, options) {
|
|
|
3256
3516
|
sourceMapMappingCount: sourceMapMappings.length,
|
|
3257
3517
|
readiness: imported?.metadata?.semanticMergeReadiness ?? imported?.mergeCandidates?.[0]?.readiness ?? 'needs-review',
|
|
3258
3518
|
emptySemanticIndex: symbols.length === 0,
|
|
3519
|
+
regionTaxonomy,
|
|
3259
3520
|
symbols,
|
|
3260
|
-
ownershipRegions
|
|
3521
|
+
ownershipRegions
|
|
3261
3522
|
};
|
|
3262
3523
|
}
|
|
3263
3524
|
|
|
@@ -3265,15 +3526,17 @@ function semanticOwnershipRegionForSymbol(imported, symbol, mapping, nativeNode,
|
|
|
3265
3526
|
const sourcePath = mapping?.sourceSpan?.path ?? symbol.definitionSpan?.path ?? nativeNode?.span?.path ?? imported?.sourcePath ?? imported?.nativeSource?.sourcePath ?? imported?.nativeAst?.sourcePath;
|
|
3266
3527
|
const language = symbol.language ?? imported?.language ?? imported?.nativeAst?.language ?? imported?.nativeSource?.language;
|
|
3267
3528
|
const sourceSpan = mapping?.sourceSpan ?? symbol.definitionSpan ?? nativeNode?.span;
|
|
3529
|
+
const regionKind = semanticRegionKindForSymbol(symbol, mapping, nativeNode);
|
|
3268
3530
|
const key = [
|
|
3269
3531
|
options.regionPrefix ?? 'source',
|
|
3270
3532
|
sourcePath ?? `${language}:memory`,
|
|
3271
|
-
|
|
3533
|
+
regionKind,
|
|
3272
3534
|
symbol.name ?? symbol.id
|
|
3273
3535
|
].map((part) => String(part).replace(/\s+/g, ' ').trim()).join('#');
|
|
3274
3536
|
return {
|
|
3275
3537
|
id: `region_${idFragment(key)}`,
|
|
3276
3538
|
key,
|
|
3539
|
+
regionKind,
|
|
3277
3540
|
granularity: 'symbol',
|
|
3278
3541
|
language,
|
|
3279
3542
|
sourcePath,
|
|
@@ -3284,7 +3547,10 @@ function semanticOwnershipRegionForSymbol(imported, symbol, mapping, nativeNode,
|
|
|
3284
3547
|
nativeAstNodeId: symbol.nativeAstNodeId ?? nativeNode?.id,
|
|
3285
3548
|
sourceSpan,
|
|
3286
3549
|
precision: mapping?.precision ?? (sourceSpan ? 'declaration' : 'unknown'),
|
|
3287
|
-
mergePolicy:
|
|
3550
|
+
mergePolicy: semanticRegionMergePolicy(regionKind),
|
|
3551
|
+
metadata: {
|
|
3552
|
+
semanticRegionTaxonomy: true
|
|
3553
|
+
}
|
|
3288
3554
|
};
|
|
3289
3555
|
}
|
|
3290
3556
|
|
|
@@ -3292,10 +3558,12 @@ function semanticOwnershipRegionForDeclaration(input, declaration, documentId) {
|
|
|
3292
3558
|
const name = declaration.name ?? declaration.importPath ?? declaration.nodeId ?? declaration.nativeNode?.id;
|
|
3293
3559
|
const kind = declaration.symbolKind ?? declaration.kind ?? declaration.nativeNode?.kind ?? 'symbol';
|
|
3294
3560
|
const sourcePath = declaration.span?.path ?? declaration.nativeNode?.span?.path ?? input.sourcePath ?? `${input.language}:memory`;
|
|
3295
|
-
const
|
|
3561
|
+
const regionKind = semanticRegionKindForDeclaration(declaration);
|
|
3562
|
+
const key = ['source', sourcePath, regionKind, name].map((part) => String(part).replace(/\s+/g, ' ').trim()).join('#');
|
|
3296
3563
|
return {
|
|
3297
3564
|
id: `region_${idFragment(key)}`,
|
|
3298
3565
|
key,
|
|
3566
|
+
regionKind,
|
|
3299
3567
|
granularity: 'symbol',
|
|
3300
3568
|
language: input.language,
|
|
3301
3569
|
documentId,
|
|
@@ -3307,7 +3575,10 @@ function semanticOwnershipRegionForDeclaration(input, declaration, documentId) {
|
|
|
3307
3575
|
nativeAstNodeId: declaration.nodeId ?? declaration.nativeNode?.id,
|
|
3308
3576
|
sourceSpan: declaration.span ?? declaration.nativeNode?.span,
|
|
3309
3577
|
precision: declaration.span || declaration.nativeNode?.span ? 'declaration' : 'unknown',
|
|
3310
|
-
mergePolicy:
|
|
3578
|
+
mergePolicy: semanticRegionMergePolicy(regionKind),
|
|
3579
|
+
metadata: {
|
|
3580
|
+
semanticRegionTaxonomy: true
|
|
3581
|
+
}
|
|
3311
3582
|
};
|
|
3312
3583
|
}
|
|
3313
3584
|
|
|
@@ -3322,7 +3593,7 @@ function semanticPatchHintForRegion(region, readiness, options = {}) {
|
|
|
3322
3593
|
sourceSpan: region.sourceSpan,
|
|
3323
3594
|
readiness,
|
|
3324
3595
|
precision: region.precision,
|
|
3325
|
-
supportedOperations:
|
|
3596
|
+
supportedOperations: semanticRegionSupportedOperations(region),
|
|
3326
3597
|
projection: {
|
|
3327
3598
|
sourceLanguage: region.language,
|
|
3328
3599
|
targetPath: options.targetPath ?? region.sourcePath,
|
|
@@ -3331,6 +3602,79 @@ function semanticPatchHintForRegion(region, readiness, options = {}) {
|
|
|
3331
3602
|
};
|
|
3332
3603
|
}
|
|
3333
3604
|
|
|
3605
|
+
function semanticRegionKindForDeclaration(declaration) {
|
|
3606
|
+
if (declaration.role === 'import' || declaration.importPath) return 'import';
|
|
3607
|
+
const kind = declaration.symbolKind ?? declaration.kind ?? declaration.nativeNode?.kind;
|
|
3608
|
+
if (semanticKindIsType(kind)) return 'type';
|
|
3609
|
+
if (semanticKindCanOwnBody(kind, declaration.span ?? declaration.nativeNode?.span)) return 'body';
|
|
3610
|
+
return 'declaration';
|
|
3611
|
+
}
|
|
3612
|
+
|
|
3613
|
+
function semanticRegionKindForSymbol(symbol, mapping, nativeNode) {
|
|
3614
|
+
if (mapping?.generatedSpan || mapping?.generatedName || mapping?.target?.emitPath) return 'generatedOutput';
|
|
3615
|
+
if (symbol?.metadata?.ownershipRegionKind) return normalizeNativeImportRegionKind(symbol.metadata.ownershipRegionKind);
|
|
3616
|
+
if (String(symbol?.id ?? '').includes(':import:') || symbol?.metadata?.role === 'import') return 'import';
|
|
3617
|
+
if (semanticKindIsType(symbol?.kind ?? nativeNode?.kind)) return 'type';
|
|
3618
|
+
if (semanticKindCanOwnBody(symbol?.kind ?? nativeNode?.kind, nativeNode?.span ?? symbol?.definitionSpan)) return 'body';
|
|
3619
|
+
return 'declaration';
|
|
3620
|
+
}
|
|
3621
|
+
|
|
3622
|
+
function semanticKindIsType(kind) {
|
|
3623
|
+
return ['type', 'class', 'interface', 'trait', 'protocol', 'struct', 'enum', 'record'].includes(String(kind ?? '').toLowerCase());
|
|
3624
|
+
}
|
|
3625
|
+
|
|
3626
|
+
function semanticKindCanOwnBody(kind, span) {
|
|
3627
|
+
const text = String(kind ?? '').toLowerCase();
|
|
3628
|
+
if (/function|method|class|implementation|module|namespace|package|action|effect|capability/.test(text)) return true;
|
|
3629
|
+
return typeof span?.startLine === 'number' && typeof span?.endLine === 'number' && span.endLine > span.startLine;
|
|
3630
|
+
}
|
|
3631
|
+
|
|
3632
|
+
function semanticRegionMergePolicy(regionKind) {
|
|
3633
|
+
if (regionKind === 'import') return 'module-edge-review-required';
|
|
3634
|
+
if (regionKind === 'body') return 'implementation-single-writer-review-required';
|
|
3635
|
+
if (regionKind === 'call') return 'callsite-overlap-review-required';
|
|
3636
|
+
if (regionKind === 'type') return 'type-surface-review-required';
|
|
3637
|
+
if (regionKind === 'effect') return 'effect-boundary-review-required';
|
|
3638
|
+
if (regionKind === 'generatedOutput') return 'generated-output-source-map-review-required';
|
|
3639
|
+
return 'single-writer-review-required';
|
|
3640
|
+
}
|
|
3641
|
+
|
|
3642
|
+
function semanticRegionSupportedOperations(region) {
|
|
3643
|
+
if (region.regionKind === 'import') return ['replace-import', 'insert-import-before', 'insert-import-after', 'replace-region'];
|
|
3644
|
+
if (region.regionKind === 'body') return ['replace-body', 'insert-before-body', 'insert-after-body'];
|
|
3645
|
+
if (region.regionKind === 'call') return ['replace-callsite', 'review-callsite'];
|
|
3646
|
+
if (region.regionKind === 'type') return ['replace-type-declaration', 'merge-type-members', 'replace-region'];
|
|
3647
|
+
if (region.regionKind === 'effect') return ['route-effect', 'replace-effect-boundary', 'review-effect-policy'];
|
|
3648
|
+
if (region.regionKind === 'generatedOutput') return ['replace-generated-output', 'attach-generated-source-map', 'review-generator-input'];
|
|
3649
|
+
return ['replace-region', 'insert-before-region', 'insert-after-region'];
|
|
3650
|
+
}
|
|
3651
|
+
|
|
3652
|
+
function normalizeNativeImportRegionKind(value) {
|
|
3653
|
+
const text = String(value ?? 'symbol').trim();
|
|
3654
|
+
if (text === 'generated' || text === 'generated-output' || text === 'generated_output') return 'generatedOutput';
|
|
3655
|
+
if (NativeImportRegionTaxonomyKinds.includes(text)) return text;
|
|
3656
|
+
return text || 'symbol';
|
|
3657
|
+
}
|
|
3658
|
+
|
|
3659
|
+
function summarizeSemanticImportRegionTaxonomy(regions) {
|
|
3660
|
+
const byKind = {};
|
|
3661
|
+
const keysByKind = {};
|
|
3662
|
+
const keys = [];
|
|
3663
|
+
for (const region of regions ?? []) {
|
|
3664
|
+
const kind = normalizeNativeImportRegionKind(region.regionKind ?? region.granularity);
|
|
3665
|
+
byKind[kind] = (byKind[kind] ?? 0) + 1;
|
|
3666
|
+
keysByKind[kind] = [...(keysByKind[kind] ?? []), region.key].filter(Boolean);
|
|
3667
|
+
if (region.key) keys.push(region.key);
|
|
3668
|
+
}
|
|
3669
|
+
return {
|
|
3670
|
+
kinds: [...NativeImportRegionTaxonomyKinds],
|
|
3671
|
+
presentKinds: uniqueStrings(Object.keys(byKind)),
|
|
3672
|
+
byKind,
|
|
3673
|
+
keys,
|
|
3674
|
+
keysByKind
|
|
3675
|
+
};
|
|
3676
|
+
}
|
|
3677
|
+
|
|
3334
3678
|
function nativeImportCoverageReasons(profile) {
|
|
3335
3679
|
if (!profile.supportsLightweightScan) return ['No built-in scanner coverage profile; host must provide an exact adapter or mark unsupported.'];
|
|
3336
3680
|
return ['Built-in coverage is declaration-level only; use injected parser adapters for exact AST/CST, tokens, trivia, type resolution, and round-trip evidence.'];
|
|
@@ -3392,6 +3736,36 @@ function attachNativeImportLossSummary(evidence, lossSummary) {
|
|
|
3392
3736
|
}));
|
|
3393
3737
|
}
|
|
3394
3738
|
|
|
3739
|
+
function hasNativeExactAstEvidence(input, nativeAst, lightweight) {
|
|
3740
|
+
if (lightweight) return false;
|
|
3741
|
+
if (!(input?.nativeAst || input?.nodes)) return false;
|
|
3742
|
+
if (input.exactAst === true || input.metadata?.exactAst === true || input.nativeAstMetadata?.exactAst === true) return true;
|
|
3743
|
+
const coverage = input.metadata?.adapterCoverage
|
|
3744
|
+
?? input.nativeAstMetadata?.adapterCoverage
|
|
3745
|
+
?? input.nativeSourceMetadata?.adapterCoverage
|
|
3746
|
+
?? nativeAst?.metadata?.adapterCoverage;
|
|
3747
|
+
if (coverage?.exactAst !== true) return false;
|
|
3748
|
+
const observedNodes = coverage.observed?.nativeAstNodes;
|
|
3749
|
+
return observedNodes === undefined || observedNodes > 0;
|
|
3750
|
+
}
|
|
3751
|
+
|
|
3752
|
+
function unverifiedNativeAstLosses(input, nativeAst, context) {
|
|
3753
|
+
if (context.lightweight || context.exactAst || context.hasLosses) return [];
|
|
3754
|
+
if (!(input?.nativeAst || input?.nodes)) return [];
|
|
3755
|
+
return [{
|
|
3756
|
+
id: `loss_${context.importIdPart}_unverified_native_ast`,
|
|
3757
|
+
severity: 'warning',
|
|
3758
|
+
kind: 'unverifiedNativeAst',
|
|
3759
|
+
nodeId: nativeAst?.rootId,
|
|
3760
|
+
message: 'Caller supplied native AST nodes without explicit exactAst or adapter coverage evidence.',
|
|
3761
|
+
metadata: {
|
|
3762
|
+
reason: 'missing-exact-ast-evidence',
|
|
3763
|
+
nativeAstId: nativeAst?.id,
|
|
3764
|
+
parser: nativeAst?.parser
|
|
3765
|
+
}
|
|
3766
|
+
}];
|
|
3767
|
+
}
|
|
3768
|
+
|
|
3395
3769
|
function withNativeImportReadiness(importResult, lossSummary) {
|
|
3396
3770
|
const mergeCandidates = (importResult.mergeCandidates ?? []).map((candidate) => {
|
|
3397
3771
|
const readiness = maxSemanticMergeReadiness(candidate.readiness, lossSummary.semanticMergeReadiness);
|
|
@@ -3413,13 +3787,30 @@ function withNativeImportReadiness(importResult, lossSummary) {
|
|
|
3413
3787
|
}
|
|
3414
3788
|
};
|
|
3415
3789
|
});
|
|
3790
|
+
const semanticMergeReadiness = mergeCandidates[0]?.readiness ?? lossSummary.semanticMergeReadiness;
|
|
3791
|
+
const contractInput = {
|
|
3792
|
+
...importResult,
|
|
3793
|
+
mergeCandidates,
|
|
3794
|
+
metadata: {
|
|
3795
|
+
...importResult.metadata,
|
|
3796
|
+
nativeImportLossSummary: lossSummary,
|
|
3797
|
+
semanticMergeReadiness
|
|
3798
|
+
}
|
|
3799
|
+
};
|
|
3800
|
+
const importResultContract = createNativeImportResultContract(contractInput, { lossSummary });
|
|
3416
3801
|
return {
|
|
3417
3802
|
...importResult,
|
|
3418
3803
|
mergeCandidates,
|
|
3419
3804
|
metadata: {
|
|
3420
3805
|
...importResult.metadata,
|
|
3806
|
+
importResultContract,
|
|
3421
3807
|
nativeImportLossSummary: lossSummary,
|
|
3422
|
-
semanticMergeReadiness
|
|
3808
|
+
semanticMergeReadiness,
|
|
3809
|
+
readinessReasons: importResultContract.readiness.reasons,
|
|
3810
|
+
sourcePreservationSummary: importResultContract.sourcePreservation,
|
|
3811
|
+
adapterCoverageSummary: importResultContract.adapterCoverage,
|
|
3812
|
+
regionSummary: importResultContract.regions,
|
|
3813
|
+
sourceMapSummary: importResultContract.sourceMaps,
|
|
3423
3814
|
lossCategories: lossSummary.categories,
|
|
3424
3815
|
lossSeverityCounts: lossSummary.bySeverity,
|
|
3425
3816
|
lossKindCounts: lossSummary.byKind
|
|
@@ -3427,6 +3818,300 @@ function withNativeImportReadiness(importResult, lossSummary) {
|
|
|
3427
3818
|
};
|
|
3428
3819
|
}
|
|
3429
3820
|
|
|
3821
|
+
function nativeImportEntries(importResult) {
|
|
3822
|
+
if (Array.isArray(importResult?.imports)) return importResult.imports.filter(Boolean);
|
|
3823
|
+
return [importResult].filter(Boolean);
|
|
3824
|
+
}
|
|
3825
|
+
|
|
3826
|
+
function nativeImportHasExactAstCoverage(imported) {
|
|
3827
|
+
if (imported?.metadata?.nativeImportLossSummary?.exactAst === true) return true;
|
|
3828
|
+
if (imported?.adapter?.coverage?.exactAst === true && !(imported?.losses?.length)) return true;
|
|
3829
|
+
return false;
|
|
3830
|
+
}
|
|
3831
|
+
|
|
3832
|
+
function nativeImportRoundtripParser(importResult, imports) {
|
|
3833
|
+
const parsers = uniqueStrings([
|
|
3834
|
+
importResult.nativeAst?.parser,
|
|
3835
|
+
importResult.nativeSource?.parser,
|
|
3836
|
+
importResult.metadata?.parser,
|
|
3837
|
+
...imports.map((imported) => imported?.nativeAst?.parser ?? imported?.nativeSource?.parser ?? imported?.metadata?.parser)
|
|
3838
|
+
].filter(Boolean));
|
|
3839
|
+
return parsers.length === 1 ? parsers[0] : parsers.length ? parsers.join(',') : undefined;
|
|
3840
|
+
}
|
|
3841
|
+
|
|
3842
|
+
function nativeImportRoundtripReasons(status, input) {
|
|
3843
|
+
if (status === 'blocked') return uniqueStrings(input.blockingReasons);
|
|
3844
|
+
if (status === 'stub-only') {
|
|
3845
|
+
return uniqueStrings([
|
|
3846
|
+
`Native source projection emitted declaration stubs in ${input.projection.mode} mode.`,
|
|
3847
|
+
...input.projectionReadiness.reasons,
|
|
3848
|
+
...input.importReadiness.reasons.filter((reason) => input.importReadiness.readiness !== 'ready')
|
|
3849
|
+
]);
|
|
3850
|
+
}
|
|
3851
|
+
if (status === 'needs-review') return uniqueStrings(input.reviewReasons);
|
|
3852
|
+
if (status === 'exact') {
|
|
3853
|
+
return ['Exact native AST import and verified preserved source projection are available.'];
|
|
3854
|
+
}
|
|
3855
|
+
if (status === 'preserved-source') {
|
|
3856
|
+
return uniqueStrings([
|
|
3857
|
+
'Verified native source text is preserved for projection; semantic import evidence may still require review.',
|
|
3858
|
+
...input.importReadiness.reasons.filter((reason) => input.importReadiness.readiness !== 'ready')
|
|
3859
|
+
]);
|
|
3860
|
+
}
|
|
3861
|
+
return ['Native import roundtrip readiness requires review.'];
|
|
3862
|
+
}
|
|
3863
|
+
|
|
3864
|
+
function collectImportSourceMaps(importResult, imports) {
|
|
3865
|
+
return uniqueRecordsById([
|
|
3866
|
+
...(importResult?.sourceMaps ?? importResult?.universalAst?.sourceMaps ?? []),
|
|
3867
|
+
...imports.flatMap((imported) => imported?.sourceMaps ?? imported?.universalAst?.sourceMaps ?? [])
|
|
3868
|
+
]);
|
|
3869
|
+
}
|
|
3870
|
+
|
|
3871
|
+
function summarizeImportSourceMaps(sourceMaps) {
|
|
3872
|
+
const mappings = sourceMaps.flatMap((sourceMap) => sourceMap?.mappings ?? []);
|
|
3873
|
+
return {
|
|
3874
|
+
total: sourceMaps.length,
|
|
3875
|
+
ids: sourceMaps.map((sourceMap) => sourceMap.id).filter(Boolean),
|
|
3876
|
+
mappingCount: mappings.length,
|
|
3877
|
+
sourcePaths: uniqueStrings([
|
|
3878
|
+
...sourceMaps.map((sourceMap) => sourceMap.sourcePath),
|
|
3879
|
+
...mappings.map((mapping) => mapping.sourceSpan?.path)
|
|
3880
|
+
].filter(Boolean)),
|
|
3881
|
+
targetPaths: uniqueStrings([
|
|
3882
|
+
...sourceMaps.map((sourceMap) => sourceMap.targetPath ?? sourceMap.target?.emitPath),
|
|
3883
|
+
...mappings.map((mapping) => mapping.generatedSpan?.targetPath ?? mapping.target?.emitPath)
|
|
3884
|
+
].filter(Boolean)),
|
|
3885
|
+
byPrecision: countBy(mappings.map((mapping) => mapping.precision ?? 'unknown')),
|
|
3886
|
+
sourceRangeMappings: mappings.filter((mapping) => mapping.sourceSpan).length,
|
|
3887
|
+
generatedRangeMappings: mappings.filter((mapping) => mapping.generatedSpan).length
|
|
3888
|
+
};
|
|
3889
|
+
}
|
|
3890
|
+
|
|
3891
|
+
function summarizeImportRegions(importResult, imports, options = {}) {
|
|
3892
|
+
const entries = imports.map((imported, index) => semanticImportSidecarEntry(imported, index, options));
|
|
3893
|
+
const regions = uniqueRecordsById(entries.flatMap((entry) => entry.ownershipRegions ?? []));
|
|
3894
|
+
const taxonomy = summarizeSemanticImportRegionTaxonomy(regions);
|
|
3895
|
+
return {
|
|
3896
|
+
total: regions.length,
|
|
3897
|
+
ids: regions.map((region) => region.id),
|
|
3898
|
+
keys: regions.map((region) => region.key),
|
|
3899
|
+
sourcePaths: uniqueStrings(regions.map((region) => region.sourcePath).filter(Boolean)),
|
|
3900
|
+
byKind: taxonomy.byKind,
|
|
3901
|
+
byGranularity: countBy(regions.map((region) => region.granularity ?? 'unknown')),
|
|
3902
|
+
byPrecision: countBy(regions.map((region) => region.precision ?? 'unknown')),
|
|
3903
|
+
byLanguage: countBy(regions.map((region) => region.language ?? importResult?.language ?? 'unknown')),
|
|
3904
|
+
symbolIds: uniqueStrings(regions.map((region) => region.symbolId).filter(Boolean)),
|
|
3905
|
+
taxonomy
|
|
3906
|
+
};
|
|
3907
|
+
}
|
|
3908
|
+
|
|
3909
|
+
function summarizeImportSourcePreservation(importResult, imports) {
|
|
3910
|
+
const records = uniqueSourcePreservationRecords([
|
|
3911
|
+
...collectSourcePreservationFromImport(importResult),
|
|
3912
|
+
...imports.flatMap((imported) => collectSourcePreservationFromImport(imported))
|
|
3913
|
+
]);
|
|
3914
|
+
const compactRecords = records.map(compactSourcePreservationRecord);
|
|
3915
|
+
return {
|
|
3916
|
+
total: compactRecords.length,
|
|
3917
|
+
ids: compactRecords.map((record) => record.id).filter(Boolean),
|
|
3918
|
+
sourcePaths: uniqueStrings(compactRecords.map((record) => record.sourcePath).filter(Boolean)),
|
|
3919
|
+
sourceHashes: uniqueStrings(compactRecords.map((record) => record.sourceHash).filter(Boolean)),
|
|
3920
|
+
exactSourceAvailable: compactRecords.filter((record) => record.exactSourceAvailable).length,
|
|
3921
|
+
sourceBytes: compactRecords.reduce((sum, record) => sum + (record.sourceBytes ?? 0), 0),
|
|
3922
|
+
lineCount: compactRecords.reduce((sum, record) => sum + (record.lineCount ?? 0), 0),
|
|
3923
|
+
tokens: compactRecords.reduce((sum, record) => sum + (record.tokens ?? 0), 0),
|
|
3924
|
+
trivia: compactRecords.reduce((sum, record) => sum + (record.trivia ?? 0), 0),
|
|
3925
|
+
directives: compactRecords.reduce((sum, record) => sum + (record.directives ?? 0), 0),
|
|
3926
|
+
comments: compactRecords.reduce((sum, record) => sum + (record.comments ?? 0), 0),
|
|
3927
|
+
whitespace: compactRecords.reduce((sum, record) => sum + (record.whitespace ?? 0), 0),
|
|
3928
|
+
truncated: compactRecords.some((record) => record.truncated),
|
|
3929
|
+
records: compactRecords
|
|
3930
|
+
};
|
|
3931
|
+
}
|
|
3932
|
+
|
|
3933
|
+
function collectSourcePreservationFromImport(imported) {
|
|
3934
|
+
const nativeAst = imported?.nativeAst ?? imported?.nativeSource?.ast;
|
|
3935
|
+
return [
|
|
3936
|
+
imported?.metadata?.sourcePreservation,
|
|
3937
|
+
imported?.nativeSource?.metadata?.sourcePreservation,
|
|
3938
|
+
nativeAst?.metadata?.sourcePreservation,
|
|
3939
|
+
imported?.universalAst?.metadata?.sourcePreservation,
|
|
3940
|
+
...(imported?.nativeSources ?? []).map((nativeSource) => nativeSource?.metadata?.sourcePreservation ?? nativeSource?.ast?.metadata?.sourcePreservation)
|
|
3941
|
+
].filter(Boolean);
|
|
3942
|
+
}
|
|
3943
|
+
|
|
3944
|
+
function uniqueSourcePreservationRecords(records) {
|
|
3945
|
+
const seen = new Set();
|
|
3946
|
+
const result = [];
|
|
3947
|
+
for (const record of records) {
|
|
3948
|
+
const key = record.id ?? `${record.sourcePath ?? 'source'}#${record.sourceHash ?? result.length}`;
|
|
3949
|
+
if (seen.has(key)) continue;
|
|
3950
|
+
seen.add(key);
|
|
3951
|
+
result.push(record);
|
|
3952
|
+
}
|
|
3953
|
+
return result;
|
|
3954
|
+
}
|
|
3955
|
+
|
|
3956
|
+
function compactSourcePreservationRecord(record) {
|
|
3957
|
+
return {
|
|
3958
|
+
id: record.id,
|
|
3959
|
+
language: record.language,
|
|
3960
|
+
sourcePath: record.sourcePath,
|
|
3961
|
+
sourceHash: record.sourceHash,
|
|
3962
|
+
sourceBytes: record.sourceBytes,
|
|
3963
|
+
lineCount: record.lineCount,
|
|
3964
|
+
newline: record.newline,
|
|
3965
|
+
encoding: record.encoding,
|
|
3966
|
+
exactSourceAvailable: record.summary?.exactSourceAvailable === true,
|
|
3967
|
+
tokens: record.summary?.tokens ?? record.tokens?.length ?? 0,
|
|
3968
|
+
trivia: record.summary?.trivia ?? record.trivia?.length ?? 0,
|
|
3969
|
+
directives: record.summary?.directives ?? record.directives?.length ?? 0,
|
|
3970
|
+
comments: record.summary?.comments ?? 0,
|
|
3971
|
+
whitespace: record.summary?.whitespace ?? 0,
|
|
3972
|
+
truncated: record.summary?.truncated === true
|
|
3973
|
+
};
|
|
3974
|
+
}
|
|
3975
|
+
|
|
3976
|
+
function summarizeImportAdapterCoverage(importResult, imports) {
|
|
3977
|
+
const records = uniqueAdapterCoverageRecords([
|
|
3978
|
+
compactAdapterCoverageRecord(importResult),
|
|
3979
|
+
...imports.map((imported) => compactAdapterCoverageRecord(imported))
|
|
3980
|
+
].filter(Boolean));
|
|
3981
|
+
const observed = records.reduce((totals, record) => {
|
|
3982
|
+
for (const key of ['diagnostics', 'losses', 'nativeAstNodes', 'semanticSymbols', 'sourceMapMappings']) {
|
|
3983
|
+
totals[key] += record.observed?.[key] ?? 0;
|
|
3984
|
+
}
|
|
3985
|
+
totals.sourceRanges = totals.sourceRanges || record.observed?.sourceRanges === true;
|
|
3986
|
+
totals.generatedRanges = totals.generatedRanges || record.observed?.generatedRanges === true;
|
|
3987
|
+
return totals;
|
|
3988
|
+
}, {
|
|
3989
|
+
diagnostics: 0,
|
|
3990
|
+
losses: 0,
|
|
3991
|
+
nativeAstNodes: 0,
|
|
3992
|
+
semanticSymbols: 0,
|
|
3993
|
+
sourceMapMappings: 0,
|
|
3994
|
+
sourceRanges: false,
|
|
3995
|
+
generatedRanges: false
|
|
3996
|
+
});
|
|
3997
|
+
return {
|
|
3998
|
+
total: records.length,
|
|
3999
|
+
adapterIds: uniqueStrings(records.map((record) => record.adapterId).filter(Boolean)),
|
|
4000
|
+
parsers: uniqueStrings(records.map((record) => record.parser).filter(Boolean)),
|
|
4001
|
+
exactness: uniqueStrings(records.map((record) => record.exactness).filter(Boolean)),
|
|
4002
|
+
exactAst: records.filter((record) => record.exactAst).length,
|
|
4003
|
+
tokens: records.filter((record) => record.tokens).length,
|
|
4004
|
+
trivia: records.filter((record) => record.trivia).length,
|
|
4005
|
+
diagnostics: records.filter((record) => record.diagnostics).length,
|
|
4006
|
+
sourceRanges: records.filter((record) => record.sourceRanges).length,
|
|
4007
|
+
generatedRanges: records.filter((record) => record.generatedRanges).length,
|
|
4008
|
+
semanticCoverageLevels: uniqueStrings(records.map((record) => record.semanticCoverage?.level).filter(Boolean)),
|
|
4009
|
+
observed,
|
|
4010
|
+
records
|
|
4011
|
+
};
|
|
4012
|
+
}
|
|
4013
|
+
|
|
4014
|
+
function compactAdapterCoverageRecord(imported) {
|
|
4015
|
+
const nativeAst = imported?.nativeAst ?? imported?.nativeSource?.ast;
|
|
4016
|
+
const nativeSource = imported?.nativeSource;
|
|
4017
|
+
const coverage = imported?.adapter?.coverage
|
|
4018
|
+
?? imported?.metadata?.adapterCoverage
|
|
4019
|
+
?? nativeAst?.metadata?.adapterCoverage
|
|
4020
|
+
?? nativeSource?.metadata?.adapterCoverage;
|
|
4021
|
+
if (!coverage) return undefined;
|
|
4022
|
+
return {
|
|
4023
|
+
adapterId: imported?.adapter?.id ?? imported?.metadata?.adapterId ?? nativeAst?.metadata?.adapterId ?? nativeSource?.metadata?.adapterId,
|
|
4024
|
+
adapterVersion: imported?.adapter?.version ?? imported?.metadata?.adapterVersion ?? nativeAst?.metadata?.adapterVersion ?? nativeSource?.metadata?.adapterVersion,
|
|
4025
|
+
parser: imported?.adapter?.parser ?? nativeAst?.parser ?? nativeSource?.parser ?? imported?.metadata?.parser,
|
|
4026
|
+
capabilities: uniqueStrings(imported?.adapter?.capabilities ?? imported?.metadata?.adapterCapabilities ?? []),
|
|
4027
|
+
supportedExtensions: uniqueStrings(imported?.adapter?.supportedExtensions ?? imported?.metadata?.supportedExtensions ?? []),
|
|
4028
|
+
exactness: coverage.exactness,
|
|
4029
|
+
exactAst: Boolean(coverage.exactAst),
|
|
4030
|
+
tokens: Boolean(coverage.tokens),
|
|
4031
|
+
trivia: Boolean(coverage.trivia),
|
|
4032
|
+
diagnostics: Boolean(coverage.diagnostics),
|
|
4033
|
+
sourceRanges: Boolean(coverage.sourceRanges),
|
|
4034
|
+
generatedRanges: Boolean(coverage.generatedRanges),
|
|
4035
|
+
semanticCoverage: coverage.semanticCoverage,
|
|
4036
|
+
observed: coverage.observed,
|
|
4037
|
+
notes: uniqueStrings(coverage.notes ?? [])
|
|
4038
|
+
};
|
|
4039
|
+
}
|
|
4040
|
+
|
|
4041
|
+
function uniqueAdapterCoverageRecords(records) {
|
|
4042
|
+
const seen = new Set();
|
|
4043
|
+
const result = [];
|
|
4044
|
+
for (const record of records) {
|
|
4045
|
+
const key = [record.adapterId, record.adapterVersion, record.parser, record.exactness].join('#');
|
|
4046
|
+
if (seen.has(key)) continue;
|
|
4047
|
+
seen.add(key);
|
|
4048
|
+
result.push(record);
|
|
4049
|
+
}
|
|
4050
|
+
return result;
|
|
4051
|
+
}
|
|
4052
|
+
|
|
4053
|
+
function compactImportContractSource(imported, index) {
|
|
4054
|
+
const nativeAst = imported?.nativeAst ?? imported?.nativeSource?.ast;
|
|
4055
|
+
const nativeSource = imported?.nativeSource;
|
|
4056
|
+
const semanticIndex = imported?.semanticIndex ?? imported?.universalAst?.semanticIndex;
|
|
4057
|
+
const sourceMaps = collectImportSourceMaps(imported, [imported].filter(Boolean));
|
|
4058
|
+
return {
|
|
4059
|
+
id: imported?.id ?? `import_${index + 1}`,
|
|
4060
|
+
language: imported?.language ?? nativeSource?.language ?? nativeAst?.language,
|
|
4061
|
+
sourcePath: imported?.sourcePath ?? nativeSource?.sourcePath ?? nativeAst?.sourcePath,
|
|
4062
|
+
sourceHash: nativeSource?.sourceHash ?? nativeAst?.sourceHash,
|
|
4063
|
+
parser: nativeAst?.parser ?? nativeSource?.parser,
|
|
4064
|
+
nativeSourceId: nativeSource?.id,
|
|
4065
|
+
nativeAstId: nativeAst?.id,
|
|
4066
|
+
semanticIndexId: semanticIndex?.id,
|
|
4067
|
+
universalAstId: imported?.universalAst?.id,
|
|
4068
|
+
patchId: imported?.patch?.id,
|
|
4069
|
+
sourceMapIds: sourceMaps.map((sourceMap) => sourceMap.id).filter(Boolean),
|
|
4070
|
+
sourceMapMappings: sourceMaps.reduce((sum, sourceMap) => sum + (sourceMap.mappings?.length ?? 0), 0),
|
|
4071
|
+
symbolCount: semanticIndex?.symbols?.length ?? 0,
|
|
4072
|
+
lossCount: imported?.losses?.length ?? nativeAst?.losses?.length ?? 0,
|
|
4073
|
+
evidenceCount: imported?.evidence?.length ?? 0,
|
|
4074
|
+
readiness: imported?.metadata?.semanticMergeReadiness ?? imported?.mergeCandidates?.[0]?.readiness
|
|
4075
|
+
};
|
|
4076
|
+
}
|
|
4077
|
+
|
|
4078
|
+
function summarizeImportContractReadiness(importResult, mergeCandidates, lossSummary) {
|
|
4079
|
+
const candidateReadiness = mergeCandidates.reduce(
|
|
4080
|
+
(current, candidate) => maxSemanticMergeReadiness(current, candidate.readiness),
|
|
4081
|
+
lossSummary.semanticMergeReadiness
|
|
4082
|
+
);
|
|
4083
|
+
const semanticMergeReadiness = maxSemanticMergeReadiness(
|
|
4084
|
+
importResult?.metadata?.semanticMergeReadiness ?? lossSummary.semanticMergeReadiness,
|
|
4085
|
+
candidateReadiness
|
|
4086
|
+
);
|
|
4087
|
+
return {
|
|
4088
|
+
semanticMergeReadiness,
|
|
4089
|
+
severityReadiness: lossSummary.semanticMergeReadiness,
|
|
4090
|
+
reasons: uniqueStrings([
|
|
4091
|
+
...(lossSummary.readinessReasons ?? []),
|
|
4092
|
+
...mergeCandidates.flatMap((candidate) => candidate?.reasons ?? []),
|
|
4093
|
+
...normalizeStringList(importResult?.metadata?.readinessReasons)
|
|
4094
|
+
]),
|
|
4095
|
+
failedEvidenceIds: lossSummary.failedEvidenceIds,
|
|
4096
|
+
blockingLossIds: lossSummary.blockingLossIds,
|
|
4097
|
+
reviewLossIds: lossSummary.reviewLossIds,
|
|
4098
|
+
informationalLossIds: lossSummary.informationalLossIds
|
|
4099
|
+
};
|
|
4100
|
+
}
|
|
4101
|
+
|
|
4102
|
+
function defaultSemanticImportSidecarId(importResult, imports = []) {
|
|
4103
|
+
return `semantic_import_${idFragment(importResult?.id ?? importResult?.projectRoot ?? imports[0]?.sourcePath ?? imports[0]?.language ?? 'source')}`;
|
|
4104
|
+
}
|
|
4105
|
+
|
|
4106
|
+
function countBy(values) {
|
|
4107
|
+
const counts = {};
|
|
4108
|
+
for (const value of values ?? []) {
|
|
4109
|
+
const key = String(value ?? 'unknown');
|
|
4110
|
+
counts[key] = (counts[key] ?? 0) + 1;
|
|
4111
|
+
}
|
|
4112
|
+
return counts;
|
|
4113
|
+
}
|
|
4114
|
+
|
|
3430
4115
|
function maxSemanticMergeReadiness(left, right) {
|
|
3431
4116
|
const leftRank = semanticMergeReadinessRank[left] ?? semanticMergeReadinessRank['needs-review'];
|
|
3432
4117
|
const rightRank = semanticMergeReadinessRank[right] ?? semanticMergeReadinessRank['needs-review'];
|
|
@@ -3822,7 +4507,8 @@ function semanticIndexFromNativeDeclarations(declarations, input, options) {
|
|
|
3822
4507
|
declaration.nativeNode.metadata = {
|
|
3823
4508
|
...declaration.nativeNode.metadata,
|
|
3824
4509
|
ownershipRegionId: ownershipRegion.id,
|
|
3825
|
-
ownershipRegionKey: ownershipRegion.key
|
|
4510
|
+
ownershipRegionKey: ownershipRegion.key,
|
|
4511
|
+
ownershipRegionKind: ownershipRegion.regionKind
|
|
3826
4512
|
};
|
|
3827
4513
|
symbols.push({
|
|
3828
4514
|
id: symbolId,
|
|
@@ -3835,7 +4521,8 @@ function semanticIndexFromNativeDeclarations(declarations, input, options) {
|
|
|
3835
4521
|
definitionSpan: declaration.nativeNode.span,
|
|
3836
4522
|
metadata: {
|
|
3837
4523
|
ownershipRegionId: ownershipRegion.id,
|
|
3838
|
-
ownershipRegionKey: ownershipRegion.key
|
|
4524
|
+
ownershipRegionKey: ownershipRegion.key,
|
|
4525
|
+
ownershipRegionKind: ownershipRegion.regionKind
|
|
3839
4526
|
}
|
|
3840
4527
|
});
|
|
3841
4528
|
occurrences.push({
|
|
@@ -3862,6 +4549,15 @@ function semanticIndexFromNativeDeclarations(declarations, input, options) {
|
|
|
3862
4549
|
predicate: 'semanticOwnershipRegion',
|
|
3863
4550
|
subjectId: symbolId,
|
|
3864
4551
|
value: ownershipRegion
|
|
4552
|
+
}, {
|
|
4553
|
+
id: `fact_${idFragment(declaration.nativeNode.id)}_ownership_region_taxonomy`,
|
|
4554
|
+
predicate: 'semanticOwnershipRegionTaxonomy',
|
|
4555
|
+
subjectId: symbolId,
|
|
4556
|
+
value: {
|
|
4557
|
+
regionKind: ownershipRegion.regionKind,
|
|
4558
|
+
granularity: ownershipRegion.granularity,
|
|
4559
|
+
key: ownershipRegion.key
|
|
4560
|
+
}
|
|
3865
4561
|
});
|
|
3866
4562
|
mappings.push({
|
|
3867
4563
|
id: `map_${idFragment(declaration.nativeNode.id)}`,
|
|
@@ -3872,6 +4568,8 @@ function semanticIndexFromNativeDeclarations(declarations, input, options) {
|
|
|
3872
4568
|
evidenceIds: [evidenceId],
|
|
3873
4569
|
lossIds: [],
|
|
3874
4570
|
ownershipRegionId: ownershipRegion.id,
|
|
4571
|
+
ownershipRegionKey: ownershipRegion.key,
|
|
4572
|
+
ownershipRegionKind: ownershipRegion.regionKind,
|
|
3875
4573
|
precision: declaration.nativeNode.span ? 'declaration' : 'unknown'
|
|
3876
4574
|
});
|
|
3877
4575
|
}
|
|
@@ -3991,7 +4689,7 @@ function createNativeProjectImportResult(input, imports) {
|
|
|
3991
4689
|
sourcePreservationSummary
|
|
3992
4690
|
}
|
|
3993
4691
|
});
|
|
3994
|
-
|
|
4692
|
+
const projectResult = {
|
|
3995
4693
|
kind: 'frontier.lang.projectImportResult',
|
|
3996
4694
|
version: 1,
|
|
3997
4695
|
id: input.id ?? `project_import_${idPart}`,
|
|
@@ -4015,6 +4713,21 @@ function createNativeProjectImportResult(input, imports) {
|
|
|
4015
4713
|
...input.metadata
|
|
4016
4714
|
}
|
|
4017
4715
|
};
|
|
4716
|
+
const importResultContract = createNativeImportResultContract(projectResult, {
|
|
4717
|
+
lossSummary: nativeImportLossSummary
|
|
4718
|
+
});
|
|
4719
|
+
return {
|
|
4720
|
+
...projectResult,
|
|
4721
|
+
metadata: {
|
|
4722
|
+
...projectResult.metadata,
|
|
4723
|
+
importResultContract,
|
|
4724
|
+
semanticMergeReadiness: importResultContract.readiness.semanticMergeReadiness,
|
|
4725
|
+
readinessReasons: importResultContract.readiness.reasons,
|
|
4726
|
+
regionSummary: importResultContract.regions,
|
|
4727
|
+
sourceMapSummary: importResultContract.sourceMaps,
|
|
4728
|
+
adapterCoverageSummary: importResultContract.adapterCoverage
|
|
4729
|
+
}
|
|
4730
|
+
};
|
|
4018
4731
|
}
|
|
4019
4732
|
|
|
4020
4733
|
function summarizeProjectSourcePreservation(imports) {
|
package/package.json
CHANGED