@shapeshift-labs/frontier-lang-compiler 0.2.19 → 0.2.21
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 +43 -2
- package/bench/smoke.mjs +31 -1
- package/dist/index.d.ts +111 -1
- package/dist/index.js +644 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -93,11 +93,12 @@ console.log(pythonProjection.sourceProjection.stubs.lossClass); // "nativeSource
|
|
|
93
93
|
console.log(pythonProjection.targets.find((entry) => entry.target === 'rust').lossClass); // "missingAdapter"
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
The projection target matrix separates
|
|
96
|
+
The projection target matrix separates five runtime/API classes:
|
|
97
97
|
|
|
98
98
|
- `exactSourceProjection`: exact source can be emitted when the import carries matching source text or source-preservation evidence.
|
|
99
99
|
- `nativeSourceStubs`: declaration stubs can be emitted, but bodies, resolved types, and executable semantics are review-required.
|
|
100
100
|
- `unsupportedTargetFeatures`: a target slot exists, but the source profile or import evidence declares features such as macros, preprocessors, dynamic runtime behavior, generated code, unsupported syntax, or unresolved inference that this facade cannot prove lossless.
|
|
101
|
+
- `targetAdapterProjection`: a host-owned native-to-target adapter is present and produced target output with its own evidence/readiness.
|
|
101
102
|
- `missingAdapter`: no native-to-target projection adapter is declared; preserve or stub the original source language instead, or inject host-owned parser/semantic adapter evidence.
|
|
102
103
|
|
|
103
104
|
Preserve exact native source text, token/trivia hashes, comments, whitespace, and source directives as evidence. This does not claim full semantic understanding; it keeps round-trip material available while exact parser adapters catch up:
|
|
@@ -182,15 +183,55 @@ console.log(compiledJs.readiness.readiness); // scanner imports can still be "ne
|
|
|
182
183
|
|
|
183
184
|
const rustCandidate = compileNativeSource(compiledJs.importResult, {
|
|
184
185
|
target: 'rust',
|
|
186
|
+
targetPath: 'dist/runtime.rs',
|
|
185
187
|
emitOnBlocked: true
|
|
186
188
|
});
|
|
187
189
|
|
|
188
190
|
console.log(rustCandidate.outputMode); // "target-stubs"
|
|
189
191
|
console.log(rustCandidate.targetCoverage.lossClass); // "missingAdapter" without a JS-to-Rust adapter
|
|
190
192
|
console.log(rustCandidate.ok); // true only because emitOnBlocked requested code anyway
|
|
193
|
+
console.log(rustCandidate.sourceMap.targetPath); // "dist/runtime.rs"
|
|
194
|
+
console.log(rustCandidate.sourceMap.mappings[0]?.semanticSymbolId); // generated span -> source symbol
|
|
191
195
|
```
|
|
192
196
|
|
|
193
|
-
`compileNativeSource` returns the import result, projection, target loss matrix cell, combined losses, readiness, evidence, and output hash. Admission queues should treat `ok` as "code was emitted", not as merge approval; `readiness` and
|
|
197
|
+
`compileNativeSource` returns the import result, projection, target loss matrix cell, combined losses, readiness, evidence, output hash, and generated-output source maps. Same-language preserved output uses exact source mappings when the hash matches; generated stubs use declaration-level spans; adapter output uses adapter-supplied maps when present and otherwise gets an estimated fallback. Admission queues should treat `ok` as "code was emitted", not as merge approval; `readiness`, `targetCoverage`, and source-map precision carry the merge signal.
|
|
198
|
+
|
|
199
|
+
Provide a target projection adapter when the host owns real native-to-target translation semantics:
|
|
200
|
+
|
|
201
|
+
```js
|
|
202
|
+
const jsToRustAdapter = {
|
|
203
|
+
id: 'app-js-to-rust',
|
|
204
|
+
sourceLanguage: 'javascript',
|
|
205
|
+
target: 'rust',
|
|
206
|
+
coverage: {
|
|
207
|
+
readiness: 'needs-review',
|
|
208
|
+
handledLossKinds: ['dynamicRuntime']
|
|
209
|
+
},
|
|
210
|
+
project(input) {
|
|
211
|
+
return {
|
|
212
|
+
output: `// projected from ${input.sourceLanguage}\npub fn add_todo() {}\n`,
|
|
213
|
+
readiness: 'needs-review',
|
|
214
|
+
evidence: [{
|
|
215
|
+
id: 'evidence_app_js_to_rust',
|
|
216
|
+
kind: 'projection',
|
|
217
|
+
status: 'passed',
|
|
218
|
+
summary: 'Host JS-to-Rust adapter emitted declaration-compatible Rust.'
|
|
219
|
+
}]
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const rustWithAdapter = compileNativeSource(compiledJs.importResult, {
|
|
225
|
+
target: 'rust',
|
|
226
|
+
targetPath: 'dist/runtime.rs',
|
|
227
|
+
targetAdapters: [jsToRustAdapter]
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
console.log(rustWithAdapter.outputMode); // "target-adapter"
|
|
231
|
+
console.log(rustWithAdapter.targetCoverage.lossClass); // "targetAdapterProjection"
|
|
232
|
+
console.log(rustWithAdapter.targetProjection.adapter.id); // "app-js-to-rust"
|
|
233
|
+
console.log(rustWithAdapter.sourceMaps.length); // adapter maps or compiler fallback map
|
|
234
|
+
```
|
|
194
235
|
|
|
195
236
|
Project a native import back to source. Exact source is preserved when the import carries matching source-preservation evidence or when supplied text matches the import hash; otherwise the compiler emits declaration stubs with review-required loss evidence:
|
|
196
237
|
|
package/bench/smoke.mjs
CHANGED
|
@@ -100,7 +100,31 @@ const nativeCompiles = nativeImportResults.map((imported, index) => compileNativ
|
|
|
100
100
|
}));
|
|
101
101
|
const nativeCompileDurationMs = performance.now() - nativeCompileStart;
|
|
102
102
|
const nativeCompileBytes = nativeCompiles.reduce((sum, result) => sum + result.output.length, 0);
|
|
103
|
+
const nativeCompileSourceMaps = nativeCompiles.reduce((sum, result) => sum + result.sourceMaps.length, 0);
|
|
104
|
+
const nativeCompileSourceMapMappings = nativeCompiles.reduce((sum, result) => sum + result.sourceMaps.reduce((mapSum, sourceMap) => mapSum + sourceMap.mappings.length, 0), 0);
|
|
103
105
|
const nativeCompileBlocked = nativeCompiles.filter((result) => result.readiness.readiness === 'blocked').length;
|
|
106
|
+
const nativeTargetAdapterStart = performance.now();
|
|
107
|
+
const nativeTargetAdapterCompiles = nativeImportResults.slice(0, 25).map((imported, index) => {
|
|
108
|
+
const target = index % 2 === 0 ? 'rust' : 'python';
|
|
109
|
+
return compileNativeSource(imported, {
|
|
110
|
+
target,
|
|
111
|
+
targetAdapters: [{
|
|
112
|
+
id: `bench-target-adapter-${index}`,
|
|
113
|
+
sourceLanguage: imported.language,
|
|
114
|
+
target,
|
|
115
|
+
coverage: {
|
|
116
|
+
readiness: 'needs-review',
|
|
117
|
+
handledLossKinds: ['dynamicRuntime', 'dynamicDispatch', 'typeInference', 'overloadResolution']
|
|
118
|
+
},
|
|
119
|
+
project() {
|
|
120
|
+
return { output: `// bench target adapter ${index}\n`, readiness: 'needs-review' };
|
|
121
|
+
}
|
|
122
|
+
}]
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
const nativeTargetAdapterDurationMs = performance.now() - nativeTargetAdapterStart;
|
|
126
|
+
const nativeTargetAdapterBytes = nativeTargetAdapterCompiles.reduce((sum, result) => sum + result.output.length, 0);
|
|
127
|
+
const nativeTargetAdapterSourceMaps = nativeTargetAdapterCompiles.reduce((sum, result) => sum + result.sourceMaps.length, 0);
|
|
104
128
|
|
|
105
129
|
console.log(JSON.stringify({
|
|
106
130
|
compiles: 250,
|
|
@@ -131,6 +155,12 @@ console.log(JSON.stringify({
|
|
|
131
155
|
projectionDurationMs: Number(projectionDurationMs.toFixed(2)),
|
|
132
156
|
nativeCompiles: nativeCompiles.length,
|
|
133
157
|
nativeCompileBytes,
|
|
158
|
+
nativeCompileSourceMaps,
|
|
159
|
+
nativeCompileSourceMapMappings,
|
|
134
160
|
nativeCompileBlocked,
|
|
135
|
-
nativeCompileDurationMs: Number(nativeCompileDurationMs.toFixed(2))
|
|
161
|
+
nativeCompileDurationMs: Number(nativeCompileDurationMs.toFixed(2)),
|
|
162
|
+
nativeTargetAdapterCompiles: nativeTargetAdapterCompiles.length,
|
|
163
|
+
nativeTargetAdapterBytes,
|
|
164
|
+
nativeTargetAdapterSourceMaps,
|
|
165
|
+
nativeTargetAdapterDurationMs: Number(nativeTargetAdapterDurationMs.toFixed(2))
|
|
136
166
|
}));
|
package/dist/index.d.ts
CHANGED
|
@@ -271,6 +271,7 @@ export type ProjectionTargetLossClass =
|
|
|
271
271
|
| 'exactSourceProjection'
|
|
272
272
|
| 'nativeSourceStubs'
|
|
273
273
|
| 'unsupportedTargetFeatures'
|
|
274
|
+
| 'targetAdapterProjection'
|
|
274
275
|
| 'missingAdapter'
|
|
275
276
|
| string;
|
|
276
277
|
|
|
@@ -299,6 +300,9 @@ export interface ProjectionTargetCoverageEntry {
|
|
|
299
300
|
readonly categories: readonly NativeImportTaxonomyKind[];
|
|
300
301
|
readonly reason: string;
|
|
301
302
|
readonly adapter?: string;
|
|
303
|
+
readonly adapterKind?: 'importer' | 'targetProjection' | string;
|
|
304
|
+
readonly adapterVersion?: string;
|
|
305
|
+
readonly adapterCoverage?: NativeTargetProjectionAdapterCoverageInput;
|
|
302
306
|
readonly notes: readonly string[];
|
|
303
307
|
}
|
|
304
308
|
|
|
@@ -339,6 +343,7 @@ export interface ProjectionTargetLossMatrix {
|
|
|
339
343
|
readonly sourceProjectionByLossClass: Readonly<Record<ProjectionTargetLossClass, number>>;
|
|
340
344
|
readonly exactSourceProjection: number;
|
|
341
345
|
readonly nativeSourceStubs: number;
|
|
346
|
+
readonly targetAdapterProjection: number;
|
|
342
347
|
readonly unsupportedTargetFeatures: number;
|
|
343
348
|
readonly missingAdapters: number;
|
|
344
349
|
};
|
|
@@ -353,6 +358,7 @@ export interface ProjectionTargetLossMatrixOptions {
|
|
|
353
358
|
readonly languages?: readonly NativeImportLanguageProfile[];
|
|
354
359
|
readonly imports?: readonly NativeSourceImportResult[];
|
|
355
360
|
readonly adapters?: readonly NativeImporterAdapter[];
|
|
361
|
+
readonly targetAdapters?: readonly NativeTargetProjectionAdapter[];
|
|
356
362
|
readonly targets?: readonly (FrontierCompileTarget | string)[];
|
|
357
363
|
readonly generatedAt?: number;
|
|
358
364
|
}
|
|
@@ -1124,6 +1130,94 @@ export type NativeImporterAdapterImportResult = NativeSourceImportResult & {
|
|
|
1124
1130
|
readonly diagnostics: readonly NativeImporterAdapterDiagnostic[];
|
|
1125
1131
|
};
|
|
1126
1132
|
|
|
1133
|
+
export interface NativeTargetProjectionAdapterCoverageInput {
|
|
1134
|
+
readonly readiness?: SemanticMergeReadiness;
|
|
1135
|
+
readonly lossKinds?: readonly NativeImportKnownLossKind[];
|
|
1136
|
+
readonly handledLossKinds?: readonly NativeImportKnownLossKind[];
|
|
1137
|
+
readonly sourceMapPrecision?: SourceMapMappingRecord['precision'] | 'none' | string;
|
|
1138
|
+
readonly semanticCoverage?: Partial<NativeImporterAdapterSemanticCoverage>;
|
|
1139
|
+
readonly notes?: readonly string[];
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
export interface NativeTargetProjectionAdapterSummary {
|
|
1143
|
+
readonly id: string;
|
|
1144
|
+
readonly sourceLanguage: FrontierSourceLanguage | string;
|
|
1145
|
+
readonly target: FrontierCompileTarget | string;
|
|
1146
|
+
readonly version?: string;
|
|
1147
|
+
readonly capabilities: readonly string[];
|
|
1148
|
+
readonly supportedParsers: readonly string[];
|
|
1149
|
+
readonly supportedExtensions: readonly string[];
|
|
1150
|
+
readonly coverage: Required<Pick<NativeTargetProjectionAdapterCoverageInput, 'readiness' | 'lossKinds' | 'handledLossKinds' | 'notes'>> & NativeTargetProjectionAdapterCoverageInput;
|
|
1151
|
+
readonly diagnostics: readonly NativeImporterAdapterDiagnostic[];
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
export interface NativeTargetProjectionAdapterInput {
|
|
1155
|
+
readonly importResult: NativeSourceImportResult;
|
|
1156
|
+
readonly sourceProjection: NativeSourceProjectionResult;
|
|
1157
|
+
readonly sourceLanguage: FrontierSourceLanguage | string;
|
|
1158
|
+
readonly target: FrontierCompileTarget | string;
|
|
1159
|
+
readonly targetPath?: string;
|
|
1160
|
+
readonly targetCoverage?: ProjectionTargetCoverageEntry;
|
|
1161
|
+
readonly options: Record<string, unknown>;
|
|
1162
|
+
readonly metadata: Record<string, unknown>;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
export interface NativeTargetProjectionAdapterResult {
|
|
1166
|
+
readonly id?: string;
|
|
1167
|
+
readonly output?: string;
|
|
1168
|
+
readonly outputHash?: string;
|
|
1169
|
+
readonly sourceMaps?: readonly SourceMapRecord[];
|
|
1170
|
+
readonly losses?: readonly NativeAstLossRecord[];
|
|
1171
|
+
readonly evidence?: readonly EvidenceRecord[];
|
|
1172
|
+
readonly diagnostics?: readonly NativeImporterAdapterDiagnostic[];
|
|
1173
|
+
readonly readiness?: SemanticMergeReadiness;
|
|
1174
|
+
readonly metadata?: Record<string, unknown>;
|
|
1175
|
+
}
|
|
1176
|
+
|
|
1177
|
+
export interface NativeTargetProjectionAdapter {
|
|
1178
|
+
readonly id: string;
|
|
1179
|
+
readonly sourceLanguage?: FrontierSourceLanguage | string;
|
|
1180
|
+
readonly language?: FrontierSourceLanguage | string;
|
|
1181
|
+
readonly target: FrontierCompileTarget | string;
|
|
1182
|
+
readonly targetLanguage?: FrontierCompileTarget | string;
|
|
1183
|
+
readonly version?: string;
|
|
1184
|
+
readonly capabilities?: readonly string[];
|
|
1185
|
+
readonly supportedParsers?: readonly string[];
|
|
1186
|
+
readonly supportedExtensions?: readonly string[];
|
|
1187
|
+
readonly coverage?: NativeTargetProjectionAdapterCoverageInput;
|
|
1188
|
+
readonly diagnostics?: readonly NativeImporterAdapterDiagnostic[];
|
|
1189
|
+
readonly project: (input: NativeTargetProjectionAdapterInput) => NativeTargetProjectionAdapterResult;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
export interface NativeTargetProjectionAdapterResolverInput {
|
|
1193
|
+
readonly importResult: NativeSourceImportResult;
|
|
1194
|
+
readonly sourceProjection: NativeSourceProjectionResult;
|
|
1195
|
+
readonly sourceLanguage: FrontierSourceLanguage | string;
|
|
1196
|
+
readonly target: FrontierCompileTarget | string;
|
|
1197
|
+
readonly sourcePath?: string;
|
|
1198
|
+
readonly parser?: string;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
export interface NativeTargetProjectionResult {
|
|
1202
|
+
readonly kind: 'frontier.lang.nativeTargetProjection';
|
|
1203
|
+
readonly version: 1;
|
|
1204
|
+
readonly id: string;
|
|
1205
|
+
readonly sourceLanguage: FrontierSourceLanguage | string;
|
|
1206
|
+
readonly target: FrontierCompileTarget | string;
|
|
1207
|
+
readonly targetPath?: string;
|
|
1208
|
+
readonly adapter: NativeTargetProjectionAdapterSummary;
|
|
1209
|
+
readonly output: string;
|
|
1210
|
+
readonly outputHash: string;
|
|
1211
|
+
readonly outputMode: 'target-adapter';
|
|
1212
|
+
readonly sourceMaps: readonly SourceMapRecord[];
|
|
1213
|
+
readonly losses: readonly NativeAstLossRecord[];
|
|
1214
|
+
readonly lossSummary: NativeImportLossSummary;
|
|
1215
|
+
readonly readiness: NativeImportReadinessClassification;
|
|
1216
|
+
readonly evidence: readonly EvidenceRecord[];
|
|
1217
|
+
readonly diagnostics: readonly NativeImporterAdapterDiagnostic[];
|
|
1218
|
+
readonly metadata: Record<string, unknown>;
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1127
1221
|
export interface NativeProjectSourceInput extends ImportNativeSourceOptions {
|
|
1128
1222
|
readonly adapter?: NativeImporterAdapter | string;
|
|
1129
1223
|
readonly adapterOptions?: Record<string, unknown>;
|
|
@@ -1221,14 +1315,26 @@ export interface NativeSourceProjectionResult {
|
|
|
1221
1315
|
readonly metadata: Record<string, unknown>;
|
|
1222
1316
|
}
|
|
1223
1317
|
|
|
1224
|
-
export type NativeSourceCompileOutputMode = NativeSourceProjectionMode | 'target-stubs';
|
|
1318
|
+
export type NativeSourceCompileOutputMode = NativeSourceProjectionMode | 'target-stubs' | 'target-adapter';
|
|
1225
1319
|
|
|
1226
1320
|
export interface CompileNativeSourceOptions extends ProjectNativeImportToSourceOptions {
|
|
1227
1321
|
readonly target?: FrontierCompileTarget | string;
|
|
1228
1322
|
readonly adapters?: readonly NativeImporterAdapter[];
|
|
1323
|
+
readonly targetAdapters?: readonly NativeTargetProjectionAdapter[];
|
|
1324
|
+
readonly targetAdapter?: NativeTargetProjectionAdapter | string;
|
|
1325
|
+
readonly targetAdapterResolver?: (
|
|
1326
|
+
input: NativeTargetProjectionAdapterResolverInput,
|
|
1327
|
+
adapters: readonly NativeTargetProjectionAdapter[]
|
|
1328
|
+
) => NativeTargetProjectionAdapter | undefined;
|
|
1329
|
+
readonly targetAdapterOptions?: Record<string, unknown>;
|
|
1330
|
+
readonly targetAdapterMetadata?: Record<string, unknown>;
|
|
1229
1331
|
readonly languages?: readonly NativeImportLanguageProfile[];
|
|
1230
1332
|
readonly generatedAt?: number;
|
|
1231
1333
|
readonly emitOnBlocked?: boolean;
|
|
1334
|
+
readonly emitSourceMap?: boolean;
|
|
1335
|
+
readonly targetPath?: string;
|
|
1336
|
+
readonly targetHash?: string;
|
|
1337
|
+
readonly sourceMapId?: string;
|
|
1232
1338
|
readonly projectionId?: string;
|
|
1233
1339
|
readonly projectionEvidenceId?: string;
|
|
1234
1340
|
readonly compileEvidenceId?: string;
|
|
@@ -1247,8 +1353,11 @@ export interface NativeSourceCompileResult {
|
|
|
1247
1353
|
readonly output: string;
|
|
1248
1354
|
readonly outputHash: string;
|
|
1249
1355
|
readonly outputMode: NativeSourceCompileOutputMode;
|
|
1356
|
+
readonly sourceMap?: SourceMapRecord;
|
|
1357
|
+
readonly sourceMaps: readonly SourceMapRecord[];
|
|
1250
1358
|
readonly importResult: NativeSourceImportResult;
|
|
1251
1359
|
readonly projection: NativeSourceProjectionResult;
|
|
1360
|
+
readonly targetProjection?: NativeTargetProjectionResult;
|
|
1252
1361
|
readonly targetCoverage: ProjectionTargetCoverageEntry;
|
|
1253
1362
|
readonly projectionMatrix: ProjectionTargetLossMatrix;
|
|
1254
1363
|
readonly losses: readonly NativeAstLossRecord[];
|
|
@@ -1342,6 +1451,7 @@ export declare function createBabelNativeImporterAdapter(options?: JavaScriptNat
|
|
|
1342
1451
|
export declare function createTypeScriptCompilerNativeImporterAdapter(options?: TypeScriptCompilerNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1343
1452
|
export declare function createTreeSitterNativeImporterAdapter(options?: TreeSitterNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1344
1453
|
export declare function runNativeImporterAdapter(adapter: NativeImporterAdapter, input: RunNativeImporterAdapterOptions): Promise<NativeImporterAdapterImportResult>;
|
|
1454
|
+
export declare function runNativeTargetProjectionAdapter(adapter: NativeTargetProjectionAdapter, input: NativeTargetProjectionAdapterInput): NativeTargetProjectionResult;
|
|
1345
1455
|
export declare function projectNativeImportToSource(importResult: NativeSourceImportResult | NativeProjectImportResult, options?: ProjectNativeImportToSourceOptions): NativeSourceProjectionResult;
|
|
1346
1456
|
export declare function importNativeSource(input: ImportNativeSourceOptions): NativeSourceImportResult;
|
|
1347
1457
|
export declare function diffNativeSources(input: DiffNativeSourcesOptions): NativeSourceChangeSet;
|
package/dist/index.js
CHANGED
|
@@ -151,6 +151,7 @@ export const ProjectionTargetLossClasses = Object.freeze([
|
|
|
151
151
|
'exactSourceProjection',
|
|
152
152
|
'nativeSourceStubs',
|
|
153
153
|
'unsupportedTargetFeatures',
|
|
154
|
+
'targetAdapterProjection',
|
|
154
155
|
'missingAdapter'
|
|
155
156
|
]);
|
|
156
157
|
|
|
@@ -277,11 +278,38 @@ export function compileNativeSource(input, options = {}) {
|
|
|
277
278
|
const projectionMatrix = createProjectionTargetLossMatrix({
|
|
278
279
|
imports: [importResult],
|
|
279
280
|
adapters: options.adapters,
|
|
281
|
+
targetAdapters: options.targetAdapters,
|
|
280
282
|
languages: options.languages,
|
|
281
283
|
targets: [target],
|
|
282
284
|
generatedAt: options.generatedAt
|
|
283
285
|
});
|
|
284
286
|
const targetCoverage = nativeSourceCompileTargetCoverage(projectionMatrix, sourceLanguage, target);
|
|
287
|
+
const targetAdapter = resolveNativeTargetProjectionAdapter({
|
|
288
|
+
importResult,
|
|
289
|
+
sourceProjection: projection,
|
|
290
|
+
sourceLanguage,
|
|
291
|
+
target,
|
|
292
|
+
sourcePath: importResult.sourcePath ?? importResult.nativeSource?.sourcePath,
|
|
293
|
+
parser: importResult.nativeAst?.parser ?? importResult.nativeSource?.parser ?? options.parser
|
|
294
|
+
}, options);
|
|
295
|
+
const targetProjection = targetAdapter
|
|
296
|
+
? runNativeTargetProjectionAdapter(targetAdapter, {
|
|
297
|
+
importResult,
|
|
298
|
+
sourceProjection: projection,
|
|
299
|
+
sourceLanguage,
|
|
300
|
+
target,
|
|
301
|
+
targetPath: options.targetPath,
|
|
302
|
+
targetCoverage,
|
|
303
|
+
options: options.targetAdapterOptions ?? {},
|
|
304
|
+
metadata: {
|
|
305
|
+
nativeCompileResultId: id,
|
|
306
|
+
sourceLanguage,
|
|
307
|
+
target,
|
|
308
|
+
projectionId: projection.id,
|
|
309
|
+
...options.targetAdapterMetadata
|
|
310
|
+
}
|
|
311
|
+
})
|
|
312
|
+
: undefined;
|
|
285
313
|
const targetLosses = nativeSourceCompileTargetLosses({
|
|
286
314
|
importResult,
|
|
287
315
|
projection,
|
|
@@ -290,26 +318,32 @@ export function compileNativeSource(input, options = {}) {
|
|
|
290
318
|
target,
|
|
291
319
|
idPart
|
|
292
320
|
});
|
|
293
|
-
const
|
|
321
|
+
const output = targetProjection?.output ?? projection.sourceText;
|
|
322
|
+
const outputHash = targetProjection?.outputHash ?? projection.outputHash;
|
|
323
|
+
const outputMode = targetProjection ? targetProjection.outputMode : sameSourceTarget ? projection.mode : 'target-stubs';
|
|
294
324
|
const compileEvidence = nativeSourceCompileEvidence({
|
|
295
325
|
id: options.compileEvidenceId ?? `evidence_${idPart}_${idFragment(target)}_native_source_compile`,
|
|
296
326
|
importResult,
|
|
297
327
|
projection,
|
|
328
|
+
targetProjection,
|
|
298
329
|
targetCoverage,
|
|
299
330
|
targetLosses,
|
|
300
331
|
sourceLanguage,
|
|
301
332
|
target,
|
|
333
|
+
outputHash,
|
|
302
334
|
outputMode
|
|
303
335
|
});
|
|
304
336
|
const evidence = uniqueByEvidenceId([
|
|
305
337
|
...(importResult.evidence ?? []),
|
|
306
338
|
...(projection.evidence ?? []),
|
|
339
|
+
...(targetProjection?.evidence ?? []),
|
|
307
340
|
compileEvidence,
|
|
308
341
|
...(options.evidence ?? [])
|
|
309
342
|
]);
|
|
310
343
|
const losses = uniqueByLossId([
|
|
311
344
|
...(importResult.losses ?? []),
|
|
312
345
|
...(projection.losses ?? []),
|
|
346
|
+
...(targetProjection?.losses ?? []),
|
|
313
347
|
...targetLosses,
|
|
314
348
|
...(options.losses ?? [])
|
|
315
349
|
]);
|
|
@@ -325,6 +359,25 @@ export function compileNativeSource(input, options = {}) {
|
|
|
325
359
|
scanKind: 'native-source-compile',
|
|
326
360
|
semanticStatus: importResult.metadata?.semanticStatus ?? options.semanticStatus
|
|
327
361
|
});
|
|
362
|
+
const sourceMaps = options.emitSourceMap === false
|
|
363
|
+
? []
|
|
364
|
+
: nativeSourceCompileSourceMaps({
|
|
365
|
+
id: options.sourceMapId ?? `source_map_${idFragment(id)}_${idFragment(target)}`,
|
|
366
|
+
importResult,
|
|
367
|
+
projection,
|
|
368
|
+
targetProjection,
|
|
369
|
+
sourceLanguage,
|
|
370
|
+
target,
|
|
371
|
+
targetPath: options.targetPath ?? targetProjection?.targetPath,
|
|
372
|
+
targetHash: options.targetHash ?? outputHash,
|
|
373
|
+
output,
|
|
374
|
+
outputHash,
|
|
375
|
+
outputMode,
|
|
376
|
+
evidence,
|
|
377
|
+
losses,
|
|
378
|
+
compileResultId: id
|
|
379
|
+
});
|
|
380
|
+
const sourceMap = sourceMaps[0];
|
|
328
381
|
return {
|
|
329
382
|
kind: 'frontier.lang.nativeSourceCompileResult',
|
|
330
383
|
version: 1,
|
|
@@ -333,11 +386,14 @@ export function compileNativeSource(input, options = {}) {
|
|
|
333
386
|
target,
|
|
334
387
|
language: sourceLanguage,
|
|
335
388
|
sourcePath: importResult.sourcePath ?? importResult.nativeSource?.sourcePath,
|
|
336
|
-
output
|
|
337
|
-
outputHash
|
|
389
|
+
output,
|
|
390
|
+
outputHash,
|
|
338
391
|
outputMode,
|
|
392
|
+
sourceMap,
|
|
393
|
+
sourceMaps,
|
|
339
394
|
importResult,
|
|
340
395
|
projection,
|
|
396
|
+
targetProjection,
|
|
341
397
|
targetCoverage,
|
|
342
398
|
projectionMatrix,
|
|
343
399
|
losses,
|
|
@@ -351,8 +407,15 @@ export function compileNativeSource(input, options = {}) {
|
|
|
351
407
|
semanticIndexId: importResult.semanticIndex?.id ?? importResult.universalAst?.semanticIndex?.id,
|
|
352
408
|
universalAstId: importResult.universalAst?.id,
|
|
353
409
|
projectionId: projection.id,
|
|
410
|
+
targetProjectionId: targetProjection?.id,
|
|
411
|
+
targetProjectionAdapterId: targetProjection?.adapter?.id,
|
|
412
|
+
sourceMapId: sourceMap?.id,
|
|
413
|
+
sourceMapIds: sourceMaps.map((record) => record.id).filter(Boolean),
|
|
414
|
+
sourceMapMappings: sourceMaps.reduce((sum, record) => sum + (record.mappings?.length ?? 0), 0),
|
|
354
415
|
projectionMode: projection.mode,
|
|
355
416
|
outputMode,
|
|
417
|
+
targetPath: sourceMap?.targetPath ?? options.targetPath ?? targetProjection?.targetPath,
|
|
418
|
+
targetHash: sourceMap?.targetHash ?? options.targetHash ?? outputHash,
|
|
356
419
|
sourceTarget,
|
|
357
420
|
sameSourceTarget,
|
|
358
421
|
targetLossClass: targetCoverage.lossClass,
|
|
@@ -657,11 +720,13 @@ export function createNativeImportCoverageMatrix(input = {}) {
|
|
|
657
720
|
export function createProjectionTargetLossMatrix(input = {}) {
|
|
658
721
|
const imports = input.imports ?? [];
|
|
659
722
|
const adapters = input.adapters ?? [];
|
|
660
|
-
const
|
|
723
|
+
const targetAdapters = input.targetAdapters ?? [];
|
|
724
|
+
const profiles = mergeNativeImportProfiles(input.languages ?? NativeImportLanguageProfiles, imports, adapters, targetAdapters);
|
|
661
725
|
const targets = normalizeProjectionMatrixTargets(input.targets ?? FrontierCompileTargets);
|
|
662
726
|
const languages = profiles.map((profile) => projectionTargetCoverageForProfile(profile, {
|
|
663
727
|
imports,
|
|
664
728
|
adapters,
|
|
729
|
+
targetAdapters,
|
|
665
730
|
targets
|
|
666
731
|
}));
|
|
667
732
|
const summary = projectionTargetLossMatrixSummary(languages);
|
|
@@ -674,7 +739,7 @@ export function createProjectionTargetLossMatrix(input = {}) {
|
|
|
674
739
|
metadata: {
|
|
675
740
|
compileTargets: targets,
|
|
676
741
|
lossClasses: [...ProjectionTargetLossClasses],
|
|
677
|
-
note: 'Projection target coverage separates exact source preservation, declaration stubs, known unsupported target features, and missing native-to-target adapters.'
|
|
742
|
+
note: 'Projection target coverage separates exact source preservation, declaration stubs, host-owned target adapters, known unsupported target features, and missing native-to-target adapters.'
|
|
678
743
|
}
|
|
679
744
|
};
|
|
680
745
|
}
|
|
@@ -1159,6 +1224,120 @@ export async function runNativeImporterAdapter(adapter, input = {}) {
|
|
|
1159
1224
|
};
|
|
1160
1225
|
}
|
|
1161
1226
|
|
|
1227
|
+
export function runNativeTargetProjectionAdapter(adapter, input = {}) {
|
|
1228
|
+
const summary = normalizeNativeTargetProjectionAdapter(adapter);
|
|
1229
|
+
const sourceLanguage = normalizeNativeLanguageId(input.sourceLanguage ?? summary.sourceLanguage);
|
|
1230
|
+
const target = normalizeProjectionMatrixTargets([input.target ?? summary.target])[0] ?? summary.target;
|
|
1231
|
+
const diagnosticContext = {
|
|
1232
|
+
sourcePath: input.importResult?.sourcePath ?? input.importResult?.nativeSource?.sourcePath,
|
|
1233
|
+
sourceHash: input.importResult?.sourceHash ?? input.importResult?.nativeSource?.sourceHash,
|
|
1234
|
+
language: sourceLanguage,
|
|
1235
|
+
parser: `target:${target}`,
|
|
1236
|
+
parserVersion: summary.version
|
|
1237
|
+
};
|
|
1238
|
+
const projectInput = {
|
|
1239
|
+
importResult: input.importResult,
|
|
1240
|
+
sourceProjection: input.sourceProjection,
|
|
1241
|
+
sourceLanguage,
|
|
1242
|
+
target,
|
|
1243
|
+
targetPath: input.targetPath,
|
|
1244
|
+
targetCoverage: input.targetCoverage,
|
|
1245
|
+
options: input.options ?? {},
|
|
1246
|
+
metadata: input.metadata ?? {}
|
|
1247
|
+
};
|
|
1248
|
+
let projected;
|
|
1249
|
+
let thrownDiagnostic;
|
|
1250
|
+
try {
|
|
1251
|
+
projected = adapter.project(projectInput) ?? {};
|
|
1252
|
+
} catch (error) {
|
|
1253
|
+
thrownDiagnostic = {
|
|
1254
|
+
severity: 'error',
|
|
1255
|
+
code: 'targetAdapter.project.threw',
|
|
1256
|
+
phase: 'emit',
|
|
1257
|
+
kind: 'targetProjectionLoss',
|
|
1258
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1259
|
+
metadata: {
|
|
1260
|
+
errorName: error instanceof Error ? error.name : undefined
|
|
1261
|
+
}
|
|
1262
|
+
};
|
|
1263
|
+
projected = {};
|
|
1264
|
+
}
|
|
1265
|
+
const diagnostics = [
|
|
1266
|
+
...normalizeAdapterDiagnostics(summary.diagnostics, summary, diagnosticContext, 'target-adapter'),
|
|
1267
|
+
...(thrownDiagnostic ? normalizeAdapterDiagnostics([thrownDiagnostic], summary, diagnosticContext, 'throw') : []),
|
|
1268
|
+
...normalizeAdapterDiagnostics(projected.diagnostics, summary, diagnosticContext, 'project')
|
|
1269
|
+
];
|
|
1270
|
+
const output = typeof projected.output === 'string' ? projected.output : input.sourceProjection?.sourceText ?? '';
|
|
1271
|
+
const outputHash = projected.outputHash ?? hashSemanticValue(output);
|
|
1272
|
+
const adapterEvidence = nativeTargetProjectionAdapterEvidence(summary, diagnostics, {
|
|
1273
|
+
...diagnosticContext,
|
|
1274
|
+
sourceLanguage,
|
|
1275
|
+
target,
|
|
1276
|
+
outputHash,
|
|
1277
|
+
targetPath: input.targetPath
|
|
1278
|
+
});
|
|
1279
|
+
const evidence = uniqueByEvidenceId([
|
|
1280
|
+
...(projected.evidence ?? []),
|
|
1281
|
+
adapterEvidence
|
|
1282
|
+
]);
|
|
1283
|
+
const losses = uniqueByLossId([
|
|
1284
|
+
...(projected.losses ?? []),
|
|
1285
|
+
...diagnostics.map((diagnostic, index) => nativeTargetProjectionDiagnosticToLoss(diagnostic, index, summary, {
|
|
1286
|
+
...diagnosticContext,
|
|
1287
|
+
sourceLanguage,
|
|
1288
|
+
target
|
|
1289
|
+
}))
|
|
1290
|
+
]);
|
|
1291
|
+
const lossSummary = summarizeNativeImportLosses(losses, {
|
|
1292
|
+
evidence,
|
|
1293
|
+
parser: diagnosticContext.parser,
|
|
1294
|
+
scanKind: 'native-target-projection',
|
|
1295
|
+
semanticStatus: input.importResult?.metadata?.semanticStatus
|
|
1296
|
+
});
|
|
1297
|
+
const classifiedReadiness = classifyNativeImportReadiness(losses, {
|
|
1298
|
+
evidence,
|
|
1299
|
+
parser: diagnosticContext.parser,
|
|
1300
|
+
scanKind: 'native-target-projection',
|
|
1301
|
+
semanticStatus: input.importResult?.metadata?.semanticStatus
|
|
1302
|
+
});
|
|
1303
|
+
const declaredReadiness = normalizeSemanticMergeReadiness(projected.readiness ?? summary.coverage.readiness);
|
|
1304
|
+
const readiness = declaredReadiness
|
|
1305
|
+
? {
|
|
1306
|
+
...classifiedReadiness,
|
|
1307
|
+
readiness: maxSemanticMergeReadiness(classifiedReadiness.readiness, declaredReadiness),
|
|
1308
|
+
reasons: uniqueStrings([
|
|
1309
|
+
...classifiedReadiness.reasons,
|
|
1310
|
+
...(declaredReadiness === classifiedReadiness.readiness ? [] : [`Target adapter declared readiness ${declaredReadiness}.`])
|
|
1311
|
+
])
|
|
1312
|
+
}
|
|
1313
|
+
: classifiedReadiness;
|
|
1314
|
+
return {
|
|
1315
|
+
kind: 'frontier.lang.nativeTargetProjection',
|
|
1316
|
+
version: 1,
|
|
1317
|
+
id: projected.id ?? `native_target_projection_${idFragment(summary.id)}_${idFragment(sourceLanguage)}_${idFragment(target)}`,
|
|
1318
|
+
sourceLanguage,
|
|
1319
|
+
target,
|
|
1320
|
+
targetPath: input.targetPath,
|
|
1321
|
+
adapter: summary,
|
|
1322
|
+
output,
|
|
1323
|
+
outputHash,
|
|
1324
|
+
outputMode: 'target-adapter',
|
|
1325
|
+
sourceMaps: projected.sourceMaps ?? [],
|
|
1326
|
+
losses,
|
|
1327
|
+
lossSummary,
|
|
1328
|
+
readiness,
|
|
1329
|
+
evidence,
|
|
1330
|
+
diagnostics: diagnostics.map(serializableDiagnostic),
|
|
1331
|
+
metadata: {
|
|
1332
|
+
importId: input.importResult?.id,
|
|
1333
|
+
projectionId: input.sourceProjection?.id,
|
|
1334
|
+
targetCoverageLossClass: input.targetCoverage?.lossClass,
|
|
1335
|
+
targetCoverageReadiness: input.targetCoverage?.readiness,
|
|
1336
|
+
...projected.metadata
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1162
1341
|
export function projectNativeImportToSource(importResult, options = {}) {
|
|
1163
1342
|
if (!importResult || typeof importResult !== 'object') {
|
|
1164
1343
|
throw new Error('projectNativeImportToSource requires a native import result');
|
|
@@ -3950,6 +4129,7 @@ function projectionTargetCoverageForProfile(profile, context) {
|
|
|
3950
4129
|
const aliases = new Set([profile.language, ...(profile.aliases ?? [])].map(normalizeNativeLanguageId).filter(Boolean));
|
|
3951
4130
|
const matchingImports = (context.imports ?? []).filter((imported) => aliases.has(normalizeNativeLanguageId(imported?.language ?? imported?.nativeAst?.language)));
|
|
3952
4131
|
const matchingAdapters = (context.adapters ?? []).filter((adapter) => aliases.has(normalizeNativeLanguageId(adapter?.language)));
|
|
4132
|
+
const matchingTargetAdapters = (context.targetAdapters ?? []).filter((adapter) => aliases.has(normalizeNativeLanguageId(adapter?.sourceLanguage ?? adapter?.language)));
|
|
3953
4133
|
const importedLossKinds = uniqueStrings(matchingImports.flatMap((imported) => (imported?.losses ?? []).map((loss) => loss.kind).filter(Boolean)));
|
|
3954
4134
|
const knownLossKinds = uniqueStrings([...(profile.knownLossKinds ?? []), ...importedLossKinds]);
|
|
3955
4135
|
const parserAdapters = uniqueStrings([
|
|
@@ -3960,6 +4140,7 @@ function projectionTargetCoverageForProfile(profile, context) {
|
|
|
3960
4140
|
const targets = (context.targets ?? FrontierCompileTargets).map((target) => projectionTargetCoverageEntry(profile, target, {
|
|
3961
4141
|
matchingImports,
|
|
3962
4142
|
matchingAdapters,
|
|
4143
|
+
matchingTargetAdapters,
|
|
3963
4144
|
knownLossKinds
|
|
3964
4145
|
}));
|
|
3965
4146
|
return {
|
|
@@ -4037,8 +4218,14 @@ function projectionTargetCoverageEntry(profile, target, context) {
|
|
|
4037
4218
|
const normalizedTarget = normalizeProjectionMatrixTargets([target])[0] ?? String(target);
|
|
4038
4219
|
const declaredTargets = new Set(normalizeProjectionMatrixTargets(profile.projectionTargets ?? []));
|
|
4039
4220
|
const adapterTargets = new Set((context.matchingAdapters ?? []).flatMap(adapterProjectionTargets));
|
|
4221
|
+
const targetAdapter = matchingNativeTargetProjectionAdapter({
|
|
4222
|
+
sourceLanguage: profile.language,
|
|
4223
|
+
target: normalizedTarget,
|
|
4224
|
+
sourcePath: context.matchingImports?.[0]?.sourcePath ?? context.matchingImports?.[0]?.nativeSource?.sourcePath
|
|
4225
|
+
}, context.matchingTargetAdapters ?? []);
|
|
4226
|
+
const targetAdapterSummary = targetAdapter ? normalizeNativeTargetProjectionAdapter(targetAdapter) : undefined;
|
|
4040
4227
|
const sameSourceTarget = nativeLanguageCompileTarget(profile.language, profile.aliases) === normalizedTarget;
|
|
4041
|
-
const hasProjectionAdapter = declaredTargets.has(normalizedTarget) || adapterTargets.has(normalizedTarget);
|
|
4228
|
+
const hasProjectionAdapter = Boolean(targetAdapterSummary) || declaredTargets.has(normalizedTarget) || adapterTargets.has(normalizedTarget);
|
|
4042
4229
|
if (!hasProjectionAdapter) {
|
|
4043
4230
|
return {
|
|
4044
4231
|
target: normalizedTarget,
|
|
@@ -4054,6 +4241,48 @@ function projectionTargetCoverageEntry(profile, target, context) {
|
|
|
4054
4241
|
}
|
|
4055
4242
|
|
|
4056
4243
|
const featureLossKinds = projectionUnsupportedFeatureLossKinds(context.knownLossKinds);
|
|
4244
|
+
if (targetAdapterSummary) {
|
|
4245
|
+
const handledLossKinds = new Set(targetAdapterSummary.coverage.handledLossKinds ?? []);
|
|
4246
|
+
const unhandledFeatureLossKinds = featureLossKinds.filter((kind) => !handledLossKinds.has(kind));
|
|
4247
|
+
if (unhandledFeatureLossKinds.length) {
|
|
4248
|
+
return {
|
|
4249
|
+
target: normalizedTarget,
|
|
4250
|
+
lossClass: 'unsupportedTargetFeatures',
|
|
4251
|
+
supported: true,
|
|
4252
|
+
readiness: 'needs-review',
|
|
4253
|
+
lossKinds: unhandledFeatureLossKinds,
|
|
4254
|
+
categories: uniqueStrings(unhandledFeatureLossKinds.map(nativeImportCategoryForLossKind)),
|
|
4255
|
+
reason: `${profile.language} has target adapter ${targetAdapterSummary.id}, but source feature losses remain unhandled for ${normalizedTarget}: ${unhandledFeatureLossKinds.join(', ')}.`,
|
|
4256
|
+
adapter: targetAdapterSummary.id,
|
|
4257
|
+
adapterKind: 'targetProjection',
|
|
4258
|
+
adapterVersion: targetAdapterSummary.version,
|
|
4259
|
+
adapterCoverage: targetAdapterSummary.coverage,
|
|
4260
|
+
notes: uniqueStrings([
|
|
4261
|
+
...(targetAdapterSummary.coverage.notes ?? []),
|
|
4262
|
+
'Adapter output is available, but merge readiness still requires review for unhandled source-language feature losses.'
|
|
4263
|
+
])
|
|
4264
|
+
};
|
|
4265
|
+
}
|
|
4266
|
+
const adapterLossKinds = uniqueStrings(targetAdapterSummary.coverage.lossKinds ?? []);
|
|
4267
|
+
return {
|
|
4268
|
+
target: normalizedTarget,
|
|
4269
|
+
lossClass: 'targetAdapterProjection',
|
|
4270
|
+
supported: true,
|
|
4271
|
+
readiness: targetAdapterSummary.coverage.readiness ?? 'needs-review',
|
|
4272
|
+
lossKinds: adapterLossKinds,
|
|
4273
|
+
categories: uniqueStrings(adapterLossKinds.map(nativeImportCategoryForLossKind)),
|
|
4274
|
+
reason: `${profile.language} can project to ${normalizedTarget} through host target adapter ${targetAdapterSummary.id}.`,
|
|
4275
|
+
adapter: targetAdapterSummary.id,
|
|
4276
|
+
adapterKind: 'targetProjection',
|
|
4277
|
+
adapterVersion: targetAdapterSummary.version,
|
|
4278
|
+
adapterCoverage: targetAdapterSummary.coverage,
|
|
4279
|
+
notes: uniqueStrings([
|
|
4280
|
+
...(targetAdapterSummary.coverage.notes ?? []),
|
|
4281
|
+
'The host adapter owns native-to-target translation semantics and must provide evidence for merge admission.'
|
|
4282
|
+
])
|
|
4283
|
+
};
|
|
4284
|
+
}
|
|
4285
|
+
|
|
4057
4286
|
if (featureLossKinds.length) {
|
|
4058
4287
|
return {
|
|
4059
4288
|
target: normalizedTarget,
|
|
@@ -4115,6 +4344,7 @@ function projectionTargetLossMatrixSummary(languages) {
|
|
|
4115
4344
|
sourceProjectionByLossClass,
|
|
4116
4345
|
exactSourceProjection: (sourceProjectionByLossClass.exactSourceProjection ?? 0) + (byLossClass.exactSourceProjection ?? 0),
|
|
4117
4346
|
nativeSourceStubs: (sourceProjectionByLossClass.nativeSourceStubs ?? 0) + (byLossClass.nativeSourceStubs ?? 0),
|
|
4347
|
+
targetAdapterProjection: byLossClass.targetAdapterProjection ?? 0,
|
|
4118
4348
|
unsupportedTargetFeatures: byLossClass.unsupportedTargetFeatures ?? 0,
|
|
4119
4349
|
missingAdapters: byLossClass.missingAdapter ?? 0
|
|
4120
4350
|
};
|
|
@@ -4324,9 +4554,11 @@ function nativeSourceCompileEvidence(input) {
|
|
|
4324
4554
|
metadata: {
|
|
4325
4555
|
importId: input.importResult.id,
|
|
4326
4556
|
projectionId: input.projection.id,
|
|
4557
|
+
targetProjectionId: input.targetProjection?.id,
|
|
4558
|
+
targetProjectionAdapterId: input.targetProjection?.adapter?.id,
|
|
4327
4559
|
sourceLanguage: input.sourceLanguage,
|
|
4328
4560
|
target: input.target,
|
|
4329
|
-
outputHash: input.projection.outputHash,
|
|
4561
|
+
outputHash: input.outputHash ?? input.projection.outputHash,
|
|
4330
4562
|
outputMode: input.outputMode,
|
|
4331
4563
|
projectionMode: input.projection.mode,
|
|
4332
4564
|
targetLossClass: input.targetCoverage.lossClass,
|
|
@@ -4338,6 +4570,251 @@ function nativeSourceCompileEvidence(input) {
|
|
|
4338
4570
|
};
|
|
4339
4571
|
}
|
|
4340
4572
|
|
|
4573
|
+
function nativeSourceCompileSourceMaps(input) {
|
|
4574
|
+
const adapterSourceMaps = input.targetProjection?.sourceMaps ?? [];
|
|
4575
|
+
if (adapterSourceMaps.length) return adapterSourceMaps;
|
|
4576
|
+
const targetPath = nativeSourceCompileTargetPath(input);
|
|
4577
|
+
const targetHash = input.targetHash ?? input.outputHash;
|
|
4578
|
+
const target = nativeSourceCompileMapTarget(input, targetPath);
|
|
4579
|
+
const mappings = input.projection.mode === 'preserved-source'
|
|
4580
|
+
? nativeSourceCompilePreservedMappings({ ...input, targetPath, targetHash, target })
|
|
4581
|
+
: nativeSourceCompileDeclarationMappings({ ...input, targetPath, targetHash, target });
|
|
4582
|
+
const resolvedMappings = mappings.length
|
|
4583
|
+
? mappings
|
|
4584
|
+
: [nativeSourceCompileFileMapping({ ...input, targetPath, targetHash, target })];
|
|
4585
|
+
return [createSourceMapRecord({
|
|
4586
|
+
id: input.id,
|
|
4587
|
+
sourcePath: input.importResult.sourcePath ?? input.importResult.nativeSource?.sourcePath,
|
|
4588
|
+
sourceHash: input.importResult.nativeSource?.sourceHash ?? input.importResult.nativeAst?.sourceHash ?? input.importResult.sourceHash,
|
|
4589
|
+
target,
|
|
4590
|
+
targetPath: targetPath ?? commonGeneratedTargetPath(resolvedMappings),
|
|
4591
|
+
targetHash,
|
|
4592
|
+
semanticIndexId: input.importResult.semanticIndex?.id ?? input.importResult.universalAst?.semanticIndex?.id,
|
|
4593
|
+
universalAstId: input.importResult.universalAst?.id,
|
|
4594
|
+
nativeAstId: input.importResult.nativeAst?.id ?? input.importResult.nativeSource?.ast?.id,
|
|
4595
|
+
nativeSourceId: input.importResult.nativeSource?.id,
|
|
4596
|
+
mappings: resolvedMappings,
|
|
4597
|
+
evidence: input.evidence ?? [],
|
|
4598
|
+
metadata: {
|
|
4599
|
+
compileResultId: input.compileResultId,
|
|
4600
|
+
importId: input.importResult.id,
|
|
4601
|
+
projectionId: input.projection.id,
|
|
4602
|
+
targetProjectionId: input.targetProjection?.id,
|
|
4603
|
+
targetProjectionAdapterId: input.targetProjection?.adapter?.id,
|
|
4604
|
+
sourceLanguage: input.sourceLanguage,
|
|
4605
|
+
target: input.target,
|
|
4606
|
+
outputMode: input.outputMode,
|
|
4607
|
+
outputHash: input.outputHash,
|
|
4608
|
+
generatedBy: 'compileNativeSource'
|
|
4609
|
+
}
|
|
4610
|
+
})];
|
|
4611
|
+
}
|
|
4612
|
+
|
|
4613
|
+
function nativeSourceCompilePreservedMappings(input) {
|
|
4614
|
+
const sourceMaps = input.importResult.sourceMaps ?? input.importResult.universalAst?.sourceMaps ?? [];
|
|
4615
|
+
const sourceHash = input.importResult.nativeSource?.sourceHash ?? input.importResult.nativeAst?.sourceHash ?? input.importResult.sourceHash;
|
|
4616
|
+
const exact = input.projection.mode === 'preserved-source' && (!input.projection.sourceHash || input.outputHash === input.projection.sourceHash);
|
|
4617
|
+
const usedIds = new Set();
|
|
4618
|
+
return sourceMaps
|
|
4619
|
+
.flatMap((sourceMap) => sourceMap?.mappings ?? [])
|
|
4620
|
+
.filter((mapping) => mapping?.sourceSpan)
|
|
4621
|
+
.map((mapping, index) => ({
|
|
4622
|
+
id: reserveUniqueId(`compile_map_${idFragment(mapping.id ?? mapping.semanticSymbolId ?? mapping.nativeAstNodeId ?? index + 1)}`, usedIds),
|
|
4623
|
+
nativeSourceId: mapping.nativeSourceId ?? input.importResult.nativeSource?.id,
|
|
4624
|
+
nativeAstNodeId: mapping.nativeAstNodeId,
|
|
4625
|
+
semanticSymbolId: mapping.semanticSymbolId,
|
|
4626
|
+
semanticOccurrenceId: mapping.semanticOccurrenceId,
|
|
4627
|
+
semanticNodeId: mapping.semanticNodeId,
|
|
4628
|
+
mergeCandidateId: mapping.mergeCandidateId,
|
|
4629
|
+
sourceSpan: {
|
|
4630
|
+
...mapping.sourceSpan,
|
|
4631
|
+
sourceId: mapping.sourceSpan.sourceId ?? sourceHash,
|
|
4632
|
+
path: mapping.sourceSpan.path ?? input.importResult.sourcePath ?? input.importResult.nativeSource?.sourcePath
|
|
4633
|
+
},
|
|
4634
|
+
generatedSpan: nativeSourceCompileGeneratedSpanFromSource(mapping.sourceSpan, input, mapping.generatedName),
|
|
4635
|
+
target: input.target,
|
|
4636
|
+
generatedName: mapping.generatedName,
|
|
4637
|
+
evidenceIds: uniqueStrings([
|
|
4638
|
+
...(mapping.evidenceIds ?? []),
|
|
4639
|
+
...(input.evidence ?? []).map((record) => record.id).filter(Boolean)
|
|
4640
|
+
]),
|
|
4641
|
+
lossIds: uniqueStrings([
|
|
4642
|
+
...(mapping.lossIds ?? []),
|
|
4643
|
+
...lossIdsForNativeNode(input.losses ?? [], mapping.nativeAstNodeId)
|
|
4644
|
+
]),
|
|
4645
|
+
ownershipRegionId: mapping.ownershipRegionId,
|
|
4646
|
+
ownershipRegionKey: mapping.ownershipRegionKey,
|
|
4647
|
+
ownershipRegionKind: mapping.ownershipRegionKind,
|
|
4648
|
+
precision: exact ? 'exact' : mapping.precision === 'exact' ? 'line' : mapping.precision ?? 'line',
|
|
4649
|
+
metadata: {
|
|
4650
|
+
...mapping.metadata,
|
|
4651
|
+
compileResultId: input.compileResultId,
|
|
4652
|
+
sourceMapOrigin: 'preserved-source'
|
|
4653
|
+
}
|
|
4654
|
+
}));
|
|
4655
|
+
}
|
|
4656
|
+
|
|
4657
|
+
function nativeSourceCompileDeclarationMappings(input) {
|
|
4658
|
+
const usedIds = new Set();
|
|
4659
|
+
return (input.projection.declarations ?? []).map((declaration, index) => {
|
|
4660
|
+
const generated = nativeSourceCompileDeclarationGeneratedSpan(input, declaration);
|
|
4661
|
+
return {
|
|
4662
|
+
id: reserveUniqueId(`compile_map_${idFragment(declaration.symbolId ?? declaration.nativeAstNodeId ?? declaration.name ?? index + 1)}`, usedIds),
|
|
4663
|
+
nativeSourceId: input.importResult.nativeSource?.id,
|
|
4664
|
+
nativeAstNodeId: declaration.nativeAstNodeId,
|
|
4665
|
+
semanticSymbolId: declaration.symbolId,
|
|
4666
|
+
sourceSpan: declaration.sourceSpan,
|
|
4667
|
+
generatedSpan: generated.span,
|
|
4668
|
+
target: input.target,
|
|
4669
|
+
generatedName: generated.name,
|
|
4670
|
+
evidenceIds: (input.evidence ?? []).map((record) => record.id).filter(Boolean),
|
|
4671
|
+
lossIds: lossIdsForNativeNode(input.losses ?? [], declaration.nativeAstNodeId),
|
|
4672
|
+
ownershipRegionId: declaration.ownershipRegionId,
|
|
4673
|
+
ownershipRegionKey: declaration.metadata?.ownershipRegionKey,
|
|
4674
|
+
ownershipRegionKind: declaration.metadata?.ownershipRegionKind,
|
|
4675
|
+
precision: generated.exactName ? 'declaration' : 'estimated',
|
|
4676
|
+
metadata: {
|
|
4677
|
+
...declaration.metadata,
|
|
4678
|
+
compileResultId: input.compileResultId,
|
|
4679
|
+
declarationKind: declaration.kind,
|
|
4680
|
+
sourceMapOrigin: input.outputMode === 'target-adapter' ? 'target-adapter-fallback' : 'declaration-stub'
|
|
4681
|
+
}
|
|
4682
|
+
};
|
|
4683
|
+
});
|
|
4684
|
+
}
|
|
4685
|
+
|
|
4686
|
+
function nativeSourceCompileFileMapping(input) {
|
|
4687
|
+
const rootSpan = input.importResult.nativeAst?.nodes?.[input.importResult.nativeAst?.rootId]?.span
|
|
4688
|
+
?? input.importResult.nativeSource?.ast?.nodes?.[input.importResult.nativeSource?.ast?.rootId]?.span
|
|
4689
|
+
?? input.projection.declarations?.find((declaration) => declaration.sourceSpan)?.sourceSpan;
|
|
4690
|
+
return {
|
|
4691
|
+
id: `compile_map_${idFragment(input.compileResultId ?? input.id)}_file`,
|
|
4692
|
+
nativeSourceId: input.importResult.nativeSource?.id,
|
|
4693
|
+
sourceSpan: rootSpan,
|
|
4694
|
+
generatedSpan: nativeSourceCompileFullGeneratedSpan(input),
|
|
4695
|
+
target: input.target,
|
|
4696
|
+
evidenceIds: (input.evidence ?? []).map((record) => record.id).filter(Boolean),
|
|
4697
|
+
precision: input.projection.mode === 'preserved-source' && input.outputHash === input.projection.sourceHash ? 'line' : 'estimated',
|
|
4698
|
+
metadata: {
|
|
4699
|
+
compileResultId: input.compileResultId,
|
|
4700
|
+
sourceMapOrigin: 'file-fallback'
|
|
4701
|
+
}
|
|
4702
|
+
};
|
|
4703
|
+
}
|
|
4704
|
+
|
|
4705
|
+
function nativeSourceCompileGeneratedSpanFromSource(sourceSpan, input, generatedName) {
|
|
4706
|
+
if (!sourceSpan) return nativeSourceCompileFullGeneratedSpan(input, generatedName);
|
|
4707
|
+
return {
|
|
4708
|
+
...sourceSpan,
|
|
4709
|
+
sourceId: input.targetHash ?? input.outputHash,
|
|
4710
|
+
path: input.targetPath,
|
|
4711
|
+
target: input.target,
|
|
4712
|
+
targetPath: input.targetPath,
|
|
4713
|
+
targetHash: input.targetHash ?? input.outputHash,
|
|
4714
|
+
generatedName
|
|
4715
|
+
};
|
|
4716
|
+
}
|
|
4717
|
+
|
|
4718
|
+
function nativeSourceCompileDeclarationGeneratedSpan(input, declaration) {
|
|
4719
|
+
const identifiers = uniqueStrings([
|
|
4720
|
+
declaration.name,
|
|
4721
|
+
safeProjectionIdentifier(declaration.name),
|
|
4722
|
+
upperFirst(safeProjectionIdentifier(declaration.name)),
|
|
4723
|
+
safeProjectionIdentifier(declaration.name).toUpperCase()
|
|
4724
|
+
]).filter(Boolean);
|
|
4725
|
+
for (const identifier of identifiers) {
|
|
4726
|
+
const offset = input.output.indexOf(identifier);
|
|
4727
|
+
if (offset >= 0) {
|
|
4728
|
+
return {
|
|
4729
|
+
name: identifier,
|
|
4730
|
+
exactName: true,
|
|
4731
|
+
span: nativeSourceCompileGeneratedSpanForOffset(input, offset, identifier.length, identifier)
|
|
4732
|
+
};
|
|
4733
|
+
}
|
|
4734
|
+
}
|
|
4735
|
+
return {
|
|
4736
|
+
name: safeProjectionIdentifier(declaration.name),
|
|
4737
|
+
exactName: false,
|
|
4738
|
+
span: nativeSourceCompileFullGeneratedSpan(input, safeProjectionIdentifier(declaration.name))
|
|
4739
|
+
};
|
|
4740
|
+
}
|
|
4741
|
+
|
|
4742
|
+
function nativeSourceCompileGeneratedSpanForOffset(input, offset, length, generatedName) {
|
|
4743
|
+
const start = lineColumnForOffset(input.output, offset);
|
|
4744
|
+
const end = lineColumnForOffset(input.output, offset + Math.max(1, length));
|
|
4745
|
+
return {
|
|
4746
|
+
sourceId: input.targetHash ?? input.outputHash,
|
|
4747
|
+
path: input.targetPath,
|
|
4748
|
+
startLine: start.line,
|
|
4749
|
+
startColumn: start.column,
|
|
4750
|
+
endLine: end.line,
|
|
4751
|
+
endColumn: end.column,
|
|
4752
|
+
target: input.target,
|
|
4753
|
+
targetPath: input.targetPath,
|
|
4754
|
+
targetHash: input.targetHash ?? input.outputHash,
|
|
4755
|
+
generatedName
|
|
4756
|
+
};
|
|
4757
|
+
}
|
|
4758
|
+
|
|
4759
|
+
function nativeSourceCompileFullGeneratedSpan(input, generatedName) {
|
|
4760
|
+
const lines = String(input.output ?? '').split(/\r?\n/);
|
|
4761
|
+
const lastLine = lines.at(-1) ?? '';
|
|
4762
|
+
return {
|
|
4763
|
+
sourceId: input.targetHash ?? input.outputHash,
|
|
4764
|
+
path: input.targetPath,
|
|
4765
|
+
startLine: 1,
|
|
4766
|
+
startColumn: 1,
|
|
4767
|
+
endLine: Math.max(1, lines.length),
|
|
4768
|
+
endColumn: Math.max(1, lastLine.length + 1),
|
|
4769
|
+
target: input.target,
|
|
4770
|
+
targetPath: input.targetPath,
|
|
4771
|
+
targetHash: input.targetHash ?? input.outputHash,
|
|
4772
|
+
generatedName
|
|
4773
|
+
};
|
|
4774
|
+
}
|
|
4775
|
+
|
|
4776
|
+
function nativeSourceCompileTargetPath(input) {
|
|
4777
|
+
if (input.targetPath) return input.targetPath;
|
|
4778
|
+
const sourcePath = input.importResult.sourcePath ?? input.importResult.nativeSource?.sourcePath;
|
|
4779
|
+
if (!sourcePath) return undefined;
|
|
4780
|
+
const targetExt = nativeSourceCompileTargetExtension(input.target);
|
|
4781
|
+
if (!targetExt) return sourcePath;
|
|
4782
|
+
return sourcePath.replace(/(\.[^./\\]+)?$/, targetExt);
|
|
4783
|
+
}
|
|
4784
|
+
|
|
4785
|
+
function nativeSourceCompileTargetExtension(target) {
|
|
4786
|
+
const normalized = normalizeNativeLanguageId(target);
|
|
4787
|
+
if (normalized === 'typescript') return '.ts';
|
|
4788
|
+
if (normalized === 'javascript') return '.js';
|
|
4789
|
+
if (normalized === 'rust') return '.rs';
|
|
4790
|
+
if (normalized === 'python') return '.py';
|
|
4791
|
+
if (normalized === 'c') return '.h';
|
|
4792
|
+
return undefined;
|
|
4793
|
+
}
|
|
4794
|
+
|
|
4795
|
+
function nativeSourceCompileMapTarget(input, targetPath) {
|
|
4796
|
+
return {
|
|
4797
|
+
language: input.target,
|
|
4798
|
+
emitPath: targetPath
|
|
4799
|
+
};
|
|
4800
|
+
}
|
|
4801
|
+
|
|
4802
|
+
function lineColumnForOffset(source, offset) {
|
|
4803
|
+
const text = String(source ?? '');
|
|
4804
|
+
const safeOffset = Math.max(0, Math.min(offset, text.length));
|
|
4805
|
+
let line = 1;
|
|
4806
|
+
let column = 1;
|
|
4807
|
+
for (let index = 0; index < safeOffset; index += 1) {
|
|
4808
|
+
if (text[index] === '\n') {
|
|
4809
|
+
line += 1;
|
|
4810
|
+
column = 1;
|
|
4811
|
+
} else {
|
|
4812
|
+
column += 1;
|
|
4813
|
+
}
|
|
4814
|
+
}
|
|
4815
|
+
return { line, column };
|
|
4816
|
+
}
|
|
4817
|
+
|
|
4341
4818
|
function nativeProjectionTargetsForLanguage(language, aliases = []) {
|
|
4342
4819
|
const target = nativeLanguageCompileTarget(language, aliases);
|
|
4343
4820
|
return target ? [target] : [];
|
|
@@ -4359,7 +4836,7 @@ function nativeImportLanguageProfile(language, input = {}) {
|
|
|
4359
4836
|
});
|
|
4360
4837
|
}
|
|
4361
4838
|
|
|
4362
|
-
function mergeNativeImportProfiles(languages, imports, adapters) {
|
|
4839
|
+
function mergeNativeImportProfiles(languages, imports, adapters, targetAdapters = []) {
|
|
4363
4840
|
const profilesByLanguage = new Map();
|
|
4364
4841
|
for (const profile of languages) {
|
|
4365
4842
|
const normalized = normalizeNativeLanguageId(profile.language ?? profile);
|
|
@@ -4385,6 +4862,16 @@ function mergeNativeImportProfiles(languages, imports, adapters) {
|
|
|
4385
4862
|
parserAdapters: uniqueStrings([...(existing.parserAdapters ?? []), adapter.parser ?? adapter.id].filter(Boolean))
|
|
4386
4863
|
});
|
|
4387
4864
|
}
|
|
4865
|
+
for (const adapter of targetAdapters) {
|
|
4866
|
+
const summary = safeNativeTargetProjectionAdapterSummary(adapter);
|
|
4867
|
+
const normalized = normalizeNativeLanguageId(summary?.sourceLanguage);
|
|
4868
|
+
if (!normalized) continue;
|
|
4869
|
+
const existing = profilesByLanguage.get(normalized) ?? nativeImportLanguageProfile(normalized, { supportsLightweightScan: false, parserAdapters: [] });
|
|
4870
|
+
profilesByLanguage.set(normalized, {
|
|
4871
|
+
...existing,
|
|
4872
|
+
projectionTargets: uniqueStrings([...(existing.projectionTargets ?? []), summary.target].filter(Boolean))
|
|
4873
|
+
});
|
|
4874
|
+
}
|
|
4388
4875
|
return [...profilesByLanguage.values()].sort((left, right) => left.language.localeCompare(right.language));
|
|
4389
4876
|
}
|
|
4390
4877
|
|
|
@@ -5217,6 +5704,11 @@ function maxSemanticMergeReadiness(left, right) {
|
|
|
5217
5704
|
return leftRank >= rightRank ? left : right;
|
|
5218
5705
|
}
|
|
5219
5706
|
|
|
5707
|
+
function normalizeSemanticMergeReadiness(value) {
|
|
5708
|
+
const readiness = String(value ?? '').toLowerCase();
|
|
5709
|
+
return Object.prototype.hasOwnProperty.call(semanticMergeReadinessRank, readiness) ? readiness : undefined;
|
|
5710
|
+
}
|
|
5711
|
+
|
|
5220
5712
|
export function createUniversalAstFromDocument(document, input = {}) {
|
|
5221
5713
|
return createUniversalAstEnvelope({
|
|
5222
5714
|
id: input.id ?? `universal_ast_${idFragment(document.id)}`,
|
|
@@ -5886,6 +6378,150 @@ function resolveNativeProjectAdapter(source, adapters, input) {
|
|
|
5886
6378
|
});
|
|
5887
6379
|
}
|
|
5888
6380
|
|
|
6381
|
+
function resolveNativeTargetProjectionAdapter(input, options = {}) {
|
|
6382
|
+
const adapters = options.targetAdapters ?? [];
|
|
6383
|
+
if (options.targetAdapter && typeof options.targetAdapter === 'object') return options.targetAdapter;
|
|
6384
|
+
if (typeof options.targetAdapter === 'string') {
|
|
6385
|
+
const explicit = adapters.find((adapter) => adapter?.id === options.targetAdapter);
|
|
6386
|
+
if (explicit) return explicit;
|
|
6387
|
+
}
|
|
6388
|
+
if (typeof options.targetAdapterResolver === 'function') {
|
|
6389
|
+
const resolved = options.targetAdapterResolver(input, adapters);
|
|
6390
|
+
if (resolved) return resolved;
|
|
6391
|
+
}
|
|
6392
|
+
return matchingNativeTargetProjectionAdapter(input, adapters);
|
|
6393
|
+
}
|
|
6394
|
+
|
|
6395
|
+
function matchingNativeTargetProjectionAdapter(input, adapters = []) {
|
|
6396
|
+
return adapters.find((adapter) => nativeTargetProjectionAdapterMatches(adapter, input));
|
|
6397
|
+
}
|
|
6398
|
+
|
|
6399
|
+
function nativeTargetProjectionAdapterMatches(adapter, input = {}) {
|
|
6400
|
+
const summary = safeNativeTargetProjectionAdapterSummary(adapter);
|
|
6401
|
+
if (!summary) return false;
|
|
6402
|
+
if (input.sourceLanguage && normalizeNativeLanguageId(input.sourceLanguage) !== summary.sourceLanguage) return false;
|
|
6403
|
+
const target = normalizeProjectionMatrixTargets([input.target])[0] ?? String(input.target ?? '').toLowerCase();
|
|
6404
|
+
if (target && target !== summary.target) return false;
|
|
6405
|
+
const parser = input.parser ? String(input.parser).toLowerCase() : undefined;
|
|
6406
|
+
if (parser && summary.supportedParsers.length && !summary.supportedParsers.map((item) => item.toLowerCase()).includes(parser)) return false;
|
|
6407
|
+
const sourcePath = String(input.sourcePath ?? '').toLowerCase();
|
|
6408
|
+
if (sourcePath && summary.supportedExtensions.length) {
|
|
6409
|
+
return summary.supportedExtensions.some((extension) => sourcePath.endsWith(extension));
|
|
6410
|
+
}
|
|
6411
|
+
return true;
|
|
6412
|
+
}
|
|
6413
|
+
|
|
6414
|
+
function safeNativeTargetProjectionAdapterSummary(adapter) {
|
|
6415
|
+
try {
|
|
6416
|
+
return normalizeNativeTargetProjectionAdapter(adapter);
|
|
6417
|
+
} catch {
|
|
6418
|
+
return undefined;
|
|
6419
|
+
}
|
|
6420
|
+
}
|
|
6421
|
+
|
|
6422
|
+
function normalizeNativeTargetProjectionAdapter(adapter) {
|
|
6423
|
+
if (!adapter || typeof adapter !== 'object') {
|
|
6424
|
+
throw new Error('Native target projection adapter must be an object');
|
|
6425
|
+
}
|
|
6426
|
+
if (!adapter.id) throw new Error('Native target projection adapter requires an id');
|
|
6427
|
+
const sourceLanguage = normalizeNativeLanguageId(adapter.sourceLanguage ?? adapter.language);
|
|
6428
|
+
if (!sourceLanguage) throw new Error(`Native target projection adapter ${adapter.id} requires a sourceLanguage`);
|
|
6429
|
+
const target = normalizeProjectionMatrixTargets([adapter.target ?? adapter.targetLanguage])[0];
|
|
6430
|
+
if (!target) throw new Error(`Native target projection adapter ${adapter.id} requires a target`);
|
|
6431
|
+
if (typeof adapter.project !== 'function') throw new Error(`Native target projection adapter ${adapter.id} requires a project function`);
|
|
6432
|
+
const capabilities = normalizeStringList(adapter.capabilities);
|
|
6433
|
+
const summaryInput = {
|
|
6434
|
+
id: String(adapter.id),
|
|
6435
|
+
sourceLanguage,
|
|
6436
|
+
language: sourceLanguage,
|
|
6437
|
+
target,
|
|
6438
|
+
parser: `target:${target}`,
|
|
6439
|
+
version: adapter.version === undefined ? undefined : String(adapter.version)
|
|
6440
|
+
};
|
|
6441
|
+
return Object.freeze({
|
|
6442
|
+
id: summaryInput.id,
|
|
6443
|
+
sourceLanguage,
|
|
6444
|
+
target,
|
|
6445
|
+
version: summaryInput.version,
|
|
6446
|
+
capabilities,
|
|
6447
|
+
supportedParsers: normalizeStringList(adapter.supportedParsers),
|
|
6448
|
+
supportedExtensions: normalizeStringList(adapter.supportedExtensions).map((extension) => extension.startsWith('.') ? extension.toLowerCase() : `.${extension.toLowerCase()}`),
|
|
6449
|
+
coverage: normalizeNativeTargetProjectionAdapterCoverage(adapter.coverage, { capabilities }),
|
|
6450
|
+
diagnostics: normalizeAdapterDiagnostics(adapter.diagnostics, summaryInput, {
|
|
6451
|
+
language: sourceLanguage,
|
|
6452
|
+
parser: summaryInput.parser,
|
|
6453
|
+
parserVersion: summaryInput.version
|
|
6454
|
+
}, 'target-adapter')
|
|
6455
|
+
});
|
|
6456
|
+
}
|
|
6457
|
+
|
|
6458
|
+
function normalizeNativeTargetProjectionAdapterCoverage(value = {}, context = {}) {
|
|
6459
|
+
const capabilities = new Set(normalizeStringList(context.capabilities).map((capability) => capability.toLowerCase()));
|
|
6460
|
+
const lossKinds = uniqueStrings(value.lossKinds ?? []);
|
|
6461
|
+
const handledLossKinds = uniqueStrings([
|
|
6462
|
+
...(value.handledLossKinds ?? []),
|
|
6463
|
+
...(capabilities.has('macros') || capabilities.has('macroexpansion') ? ['macroExpansion', 'macroHygiene'] : []),
|
|
6464
|
+
...(capabilities.has('preprocessor') ? ['preprocessor', 'conditionalCompilation'] : []),
|
|
6465
|
+
...(capabilities.has('dynamicruntime') ? ['dynamicRuntime', 'dynamicDispatch'] : []),
|
|
6466
|
+
...(capabilities.has('typeinference') ? ['typeInference', 'overloadResolution'] : [])
|
|
6467
|
+
]);
|
|
6468
|
+
return Object.freeze({
|
|
6469
|
+
readiness: normalizeSemanticMergeReadiness(value.readiness) ?? 'needs-review',
|
|
6470
|
+
lossKinds,
|
|
6471
|
+
handledLossKinds,
|
|
6472
|
+
sourceMapPrecision: value.sourceMapPrecision,
|
|
6473
|
+
semanticCoverage: value.semanticCoverage ?? {},
|
|
6474
|
+
notes: uniqueStrings(value.notes ?? ['Target projection adapter output is host-owned evidence and should be reviewed unless declared ready.'])
|
|
6475
|
+
});
|
|
6476
|
+
}
|
|
6477
|
+
|
|
6478
|
+
function nativeTargetProjectionAdapterEvidence(adapter, diagnostics, input) {
|
|
6479
|
+
const errors = diagnostics.filter((diagnostic) => diagnostic.severity === 'error').length;
|
|
6480
|
+
const warnings = diagnostics.filter((diagnostic) => diagnostic.severity === 'warning').length;
|
|
6481
|
+
return {
|
|
6482
|
+
id: `evidence_${idFragment(adapter.id)}_native_target_projection_adapter`,
|
|
6483
|
+
kind: 'projection',
|
|
6484
|
+
status: errors ? 'failed' : 'passed',
|
|
6485
|
+
path: input.sourcePath,
|
|
6486
|
+
summary: `Ran ${adapter.id} native target projection adapter from ${input.sourceLanguage} to ${input.target} with ${diagnostics.length} diagnostic(s).`,
|
|
6487
|
+
metadata: {
|
|
6488
|
+
adapterId: adapter.id,
|
|
6489
|
+
adapterVersion: adapter.version,
|
|
6490
|
+
sourceLanguage: input.sourceLanguage,
|
|
6491
|
+
target: input.target,
|
|
6492
|
+
targetPath: input.targetPath,
|
|
6493
|
+
outputHash: input.outputHash,
|
|
6494
|
+
capabilities: adapter.capabilities,
|
|
6495
|
+
coverage: adapter.coverage,
|
|
6496
|
+
diagnostics: diagnostics.map(serializableDiagnostic),
|
|
6497
|
+
errors,
|
|
6498
|
+
warnings
|
|
6499
|
+
}
|
|
6500
|
+
};
|
|
6501
|
+
}
|
|
6502
|
+
|
|
6503
|
+
function nativeTargetProjectionDiagnosticToLoss(diagnostic, index, adapter, input) {
|
|
6504
|
+
return {
|
|
6505
|
+
id: `loss_${idFragment(diagnostic.id ?? `${adapter.id}_${index}_${diagnostic.code ?? diagnostic.severity}`)}`,
|
|
6506
|
+
severity: diagnostic.severity,
|
|
6507
|
+
phase: diagnostic.phase ?? 'emit',
|
|
6508
|
+
sourceFormat: input.sourceLanguage,
|
|
6509
|
+
kind: diagnostic.kind ?? 'targetProjectionLoss',
|
|
6510
|
+
message: diagnostic.message,
|
|
6511
|
+
span: diagnostic.span,
|
|
6512
|
+
metadata: {
|
|
6513
|
+
adapterId: adapter.id,
|
|
6514
|
+
adapterVersion: adapter.version,
|
|
6515
|
+
diagnosticId: diagnostic.id,
|
|
6516
|
+
diagnosticCode: diagnostic.code,
|
|
6517
|
+
sourceLanguage: input.sourceLanguage,
|
|
6518
|
+
target: input.target,
|
|
6519
|
+
path: diagnostic.path,
|
|
6520
|
+
...diagnostic.metadata
|
|
6521
|
+
}
|
|
6522
|
+
};
|
|
6523
|
+
}
|
|
6524
|
+
|
|
5889
6525
|
function normalizeNativeImporterAdapter(adapter) {
|
|
5890
6526
|
if (!adapter || typeof adapter !== 'object') {
|
|
5891
6527
|
throw new Error('Native importer adapter must be an object');
|
package/package.json
CHANGED