@shapeshift-labs/frontier-lang-compiler 0.2.18 → 0.2.20
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 +63 -1
- package/bench/smoke.mjs +39 -1
- package/dist/index.d.ts +142 -0
- package/dist/index.js +632 -4
- 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:
|
|
@@ -166,6 +167,67 @@ console.log(changeSet.mergeCandidate.readiness); // merge-admission classificati
|
|
|
166
167
|
|
|
167
168
|
Use `diffNativeSourceImports` when the worker or runner already produced `importNativeSource` results. Body-only edits that the lightweight scanner cannot anchor to a symbol are still reported as file-level changed regions instead of being silently treated as safe.
|
|
168
169
|
|
|
170
|
+
Compile native source imports through the same reader/IR/writer facade that swarms use for sidecar evidence. Same-language targets preserve exact source when hashes match; cross-language targets emit declaration stubs until a real adapter provides stronger evidence:
|
|
171
|
+
|
|
172
|
+
```js
|
|
173
|
+
import { compileNativeSource } from '@shapeshift-labs/frontier-lang-compiler';
|
|
174
|
+
|
|
175
|
+
const compiledJs = compileNativeSource({
|
|
176
|
+
language: 'javascript',
|
|
177
|
+
sourcePath: 'src/runtime.js',
|
|
178
|
+
sourceText: 'export function step(frame) { return frame + 1; }\n'
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
console.log(compiledJs.outputMode); // "preserved-source"
|
|
182
|
+
console.log(compiledJs.readiness.readiness); // scanner imports can still be "needs-review"
|
|
183
|
+
|
|
184
|
+
const rustCandidate = compileNativeSource(compiledJs.importResult, {
|
|
185
|
+
target: 'rust',
|
|
186
|
+
emitOnBlocked: true
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
console.log(rustCandidate.outputMode); // "target-stubs"
|
|
190
|
+
console.log(rustCandidate.targetCoverage.lossClass); // "missingAdapter" without a JS-to-Rust adapter
|
|
191
|
+
console.log(rustCandidate.ok); // true only because emitOnBlocked requested code anyway
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
`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 `targetCoverage` carry the merge signal.
|
|
195
|
+
|
|
196
|
+
Provide a target projection adapter when the host owns real native-to-target translation semantics:
|
|
197
|
+
|
|
198
|
+
```js
|
|
199
|
+
const jsToRustAdapter = {
|
|
200
|
+
id: 'app-js-to-rust',
|
|
201
|
+
sourceLanguage: 'javascript',
|
|
202
|
+
target: 'rust',
|
|
203
|
+
coverage: {
|
|
204
|
+
readiness: 'needs-review',
|
|
205
|
+
handledLossKinds: ['dynamicRuntime']
|
|
206
|
+
},
|
|
207
|
+
project(input) {
|
|
208
|
+
return {
|
|
209
|
+
output: `// projected from ${input.sourceLanguage}\npub fn add_todo() {}\n`,
|
|
210
|
+
readiness: 'needs-review',
|
|
211
|
+
evidence: [{
|
|
212
|
+
id: 'evidence_app_js_to_rust',
|
|
213
|
+
kind: 'projection',
|
|
214
|
+
status: 'passed',
|
|
215
|
+
summary: 'Host JS-to-Rust adapter emitted declaration-compatible Rust.'
|
|
216
|
+
}]
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const rustWithAdapter = compileNativeSource(compiledJs.importResult, {
|
|
222
|
+
target: 'rust',
|
|
223
|
+
targetAdapters: [jsToRustAdapter]
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
console.log(rustWithAdapter.outputMode); // "target-adapter"
|
|
227
|
+
console.log(rustWithAdapter.targetCoverage.lossClass); // "targetAdapterProjection"
|
|
228
|
+
console.log(rustWithAdapter.targetProjection.adapter.id); // "app-js-to-rust"
|
|
229
|
+
```
|
|
230
|
+
|
|
169
231
|
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:
|
|
170
232
|
|
|
171
233
|
```js
|
package/bench/smoke.mjs
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { performance } from 'node:perf_hooks';
|
|
2
2
|
import {
|
|
3
|
+
compileNativeSource,
|
|
3
4
|
compileFrontierSource,
|
|
4
5
|
createEstreeNativeImporterAdapter,
|
|
5
6
|
createNativeImportCoverageMatrix,
|
|
@@ -92,6 +93,36 @@ const nativeProjections = nativeImportResults.map((imported) => projectNativeImp
|
|
|
92
93
|
const projectionDurationMs = performance.now() - projectionStart;
|
|
93
94
|
const projectionBytes = nativeProjections.reduce((sum, projection) => sum + projection.sourceText.length, 0);
|
|
94
95
|
|
|
96
|
+
const nativeCompileStart = performance.now();
|
|
97
|
+
const nativeCompiles = nativeImportResults.map((imported, index) => compileNativeSource(imported, {
|
|
98
|
+
target: index % 2 === 0 ? 'javascript' : 'rust',
|
|
99
|
+
emitOnBlocked: true
|
|
100
|
+
}));
|
|
101
|
+
const nativeCompileDurationMs = performance.now() - nativeCompileStart;
|
|
102
|
+
const nativeCompileBytes = nativeCompiles.reduce((sum, result) => sum + result.output.length, 0);
|
|
103
|
+
const nativeCompileBlocked = nativeCompiles.filter((result) => result.readiness.readiness === 'blocked').length;
|
|
104
|
+
const nativeTargetAdapterStart = performance.now();
|
|
105
|
+
const nativeTargetAdapterCompiles = nativeImportResults.slice(0, 25).map((imported, index) => {
|
|
106
|
+
const target = index % 2 === 0 ? 'rust' : 'python';
|
|
107
|
+
return compileNativeSource(imported, {
|
|
108
|
+
target,
|
|
109
|
+
targetAdapters: [{
|
|
110
|
+
id: `bench-target-adapter-${index}`,
|
|
111
|
+
sourceLanguage: imported.language,
|
|
112
|
+
target,
|
|
113
|
+
coverage: {
|
|
114
|
+
readiness: 'needs-review',
|
|
115
|
+
handledLossKinds: ['dynamicRuntime', 'dynamicDispatch', 'typeInference', 'overloadResolution']
|
|
116
|
+
},
|
|
117
|
+
project() {
|
|
118
|
+
return { output: `// bench target adapter ${index}\n`, readiness: 'needs-review' };
|
|
119
|
+
}
|
|
120
|
+
}]
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
const nativeTargetAdapterDurationMs = performance.now() - nativeTargetAdapterStart;
|
|
124
|
+
const nativeTargetAdapterBytes = nativeTargetAdapterCompiles.reduce((sum, result) => sum + result.output.length, 0);
|
|
125
|
+
|
|
95
126
|
console.log(JSON.stringify({
|
|
96
127
|
compiles: 250,
|
|
97
128
|
bytes,
|
|
@@ -118,5 +149,12 @@ console.log(JSON.stringify({
|
|
|
118
149
|
sidecarDurationMs: Number(sidecarDurationMs.toFixed(2)),
|
|
119
150
|
nativeProjections: nativeProjections.length,
|
|
120
151
|
projectionBytes,
|
|
121
|
-
projectionDurationMs: Number(projectionDurationMs.toFixed(2))
|
|
152
|
+
projectionDurationMs: Number(projectionDurationMs.toFixed(2)),
|
|
153
|
+
nativeCompiles: nativeCompiles.length,
|
|
154
|
+
nativeCompileBytes,
|
|
155
|
+
nativeCompileBlocked,
|
|
156
|
+
nativeCompileDurationMs: Number(nativeCompileDurationMs.toFixed(2)),
|
|
157
|
+
nativeTargetAdapterCompiles: nativeTargetAdapterCompiles.length,
|
|
158
|
+
nativeTargetAdapterBytes,
|
|
159
|
+
nativeTargetAdapterDurationMs: Number(nativeTargetAdapterDurationMs.toFixed(2))
|
|
122
160
|
}));
|
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,6 +1315,52 @@ export interface NativeSourceProjectionResult {
|
|
|
1221
1315
|
readonly metadata: Record<string, unknown>;
|
|
1222
1316
|
}
|
|
1223
1317
|
|
|
1318
|
+
export type NativeSourceCompileOutputMode = NativeSourceProjectionMode | 'target-stubs' | 'target-adapter';
|
|
1319
|
+
|
|
1320
|
+
export interface CompileNativeSourceOptions extends ProjectNativeImportToSourceOptions {
|
|
1321
|
+
readonly target?: FrontierCompileTarget | string;
|
|
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>;
|
|
1331
|
+
readonly languages?: readonly NativeImportLanguageProfile[];
|
|
1332
|
+
readonly generatedAt?: number;
|
|
1333
|
+
readonly emitOnBlocked?: boolean;
|
|
1334
|
+
readonly projectionId?: string;
|
|
1335
|
+
readonly projectionEvidenceId?: string;
|
|
1336
|
+
readonly compileEvidenceId?: string;
|
|
1337
|
+
readonly evidence?: readonly EvidenceRecord[];
|
|
1338
|
+
readonly losses?: readonly NativeAstLossRecord[];
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
export interface NativeSourceCompileResult {
|
|
1342
|
+
readonly kind: 'frontier.lang.nativeSourceCompileResult';
|
|
1343
|
+
readonly version: 1;
|
|
1344
|
+
readonly id: string;
|
|
1345
|
+
readonly ok: boolean;
|
|
1346
|
+
readonly target: FrontierCompileTarget | string;
|
|
1347
|
+
readonly language: FrontierSourceLanguage | string;
|
|
1348
|
+
readonly sourcePath?: string;
|
|
1349
|
+
readonly output: string;
|
|
1350
|
+
readonly outputHash: string;
|
|
1351
|
+
readonly outputMode: NativeSourceCompileOutputMode;
|
|
1352
|
+
readonly importResult: NativeSourceImportResult;
|
|
1353
|
+
readonly projection: NativeSourceProjectionResult;
|
|
1354
|
+
readonly targetProjection?: NativeTargetProjectionResult;
|
|
1355
|
+
readonly targetCoverage: ProjectionTargetCoverageEntry;
|
|
1356
|
+
readonly projectionMatrix: ProjectionTargetLossMatrix;
|
|
1357
|
+
readonly losses: readonly NativeAstLossRecord[];
|
|
1358
|
+
readonly lossSummary: NativeImportLossSummary;
|
|
1359
|
+
readonly readiness: NativeImportReadinessClassification;
|
|
1360
|
+
readonly evidence: readonly EvidenceRecord[];
|
|
1361
|
+
readonly metadata: Record<string, unknown>;
|
|
1362
|
+
}
|
|
1363
|
+
|
|
1224
1364
|
export type NativeImportRoundtripReadinessStatus =
|
|
1225
1365
|
| 'exact'
|
|
1226
1366
|
| 'preserved-source'
|
|
@@ -1286,6 +1426,7 @@ export declare const NativeImportLanguageProfiles: readonly NativeImportLanguage
|
|
|
1286
1426
|
export declare function normalizeCompileTarget(target?: string): FrontierCompileTarget;
|
|
1287
1427
|
export declare function compileFrontierSource(source: string, options?: FrontierCompileOptions): FrontierCompileResult;
|
|
1288
1428
|
export declare function compileFrontierDocument(document: FrontierLangDocument, options?: FrontierCompileOptions): FrontierCompileResult;
|
|
1429
|
+
export declare function compileNativeSource(input: ImportNativeSourceOptions | NativeSourceImportResult, options?: CompileNativeSourceOptions): NativeSourceCompileResult;
|
|
1289
1430
|
export declare function projectFrontierAst(document: FrontierLangDocument, target?: FrontierCompileOptions['target'], options?: FrontierCompileEmitOptions): FrontierTargetAst;
|
|
1290
1431
|
export declare function renderTargetAst(ast: FrontierTargetAst, target?: FrontierCompileOptions['target']): string;
|
|
1291
1432
|
export declare function renderTargetAstWithSourceMap(ast: FrontierTargetAst, target?: FrontierCompileOptions['target'], options?: FrontierCompileEmitOptions): FrontierTargetSourceMapResult;
|
|
@@ -1304,6 +1445,7 @@ export declare function createBabelNativeImporterAdapter(options?: JavaScriptNat
|
|
|
1304
1445
|
export declare function createTypeScriptCompilerNativeImporterAdapter(options?: TypeScriptCompilerNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1305
1446
|
export declare function createTreeSitterNativeImporterAdapter(options?: TreeSitterNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1306
1447
|
export declare function runNativeImporterAdapter(adapter: NativeImporterAdapter, input: RunNativeImporterAdapterOptions): Promise<NativeImporterAdapterImportResult>;
|
|
1448
|
+
export declare function runNativeTargetProjectionAdapter(adapter: NativeTargetProjectionAdapter, input: NativeTargetProjectionAdapterInput): NativeTargetProjectionResult;
|
|
1307
1449
|
export declare function projectNativeImportToSource(importResult: NativeSourceImportResult | NativeProjectImportResult, options?: ProjectNativeImportToSourceOptions): NativeSourceProjectionResult;
|
|
1308
1450
|
export declare function importNativeSource(input: ImportNativeSourceOptions): NativeSourceImportResult;
|
|
1309
1451
|
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
|
|
|
@@ -253,6 +254,152 @@ export function compileFrontierDocument(document, options = {}) {
|
|
|
253
254
|
};
|
|
254
255
|
}
|
|
255
256
|
|
|
257
|
+
export function compileNativeSource(input, options = {}) {
|
|
258
|
+
const importResult = isNativeSourceImportResult(input) ? input : importNativeSource(input);
|
|
259
|
+
const sourceLanguage = nativeCompileSourceLanguage(importResult, input);
|
|
260
|
+
const target = nativeCompileTarget(input, importResult, options);
|
|
261
|
+
const sourceTarget = nativeLanguageCompileTarget(sourceLanguage);
|
|
262
|
+
const sameSourceTarget = sourceTarget === target;
|
|
263
|
+
const idPart = idFragment(options.id ?? importResult.id ?? importResult.sourcePath ?? sourceLanguage ?? target);
|
|
264
|
+
const id = options.id ?? `native_source_compile_${idPart}_${idFragment(target)}`;
|
|
265
|
+
const projection = projectNativeImportToSource(importResult, {
|
|
266
|
+
...options,
|
|
267
|
+
id: options.projectionId ?? `${id}_projection`,
|
|
268
|
+
language: sameSourceTarget ? sourceLanguage : target,
|
|
269
|
+
preferPreservedSource: sameSourceTarget ? options.preferPreservedSource : false,
|
|
270
|
+
evidenceId: options.projectionEvidenceId ?? options.evidenceId,
|
|
271
|
+
metadata: {
|
|
272
|
+
sourceLanguage,
|
|
273
|
+
target,
|
|
274
|
+
nativeCompileResultId: id,
|
|
275
|
+
...options.metadata
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
const projectionMatrix = createProjectionTargetLossMatrix({
|
|
279
|
+
imports: [importResult],
|
|
280
|
+
adapters: options.adapters,
|
|
281
|
+
targetAdapters: options.targetAdapters,
|
|
282
|
+
languages: options.languages,
|
|
283
|
+
targets: [target],
|
|
284
|
+
generatedAt: options.generatedAt
|
|
285
|
+
});
|
|
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;
|
|
313
|
+
const targetLosses = nativeSourceCompileTargetLosses({
|
|
314
|
+
importResult,
|
|
315
|
+
projection,
|
|
316
|
+
targetCoverage,
|
|
317
|
+
sourceLanguage,
|
|
318
|
+
target,
|
|
319
|
+
idPart
|
|
320
|
+
});
|
|
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';
|
|
324
|
+
const compileEvidence = nativeSourceCompileEvidence({
|
|
325
|
+
id: options.compileEvidenceId ?? `evidence_${idPart}_${idFragment(target)}_native_source_compile`,
|
|
326
|
+
importResult,
|
|
327
|
+
projection,
|
|
328
|
+
targetProjection,
|
|
329
|
+
targetCoverage,
|
|
330
|
+
targetLosses,
|
|
331
|
+
sourceLanguage,
|
|
332
|
+
target,
|
|
333
|
+
outputHash,
|
|
334
|
+
outputMode
|
|
335
|
+
});
|
|
336
|
+
const evidence = uniqueByEvidenceId([
|
|
337
|
+
...(importResult.evidence ?? []),
|
|
338
|
+
...(projection.evidence ?? []),
|
|
339
|
+
...(targetProjection?.evidence ?? []),
|
|
340
|
+
compileEvidence,
|
|
341
|
+
...(options.evidence ?? [])
|
|
342
|
+
]);
|
|
343
|
+
const losses = uniqueByLossId([
|
|
344
|
+
...(importResult.losses ?? []),
|
|
345
|
+
...(projection.losses ?? []),
|
|
346
|
+
...(targetProjection?.losses ?? []),
|
|
347
|
+
...targetLosses,
|
|
348
|
+
...(options.losses ?? [])
|
|
349
|
+
]);
|
|
350
|
+
const lossSummary = summarizeNativeImportLosses(losses, {
|
|
351
|
+
evidence,
|
|
352
|
+
parser: importResult.nativeAst?.parser ?? importResult.nativeSource?.parser ?? options.parser,
|
|
353
|
+
scanKind: 'native-source-compile',
|
|
354
|
+
semanticStatus: importResult.metadata?.semanticStatus ?? options.semanticStatus
|
|
355
|
+
});
|
|
356
|
+
const readiness = classifyNativeImportReadiness(losses, {
|
|
357
|
+
evidence,
|
|
358
|
+
parser: importResult.nativeAst?.parser ?? importResult.nativeSource?.parser ?? options.parser,
|
|
359
|
+
scanKind: 'native-source-compile',
|
|
360
|
+
semanticStatus: importResult.metadata?.semanticStatus ?? options.semanticStatus
|
|
361
|
+
});
|
|
362
|
+
return {
|
|
363
|
+
kind: 'frontier.lang.nativeSourceCompileResult',
|
|
364
|
+
version: 1,
|
|
365
|
+
id,
|
|
366
|
+
ok: readiness.readiness !== 'blocked' || options.emitOnBlocked === true,
|
|
367
|
+
target,
|
|
368
|
+
language: sourceLanguage,
|
|
369
|
+
sourcePath: importResult.sourcePath ?? importResult.nativeSource?.sourcePath,
|
|
370
|
+
output,
|
|
371
|
+
outputHash,
|
|
372
|
+
outputMode,
|
|
373
|
+
importResult,
|
|
374
|
+
projection,
|
|
375
|
+
targetProjection,
|
|
376
|
+
targetCoverage,
|
|
377
|
+
projectionMatrix,
|
|
378
|
+
losses,
|
|
379
|
+
lossSummary,
|
|
380
|
+
readiness,
|
|
381
|
+
evidence,
|
|
382
|
+
metadata: {
|
|
383
|
+
nativeImportId: importResult.id,
|
|
384
|
+
nativeSourceId: importResult.nativeSource?.id,
|
|
385
|
+
nativeAstId: importResult.nativeAst?.id ?? importResult.nativeSource?.ast?.id,
|
|
386
|
+
semanticIndexId: importResult.semanticIndex?.id ?? importResult.universalAst?.semanticIndex?.id,
|
|
387
|
+
universalAstId: importResult.universalAst?.id,
|
|
388
|
+
projectionId: projection.id,
|
|
389
|
+
targetProjectionId: targetProjection?.id,
|
|
390
|
+
targetProjectionAdapterId: targetProjection?.adapter?.id,
|
|
391
|
+
projectionMode: projection.mode,
|
|
392
|
+
outputMode,
|
|
393
|
+
sourceTarget,
|
|
394
|
+
sameSourceTarget,
|
|
395
|
+
targetLossClass: targetCoverage.lossClass,
|
|
396
|
+
targetReadiness: targetCoverage.readiness,
|
|
397
|
+
targetSupported: targetCoverage.supported,
|
|
398
|
+
...options.metadata
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
|
|
256
403
|
export function projectFrontierAst(document, target = 'typescript', options = {}) {
|
|
257
404
|
const normalized = normalizeCompileTarget(target);
|
|
258
405
|
const projector = projectors[normalized];
|
|
@@ -547,11 +694,13 @@ export function createNativeImportCoverageMatrix(input = {}) {
|
|
|
547
694
|
export function createProjectionTargetLossMatrix(input = {}) {
|
|
548
695
|
const imports = input.imports ?? [];
|
|
549
696
|
const adapters = input.adapters ?? [];
|
|
550
|
-
const
|
|
697
|
+
const targetAdapters = input.targetAdapters ?? [];
|
|
698
|
+
const profiles = mergeNativeImportProfiles(input.languages ?? NativeImportLanguageProfiles, imports, adapters, targetAdapters);
|
|
551
699
|
const targets = normalizeProjectionMatrixTargets(input.targets ?? FrontierCompileTargets);
|
|
552
700
|
const languages = profiles.map((profile) => projectionTargetCoverageForProfile(profile, {
|
|
553
701
|
imports,
|
|
554
702
|
adapters,
|
|
703
|
+
targetAdapters,
|
|
555
704
|
targets
|
|
556
705
|
}));
|
|
557
706
|
const summary = projectionTargetLossMatrixSummary(languages);
|
|
@@ -564,7 +713,7 @@ export function createProjectionTargetLossMatrix(input = {}) {
|
|
|
564
713
|
metadata: {
|
|
565
714
|
compileTargets: targets,
|
|
566
715
|
lossClasses: [...ProjectionTargetLossClasses],
|
|
567
|
-
note: 'Projection target coverage separates exact source preservation, declaration stubs, known unsupported target features, and missing native-to-target adapters.'
|
|
716
|
+
note: 'Projection target coverage separates exact source preservation, declaration stubs, host-owned target adapters, known unsupported target features, and missing native-to-target adapters.'
|
|
568
717
|
}
|
|
569
718
|
};
|
|
570
719
|
}
|
|
@@ -1049,6 +1198,120 @@ export async function runNativeImporterAdapter(adapter, input = {}) {
|
|
|
1049
1198
|
};
|
|
1050
1199
|
}
|
|
1051
1200
|
|
|
1201
|
+
export function runNativeTargetProjectionAdapter(adapter, input = {}) {
|
|
1202
|
+
const summary = normalizeNativeTargetProjectionAdapter(adapter);
|
|
1203
|
+
const sourceLanguage = normalizeNativeLanguageId(input.sourceLanguage ?? summary.sourceLanguage);
|
|
1204
|
+
const target = normalizeProjectionMatrixTargets([input.target ?? summary.target])[0] ?? summary.target;
|
|
1205
|
+
const diagnosticContext = {
|
|
1206
|
+
sourcePath: input.importResult?.sourcePath ?? input.importResult?.nativeSource?.sourcePath,
|
|
1207
|
+
sourceHash: input.importResult?.sourceHash ?? input.importResult?.nativeSource?.sourceHash,
|
|
1208
|
+
language: sourceLanguage,
|
|
1209
|
+
parser: `target:${target}`,
|
|
1210
|
+
parserVersion: summary.version
|
|
1211
|
+
};
|
|
1212
|
+
const projectInput = {
|
|
1213
|
+
importResult: input.importResult,
|
|
1214
|
+
sourceProjection: input.sourceProjection,
|
|
1215
|
+
sourceLanguage,
|
|
1216
|
+
target,
|
|
1217
|
+
targetPath: input.targetPath,
|
|
1218
|
+
targetCoverage: input.targetCoverage,
|
|
1219
|
+
options: input.options ?? {},
|
|
1220
|
+
metadata: input.metadata ?? {}
|
|
1221
|
+
};
|
|
1222
|
+
let projected;
|
|
1223
|
+
let thrownDiagnostic;
|
|
1224
|
+
try {
|
|
1225
|
+
projected = adapter.project(projectInput) ?? {};
|
|
1226
|
+
} catch (error) {
|
|
1227
|
+
thrownDiagnostic = {
|
|
1228
|
+
severity: 'error',
|
|
1229
|
+
code: 'targetAdapter.project.threw',
|
|
1230
|
+
phase: 'emit',
|
|
1231
|
+
kind: 'targetProjectionLoss',
|
|
1232
|
+
message: error instanceof Error ? error.message : String(error),
|
|
1233
|
+
metadata: {
|
|
1234
|
+
errorName: error instanceof Error ? error.name : undefined
|
|
1235
|
+
}
|
|
1236
|
+
};
|
|
1237
|
+
projected = {};
|
|
1238
|
+
}
|
|
1239
|
+
const diagnostics = [
|
|
1240
|
+
...normalizeAdapterDiagnostics(summary.diagnostics, summary, diagnosticContext, 'target-adapter'),
|
|
1241
|
+
...(thrownDiagnostic ? normalizeAdapterDiagnostics([thrownDiagnostic], summary, diagnosticContext, 'throw') : []),
|
|
1242
|
+
...normalizeAdapterDiagnostics(projected.diagnostics, summary, diagnosticContext, 'project')
|
|
1243
|
+
];
|
|
1244
|
+
const output = typeof projected.output === 'string' ? projected.output : input.sourceProjection?.sourceText ?? '';
|
|
1245
|
+
const outputHash = projected.outputHash ?? hashSemanticValue(output);
|
|
1246
|
+
const adapterEvidence = nativeTargetProjectionAdapterEvidence(summary, diagnostics, {
|
|
1247
|
+
...diagnosticContext,
|
|
1248
|
+
sourceLanguage,
|
|
1249
|
+
target,
|
|
1250
|
+
outputHash,
|
|
1251
|
+
targetPath: input.targetPath
|
|
1252
|
+
});
|
|
1253
|
+
const evidence = uniqueByEvidenceId([
|
|
1254
|
+
...(projected.evidence ?? []),
|
|
1255
|
+
adapterEvidence
|
|
1256
|
+
]);
|
|
1257
|
+
const losses = uniqueByLossId([
|
|
1258
|
+
...(projected.losses ?? []),
|
|
1259
|
+
...diagnostics.map((diagnostic, index) => nativeTargetProjectionDiagnosticToLoss(diagnostic, index, summary, {
|
|
1260
|
+
...diagnosticContext,
|
|
1261
|
+
sourceLanguage,
|
|
1262
|
+
target
|
|
1263
|
+
}))
|
|
1264
|
+
]);
|
|
1265
|
+
const lossSummary = summarizeNativeImportLosses(losses, {
|
|
1266
|
+
evidence,
|
|
1267
|
+
parser: diagnosticContext.parser,
|
|
1268
|
+
scanKind: 'native-target-projection',
|
|
1269
|
+
semanticStatus: input.importResult?.metadata?.semanticStatus
|
|
1270
|
+
});
|
|
1271
|
+
const classifiedReadiness = classifyNativeImportReadiness(losses, {
|
|
1272
|
+
evidence,
|
|
1273
|
+
parser: diagnosticContext.parser,
|
|
1274
|
+
scanKind: 'native-target-projection',
|
|
1275
|
+
semanticStatus: input.importResult?.metadata?.semanticStatus
|
|
1276
|
+
});
|
|
1277
|
+
const declaredReadiness = normalizeSemanticMergeReadiness(projected.readiness ?? summary.coverage.readiness);
|
|
1278
|
+
const readiness = declaredReadiness
|
|
1279
|
+
? {
|
|
1280
|
+
...classifiedReadiness,
|
|
1281
|
+
readiness: maxSemanticMergeReadiness(classifiedReadiness.readiness, declaredReadiness),
|
|
1282
|
+
reasons: uniqueStrings([
|
|
1283
|
+
...classifiedReadiness.reasons,
|
|
1284
|
+
...(declaredReadiness === classifiedReadiness.readiness ? [] : [`Target adapter declared readiness ${declaredReadiness}.`])
|
|
1285
|
+
])
|
|
1286
|
+
}
|
|
1287
|
+
: classifiedReadiness;
|
|
1288
|
+
return {
|
|
1289
|
+
kind: 'frontier.lang.nativeTargetProjection',
|
|
1290
|
+
version: 1,
|
|
1291
|
+
id: projected.id ?? `native_target_projection_${idFragment(summary.id)}_${idFragment(sourceLanguage)}_${idFragment(target)}`,
|
|
1292
|
+
sourceLanguage,
|
|
1293
|
+
target,
|
|
1294
|
+
targetPath: input.targetPath,
|
|
1295
|
+
adapter: summary,
|
|
1296
|
+
output,
|
|
1297
|
+
outputHash,
|
|
1298
|
+
outputMode: 'target-adapter',
|
|
1299
|
+
sourceMaps: projected.sourceMaps ?? [],
|
|
1300
|
+
losses,
|
|
1301
|
+
lossSummary,
|
|
1302
|
+
readiness,
|
|
1303
|
+
evidence,
|
|
1304
|
+
diagnostics: diagnostics.map(serializableDiagnostic),
|
|
1305
|
+
metadata: {
|
|
1306
|
+
importId: input.importResult?.id,
|
|
1307
|
+
projectionId: input.sourceProjection?.id,
|
|
1308
|
+
targetCoverageLossClass: input.targetCoverage?.lossClass,
|
|
1309
|
+
targetCoverageReadiness: input.targetCoverage?.readiness,
|
|
1310
|
+
...projected.metadata
|
|
1311
|
+
}
|
|
1312
|
+
};
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1052
1315
|
export function projectNativeImportToSource(importResult, options = {}) {
|
|
1053
1316
|
if (!importResult || typeof importResult !== 'object') {
|
|
1054
1317
|
throw new Error('projectNativeImportToSource requires a native import result');
|
|
@@ -3840,6 +4103,7 @@ function projectionTargetCoverageForProfile(profile, context) {
|
|
|
3840
4103
|
const aliases = new Set([profile.language, ...(profile.aliases ?? [])].map(normalizeNativeLanguageId).filter(Boolean));
|
|
3841
4104
|
const matchingImports = (context.imports ?? []).filter((imported) => aliases.has(normalizeNativeLanguageId(imported?.language ?? imported?.nativeAst?.language)));
|
|
3842
4105
|
const matchingAdapters = (context.adapters ?? []).filter((adapter) => aliases.has(normalizeNativeLanguageId(adapter?.language)));
|
|
4106
|
+
const matchingTargetAdapters = (context.targetAdapters ?? []).filter((adapter) => aliases.has(normalizeNativeLanguageId(adapter?.sourceLanguage ?? adapter?.language)));
|
|
3843
4107
|
const importedLossKinds = uniqueStrings(matchingImports.flatMap((imported) => (imported?.losses ?? []).map((loss) => loss.kind).filter(Boolean)));
|
|
3844
4108
|
const knownLossKinds = uniqueStrings([...(profile.knownLossKinds ?? []), ...importedLossKinds]);
|
|
3845
4109
|
const parserAdapters = uniqueStrings([
|
|
@@ -3850,6 +4114,7 @@ function projectionTargetCoverageForProfile(profile, context) {
|
|
|
3850
4114
|
const targets = (context.targets ?? FrontierCompileTargets).map((target) => projectionTargetCoverageEntry(profile, target, {
|
|
3851
4115
|
matchingImports,
|
|
3852
4116
|
matchingAdapters,
|
|
4117
|
+
matchingTargetAdapters,
|
|
3853
4118
|
knownLossKinds
|
|
3854
4119
|
}));
|
|
3855
4120
|
return {
|
|
@@ -3927,8 +4192,14 @@ function projectionTargetCoverageEntry(profile, target, context) {
|
|
|
3927
4192
|
const normalizedTarget = normalizeProjectionMatrixTargets([target])[0] ?? String(target);
|
|
3928
4193
|
const declaredTargets = new Set(normalizeProjectionMatrixTargets(profile.projectionTargets ?? []));
|
|
3929
4194
|
const adapterTargets = new Set((context.matchingAdapters ?? []).flatMap(adapterProjectionTargets));
|
|
4195
|
+
const targetAdapter = matchingNativeTargetProjectionAdapter({
|
|
4196
|
+
sourceLanguage: profile.language,
|
|
4197
|
+
target: normalizedTarget,
|
|
4198
|
+
sourcePath: context.matchingImports?.[0]?.sourcePath ?? context.matchingImports?.[0]?.nativeSource?.sourcePath
|
|
4199
|
+
}, context.matchingTargetAdapters ?? []);
|
|
4200
|
+
const targetAdapterSummary = targetAdapter ? normalizeNativeTargetProjectionAdapter(targetAdapter) : undefined;
|
|
3930
4201
|
const sameSourceTarget = nativeLanguageCompileTarget(profile.language, profile.aliases) === normalizedTarget;
|
|
3931
|
-
const hasProjectionAdapter = declaredTargets.has(normalizedTarget) || adapterTargets.has(normalizedTarget);
|
|
4202
|
+
const hasProjectionAdapter = Boolean(targetAdapterSummary) || declaredTargets.has(normalizedTarget) || adapterTargets.has(normalizedTarget);
|
|
3932
4203
|
if (!hasProjectionAdapter) {
|
|
3933
4204
|
return {
|
|
3934
4205
|
target: normalizedTarget,
|
|
@@ -3944,6 +4215,48 @@ function projectionTargetCoverageEntry(profile, target, context) {
|
|
|
3944
4215
|
}
|
|
3945
4216
|
|
|
3946
4217
|
const featureLossKinds = projectionUnsupportedFeatureLossKinds(context.knownLossKinds);
|
|
4218
|
+
if (targetAdapterSummary) {
|
|
4219
|
+
const handledLossKinds = new Set(targetAdapterSummary.coverage.handledLossKinds ?? []);
|
|
4220
|
+
const unhandledFeatureLossKinds = featureLossKinds.filter((kind) => !handledLossKinds.has(kind));
|
|
4221
|
+
if (unhandledFeatureLossKinds.length) {
|
|
4222
|
+
return {
|
|
4223
|
+
target: normalizedTarget,
|
|
4224
|
+
lossClass: 'unsupportedTargetFeatures',
|
|
4225
|
+
supported: true,
|
|
4226
|
+
readiness: 'needs-review',
|
|
4227
|
+
lossKinds: unhandledFeatureLossKinds,
|
|
4228
|
+
categories: uniqueStrings(unhandledFeatureLossKinds.map(nativeImportCategoryForLossKind)),
|
|
4229
|
+
reason: `${profile.language} has target adapter ${targetAdapterSummary.id}, but source feature losses remain unhandled for ${normalizedTarget}: ${unhandledFeatureLossKinds.join(', ')}.`,
|
|
4230
|
+
adapter: targetAdapterSummary.id,
|
|
4231
|
+
adapterKind: 'targetProjection',
|
|
4232
|
+
adapterVersion: targetAdapterSummary.version,
|
|
4233
|
+
adapterCoverage: targetAdapterSummary.coverage,
|
|
4234
|
+
notes: uniqueStrings([
|
|
4235
|
+
...(targetAdapterSummary.coverage.notes ?? []),
|
|
4236
|
+
'Adapter output is available, but merge readiness still requires review for unhandled source-language feature losses.'
|
|
4237
|
+
])
|
|
4238
|
+
};
|
|
4239
|
+
}
|
|
4240
|
+
const adapterLossKinds = uniqueStrings(targetAdapterSummary.coverage.lossKinds ?? []);
|
|
4241
|
+
return {
|
|
4242
|
+
target: normalizedTarget,
|
|
4243
|
+
lossClass: 'targetAdapterProjection',
|
|
4244
|
+
supported: true,
|
|
4245
|
+
readiness: targetAdapterSummary.coverage.readiness ?? 'needs-review',
|
|
4246
|
+
lossKinds: adapterLossKinds,
|
|
4247
|
+
categories: uniqueStrings(adapterLossKinds.map(nativeImportCategoryForLossKind)),
|
|
4248
|
+
reason: `${profile.language} can project to ${normalizedTarget} through host target adapter ${targetAdapterSummary.id}.`,
|
|
4249
|
+
adapter: targetAdapterSummary.id,
|
|
4250
|
+
adapterKind: 'targetProjection',
|
|
4251
|
+
adapterVersion: targetAdapterSummary.version,
|
|
4252
|
+
adapterCoverage: targetAdapterSummary.coverage,
|
|
4253
|
+
notes: uniqueStrings([
|
|
4254
|
+
...(targetAdapterSummary.coverage.notes ?? []),
|
|
4255
|
+
'The host adapter owns native-to-target translation semantics and must provide evidence for merge admission.'
|
|
4256
|
+
])
|
|
4257
|
+
};
|
|
4258
|
+
}
|
|
4259
|
+
|
|
3947
4260
|
if (featureLossKinds.length) {
|
|
3948
4261
|
return {
|
|
3949
4262
|
target: normalizedTarget,
|
|
@@ -4005,6 +4318,7 @@ function projectionTargetLossMatrixSummary(languages) {
|
|
|
4005
4318
|
sourceProjectionByLossClass,
|
|
4006
4319
|
exactSourceProjection: (sourceProjectionByLossClass.exactSourceProjection ?? 0) + (byLossClass.exactSourceProjection ?? 0),
|
|
4007
4320
|
nativeSourceStubs: (sourceProjectionByLossClass.nativeSourceStubs ?? 0) + (byLossClass.nativeSourceStubs ?? 0),
|
|
4321
|
+
targetAdapterProjection: byLossClass.targetAdapterProjection ?? 0,
|
|
4008
4322
|
unsupportedTargetFeatures: byLossClass.unsupportedTargetFeatures ?? 0,
|
|
4009
4323
|
missingAdapters: byLossClass.missingAdapter ?? 0
|
|
4010
4324
|
};
|
|
@@ -4075,6 +4389,161 @@ function nativeLanguageCompileTarget(language, aliases = []) {
|
|
|
4075
4389
|
return undefined;
|
|
4076
4390
|
}
|
|
4077
4391
|
|
|
4392
|
+
function isNativeSourceImportResult(input) {
|
|
4393
|
+
return Boolean(input && typeof input === 'object' && input.kind === 'frontier.lang.importResult' && input.nativeSource && input.universalAst);
|
|
4394
|
+
}
|
|
4395
|
+
|
|
4396
|
+
function nativeCompileSourceLanguage(importResult, input) {
|
|
4397
|
+
return normalizeNativeLanguageId(
|
|
4398
|
+
importResult.language
|
|
4399
|
+
?? importResult.nativeSource?.language
|
|
4400
|
+
?? importResult.nativeAst?.language
|
|
4401
|
+
?? importResult.nativeSource?.ast?.language
|
|
4402
|
+
?? input?.language
|
|
4403
|
+
) || String(importResult.language ?? input?.language ?? 'source');
|
|
4404
|
+
}
|
|
4405
|
+
|
|
4406
|
+
function nativeCompileTarget(input, importResult, options) {
|
|
4407
|
+
const targetInput = options.target
|
|
4408
|
+
?? compileTargetLanguage(input?.target)
|
|
4409
|
+
?? compileTargetLanguage(importResult.nativeSource?.target)
|
|
4410
|
+
?? nativeLanguageCompileTarget(nativeCompileSourceLanguage(importResult, input))
|
|
4411
|
+
?? 'typescript';
|
|
4412
|
+
return normalizeProjectionMatrixTargets([targetInput])[0] ?? String(targetInput ?? 'typescript').toLowerCase();
|
|
4413
|
+
}
|
|
4414
|
+
|
|
4415
|
+
function compileTargetLanguage(target) {
|
|
4416
|
+
if (!target) return undefined;
|
|
4417
|
+
if (typeof target === 'string') return target;
|
|
4418
|
+
return target.language ?? target.emitLanguage ?? target.target ?? target.name;
|
|
4419
|
+
}
|
|
4420
|
+
|
|
4421
|
+
function nativeSourceCompileTargetCoverage(matrix, language, target) {
|
|
4422
|
+
const sourceLanguage = normalizeNativeLanguageId(language);
|
|
4423
|
+
const entry = (matrix.languages ?? []).find((candidate) => {
|
|
4424
|
+
const ids = [candidate.language, ...(candidate.aliases ?? [])].map(normalizeNativeLanguageId);
|
|
4425
|
+
return ids.includes(sourceLanguage);
|
|
4426
|
+
});
|
|
4427
|
+
const coverage = entry?.targets?.find((candidate) => candidate.target === target);
|
|
4428
|
+
if (coverage) return coverage;
|
|
4429
|
+
return {
|
|
4430
|
+
target,
|
|
4431
|
+
lossClass: 'missingAdapter',
|
|
4432
|
+
supported: false,
|
|
4433
|
+
readiness: 'blocked',
|
|
4434
|
+
lossKinds: ['targetProjectionLoss'],
|
|
4435
|
+
categories: ['targetProjectionLoss'],
|
|
4436
|
+
reason: `No native-to-${target} projection coverage is available for ${language}.`,
|
|
4437
|
+
adapter: undefined,
|
|
4438
|
+
notes: ['Inject a source-language parser and target projection adapter before treating this cross-language output as merge-ready.']
|
|
4439
|
+
};
|
|
4440
|
+
}
|
|
4441
|
+
|
|
4442
|
+
function nativeSourceCompileTargetLosses(input) {
|
|
4443
|
+
const { importResult, projection, targetCoverage, sourceLanguage, target, idPart } = input;
|
|
4444
|
+
if (!targetCoverage || targetCoverage.lossClass === 'exactSourceProjection') return [];
|
|
4445
|
+
if (targetCoverage.lossClass === 'missingAdapter') {
|
|
4446
|
+
return [nativeSourceCompileTargetLoss({
|
|
4447
|
+
id: `loss_${idPart}_${idFragment(target)}_missing_projection_adapter`,
|
|
4448
|
+
severity: 'error',
|
|
4449
|
+
message: targetCoverage.reason,
|
|
4450
|
+
importResult,
|
|
4451
|
+
projection,
|
|
4452
|
+
targetCoverage,
|
|
4453
|
+
sourceLanguage,
|
|
4454
|
+
target
|
|
4455
|
+
})];
|
|
4456
|
+
}
|
|
4457
|
+
if (targetCoverage.lossClass === 'unsupportedTargetFeatures') {
|
|
4458
|
+
return [nativeSourceCompileTargetLoss({
|
|
4459
|
+
id: `loss_${idPart}_${idFragment(target)}_unsupported_target_features`,
|
|
4460
|
+
severity: 'warning',
|
|
4461
|
+
message: targetCoverage.reason,
|
|
4462
|
+
importResult,
|
|
4463
|
+
projection,
|
|
4464
|
+
targetCoverage,
|
|
4465
|
+
sourceLanguage,
|
|
4466
|
+
target
|
|
4467
|
+
})];
|
|
4468
|
+
}
|
|
4469
|
+
if (targetCoverage.lossClass === 'nativeSourceStubs') {
|
|
4470
|
+
return [nativeSourceCompileTargetLoss({
|
|
4471
|
+
id: `loss_${idPart}_${idFragment(target)}_target_stubs`,
|
|
4472
|
+
severity: 'warning',
|
|
4473
|
+
message: targetCoverage.reason,
|
|
4474
|
+
importResult,
|
|
4475
|
+
projection,
|
|
4476
|
+
targetCoverage,
|
|
4477
|
+
sourceLanguage,
|
|
4478
|
+
target
|
|
4479
|
+
})];
|
|
4480
|
+
}
|
|
4481
|
+
return [];
|
|
4482
|
+
}
|
|
4483
|
+
|
|
4484
|
+
function nativeSourceCompileTargetLoss(input) {
|
|
4485
|
+
const rootSpan = input.importResult.nativeAst?.nodes?.[input.importResult.nativeAst?.rootId]?.span
|
|
4486
|
+
?? input.importResult.nativeSource?.ast?.nodes?.[input.importResult.nativeSource?.ast?.rootId]?.span;
|
|
4487
|
+
return {
|
|
4488
|
+
id: input.id,
|
|
4489
|
+
severity: input.severity,
|
|
4490
|
+
phase: 'emit',
|
|
4491
|
+
sourceFormat: input.sourceLanguage,
|
|
4492
|
+
kind: 'targetProjectionLoss',
|
|
4493
|
+
message: input.message,
|
|
4494
|
+
span: rootSpan ?? {
|
|
4495
|
+
sourceId: input.importResult.nativeSource?.sourceHash ?? input.importResult.sourceHash,
|
|
4496
|
+
path: input.importResult.sourcePath ?? input.importResult.nativeSource?.sourcePath,
|
|
4497
|
+
startLine: 1,
|
|
4498
|
+
startColumn: 1
|
|
4499
|
+
},
|
|
4500
|
+
metadata: {
|
|
4501
|
+
target: input.target,
|
|
4502
|
+
sourceLanguage: input.sourceLanguage,
|
|
4503
|
+
projectionId: input.projection.id,
|
|
4504
|
+
projectionMode: input.projection.mode,
|
|
4505
|
+
targetLossClass: input.targetCoverage.lossClass,
|
|
4506
|
+
targetReadiness: input.targetCoverage.readiness,
|
|
4507
|
+
targetSupported: input.targetCoverage.supported,
|
|
4508
|
+
targetAdapter: input.targetCoverage.adapter,
|
|
4509
|
+
targetLossKinds: input.targetCoverage.lossKinds,
|
|
4510
|
+
lossCategory: 'targetProjectionLoss',
|
|
4511
|
+
semanticMergeAdmission: semanticMergeAdmissionForSeverity(input.severity)
|
|
4512
|
+
}
|
|
4513
|
+
};
|
|
4514
|
+
}
|
|
4515
|
+
|
|
4516
|
+
function nativeSourceCompileEvidence(input) {
|
|
4517
|
+
const failed = input.targetLosses.some((loss) => loss.severity === 'error')
|
|
4518
|
+
|| input.projection.evidence?.some((record) => record.status === 'failed')
|
|
4519
|
+
|| input.targetCoverage.readiness === 'blocked';
|
|
4520
|
+
return {
|
|
4521
|
+
id: input.id,
|
|
4522
|
+
kind: 'projection',
|
|
4523
|
+
status: failed ? 'failed' : 'passed',
|
|
4524
|
+
path: input.importResult.sourcePath ?? input.importResult.nativeSource?.sourcePath,
|
|
4525
|
+
summary: failed
|
|
4526
|
+
? `Compiled ${input.sourceLanguage} native source to ${input.target} with blocked projection evidence.`
|
|
4527
|
+
: `Compiled ${input.sourceLanguage} native source to ${input.target} as ${input.outputMode}.`,
|
|
4528
|
+
metadata: {
|
|
4529
|
+
importId: input.importResult.id,
|
|
4530
|
+
projectionId: input.projection.id,
|
|
4531
|
+
targetProjectionId: input.targetProjection?.id,
|
|
4532
|
+
targetProjectionAdapterId: input.targetProjection?.adapter?.id,
|
|
4533
|
+
sourceLanguage: input.sourceLanguage,
|
|
4534
|
+
target: input.target,
|
|
4535
|
+
outputHash: input.outputHash ?? input.projection.outputHash,
|
|
4536
|
+
outputMode: input.outputMode,
|
|
4537
|
+
projectionMode: input.projection.mode,
|
|
4538
|
+
targetLossClass: input.targetCoverage.lossClass,
|
|
4539
|
+
targetReadiness: input.targetCoverage.readiness,
|
|
4540
|
+
targetSupported: input.targetCoverage.supported,
|
|
4541
|
+
targetReason: input.targetCoverage.reason,
|
|
4542
|
+
targetLossIds: input.targetLosses.map((loss) => loss.id)
|
|
4543
|
+
}
|
|
4544
|
+
};
|
|
4545
|
+
}
|
|
4546
|
+
|
|
4078
4547
|
function nativeProjectionTargetsForLanguage(language, aliases = []) {
|
|
4079
4548
|
const target = nativeLanguageCompileTarget(language, aliases);
|
|
4080
4549
|
return target ? [target] : [];
|
|
@@ -4096,7 +4565,7 @@ function nativeImportLanguageProfile(language, input = {}) {
|
|
|
4096
4565
|
});
|
|
4097
4566
|
}
|
|
4098
4567
|
|
|
4099
|
-
function mergeNativeImportProfiles(languages, imports, adapters) {
|
|
4568
|
+
function mergeNativeImportProfiles(languages, imports, adapters, targetAdapters = []) {
|
|
4100
4569
|
const profilesByLanguage = new Map();
|
|
4101
4570
|
for (const profile of languages) {
|
|
4102
4571
|
const normalized = normalizeNativeLanguageId(profile.language ?? profile);
|
|
@@ -4122,6 +4591,16 @@ function mergeNativeImportProfiles(languages, imports, adapters) {
|
|
|
4122
4591
|
parserAdapters: uniqueStrings([...(existing.parserAdapters ?? []), adapter.parser ?? adapter.id].filter(Boolean))
|
|
4123
4592
|
});
|
|
4124
4593
|
}
|
|
4594
|
+
for (const adapter of targetAdapters) {
|
|
4595
|
+
const summary = safeNativeTargetProjectionAdapterSummary(adapter);
|
|
4596
|
+
const normalized = normalizeNativeLanguageId(summary?.sourceLanguage);
|
|
4597
|
+
if (!normalized) continue;
|
|
4598
|
+
const existing = profilesByLanguage.get(normalized) ?? nativeImportLanguageProfile(normalized, { supportsLightweightScan: false, parserAdapters: [] });
|
|
4599
|
+
profilesByLanguage.set(normalized, {
|
|
4600
|
+
...existing,
|
|
4601
|
+
projectionTargets: uniqueStrings([...(existing.projectionTargets ?? []), summary.target].filter(Boolean))
|
|
4602
|
+
});
|
|
4603
|
+
}
|
|
4125
4604
|
return [...profilesByLanguage.values()].sort((left, right) => left.language.localeCompare(right.language));
|
|
4126
4605
|
}
|
|
4127
4606
|
|
|
@@ -4954,6 +5433,11 @@ function maxSemanticMergeReadiness(left, right) {
|
|
|
4954
5433
|
return leftRank >= rightRank ? left : right;
|
|
4955
5434
|
}
|
|
4956
5435
|
|
|
5436
|
+
function normalizeSemanticMergeReadiness(value) {
|
|
5437
|
+
const readiness = String(value ?? '').toLowerCase();
|
|
5438
|
+
return Object.prototype.hasOwnProperty.call(semanticMergeReadinessRank, readiness) ? readiness : undefined;
|
|
5439
|
+
}
|
|
5440
|
+
|
|
4957
5441
|
export function createUniversalAstFromDocument(document, input = {}) {
|
|
4958
5442
|
return createUniversalAstEnvelope({
|
|
4959
5443
|
id: input.id ?? `universal_ast_${idFragment(document.id)}`,
|
|
@@ -5623,6 +6107,150 @@ function resolveNativeProjectAdapter(source, adapters, input) {
|
|
|
5623
6107
|
});
|
|
5624
6108
|
}
|
|
5625
6109
|
|
|
6110
|
+
function resolveNativeTargetProjectionAdapter(input, options = {}) {
|
|
6111
|
+
const adapters = options.targetAdapters ?? [];
|
|
6112
|
+
if (options.targetAdapter && typeof options.targetAdapter === 'object') return options.targetAdapter;
|
|
6113
|
+
if (typeof options.targetAdapter === 'string') {
|
|
6114
|
+
const explicit = adapters.find((adapter) => adapter?.id === options.targetAdapter);
|
|
6115
|
+
if (explicit) return explicit;
|
|
6116
|
+
}
|
|
6117
|
+
if (typeof options.targetAdapterResolver === 'function') {
|
|
6118
|
+
const resolved = options.targetAdapterResolver(input, adapters);
|
|
6119
|
+
if (resolved) return resolved;
|
|
6120
|
+
}
|
|
6121
|
+
return matchingNativeTargetProjectionAdapter(input, adapters);
|
|
6122
|
+
}
|
|
6123
|
+
|
|
6124
|
+
function matchingNativeTargetProjectionAdapter(input, adapters = []) {
|
|
6125
|
+
return adapters.find((adapter) => nativeTargetProjectionAdapterMatches(adapter, input));
|
|
6126
|
+
}
|
|
6127
|
+
|
|
6128
|
+
function nativeTargetProjectionAdapterMatches(adapter, input = {}) {
|
|
6129
|
+
const summary = safeNativeTargetProjectionAdapterSummary(adapter);
|
|
6130
|
+
if (!summary) return false;
|
|
6131
|
+
if (input.sourceLanguage && normalizeNativeLanguageId(input.sourceLanguage) !== summary.sourceLanguage) return false;
|
|
6132
|
+
const target = normalizeProjectionMatrixTargets([input.target])[0] ?? String(input.target ?? '').toLowerCase();
|
|
6133
|
+
if (target && target !== summary.target) return false;
|
|
6134
|
+
const parser = input.parser ? String(input.parser).toLowerCase() : undefined;
|
|
6135
|
+
if (parser && summary.supportedParsers.length && !summary.supportedParsers.map((item) => item.toLowerCase()).includes(parser)) return false;
|
|
6136
|
+
const sourcePath = String(input.sourcePath ?? '').toLowerCase();
|
|
6137
|
+
if (sourcePath && summary.supportedExtensions.length) {
|
|
6138
|
+
return summary.supportedExtensions.some((extension) => sourcePath.endsWith(extension));
|
|
6139
|
+
}
|
|
6140
|
+
return true;
|
|
6141
|
+
}
|
|
6142
|
+
|
|
6143
|
+
function safeNativeTargetProjectionAdapterSummary(adapter) {
|
|
6144
|
+
try {
|
|
6145
|
+
return normalizeNativeTargetProjectionAdapter(adapter);
|
|
6146
|
+
} catch {
|
|
6147
|
+
return undefined;
|
|
6148
|
+
}
|
|
6149
|
+
}
|
|
6150
|
+
|
|
6151
|
+
function normalizeNativeTargetProjectionAdapter(adapter) {
|
|
6152
|
+
if (!adapter || typeof adapter !== 'object') {
|
|
6153
|
+
throw new Error('Native target projection adapter must be an object');
|
|
6154
|
+
}
|
|
6155
|
+
if (!adapter.id) throw new Error('Native target projection adapter requires an id');
|
|
6156
|
+
const sourceLanguage = normalizeNativeLanguageId(adapter.sourceLanguage ?? adapter.language);
|
|
6157
|
+
if (!sourceLanguage) throw new Error(`Native target projection adapter ${adapter.id} requires a sourceLanguage`);
|
|
6158
|
+
const target = normalizeProjectionMatrixTargets([adapter.target ?? adapter.targetLanguage])[0];
|
|
6159
|
+
if (!target) throw new Error(`Native target projection adapter ${adapter.id} requires a target`);
|
|
6160
|
+
if (typeof adapter.project !== 'function') throw new Error(`Native target projection adapter ${adapter.id} requires a project function`);
|
|
6161
|
+
const capabilities = normalizeStringList(adapter.capabilities);
|
|
6162
|
+
const summaryInput = {
|
|
6163
|
+
id: String(adapter.id),
|
|
6164
|
+
sourceLanguage,
|
|
6165
|
+
language: sourceLanguage,
|
|
6166
|
+
target,
|
|
6167
|
+
parser: `target:${target}`,
|
|
6168
|
+
version: adapter.version === undefined ? undefined : String(adapter.version)
|
|
6169
|
+
};
|
|
6170
|
+
return Object.freeze({
|
|
6171
|
+
id: summaryInput.id,
|
|
6172
|
+
sourceLanguage,
|
|
6173
|
+
target,
|
|
6174
|
+
version: summaryInput.version,
|
|
6175
|
+
capabilities,
|
|
6176
|
+
supportedParsers: normalizeStringList(adapter.supportedParsers),
|
|
6177
|
+
supportedExtensions: normalizeStringList(adapter.supportedExtensions).map((extension) => extension.startsWith('.') ? extension.toLowerCase() : `.${extension.toLowerCase()}`),
|
|
6178
|
+
coverage: normalizeNativeTargetProjectionAdapterCoverage(adapter.coverage, { capabilities }),
|
|
6179
|
+
diagnostics: normalizeAdapterDiagnostics(adapter.diagnostics, summaryInput, {
|
|
6180
|
+
language: sourceLanguage,
|
|
6181
|
+
parser: summaryInput.parser,
|
|
6182
|
+
parserVersion: summaryInput.version
|
|
6183
|
+
}, 'target-adapter')
|
|
6184
|
+
});
|
|
6185
|
+
}
|
|
6186
|
+
|
|
6187
|
+
function normalizeNativeTargetProjectionAdapterCoverage(value = {}, context = {}) {
|
|
6188
|
+
const capabilities = new Set(normalizeStringList(context.capabilities).map((capability) => capability.toLowerCase()));
|
|
6189
|
+
const lossKinds = uniqueStrings(value.lossKinds ?? []);
|
|
6190
|
+
const handledLossKinds = uniqueStrings([
|
|
6191
|
+
...(value.handledLossKinds ?? []),
|
|
6192
|
+
...(capabilities.has('macros') || capabilities.has('macroexpansion') ? ['macroExpansion', 'macroHygiene'] : []),
|
|
6193
|
+
...(capabilities.has('preprocessor') ? ['preprocessor', 'conditionalCompilation'] : []),
|
|
6194
|
+
...(capabilities.has('dynamicruntime') ? ['dynamicRuntime', 'dynamicDispatch'] : []),
|
|
6195
|
+
...(capabilities.has('typeinference') ? ['typeInference', 'overloadResolution'] : [])
|
|
6196
|
+
]);
|
|
6197
|
+
return Object.freeze({
|
|
6198
|
+
readiness: normalizeSemanticMergeReadiness(value.readiness) ?? 'needs-review',
|
|
6199
|
+
lossKinds,
|
|
6200
|
+
handledLossKinds,
|
|
6201
|
+
sourceMapPrecision: value.sourceMapPrecision,
|
|
6202
|
+
semanticCoverage: value.semanticCoverage ?? {},
|
|
6203
|
+
notes: uniqueStrings(value.notes ?? ['Target projection adapter output is host-owned evidence and should be reviewed unless declared ready.'])
|
|
6204
|
+
});
|
|
6205
|
+
}
|
|
6206
|
+
|
|
6207
|
+
function nativeTargetProjectionAdapterEvidence(adapter, diagnostics, input) {
|
|
6208
|
+
const errors = diagnostics.filter((diagnostic) => diagnostic.severity === 'error').length;
|
|
6209
|
+
const warnings = diagnostics.filter((diagnostic) => diagnostic.severity === 'warning').length;
|
|
6210
|
+
return {
|
|
6211
|
+
id: `evidence_${idFragment(adapter.id)}_native_target_projection_adapter`,
|
|
6212
|
+
kind: 'projection',
|
|
6213
|
+
status: errors ? 'failed' : 'passed',
|
|
6214
|
+
path: input.sourcePath,
|
|
6215
|
+
summary: `Ran ${adapter.id} native target projection adapter from ${input.sourceLanguage} to ${input.target} with ${diagnostics.length} diagnostic(s).`,
|
|
6216
|
+
metadata: {
|
|
6217
|
+
adapterId: adapter.id,
|
|
6218
|
+
adapterVersion: adapter.version,
|
|
6219
|
+
sourceLanguage: input.sourceLanguage,
|
|
6220
|
+
target: input.target,
|
|
6221
|
+
targetPath: input.targetPath,
|
|
6222
|
+
outputHash: input.outputHash,
|
|
6223
|
+
capabilities: adapter.capabilities,
|
|
6224
|
+
coverage: adapter.coverage,
|
|
6225
|
+
diagnostics: diagnostics.map(serializableDiagnostic),
|
|
6226
|
+
errors,
|
|
6227
|
+
warnings
|
|
6228
|
+
}
|
|
6229
|
+
};
|
|
6230
|
+
}
|
|
6231
|
+
|
|
6232
|
+
function nativeTargetProjectionDiagnosticToLoss(diagnostic, index, adapter, input) {
|
|
6233
|
+
return {
|
|
6234
|
+
id: `loss_${idFragment(diagnostic.id ?? `${adapter.id}_${index}_${diagnostic.code ?? diagnostic.severity}`)}`,
|
|
6235
|
+
severity: diagnostic.severity,
|
|
6236
|
+
phase: diagnostic.phase ?? 'emit',
|
|
6237
|
+
sourceFormat: input.sourceLanguage,
|
|
6238
|
+
kind: diagnostic.kind ?? 'targetProjectionLoss',
|
|
6239
|
+
message: diagnostic.message,
|
|
6240
|
+
span: diagnostic.span,
|
|
6241
|
+
metadata: {
|
|
6242
|
+
adapterId: adapter.id,
|
|
6243
|
+
adapterVersion: adapter.version,
|
|
6244
|
+
diagnosticId: diagnostic.id,
|
|
6245
|
+
diagnosticCode: diagnostic.code,
|
|
6246
|
+
sourceLanguage: input.sourceLanguage,
|
|
6247
|
+
target: input.target,
|
|
6248
|
+
path: diagnostic.path,
|
|
6249
|
+
...diagnostic.metadata
|
|
6250
|
+
}
|
|
6251
|
+
};
|
|
6252
|
+
}
|
|
6253
|
+
|
|
5626
6254
|
function normalizeNativeImporterAdapter(adapter) {
|
|
5627
6255
|
if (!adapter || typeof adapter !== 'object') {
|
|
5628
6256
|
throw new Error('Native importer adapter must be an object');
|
package/package.json
CHANGED