@shapeshift-labs/frontier-lang-compiler 0.2.2 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +319 -8
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -75,6 +75,7 @@ export interface ImportNativeSourceOptions {
|
|
|
75
75
|
readonly parserVersion?: string;
|
|
76
76
|
readonly sourcePath?: string;
|
|
77
77
|
readonly sourceHash?: string;
|
|
78
|
+
readonly sourceText?: string;
|
|
78
79
|
readonly symbol?: string;
|
|
79
80
|
readonly name?: string;
|
|
80
81
|
readonly nativeAst?: NativeAstRecord;
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
createImportResult,
|
|
4
4
|
createNativeAstRecord,
|
|
5
5
|
createPatch,
|
|
6
|
+
createSemanticIndexRecord,
|
|
6
7
|
createUniversalAstEnvelope,
|
|
7
8
|
hashDocumentBase,
|
|
8
9
|
hashSemanticValue,
|
|
@@ -138,17 +139,26 @@ export function importNativeSource(input) {
|
|
|
138
139
|
const language = input.language ?? input.nativeAst?.language;
|
|
139
140
|
if (!language) throw new Error('importNativeSource requires a language or nativeAst.language');
|
|
140
141
|
const sourcePath = input.sourcePath ?? input.nativeAst?.sourcePath;
|
|
141
|
-
const sourceHash = input.sourceHash ?? input.nativeAst?.sourceHash ?? hashSemanticValue(input.nativeAst?.nodes ?? input.nativeAst ?? {});
|
|
142
|
+
const sourceHash = input.sourceHash ?? input.nativeAst?.sourceHash ?? (input.sourceText ? hashSemanticValue(input.sourceText) : hashSemanticValue(input.nativeAst?.nodes ?? input.nativeAst ?? {}));
|
|
142
143
|
const importIdPart = idFragment(input.id ?? input.nativeSourceId ?? sourcePath ?? language);
|
|
144
|
+
const lightweight = !input.nativeAst && !input.nodes && input.sourceText
|
|
145
|
+
? createLightweightNativeImport({
|
|
146
|
+
language,
|
|
147
|
+
sourceText: input.sourceText,
|
|
148
|
+
sourcePath,
|
|
149
|
+
sourceHash,
|
|
150
|
+
parser: input.parser
|
|
151
|
+
})
|
|
152
|
+
: undefined;
|
|
143
153
|
const nativeAst = input.nativeAst ?? createNativeAstRecord({
|
|
144
154
|
id: input.nativeAstId ?? `native_ast_${importIdPart}`,
|
|
145
155
|
language,
|
|
146
|
-
parser: input.parser,
|
|
156
|
+
parser: input.parser ?? lightweight?.parser,
|
|
147
157
|
parserVersion: input.parserVersion,
|
|
148
158
|
sourcePath,
|
|
149
159
|
sourceHash,
|
|
150
|
-
rootId: input.rootId ?? 'native_root',
|
|
151
|
-
nodes: input.nodes ?? {
|
|
160
|
+
rootId: input.rootId ?? lightweight?.rootId ?? 'native_root',
|
|
161
|
+
nodes: input.nodes ?? lightweight?.nodes ?? {
|
|
152
162
|
native_root: {
|
|
153
163
|
id: 'native_root',
|
|
154
164
|
kind: 'Unknown',
|
|
@@ -157,11 +167,15 @@ export function importNativeSource(input) {
|
|
|
157
167
|
metadata: { reason: 'no-native-ast-nodes-provided' }
|
|
158
168
|
}
|
|
159
169
|
},
|
|
160
|
-
losses: input.losses,
|
|
161
|
-
metadata:
|
|
170
|
+
losses: input.losses ?? lightweight?.losses,
|
|
171
|
+
metadata: {
|
|
172
|
+
...(input.sourceText ? { sourceBytes: input.sourceText.length } : {}),
|
|
173
|
+
...lightweight?.metadata,
|
|
174
|
+
...input.nativeAstMetadata
|
|
175
|
+
}
|
|
162
176
|
});
|
|
163
177
|
const frontierNodeIds = input.frontierNodeIds ?? input.semanticNodes?.map((node) => node.id) ?? [];
|
|
164
|
-
const losses = input.losses ?? nativeAst.losses ?? [];
|
|
178
|
+
const losses = input.losses ?? nativeAst.losses ?? lightweight?.losses ?? [];
|
|
165
179
|
const nativeSource = nativeSourceNode({
|
|
166
180
|
id: input.nativeSourceId ?? `native_source_${importIdPart}`,
|
|
167
181
|
name: input.name ?? sourcePath?.split(/[\\/]/).filter(Boolean).at(-1) ?? `${language}NativeSource`,
|
|
@@ -205,7 +219,7 @@ export function importNativeSource(input) {
|
|
|
205
219
|
semanticStatus: input.semanticStatus ?? (semanticNodes.length ? 'mapped' : 'native-only')
|
|
206
220
|
}
|
|
207
221
|
}];
|
|
208
|
-
const semanticIndex = input.semanticIndex;
|
|
222
|
+
const semanticIndex = input.semanticIndex ?? lightweight?.semanticIndex;
|
|
209
223
|
const universalAst = createUniversalAstEnvelope({
|
|
210
224
|
id: input.universalAstId ?? `universal_ast_${importIdPart}`,
|
|
211
225
|
document,
|
|
@@ -257,6 +271,303 @@ export function importNativeSource(input) {
|
|
|
257
271
|
};
|
|
258
272
|
}
|
|
259
273
|
|
|
274
|
+
function createLightweightNativeImport(input) {
|
|
275
|
+
const parser = input.parser ?? `${input.language}.lightweight-declaration-scan`;
|
|
276
|
+
const rootId = 'native_root';
|
|
277
|
+
const nodes = {
|
|
278
|
+
[rootId]: {
|
|
279
|
+
id: rootId,
|
|
280
|
+
kind: 'Program',
|
|
281
|
+
languageKind: `${input.language}.program`,
|
|
282
|
+
children: [],
|
|
283
|
+
metadata: { parser, sourceHash: input.sourceHash }
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
const declarations = scanNativeDeclarations(input);
|
|
287
|
+
const losses = [];
|
|
288
|
+
const documentId = `doc_${idFragment(input.sourcePath ?? input.language)}`;
|
|
289
|
+
const symbols = [];
|
|
290
|
+
const occurrences = [];
|
|
291
|
+
const relations = [];
|
|
292
|
+
const facts = [];
|
|
293
|
+
|
|
294
|
+
for (const declaration of declarations) {
|
|
295
|
+
nodes[rootId].children.push(declaration.nodeId);
|
|
296
|
+
nodes[declaration.nodeId] = {
|
|
297
|
+
id: declaration.nodeId,
|
|
298
|
+
kind: declaration.kind,
|
|
299
|
+
languageKind: declaration.languageKind,
|
|
300
|
+
span: declaration.span,
|
|
301
|
+
value: declaration.name ?? declaration.importPath ?? null,
|
|
302
|
+
fields: declaration.fields,
|
|
303
|
+
metadata: declaration.metadata
|
|
304
|
+
};
|
|
305
|
+
if (declaration.symbolId) {
|
|
306
|
+
symbols.push({
|
|
307
|
+
id: declaration.symbolId,
|
|
308
|
+
scheme: 'frontier',
|
|
309
|
+
name: declaration.name,
|
|
310
|
+
kind: declaration.symbolKind,
|
|
311
|
+
language: input.language,
|
|
312
|
+
nativeAstNodeId: declaration.nodeId,
|
|
313
|
+
signatureHash: hashSemanticValue([input.language, declaration.kind, declaration.name, declaration.fields ?? {}]),
|
|
314
|
+
definitionSpan: declaration.span
|
|
315
|
+
});
|
|
316
|
+
occurrences.push({
|
|
317
|
+
id: `occ_${idFragment(declaration.nodeId)}_def`,
|
|
318
|
+
documentId,
|
|
319
|
+
symbolId: declaration.symbolId,
|
|
320
|
+
role: declaration.role ?? 'definition',
|
|
321
|
+
span: declaration.span,
|
|
322
|
+
nativeAstNodeId: declaration.nodeId
|
|
323
|
+
});
|
|
324
|
+
relations.push({
|
|
325
|
+
id: `rel_${idFragment(documentId)}_${idFragment(declaration.nodeId)}`,
|
|
326
|
+
sourceId: documentId,
|
|
327
|
+
predicate: declaration.role === 'import' ? 'imports' : 'defines',
|
|
328
|
+
targetId: declaration.symbolId
|
|
329
|
+
});
|
|
330
|
+
facts.push({
|
|
331
|
+
id: `fact_${idFragment(declaration.nodeId)}_kind`,
|
|
332
|
+
predicate: 'nativeKind',
|
|
333
|
+
subjectId: declaration.symbolId,
|
|
334
|
+
value: declaration.languageKind
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
if (declaration.loss) losses.push(declaration.loss);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
const semanticIndex = createSemanticIndexRecord({
|
|
341
|
+
id: `index_${idFragment(input.sourcePath ?? input.language)}`,
|
|
342
|
+
documents: [{
|
|
343
|
+
id: documentId,
|
|
344
|
+
path: input.sourcePath ?? `${input.language}:memory`,
|
|
345
|
+
language: input.language,
|
|
346
|
+
sourceHash: input.sourceHash
|
|
347
|
+
}],
|
|
348
|
+
symbols,
|
|
349
|
+
occurrences,
|
|
350
|
+
relations,
|
|
351
|
+
facts,
|
|
352
|
+
evidence: [{
|
|
353
|
+
id: `evidence_${idFragment(input.sourcePath ?? input.language)}_lightweight_scan`,
|
|
354
|
+
kind: 'import',
|
|
355
|
+
status: 'passed',
|
|
356
|
+
path: input.sourcePath,
|
|
357
|
+
summary: `Lightweight declaration scan found ${symbols.length} symbol(s).`,
|
|
358
|
+
metadata: { parser }
|
|
359
|
+
}],
|
|
360
|
+
metadata: {
|
|
361
|
+
parser,
|
|
362
|
+
coverage: 'declarations-only',
|
|
363
|
+
unsupported: ['full expression AST', 'type checking', 'control flow', 'comments and formatting preservation']
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
return {
|
|
368
|
+
parser,
|
|
369
|
+
rootId,
|
|
370
|
+
nodes,
|
|
371
|
+
losses,
|
|
372
|
+
semanticIndex,
|
|
373
|
+
metadata: { parser, scanKind: 'lightweight-declaration-scan', declarationCount: declarations.length }
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function scanNativeDeclarations(input) {
|
|
378
|
+
const language = String(input.language).toLowerCase();
|
|
379
|
+
if (language === 'javascript' || language === 'typescript') return scanJavaScriptLike(input);
|
|
380
|
+
if (language === 'python') return scanPython(input);
|
|
381
|
+
if (language === 'rust') return scanRust(input);
|
|
382
|
+
if (language === 'c' || language === 'cpp' || language === 'c++') return scanCLike(input);
|
|
383
|
+
return scanGenericDeclarations(input);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function scanJavaScriptLike(input) {
|
|
387
|
+
const declarations = [];
|
|
388
|
+
for (const { line, number } of sourceLines(input.sourceText)) {
|
|
389
|
+
const trimmed = line.trim();
|
|
390
|
+
let match;
|
|
391
|
+
if ((match = trimmed.match(/^(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)\s*\(([^)]*)\)/))) {
|
|
392
|
+
declarations.push(nativeDeclaration(input, number, 'FunctionDeclaration', 'function', match[1], { parameters: splitParameters(match[2]) }, trimmed.includes('{')));
|
|
393
|
+
} else if ((match = trimmed.match(/^(?:export\s+)?class\s+([A-Za-z_$][\w$]*)/))) {
|
|
394
|
+
declarations.push(nativeDeclaration(input, number, 'ClassDeclaration', 'class', match[1], {}, trimmed.includes('{')));
|
|
395
|
+
} else if ((match = trimmed.match(/^(?:export\s+)?interface\s+([A-Za-z_$][\w$]*)/))) {
|
|
396
|
+
declarations.push(nativeDeclaration(input, number, 'InterfaceDeclaration', 'interface', match[1], {}, trimmed.includes('{')));
|
|
397
|
+
} else if ((match = trimmed.match(/^(?:export\s+)?type\s+([A-Za-z_$][\w$]*)\s*=/))) {
|
|
398
|
+
declarations.push(nativeDeclaration(input, number, 'TypeAliasDeclaration', 'type', match[1], {}, false));
|
|
399
|
+
} else if ((match = trimmed.match(/^(?:export\s+)?(?:const|let|var)\s+([A-Za-z_$][\w$]*)\s*=\s*(?:async\s*)?\(?([^=;]*)\)?\s*=>/))) {
|
|
400
|
+
declarations.push(nativeDeclaration(input, number, 'VariableFunctionDeclaration', 'function', match[1], { parameters: splitParameters(match[2]) }, true));
|
|
401
|
+
} else if ((match = trimmed.match(/^import\s+(?:.+?\s+from\s+)?['"]([^'"]+)['"]/))) {
|
|
402
|
+
declarations.push(nativeImportDeclaration(input, number, match[1], 'ImportDeclaration', 'module'));
|
|
403
|
+
} else if ((match = trimmed.match(/^export\s+\{[^}]*\}\s+from\s+['"]([^'"]+)['"]/))) {
|
|
404
|
+
declarations.push(nativeImportDeclaration(input, number, match[1], 'ExportFromDeclaration', 'module'));
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return declarations;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
function scanPython(input) {
|
|
411
|
+
const declarations = [];
|
|
412
|
+
for (const { line, number } of sourceLines(input.sourceText)) {
|
|
413
|
+
const trimmed = line.trim();
|
|
414
|
+
let match;
|
|
415
|
+
if ((match = trimmed.match(/^(?:async\s+)?def\s+([A-Za-z_]\w*)\s*\(([^)]*)\)\s*:/))) {
|
|
416
|
+
declarations.push(nativeDeclaration(input, number, 'FunctionDef', 'function', match[1], { parameters: splitParameters(match[2]) }, true));
|
|
417
|
+
} else if ((match = trimmed.match(/^class\s+([A-Za-z_]\w*)/))) {
|
|
418
|
+
declarations.push(nativeDeclaration(input, number, 'ClassDef', 'class', match[1], {}, true));
|
|
419
|
+
} else if ((match = trimmed.match(/^(?:from\s+([A-Za-z_][\w.]*)\s+import\s+.+|import\s+([A-Za-z_][\w.]*))/))) {
|
|
420
|
+
declarations.push(nativeImportDeclaration(input, number, match[1] ?? match[2], 'Import', 'module'));
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
return declarations;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
function scanRust(input) {
|
|
427
|
+
const declarations = [];
|
|
428
|
+
for (const { line, number } of sourceLines(input.sourceText)) {
|
|
429
|
+
const trimmed = line.trim();
|
|
430
|
+
let match;
|
|
431
|
+
if ((match = trimmed.match(/^(?:pub(?:\([^)]*\))?\s+)?(?:async\s+)?fn\s+([A-Za-z_]\w*)\s*\(([^)]*)\)/))) {
|
|
432
|
+
declarations.push(nativeDeclaration(input, number, 'ItemFn', 'function', match[1], { parameters: splitParameters(match[2]) }, trimmed.includes('{')));
|
|
433
|
+
} else if ((match = trimmed.match(/^(?:pub(?:\([^)]*\))?\s+)?struct\s+([A-Za-z_]\w*)/))) {
|
|
434
|
+
declarations.push(nativeDeclaration(input, number, 'ItemStruct', 'type', match[1], {}, trimmed.includes('{')));
|
|
435
|
+
} else if ((match = trimmed.match(/^(?:pub(?:\([^)]*\))?\s+)?enum\s+([A-Za-z_]\w*)/))) {
|
|
436
|
+
declarations.push(nativeDeclaration(input, number, 'ItemEnum', 'type', match[1], {}, trimmed.includes('{')));
|
|
437
|
+
} else if ((match = trimmed.match(/^(?:pub(?:\([^)]*\))?\s+)?trait\s+([A-Za-z_]\w*)/))) {
|
|
438
|
+
declarations.push(nativeDeclaration(input, number, 'ItemTrait', 'trait', match[1], {}, trimmed.includes('{')));
|
|
439
|
+
} else if ((match = trimmed.match(/^impl(?:\s*<[^>]+>)?\s+(.+?)\s*\{/))) {
|
|
440
|
+
declarations.push(nativeDeclaration(input, number, 'ItemImpl', 'implementation', idFragment(match[1]), { target: match[1].trim() }, true));
|
|
441
|
+
} else if ((match = trimmed.match(/^(?:pub(?:\([^)]*\))?\s+)?mod\s+([A-Za-z_]\w*)/))) {
|
|
442
|
+
declarations.push(nativeDeclaration(input, number, 'ItemMod', 'module', match[1], {}, trimmed.includes('{')));
|
|
443
|
+
} else if ((match = trimmed.match(/^use\s+(.+?);/))) {
|
|
444
|
+
declarations.push(nativeImportDeclaration(input, number, match[1], 'ItemUse', 'module'));
|
|
445
|
+
} else if (/^[A-Za-z_]\w*!\s*[({[]/.test(trimmed)) {
|
|
446
|
+
declarations.push(nativeMacroLoss(input, number, trimmed, 'macroExpansion'));
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
return declarations;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
function scanCLike(input) {
|
|
453
|
+
const declarations = [];
|
|
454
|
+
for (const { line, number } of sourceLines(input.sourceText)) {
|
|
455
|
+
const trimmed = line.trim();
|
|
456
|
+
let match;
|
|
457
|
+
if ((match = trimmed.match(/^#\s*include\s+[<"]([^>"]+)[>"]/))) {
|
|
458
|
+
declarations.push(nativeImportDeclaration(input, number, match[1], 'IncludeDirective', 'header'));
|
|
459
|
+
} else if ((match = trimmed.match(/^#\s*define\s+([A-Za-z_]\w*)/))) {
|
|
460
|
+
declarations.push(nativeMacroLoss(input, number, trimmed, 'preprocessor', match[1]));
|
|
461
|
+
} else if ((match = trimmed.match(/^typedef\s+struct(?:\s+([A-Za-z_]\w*))?/))) {
|
|
462
|
+
declarations.push(nativeDeclaration(input, number, 'TypedefStructDeclaration', 'type', match[1] ?? `anonymous_struct_${number}`, {}, trimmed.includes('{')));
|
|
463
|
+
} else if ((match = trimmed.match(/^(?:struct|enum)\s+([A-Za-z_]\w*)/))) {
|
|
464
|
+
declarations.push(nativeDeclaration(input, number, 'TagDeclaration', 'type', match[1], {}, trimmed.includes('{')));
|
|
465
|
+
} else if ((match = trimmed.match(/^(?:[A-Za-z_][\w\s*:&<>]+)\s+([A-Za-z_]\w*)\s*\(([^;{}]*)\)\s*(?:;|\{)?$/))) {
|
|
466
|
+
declarations.push(nativeDeclaration(input, number, 'FunctionDeclaration', 'function', match[1], { parameters: splitParameters(match[2]) }, trimmed.endsWith('{')));
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
return declarations;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
function scanGenericDeclarations(input) {
|
|
473
|
+
return sourceLines(input.sourceText)
|
|
474
|
+
.filter(({ line }) => /\b(function|class|struct|enum|trait|interface|def)\b/.test(line))
|
|
475
|
+
.map(({ line, number }) => nativeDeclaration(input, number, 'NativeDeclaration', 'variable', idFragment(line.trim()).slice(0, 40), { source: line.trim() }, true));
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
function nativeDeclaration(input, lineNumber, languageKind, symbolKind, name, fields = {}, hasBody = false) {
|
|
479
|
+
const nodeId = `native_${idFragment(languageKind)}_${lineNumber}_${idFragment(name)}`;
|
|
480
|
+
return {
|
|
481
|
+
nodeId,
|
|
482
|
+
kind: languageKind,
|
|
483
|
+
languageKind: `${input.language}.${languageKind}`,
|
|
484
|
+
name,
|
|
485
|
+
symbolKind,
|
|
486
|
+
symbolId: `symbol:${input.language}:${idFragment(name)}`,
|
|
487
|
+
span: spanForLine(input, lineNumber),
|
|
488
|
+
fields,
|
|
489
|
+
metadata: { scan: 'lightweight-declaration', hasBody },
|
|
490
|
+
...(hasBody ? { loss: opaqueBodyLoss(input, lineNumber, nodeId, name) } : {})
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
function nativeImportDeclaration(input, lineNumber, importPath, languageKind, symbolKind) {
|
|
495
|
+
const name = String(importPath);
|
|
496
|
+
const nodeId = `native_${idFragment(languageKind)}_${lineNumber}_${idFragment(name)}`;
|
|
497
|
+
return {
|
|
498
|
+
nodeId,
|
|
499
|
+
kind: languageKind,
|
|
500
|
+
languageKind: `${input.language}.${languageKind}`,
|
|
501
|
+
name,
|
|
502
|
+
symbolKind,
|
|
503
|
+
symbolId: `symbol:${input.language}:import:${idFragment(name)}`,
|
|
504
|
+
role: 'import',
|
|
505
|
+
importPath: name,
|
|
506
|
+
span: spanForLine(input, lineNumber),
|
|
507
|
+
fields: { importPath: name },
|
|
508
|
+
metadata: { scan: 'lightweight-import' }
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
function nativeMacroLoss(input, lineNumber, source, kind, name = idFragment(source).slice(0, 40)) {
|
|
513
|
+
const nodeId = `native_${kind}_${lineNumber}_${idFragment(name)}`;
|
|
514
|
+
return {
|
|
515
|
+
nodeId,
|
|
516
|
+
kind: kind === 'preprocessor' ? 'PreprocessorDirective' : 'MacroInvocation',
|
|
517
|
+
languageKind: `${input.language}.${kind}`,
|
|
518
|
+
name,
|
|
519
|
+
symbolKind: 'constant',
|
|
520
|
+
symbolId: `symbol:${input.language}:${kind}:${idFragment(name)}`,
|
|
521
|
+
span: spanForLine(input, lineNumber),
|
|
522
|
+
fields: { source },
|
|
523
|
+
metadata: { scan: 'lightweight-macro' },
|
|
524
|
+
loss: {
|
|
525
|
+
id: `loss_${idFragment(nodeId)}`,
|
|
526
|
+
severity: 'warning',
|
|
527
|
+
phase: 'read',
|
|
528
|
+
sourceFormat: input.language,
|
|
529
|
+
kind,
|
|
530
|
+
message: `${input.language} ${kind} retained as native source; expansion is not evaluated by the lightweight importer.`,
|
|
531
|
+
span: spanForLine(input, lineNumber),
|
|
532
|
+
nodeId
|
|
533
|
+
}
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
function opaqueBodyLoss(input, lineNumber, nodeId, name) {
|
|
538
|
+
return {
|
|
539
|
+
id: `loss_${idFragment(nodeId)}_body`,
|
|
540
|
+
severity: 'info',
|
|
541
|
+
phase: 'read',
|
|
542
|
+
sourceFormat: input.language,
|
|
543
|
+
kind: 'opaqueNative',
|
|
544
|
+
message: `Body for ${name} is retained as native source by the lightweight declaration importer.`,
|
|
545
|
+
span: spanForLine(input, lineNumber),
|
|
546
|
+
nodeId
|
|
547
|
+
};
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
function sourceLines(sourceText) {
|
|
551
|
+
return String(sourceText ?? '').split(/\r?\n/).map((line, index) => ({ line, number: index + 1 }));
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
function spanForLine(input, lineNumber) {
|
|
555
|
+
return {
|
|
556
|
+
sourceId: input.sourceHash,
|
|
557
|
+
path: input.sourcePath,
|
|
558
|
+
startLine: lineNumber,
|
|
559
|
+
endLine: lineNumber,
|
|
560
|
+
startColumn: 1
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
function splitParameters(raw) {
|
|
565
|
+
return String(raw ?? '')
|
|
566
|
+
.split(',')
|
|
567
|
+
.map((part) => part.trim())
|
|
568
|
+
.filter(Boolean);
|
|
569
|
+
}
|
|
570
|
+
|
|
260
571
|
export function createUniversalAstFromDocument(document, input = {}) {
|
|
261
572
|
return createUniversalAstEnvelope({
|
|
262
573
|
id: input.id ?? `universal_ast_${idFragment(document.id)}`,
|
package/package.json
CHANGED