@shapeshift-labs/frontier-lang-compiler 0.2.6 → 0.2.7
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 +6 -1
- package/dist/index.js +346 -4
- package/package.json +9 -9
package/dist/index.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ import type {
|
|
|
14
14
|
SemanticIndexRecord,
|
|
15
15
|
SemanticNode,
|
|
16
16
|
SemanticPatchBundle,
|
|
17
|
+
SourceMapMappingRecord,
|
|
18
|
+
SourceMapRecord,
|
|
17
19
|
SourceSpan
|
|
18
20
|
} from '@shapeshift-labs/frontier-lang-kernel';
|
|
19
21
|
import type { Diagnostic } from '@shapeshift-labs/frontier-lang-checker';
|
|
@@ -104,7 +106,7 @@ export interface ImportNativeSourceOptions {
|
|
|
104
106
|
readonly nodes?: Readonly<Record<string, NativeAstNode>>;
|
|
105
107
|
readonly semanticNodes?: readonly SemanticNode[];
|
|
106
108
|
readonly frontierNodeIds?: readonly string[];
|
|
107
|
-
readonly mappings?: readonly
|
|
109
|
+
readonly mappings?: readonly SourceMapMappingRecord[];
|
|
108
110
|
readonly semanticStatus?: 'native-only' | 'mapped' | 'partial' | string;
|
|
109
111
|
readonly losses?: readonly NativeAstLossRecord[];
|
|
110
112
|
readonly evidence?: readonly EvidenceRecord[];
|
|
@@ -114,6 +116,8 @@ export interface ImportNativeSourceOptions {
|
|
|
114
116
|
readonly author?: string;
|
|
115
117
|
readonly target?: CompileTarget;
|
|
116
118
|
readonly semanticIndex?: SemanticIndexRecord;
|
|
119
|
+
readonly sourceMapId?: string;
|
|
120
|
+
readonly sourceMaps?: readonly SourceMapRecord[];
|
|
117
121
|
readonly universalAstId?: string;
|
|
118
122
|
readonly universalAstMetadata?: Record<string, unknown>;
|
|
119
123
|
readonly metadata?: Record<string, unknown>;
|
|
@@ -189,6 +193,7 @@ export declare function importNativeSource(input: ImportNativeSourceOptions): Na
|
|
|
189
193
|
export declare function createUniversalAstFromDocument(document: FrontierLangDocument, input?: {
|
|
190
194
|
readonly id?: string;
|
|
191
195
|
readonly semanticIndex?: SemanticIndexRecord;
|
|
196
|
+
readonly sourceMaps?: readonly SourceMapRecord[];
|
|
192
197
|
readonly evidence?: readonly EvidenceRecord[];
|
|
193
198
|
readonly metadata?: Record<string, unknown>;
|
|
194
199
|
}): FrontierUniversalAstEnvelope;
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
createNativeAstRecord,
|
|
5
5
|
createPatch,
|
|
6
6
|
createSemanticIndexRecord,
|
|
7
|
+
createSourceMapRecord,
|
|
7
8
|
createUniversalAstEnvelope,
|
|
8
9
|
hashDocumentBase,
|
|
9
10
|
hashSemanticValue,
|
|
@@ -339,11 +340,48 @@ export function importNativeSource(input) {
|
|
|
339
340
|
}
|
|
340
341
|
}];
|
|
341
342
|
const semanticIndex = input.semanticIndex ?? lightweight?.semanticIndex;
|
|
343
|
+
const sourceMapMappings = normalizeSourceMapMappings(
|
|
344
|
+
input.mappings ?? lightweight?.mappings ?? inferSourceMapMappings({
|
|
345
|
+
semanticIndex,
|
|
346
|
+
nativeAst,
|
|
347
|
+
nativeSource,
|
|
348
|
+
evidence
|
|
349
|
+
}),
|
|
350
|
+
{
|
|
351
|
+
semanticIndex,
|
|
352
|
+
nativeAst,
|
|
353
|
+
nativeSource,
|
|
354
|
+
evidence,
|
|
355
|
+
losses,
|
|
356
|
+
target: input.target
|
|
357
|
+
}
|
|
358
|
+
);
|
|
359
|
+
const inferredSourceMaps = sourceMapMappings.length
|
|
360
|
+
? [createSourceMapRecord({
|
|
361
|
+
id: input.sourceMapId ?? `source_map_${importIdPart}`,
|
|
362
|
+
sourcePath,
|
|
363
|
+
sourceHash,
|
|
364
|
+
target: input.target,
|
|
365
|
+
targetPath: input.target?.emitPath,
|
|
366
|
+
semanticIndexId: semanticIndex?.id,
|
|
367
|
+
nativeAstId: nativeAst.id,
|
|
368
|
+
nativeSourceId: nativeSource.id,
|
|
369
|
+
mappings: sourceMapMappings,
|
|
370
|
+
evidence,
|
|
371
|
+
metadata: {
|
|
372
|
+
sourceLanguage: language,
|
|
373
|
+
parser: nativeAst.parser,
|
|
374
|
+
semanticStatus: input.semanticStatus ?? (semanticNodes.length ? 'mapped' : 'native-only')
|
|
375
|
+
}
|
|
376
|
+
})]
|
|
377
|
+
: [];
|
|
378
|
+
const sourceMaps = input.sourceMaps ?? inferredSourceMaps;
|
|
342
379
|
const universalAst = createUniversalAstEnvelope({
|
|
343
380
|
id: input.universalAstId ?? `universal_ast_${importIdPart}`,
|
|
344
381
|
document,
|
|
345
382
|
nativeSources: [nativeSource],
|
|
346
383
|
semanticIndex,
|
|
384
|
+
sourceMaps,
|
|
347
385
|
losses,
|
|
348
386
|
evidence,
|
|
349
387
|
metadata: {
|
|
@@ -363,7 +401,13 @@ export function importNativeSource(input) {
|
|
|
363
401
|
touches: [{ id: node.id, access: node.kind === 'nativeSource' ? 'evidence' : 'schema' }]
|
|
364
402
|
})),
|
|
365
403
|
evidence,
|
|
366
|
-
metadata: {
|
|
404
|
+
metadata: {
|
|
405
|
+
sourceLanguage: language,
|
|
406
|
+
sourcePath,
|
|
407
|
+
semanticIndexId: semanticIndex?.id,
|
|
408
|
+
universalAstId: universalAst.id,
|
|
409
|
+
sourceMapIds: sourceMaps.map((sourceMap) => sourceMap.id)
|
|
410
|
+
}
|
|
367
411
|
});
|
|
368
412
|
return {
|
|
369
413
|
...createImportResult({
|
|
@@ -375,14 +419,16 @@ export function importNativeSource(input) {
|
|
|
375
419
|
nativeAst,
|
|
376
420
|
semanticIndex,
|
|
377
421
|
universalAst,
|
|
422
|
+
sourceMaps,
|
|
378
423
|
losses,
|
|
379
424
|
evidence,
|
|
380
425
|
metadata: {
|
|
381
426
|
nativeSourceId: nativeSource.id,
|
|
382
427
|
semanticIndexId: semanticIndex?.id,
|
|
383
428
|
universalAstId: universalAst.id,
|
|
429
|
+
sourceMapIds: sourceMaps.map((sourceMap) => sourceMap.id),
|
|
384
430
|
semanticStatus: input.semanticStatus ?? (semanticNodes.length ? 'mapped' : 'native-only'),
|
|
385
|
-
mappings:
|
|
431
|
+
mappings: sourceMapMappings,
|
|
386
432
|
...input.metadata
|
|
387
433
|
}
|
|
388
434
|
}),
|
|
@@ -409,6 +455,8 @@ function createLightweightNativeImport(input) {
|
|
|
409
455
|
const occurrences = [];
|
|
410
456
|
const relations = [];
|
|
411
457
|
const facts = [];
|
|
458
|
+
const mappings = [];
|
|
459
|
+
const evidenceId = `evidence_${idFragment(input.sourcePath ?? input.language)}_lightweight_scan`;
|
|
412
460
|
|
|
413
461
|
for (const declaration of declarations) {
|
|
414
462
|
nodes[rootId].children.push(declaration.nodeId);
|
|
@@ -422,6 +470,7 @@ function createLightweightNativeImport(input) {
|
|
|
422
470
|
metadata: declaration.metadata
|
|
423
471
|
};
|
|
424
472
|
if (declaration.symbolId) {
|
|
473
|
+
const occurrenceId = `occ_${idFragment(declaration.nodeId)}_def`;
|
|
425
474
|
symbols.push({
|
|
426
475
|
id: declaration.symbolId,
|
|
427
476
|
scheme: 'frontier',
|
|
@@ -433,7 +482,7 @@ function createLightweightNativeImport(input) {
|
|
|
433
482
|
definitionSpan: declaration.span
|
|
434
483
|
});
|
|
435
484
|
occurrences.push({
|
|
436
|
-
id:
|
|
485
|
+
id: occurrenceId,
|
|
437
486
|
documentId,
|
|
438
487
|
symbolId: declaration.symbolId,
|
|
439
488
|
role: declaration.role ?? 'definition',
|
|
@@ -452,9 +501,20 @@ function createLightweightNativeImport(input) {
|
|
|
452
501
|
subjectId: declaration.symbolId,
|
|
453
502
|
value: declaration.languageKind
|
|
454
503
|
});
|
|
504
|
+
mappings.push({
|
|
505
|
+
id: `map_${idFragment(declaration.nodeId)}`,
|
|
506
|
+
nativeAstNodeId: declaration.nodeId,
|
|
507
|
+
semanticSymbolId: declaration.symbolId,
|
|
508
|
+
semanticOccurrenceId: occurrenceId,
|
|
509
|
+
sourceSpan: declaration.span,
|
|
510
|
+
evidenceIds: [evidenceId],
|
|
511
|
+
lossIds: declaration.loss ? [declaration.loss.id] : [],
|
|
512
|
+
precision: 'declaration'
|
|
513
|
+
});
|
|
455
514
|
}
|
|
456
515
|
if (declaration.loss) losses.push(declaration.loss);
|
|
457
516
|
}
|
|
517
|
+
losses.push(...lightweightCoverageLosses(input, declarations));
|
|
458
518
|
|
|
459
519
|
const semanticIndex = createSemanticIndexRecord({
|
|
460
520
|
id: `index_${idFragment(input.sourcePath ?? input.language)}`,
|
|
@@ -469,7 +529,7 @@ function createLightweightNativeImport(input) {
|
|
|
469
529
|
relations,
|
|
470
530
|
facts,
|
|
471
531
|
evidence: [{
|
|
472
|
-
id:
|
|
532
|
+
id: evidenceId,
|
|
473
533
|
kind: 'import',
|
|
474
534
|
status: 'passed',
|
|
475
535
|
path: input.sourcePath,
|
|
@@ -489,6 +549,7 @@ function createLightweightNativeImport(input) {
|
|
|
489
549
|
nodes,
|
|
490
550
|
losses,
|
|
491
551
|
semanticIndex,
|
|
552
|
+
mappings,
|
|
492
553
|
metadata: { parser, scanKind: 'lightweight-declaration-scan', declarationCount: declarations.length }
|
|
493
554
|
};
|
|
494
555
|
}
|
|
@@ -499,6 +560,12 @@ function scanNativeDeclarations(input) {
|
|
|
499
560
|
if (language === 'python') return scanPython(input);
|
|
500
561
|
if (language === 'rust') return scanRust(input);
|
|
501
562
|
if (language === 'c' || language === 'cpp' || language === 'c++') return scanCLike(input);
|
|
563
|
+
if (language === 'java') return scanJava(input);
|
|
564
|
+
if (language === 'go') return scanGo(input);
|
|
565
|
+
if (language === 'swift') return scanSwift(input);
|
|
566
|
+
if (language === 'csharp' || language === 'c#') return scanCSharp(input);
|
|
567
|
+
if (language === 'php') return scanPhp(input);
|
|
568
|
+
if (language === 'ruby' || language === 'rb') return scanRuby(input);
|
|
502
569
|
return scanGenericDeclarations(input);
|
|
503
570
|
}
|
|
504
571
|
|
|
@@ -588,12 +655,155 @@ function scanCLike(input) {
|
|
|
588
655
|
return declarations;
|
|
589
656
|
}
|
|
590
657
|
|
|
658
|
+
function scanJava(input) {
|
|
659
|
+
const declarations = [];
|
|
660
|
+
for (const { line, number } of sourceLines(input.sourceText)) {
|
|
661
|
+
const trimmed = line.trim();
|
|
662
|
+
let match;
|
|
663
|
+
if ((match = trimmed.match(/^package\s+([A-Za-z_][\w.]*);/))) {
|
|
664
|
+
declarations.push(nativeDeclaration(input, number, 'PackageDeclaration', 'package', match[1], {}, false));
|
|
665
|
+
} else if ((match = trimmed.match(/^import\s+(?:static\s+)?([A-Za-z_][\w.*]*);/))) {
|
|
666
|
+
declarations.push(nativeImportDeclaration(input, number, match[1], 'ImportDeclaration', 'package'));
|
|
667
|
+
} else if ((match = trimmed.match(/^(?:(?:public|protected|private|abstract|final|static|sealed|non-sealed)\s+)*(class|interface|enum|record|@interface)\s+([A-Za-z_$][\w$]*)/))) {
|
|
668
|
+
const kind = match[1] === '@interface' ? 'AnnotationDeclaration' : `${upperFirst(match[1])}Declaration`;
|
|
669
|
+
declarations.push(nativeDeclaration(input, number, kind, javaSymbolKind(match[1]), match[2], {}, trimmed.includes('{')));
|
|
670
|
+
} else if ((match = trimmed.match(/^(?:(?:public|protected|private|abstract|final|static|synchronized|native)\s+)*(?:<[^>]+>\s+)?[A-Za-z_$][\w$<>\[\].?,\s]*\s+([A-Za-z_$][\w$]*)\s*\(([^)]*)\)\s*(?:throws\s+[^{]+)?(?:\{|;)?$/))) {
|
|
671
|
+
declarations.push(nativeDeclaration(input, number, 'MethodDeclaration', 'method', match[1], { parameters: splitParameters(match[2]) }, trimmed.includes('{')));
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
return declarations;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
function scanGo(input) {
|
|
678
|
+
const declarations = [];
|
|
679
|
+
for (const { line, number } of sourceLines(input.sourceText)) {
|
|
680
|
+
const trimmed = line.trim();
|
|
681
|
+
let match;
|
|
682
|
+
if ((match = trimmed.match(/^package\s+([A-Za-z_]\w*)/))) {
|
|
683
|
+
declarations.push(nativeDeclaration(input, number, 'PackageClause', 'package', match[1], {}, false));
|
|
684
|
+
} else if ((match = trimmed.match(/^import\s+(?:[A-Za-z_]\w*\s+)?["']([^"']+)["']/))) {
|
|
685
|
+
declarations.push(nativeImportDeclaration(input, number, match[1], 'ImportSpec', 'package'));
|
|
686
|
+
} else if ((match = trimmed.match(/^type\s+([A-Za-z_]\w*)\s+(struct|interface)\b/))) {
|
|
687
|
+
declarations.push(nativeDeclaration(input, number, match[2] === 'struct' ? 'TypeSpecStruct' : 'TypeSpecInterface', 'type', match[1], {}, trimmed.includes('{')));
|
|
688
|
+
} else if ((match = trimmed.match(/^func\s+(?:\([^)]*\)\s*)?([A-Za-z_]\w*)\s*\(([^)]*)\)/))) {
|
|
689
|
+
declarations.push(nativeDeclaration(input, number, 'FuncDecl', 'function', match[1], { parameters: splitParameters(match[2]) }, trimmed.includes('{')));
|
|
690
|
+
} else if ((match = trimmed.match(/^var\s+([A-Za-z_]\w*)\b/))) {
|
|
691
|
+
declarations.push(nativeDeclaration(input, number, 'VarDecl', 'variable', match[1], {}, false));
|
|
692
|
+
} else if ((match = trimmed.match(/^const\s+([A-Za-z_]\w*)\b/))) {
|
|
693
|
+
declarations.push(nativeDeclaration(input, number, 'ConstDecl', 'constant', match[1], {}, false));
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
return declarations;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
function scanSwift(input) {
|
|
700
|
+
const declarations = [];
|
|
701
|
+
for (const { line, number } of sourceLines(input.sourceText)) {
|
|
702
|
+
const trimmed = line.trim();
|
|
703
|
+
let match;
|
|
704
|
+
if ((match = trimmed.match(/^import\s+([A-Za-z_]\w*)/))) {
|
|
705
|
+
declarations.push(nativeImportDeclaration(input, number, match[1], 'ImportDecl', 'module'));
|
|
706
|
+
} else if ((match = trimmed.match(/^(?:(?:public|private|fileprivate|internal|open|final)\s+)*(struct|class|enum|protocol|actor|extension)\s+([A-Za-z_]\w*)/))) {
|
|
707
|
+
declarations.push(nativeDeclaration(input, number, `${upperFirst(match[1])}Decl`, swiftSymbolKind(match[1]), match[2], {}, trimmed.includes('{')));
|
|
708
|
+
} else if ((match = trimmed.match(/^(?:(?:public|private|fileprivate|internal|open|static|class|mutating)\s+)*func\s+([A-Za-z_]\w*)\s*\(([^)]*)\)/))) {
|
|
709
|
+
declarations.push(nativeDeclaration(input, number, 'FunctionDecl', 'function', match[1], { parameters: splitParameters(match[2]) }, trimmed.includes('{')));
|
|
710
|
+
} else if ((match = trimmed.match(/^(?:let|var)\s+([A-Za-z_]\w*)\b/))) {
|
|
711
|
+
declarations.push(nativeDeclaration(input, number, 'ValueBindingDecl', 'variable', match[1], {}, false));
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
return declarations;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
function scanCSharp(input) {
|
|
718
|
+
const declarations = [];
|
|
719
|
+
for (const { line, number } of sourceLines(input.sourceText)) {
|
|
720
|
+
const trimmed = line.trim();
|
|
721
|
+
let match;
|
|
722
|
+
if ((match = trimmed.match(/^using\s+(?:static\s+)?([A-Za-z_][\w.]*)\s*;/))) {
|
|
723
|
+
declarations.push(nativeImportDeclaration(input, number, match[1], 'UsingDirective', 'namespace'));
|
|
724
|
+
} else if ((match = trimmed.match(/^namespace\s+([A-Za-z_][\w.]*)/))) {
|
|
725
|
+
declarations.push(nativeDeclaration(input, number, 'NamespaceDeclaration', 'namespace', match[1], {}, trimmed.includes('{')));
|
|
726
|
+
} else if ((match = trimmed.match(/^(?:(?:public|protected|private|internal|abstract|sealed|static|partial|readonly)\s+)*(class|interface|struct|enum|record)\s+([A-Za-z_]\w*)/))) {
|
|
727
|
+
declarations.push(nativeDeclaration(input, number, `${upperFirst(match[1])}Declaration`, csharpSymbolKind(match[1]), match[2], {}, trimmed.includes('{')));
|
|
728
|
+
} else if ((match = trimmed.match(/^(?:(?:public|protected|private|internal|static|virtual|override|async|partial|sealed|abstract|extern)\s+)*[A-Za-z_][\w<>\[\].?,\s]*\s+([A-Za-z_]\w*)\s*\(([^)]*)\)\s*(?:\{|;)?$/))) {
|
|
729
|
+
declarations.push(nativeDeclaration(input, number, 'MethodDeclaration', 'method', match[1], { parameters: splitParameters(match[2]) }, trimmed.includes('{')));
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
return declarations;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
function scanPhp(input) {
|
|
736
|
+
const declarations = [];
|
|
737
|
+
for (const { line, number } of sourceLines(input.sourceText)) {
|
|
738
|
+
const trimmed = line.trim().replace(/^<\?php\s*/, '');
|
|
739
|
+
let match;
|
|
740
|
+
if ((match = trimmed.match(/^namespace\s+([A-Za-z_][\w\\]*)\s*;/))) {
|
|
741
|
+
declarations.push(nativeDeclaration(input, number, 'NamespaceDefinition', 'namespace', match[1], {}, false));
|
|
742
|
+
} else if ((match = trimmed.match(/^use\s+([A-Za-z_][\w\\]*)(?:\s+as\s+([A-Za-z_]\w*))?\s*;/))) {
|
|
743
|
+
declarations.push(nativeImportDeclaration(input, number, match[1], 'UseDeclaration', 'namespace'));
|
|
744
|
+
} else if ((match = trimmed.match(/^(?:(?:abstract|final|readonly)\s+)*(class|interface|trait|enum)\s+([A-Za-z_]\w*)/))) {
|
|
745
|
+
declarations.push(nativeDeclaration(input, number, `${upperFirst(match[1])}Declaration`, phpSymbolKind(match[1]), match[2], {}, trimmed.includes('{')));
|
|
746
|
+
} else if ((match = trimmed.match(/^(?:(?:public|protected|private|static|final|abstract)\s+)*function\s+&?\s*([A-Za-z_]\w*)\s*\(([^)]*)\)/))) {
|
|
747
|
+
declarations.push(nativeDeclaration(input, number, 'FunctionDeclaration', 'function', match[1], { parameters: splitParameters(match[2]) }, trimmed.includes('{')));
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
return declarations;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
function scanRuby(input) {
|
|
754
|
+
const declarations = [];
|
|
755
|
+
for (const { line, number } of sourceLines(input.sourceText)) {
|
|
756
|
+
const trimmed = line.trim();
|
|
757
|
+
let match;
|
|
758
|
+
if ((match = trimmed.match(/^(?:require|load)\s+['"]([^'"]+)['"]/))) {
|
|
759
|
+
declarations.push(nativeImportDeclaration(input, number, match[1], 'Require', 'module'));
|
|
760
|
+
} else if ((match = trimmed.match(/^module\s+([A-Za-z_]\w*(?:::[A-Za-z_]\w*)*)/))) {
|
|
761
|
+
declarations.push(nativeDeclaration(input, number, 'Module', 'module', match[1], {}, true));
|
|
762
|
+
} else if ((match = trimmed.match(/^class\s+([A-Za-z_]\w*(?:::[A-Za-z_]\w*)*)/))) {
|
|
763
|
+
declarations.push(nativeDeclaration(input, number, 'Class', 'class', match[1], {}, true));
|
|
764
|
+
} else if ((match = trimmed.match(/^def\s+(?:self\.)?([A-Za-z_]\w*[!?=]?)\s*(?:\(([^)]*)\)|([^#=]*))?/))) {
|
|
765
|
+
declarations.push(nativeDeclaration(input, number, 'Def', 'method', match[1], { parameters: splitParameters(match[2] ?? match[3]) }, true));
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
return declarations;
|
|
769
|
+
}
|
|
770
|
+
|
|
591
771
|
function scanGenericDeclarations(input) {
|
|
592
772
|
return sourceLines(input.sourceText)
|
|
593
773
|
.filter(({ line }) => /\b(function|class|struct|enum|trait|interface|def)\b/.test(line))
|
|
594
774
|
.map(({ line, number }) => nativeDeclaration(input, number, 'NativeDeclaration', 'variable', idFragment(line.trim()).slice(0, 40), { source: line.trim() }, true));
|
|
595
775
|
}
|
|
596
776
|
|
|
777
|
+
function upperFirst(value) {
|
|
778
|
+
return String(value).charAt(0).toUpperCase() + String(value).slice(1);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
function javaSymbolKind(kind) {
|
|
782
|
+
if (kind === 'interface' || kind === '@interface') return 'interface';
|
|
783
|
+
if (kind === 'enum' || kind === 'record') return 'type';
|
|
784
|
+
return 'class';
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
function swiftSymbolKind(kind) {
|
|
788
|
+
if (kind === 'protocol') return 'protocol';
|
|
789
|
+
if (kind === 'extension') return 'implementation';
|
|
790
|
+
if (kind === 'struct' || kind === 'enum' || kind === 'actor') return 'type';
|
|
791
|
+
return 'class';
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
function csharpSymbolKind(kind) {
|
|
795
|
+
if (kind === 'interface') return 'interface';
|
|
796
|
+
if (kind === 'struct' || kind === 'enum' || kind === 'record') return 'type';
|
|
797
|
+
return 'class';
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
function phpSymbolKind(kind) {
|
|
801
|
+
if (kind === 'interface') return 'interface';
|
|
802
|
+
if (kind === 'trait') return 'trait';
|
|
803
|
+
if (kind === 'enum') return 'type';
|
|
804
|
+
return 'class';
|
|
805
|
+
}
|
|
806
|
+
|
|
597
807
|
function nativeDeclaration(input, lineNumber, languageKind, symbolKind, name, fields = {}, hasBody = false) {
|
|
598
808
|
const nodeId = `native_${idFragment(languageKind)}_${lineNumber}_${idFragment(name)}`;
|
|
599
809
|
return {
|
|
@@ -666,6 +876,54 @@ function opaqueBodyLoss(input, lineNumber, nodeId, name) {
|
|
|
666
876
|
};
|
|
667
877
|
}
|
|
668
878
|
|
|
879
|
+
function lightweightCoverageLosses(input, declarations) {
|
|
880
|
+
const id = idFragment(input.sourcePath ?? input.language);
|
|
881
|
+
const span = declarations[0]?.span ?? {
|
|
882
|
+
sourceId: input.sourceHash,
|
|
883
|
+
path: input.sourcePath,
|
|
884
|
+
startLine: 1,
|
|
885
|
+
startColumn: 1
|
|
886
|
+
};
|
|
887
|
+
return [
|
|
888
|
+
{
|
|
889
|
+
id: `loss_${id}_declaration_only_coverage`,
|
|
890
|
+
severity: 'info',
|
|
891
|
+
phase: 'read',
|
|
892
|
+
sourceFormat: input.language,
|
|
893
|
+
kind: 'declarationOnlyCoverage',
|
|
894
|
+
message: 'Lightweight importer scanned declarations and imports only; expressions, control flow, and full type checking were not evaluated.',
|
|
895
|
+
span
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
id: `loss_${id}_partial_semantic_index`,
|
|
899
|
+
severity: 'info',
|
|
900
|
+
phase: 'index',
|
|
901
|
+
sourceFormat: input.language,
|
|
902
|
+
kind: 'partialSemanticIndex',
|
|
903
|
+
message: 'Semantic index contains lightweight declaration/import facts only; references, calls, resolved types, and cross-file links may be missing.',
|
|
904
|
+
span
|
|
905
|
+
},
|
|
906
|
+
{
|
|
907
|
+
id: `loss_${id}_source_map_approximation`,
|
|
908
|
+
severity: 'info',
|
|
909
|
+
phase: 'map',
|
|
910
|
+
sourceFormat: input.language,
|
|
911
|
+
kind: 'sourceMapApproximation',
|
|
912
|
+
message: 'Source-map spans are declaration or line estimates; exact token ranges require a parser adapter.',
|
|
913
|
+
span
|
|
914
|
+
},
|
|
915
|
+
{
|
|
916
|
+
id: `loss_${id}_source_preservation`,
|
|
917
|
+
severity: 'warning',
|
|
918
|
+
phase: 'read',
|
|
919
|
+
sourceFormat: input.language,
|
|
920
|
+
kind: 'sourcePreservation',
|
|
921
|
+
message: 'Comments, whitespace, token order, directives, and formatting are not preserved by the lightweight importer.',
|
|
922
|
+
span
|
|
923
|
+
}
|
|
924
|
+
];
|
|
925
|
+
}
|
|
926
|
+
|
|
669
927
|
function sourceLines(sourceText) {
|
|
670
928
|
return String(sourceText ?? '').split(/\r?\n/).map((line, index) => ({ line, number: index + 1 }));
|
|
671
929
|
}
|
|
@@ -687,11 +945,95 @@ function splitParameters(raw) {
|
|
|
687
945
|
.filter(Boolean);
|
|
688
946
|
}
|
|
689
947
|
|
|
948
|
+
function inferSourceMapMappings(input) {
|
|
949
|
+
const semanticIndex = input.semanticIndex;
|
|
950
|
+
const nativeAst = input.nativeAst;
|
|
951
|
+
const nativeSource = input.nativeSource;
|
|
952
|
+
const evidenceIds = [
|
|
953
|
+
...(semanticIndex?.evidence ?? []).map((record) => record.id),
|
|
954
|
+
...(input.evidence ?? []).map((record) => record.id)
|
|
955
|
+
];
|
|
956
|
+
const symbolsById = new Map((semanticIndex?.symbols ?? []).map((symbol) => [symbol.id, symbol]));
|
|
957
|
+
|
|
958
|
+
if (semanticIndex?.occurrences?.length) {
|
|
959
|
+
return semanticIndex.occurrences
|
|
960
|
+
.filter((occurrence) => occurrence.nativeAstNodeId || occurrence.span)
|
|
961
|
+
.map((occurrence) => {
|
|
962
|
+
const symbol = symbolsById.get(occurrence.symbolId);
|
|
963
|
+
const nativeNode = occurrence.nativeAstNodeId ? nativeAst?.nodes?.[occurrence.nativeAstNodeId] : undefined;
|
|
964
|
+
return {
|
|
965
|
+
id: `map_${idFragment(occurrence.id)}`,
|
|
966
|
+
nativeSourceId: nativeSource?.id,
|
|
967
|
+
nativeAstNodeId: occurrence.nativeAstNodeId,
|
|
968
|
+
semanticSymbolId: occurrence.symbolId,
|
|
969
|
+
semanticOccurrenceId: occurrence.id,
|
|
970
|
+
semanticNodeId: occurrence.semanticNodeId ?? symbol?.semanticNodeId,
|
|
971
|
+
sourceSpan: occurrence.span ?? nativeNode?.span,
|
|
972
|
+
evidenceIds,
|
|
973
|
+
lossIds: lossIdsForNativeNode(input.losses ?? nativeAst?.losses ?? [], occurrence.nativeAstNodeId),
|
|
974
|
+
precision: occurrence.span || nativeNode?.span ? 'declaration' : 'unknown'
|
|
975
|
+
};
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
return Object.values(nativeAst?.nodes ?? {})
|
|
980
|
+
.filter((node) => node.span)
|
|
981
|
+
.map((node) => ({
|
|
982
|
+
id: `map_${idFragment(node.id)}`,
|
|
983
|
+
nativeSourceId: nativeSource?.id,
|
|
984
|
+
nativeAstNodeId: node.id,
|
|
985
|
+
sourceSpan: node.span,
|
|
986
|
+
evidenceIds,
|
|
987
|
+
lossIds: lossIdsForNativeNode(input.losses ?? nativeAst?.losses ?? [], node.id),
|
|
988
|
+
precision: 'line'
|
|
989
|
+
}));
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
function normalizeSourceMapMappings(mappings, context) {
|
|
993
|
+
const semanticIndex = context.semanticIndex;
|
|
994
|
+
const nativeAst = context.nativeAst;
|
|
995
|
+
const nativeSource = context.nativeSource;
|
|
996
|
+
const symbolsById = new Map((semanticIndex?.symbols ?? []).map((symbol) => [symbol.id, symbol]));
|
|
997
|
+
const occurrencesById = new Map((semanticIndex?.occurrences ?? []).map((occurrence) => [occurrence.id, occurrence]));
|
|
998
|
+
const evidenceIds = (context.evidence ?? []).map((record) => record.id);
|
|
999
|
+
return (mappings ?? [])
|
|
1000
|
+
.filter((mapping) => mapping && typeof mapping === 'object')
|
|
1001
|
+
.map((mapping, index) => {
|
|
1002
|
+
const occurrence = mapping.semanticOccurrenceId ? occurrencesById.get(mapping.semanticOccurrenceId) : undefined;
|
|
1003
|
+
const symbol = mapping.semanticSymbolId ? symbolsById.get(mapping.semanticSymbolId) : occurrence ? symbolsById.get(occurrence.symbolId) : undefined;
|
|
1004
|
+
const nativeAstNodeId = mapping.nativeAstNodeId ?? occurrence?.nativeAstNodeId;
|
|
1005
|
+
const nativeNode = nativeAstNodeId ? nativeAst?.nodes?.[nativeAstNodeId] : undefined;
|
|
1006
|
+
const sourceSpan = mapping.sourceSpan ?? occurrence?.span ?? nativeNode?.span;
|
|
1007
|
+
return {
|
|
1008
|
+
...mapping,
|
|
1009
|
+
id: mapping.id ?? `map_${idFragment(nativeAstNodeId ?? mapping.semanticSymbolId ?? mapping.semanticNodeId ?? index + 1)}`,
|
|
1010
|
+
nativeSourceId: mapping.nativeSourceId ?? nativeSource?.id,
|
|
1011
|
+
nativeAstNodeId,
|
|
1012
|
+
semanticSymbolId: mapping.semanticSymbolId ?? occurrence?.symbolId,
|
|
1013
|
+
semanticOccurrenceId: mapping.semanticOccurrenceId ?? occurrence?.id,
|
|
1014
|
+
semanticNodeId: mapping.semanticNodeId ?? occurrence?.semanticNodeId ?? symbol?.semanticNodeId,
|
|
1015
|
+
sourceSpan,
|
|
1016
|
+
target: mapping.target ?? context.target,
|
|
1017
|
+
evidenceIds: mapping.evidenceIds ?? evidenceIds,
|
|
1018
|
+
lossIds: mapping.lossIds ?? lossIdsForNativeNode(context.losses ?? nativeAst?.losses ?? [], nativeAstNodeId),
|
|
1019
|
+
precision: mapping.precision ?? (sourceSpan ? 'declaration' : 'unknown')
|
|
1020
|
+
};
|
|
1021
|
+
});
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
function lossIdsForNativeNode(losses, nativeAstNodeId) {
|
|
1025
|
+
if (!nativeAstNodeId) return [];
|
|
1026
|
+
return (losses ?? [])
|
|
1027
|
+
.filter((loss) => loss.nodeId === nativeAstNodeId)
|
|
1028
|
+
.map((loss) => loss.id);
|
|
1029
|
+
}
|
|
1030
|
+
|
|
690
1031
|
export function createUniversalAstFromDocument(document, input = {}) {
|
|
691
1032
|
return createUniversalAstEnvelope({
|
|
692
1033
|
id: input.id ?? `universal_ast_${idFragment(document.id)}`,
|
|
693
1034
|
document,
|
|
694
1035
|
semanticIndex: input.semanticIndex,
|
|
1036
|
+
sourceMaps: input.sourceMaps ?? [],
|
|
695
1037
|
evidence: input.evidence ?? [],
|
|
696
1038
|
metadata: input.metadata
|
|
697
1039
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shapeshift-labs/frontier-lang-compiler",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.7",
|
|
4
4
|
"description": "Compiler facade for Frontier Lang source documents and language projection adapters.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -56,14 +56,14 @@
|
|
|
56
56
|
"access": "public"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@shapeshift-labs/frontier-lang-c": "0.2.
|
|
60
|
-
"@shapeshift-labs/frontier-lang-checker": "0.3.
|
|
61
|
-
"@shapeshift-labs/frontier-lang-javascript": "0.2.
|
|
62
|
-
"@shapeshift-labs/frontier-lang-kernel": "0.3.
|
|
63
|
-
"@shapeshift-labs/frontier-lang-parser": "0.3.
|
|
64
|
-
"@shapeshift-labs/frontier-lang-python": "0.2.
|
|
65
|
-
"@shapeshift-labs/frontier-lang-rust": "0.2.
|
|
66
|
-
"@shapeshift-labs/frontier-lang-typescript": "0.3.
|
|
59
|
+
"@shapeshift-labs/frontier-lang-c": "0.2.3",
|
|
60
|
+
"@shapeshift-labs/frontier-lang-checker": "0.3.3",
|
|
61
|
+
"@shapeshift-labs/frontier-lang-javascript": "0.2.3",
|
|
62
|
+
"@shapeshift-labs/frontier-lang-kernel": "0.3.3",
|
|
63
|
+
"@shapeshift-labs/frontier-lang-parser": "0.3.3",
|
|
64
|
+
"@shapeshift-labs/frontier-lang-python": "0.2.3",
|
|
65
|
+
"@shapeshift-labs/frontier-lang-rust": "0.2.3",
|
|
66
|
+
"@shapeshift-labs/frontier-lang-typescript": "0.3.3"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
69
|
"typescript": "^5.9.3"
|