@shapeshift-labs/frontier-lang-compiler 0.2.32 → 0.2.33
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 +12 -1
- package/bench/smoke.mjs +35 -2
- package/dist/index.d.ts +40 -0
- package/dist/index.js +801 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -336,8 +336,10 @@ import {
|
|
|
336
336
|
createCSharpRoslynNativeImporterAdapter,
|
|
337
337
|
createGoAstNativeImporterAdapter,
|
|
338
338
|
createJavaAstNativeImporterAdapter,
|
|
339
|
+
createKotlinPsiNativeImporterAdapter,
|
|
339
340
|
createPythonAstNativeImporterAdapter,
|
|
340
341
|
createRustSynNativeImporterAdapter,
|
|
342
|
+
createSwiftSyntaxNativeImporterAdapter,
|
|
341
343
|
importNativeProject,
|
|
342
344
|
runNativeImporterAdapter
|
|
343
345
|
} from '@shapeshift-labs/frontier-lang-compiler';
|
|
@@ -366,6 +368,11 @@ const javaAstAdapter = createJavaAstNativeImporterAdapter({
|
|
|
366
368
|
javaVersion: '21',
|
|
367
369
|
sourceLevel: '21'
|
|
368
370
|
});
|
|
371
|
+
const kotlinPsiAdapter = createKotlinPsiNativeImporterAdapter({
|
|
372
|
+
parserModule: hostKotlinPsiParser,
|
|
373
|
+
kotlinVersion: '2.1',
|
|
374
|
+
analysisApiEvidence: { hash: kotlinAnalysisApiIndexHash }
|
|
375
|
+
});
|
|
369
376
|
const csharpRoslynAdapter = createCSharpRoslynNativeImporterAdapter({
|
|
370
377
|
parserModule: hostRoslynParser,
|
|
371
378
|
languageVersion: '12',
|
|
@@ -384,7 +391,7 @@ const imported = await runNativeImporterAdapter(babelAdapter, {
|
|
|
384
391
|
|
|
385
392
|
const project = await importNativeProject({
|
|
386
393
|
projectRoot: 'src',
|
|
387
|
-
adapters: [babelAdapter, pythonAstAdapter, rustSynAdapter, clangAstAdapter, goAstAdapter, javaAstAdapter, csharpRoslynAdapter, swiftSyntaxAdapter],
|
|
394
|
+
adapters: [babelAdapter, pythonAstAdapter, rustSynAdapter, clangAstAdapter, goAstAdapter, javaAstAdapter, kotlinPsiAdapter, csharpRoslynAdapter, swiftSyntaxAdapter],
|
|
388
395
|
sources: [
|
|
389
396
|
{ language: 'typescript', adapter: babelAdapter.id, sourcePath: 'src/todo.ts', sourceText },
|
|
390
397
|
{ language: 'python', adapter: pythonAstAdapter.id, sourcePath: 'tools/todo.py', sourceText: pythonSource },
|
|
@@ -392,6 +399,7 @@ const project = await importNativeProject({
|
|
|
392
399
|
{ language: 'c', adapter: clangAstAdapter.id, sourcePath: 'native/todo.c', sourceText: cSource },
|
|
393
400
|
{ language: 'go', adapter: goAstAdapter.id, sourcePath: 'cmd/todo/main.go', sourceText: goSource },
|
|
394
401
|
{ language: 'java', adapter: javaAstAdapter.id, sourcePath: 'src/main/java/Todo.java', sourceText: javaSource },
|
|
402
|
+
{ language: 'kotlin', adapter: kotlinPsiAdapter.id, sourcePath: 'src/main/kotlin/Todo.kt', sourceText: kotlinSource },
|
|
395
403
|
{ language: 'csharp', adapter: csharpRoslynAdapter.id, sourcePath: 'src/Todo.cs', sourceText: csharpSource },
|
|
396
404
|
{ language: 'swift', adapter: swiftSyntaxAdapter.id, sourcePath: 'Sources/Todo.swift', sourceText: swiftSource }
|
|
397
405
|
]
|
|
@@ -417,6 +425,7 @@ The built-in adapter factories are dependency-light wrappers for caller-owned pa
|
|
|
417
425
|
- `createClangAstNativeImporterAdapter`
|
|
418
426
|
- `createGoAstNativeImporterAdapter`
|
|
419
427
|
- `createJavaAstNativeImporterAdapter`
|
|
428
|
+
- `createKotlinPsiNativeImporterAdapter`
|
|
420
429
|
- `createCSharpRoslynNativeImporterAdapter`
|
|
421
430
|
- `createSwiftSyntaxNativeImporterAdapter`
|
|
422
431
|
- `createTreeSitterNativeImporterAdapter`
|
|
@@ -466,6 +475,7 @@ The published Frontier package family is generated from one shared package catal
|
|
|
466
475
|
- [`@shapeshift-labs/frontier-lang-rust`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-rust): Rust projection adapter for Frontier Lang semantic documents, including structs, aliases, and action stubs.
|
|
467
476
|
- [`@shapeshift-labs/frontier-lang-python`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-python): Python projection adapter for Frontier Lang semantic documents, including dataclasses, typed patch records, and action stubs.
|
|
468
477
|
- [`@shapeshift-labs/frontier-lang-c`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-c): C header projection adapter for Frontier Lang semantic documents, including structs and action prototypes.
|
|
478
|
+
- [`@shapeshift-labs/frontier-lang-swift`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-swift): Swift source-language importer package for Frontier Lang semantic documents, including package-level metadata, SwiftSyntax adapter helpers, native import results, and semantic sidecar generation for SwiftSyntax/SwiftParser-shaped syntax trees.
|
|
469
479
|
- [`@shapeshift-labs/frontier-lang-java`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-java): Java source-language importer package for Frontier Lang semantic documents, including package-level metadata, Java AST adapter helpers, native import results, and semantic sidecar generation for javac/JDT/JavaParser-shaped ASTs.
|
|
470
480
|
- [`@shapeshift-labs/frontier-lang-go`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-go): Go source-language importer package for Frontier Lang semantic documents, including package-level metadata, Go AST adapter helpers, native import results, and semantic sidecar generation for go/ast File or Package trees.
|
|
471
481
|
- [`@shapeshift-labs/frontier-lang-csharp`](https://www.npmjs.com/package/@shapeshift-labs/frontier-lang-csharp): C# Roslyn source-language importer package for Frontier Lang semantic documents, including package-level metadata, Roslyn adapter helpers, native import results, and semantic sidecar generation for SyntaxTree/SyntaxNode-shaped ASTs.
|
|
@@ -557,6 +567,7 @@ Package source repositories:
|
|
|
557
567
|
- [`siliconjungle/-shapeshift-labs-frontier-lang-python`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-python)
|
|
558
568
|
- [`siliconjungle/-shapeshift-labs-frontier-lang-c`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-c)
|
|
559
569
|
- [`siliconjungle/-shapeshift-labs-frontier-lang-compiler`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-compiler)
|
|
570
|
+
- [`siliconjungle/-shapeshift-labs-frontier-lang-swift`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-swift)
|
|
560
571
|
- [`siliconjungle/-shapeshift-labs-frontier-lang-java`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-java)
|
|
561
572
|
- [`siliconjungle/-shapeshift-labs-frontier-lang-go`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-go)
|
|
562
573
|
- [`siliconjungle/-shapeshift-labs-frontier-lang-csharp`](https://github.com/siliconjungle/-shapeshift-labs-frontier-lang-csharp)
|
package/bench/smoke.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
createEstreeNativeImporterAdapter,
|
|
8
8
|
createGoAstNativeImporterAdapter,
|
|
9
9
|
createJavaAstNativeImporterAdapter,
|
|
10
|
+
createKotlinPsiNativeImporterAdapter,
|
|
10
11
|
createNativeImportCoverageMatrix,
|
|
11
12
|
createNativeParserAstFormatMatrix,
|
|
12
13
|
createProjectionTargetLossMatrix,
|
|
@@ -48,6 +49,7 @@ const compileDurationMs = performance.now() - start;
|
|
|
48
49
|
|
|
49
50
|
const importStart = performance.now();
|
|
50
51
|
const estreeAdapter = createEstreeNativeImporterAdapter();
|
|
52
|
+
const kotlinPsiAdapter = createKotlinPsiNativeImporterAdapter();
|
|
51
53
|
let nativeSymbols = 0;
|
|
52
54
|
const nativeImportResults = [];
|
|
53
55
|
for (let index = 0; index < 150; index += 1) {
|
|
@@ -75,6 +77,37 @@ for (let index = 0; index < 150; index += 1) {
|
|
|
75
77
|
nativeSymbols += imported.semanticIndex?.symbols?.length ?? 0;
|
|
76
78
|
nativeImportResults.push(imported);
|
|
77
79
|
}
|
|
80
|
+
for (let index = 0; index < 50; index += 1) {
|
|
81
|
+
const imported = await runNativeImporterAdapter(kotlinPsiAdapter, {
|
|
82
|
+
sourcePath: `src/bench-${index}.kt`,
|
|
83
|
+
sourceText: `package bench\nclass BenchKotlin${index}(val title: String) { fun render${index}() = title }\n`,
|
|
84
|
+
adapterOptions: {
|
|
85
|
+
ast: {
|
|
86
|
+
kind: 'KtFile',
|
|
87
|
+
packageDirective: { kind: 'KtPackageDirective', fqName: 'bench' },
|
|
88
|
+
declarations: [{
|
|
89
|
+
kind: 'KtClass',
|
|
90
|
+
name: `BenchKotlin${index}`,
|
|
91
|
+
declarations: [{
|
|
92
|
+
kind: 'KtPrimaryConstructor',
|
|
93
|
+
parameters: [{
|
|
94
|
+
kind: 'KtParameter',
|
|
95
|
+
name: 'title',
|
|
96
|
+
typeReference: { text: 'String' },
|
|
97
|
+
valOrVarKeyword: 'val'
|
|
98
|
+
}]
|
|
99
|
+
}, {
|
|
100
|
+
kind: 'KtNamedFunction',
|
|
101
|
+
name: `render${index}`,
|
|
102
|
+
bodyExpression: { kind: 'KtBlockExpression' }
|
|
103
|
+
}]
|
|
104
|
+
}]
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
nativeSymbols += imported.semanticIndex?.symbols?.length ?? 0;
|
|
109
|
+
nativeImportResults.push(imported);
|
|
110
|
+
}
|
|
78
111
|
const importDurationMs = performance.now() - importStart;
|
|
79
112
|
|
|
80
113
|
const matrixStart = performance.now();
|
|
@@ -84,7 +117,7 @@ const matrixDurationMs = performance.now() - matrixStart;
|
|
|
84
117
|
const parserFormatMatrixStart = performance.now();
|
|
85
118
|
const parserFormatMatrix = createNativeParserAstFormatMatrix({
|
|
86
119
|
imports: nativeImportResults,
|
|
87
|
-
adapters: [estreeAdapter, createPythonAstNativeImporterAdapter(), createRustSynNativeImporterAdapter(), createClangAstNativeImporterAdapter(), createGoAstNativeImporterAdapter(), createJavaAstNativeImporterAdapter(), createCSharpRoslynNativeImporterAdapter(), createSwiftSyntaxNativeImporterAdapter()]
|
|
120
|
+
adapters: [estreeAdapter, createPythonAstNativeImporterAdapter(), createRustSynNativeImporterAdapter(), createClangAstNativeImporterAdapter(), createGoAstNativeImporterAdapter(), createJavaAstNativeImporterAdapter(), kotlinPsiAdapter, createCSharpRoslynNativeImporterAdapter(), createSwiftSyntaxNativeImporterAdapter()]
|
|
88
121
|
});
|
|
89
122
|
const parserFormatMatrixDurationMs = performance.now() - parserFormatMatrixStart;
|
|
90
123
|
|
|
@@ -233,7 +266,7 @@ console.log(JSON.stringify({
|
|
|
233
266
|
compiles: 250,
|
|
234
267
|
bytes,
|
|
235
268
|
compileDurationMs: Number(compileDurationMs.toFixed(2)),
|
|
236
|
-
nativeImports:
|
|
269
|
+
nativeImports: nativeImportResults.length,
|
|
237
270
|
nativeSymbols,
|
|
238
271
|
nativeImportDurationMs: Number(importDurationMs.toFixed(2)),
|
|
239
272
|
coverageMatrixLanguages: coverageMatrix.summary.languages,
|
package/dist/index.d.ts
CHANGED
|
@@ -1497,6 +1497,45 @@ export interface JavaAstNativeImporterAdapterOptions {
|
|
|
1497
1497
|
readonly maxNodes?: number;
|
|
1498
1498
|
}
|
|
1499
1499
|
|
|
1500
|
+
export interface KotlinPsiNativeImporterAdapterOptions {
|
|
1501
|
+
readonly id?: string;
|
|
1502
|
+
readonly language?: FrontierSourceLanguage;
|
|
1503
|
+
readonly parser?: string;
|
|
1504
|
+
readonly version?: string;
|
|
1505
|
+
readonly capabilities?: readonly string[];
|
|
1506
|
+
readonly coverage?: NativeImporterAdapterCoverageInput;
|
|
1507
|
+
readonly supportedExtensions?: readonly string[];
|
|
1508
|
+
readonly diagnostics?: readonly NativeImporterAdapterDiagnostic[];
|
|
1509
|
+
readonly ast?: unknown;
|
|
1510
|
+
readonly nativeAst?: unknown;
|
|
1511
|
+
readonly ktFile?: unknown;
|
|
1512
|
+
readonly file?: unknown;
|
|
1513
|
+
readonly sourceFile?: unknown;
|
|
1514
|
+
readonly root?: unknown;
|
|
1515
|
+
readonly parse?: (sourceText: string, options: Record<string, unknown>) => unknown;
|
|
1516
|
+
readonly parserModule?: { readonly parse: (sourceText: string, options: Record<string, unknown>) => unknown };
|
|
1517
|
+
readonly kotlinPsi?: { readonly parse: (sourceText: string, options: Record<string, unknown>) => unknown };
|
|
1518
|
+
readonly kotlinCompiler?: { readonly parse: (sourceText: string, options: Record<string, unknown>) => unknown };
|
|
1519
|
+
readonly intellijPsi?: { readonly parse: (sourceText: string, options: Record<string, unknown>) => unknown };
|
|
1520
|
+
readonly parserOptions?: Record<string, unknown>;
|
|
1521
|
+
readonly kotlinVersion?: string;
|
|
1522
|
+
readonly languageVersion?: string;
|
|
1523
|
+
readonly apiVersion?: string;
|
|
1524
|
+
readonly script?: boolean;
|
|
1525
|
+
readonly generated?: boolean;
|
|
1526
|
+
readonly analysisApiEvidence?: unknown;
|
|
1527
|
+
readonly firEvidence?: unknown;
|
|
1528
|
+
readonly compilerPluginEvidence?: unknown;
|
|
1529
|
+
readonly kspEvidence?: unknown;
|
|
1530
|
+
readonly kaptEvidence?: unknown;
|
|
1531
|
+
readonly multiplatformEvidence?: unknown;
|
|
1532
|
+
readonly buildVariantEvidence?: unknown;
|
|
1533
|
+
readonly positionResolver?: (position: unknown) => unknown;
|
|
1534
|
+
readonly lineMap?: unknown;
|
|
1535
|
+
readonly includeAnnotations?: boolean;
|
|
1536
|
+
readonly maxNodes?: number;
|
|
1537
|
+
}
|
|
1538
|
+
|
|
1500
1539
|
export interface CSharpRoslynNativeImporterAdapterOptions {
|
|
1501
1540
|
readonly id?: string;
|
|
1502
1541
|
readonly language?: FrontierSourceLanguage;
|
|
@@ -1938,6 +1977,7 @@ export declare function createRustSynNativeImporterAdapter(options?: RustSynNati
|
|
|
1938
1977
|
export declare function createClangAstNativeImporterAdapter(options?: ClangAstNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1939
1978
|
export declare function createGoAstNativeImporterAdapter(options?: GoAstNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1940
1979
|
export declare function createJavaAstNativeImporterAdapter(options?: JavaAstNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1980
|
+
export declare function createKotlinPsiNativeImporterAdapter(options?: KotlinPsiNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1941
1981
|
export declare function createCSharpRoslynNativeImporterAdapter(options?: CSharpRoslynNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1942
1982
|
export declare function createSwiftSyntaxNativeImporterAdapter(options?: SwiftSyntaxNativeImporterAdapterOptions): NativeImporterAdapter;
|
|
1943
1983
|
export declare function createTreeSitterNativeImporterAdapter(options?: TreeSitterNativeImporterAdapterOptions): NativeImporterAdapter;
|
package/dist/index.js
CHANGED
|
@@ -439,6 +439,18 @@ export const NativeParserAstFormatProfiles = Object.freeze([
|
|
|
439
439
|
supportsErrorRecovery: true,
|
|
440
440
|
notes: ['Java compiler/parser ASTs expose package/import/type/member declarations and source ranges; classpath/module-path, bindings, annotation processors, generated sources, Lombok expansion, comments/trivia, and control-flow evidence remain host-owned.']
|
|
441
441
|
}),
|
|
442
|
+
nativeParserAstFormatProfile('kotlin-psi', {
|
|
443
|
+
aliases: ['kotlin-compiler', 'kotlin-compiler-psi', 'intellij-psi', 'kt-psi', 'kotlin-ast'],
|
|
444
|
+
kind: 'compiler-ast',
|
|
445
|
+
languages: ['kotlin'],
|
|
446
|
+
parserAdapters: ['kotlin-compiler', 'kotlin-psi', 'intellij-psi'],
|
|
447
|
+
exactness: 'exact-parser-ast',
|
|
448
|
+
sourceRangeModel: 'text-range-line-column',
|
|
449
|
+
preservesTokens: true,
|
|
450
|
+
preservesTrivia: true,
|
|
451
|
+
supportsErrorRecovery: true,
|
|
452
|
+
notes: ['Kotlin PSI exposes source syntax and IntelliJ parser errors; Analysis API symbols, FIR/K2 types, expect/actual matching, compiler plugins, generated sources, scripts, and build variants remain host-owned evidence.']
|
|
453
|
+
}),
|
|
442
454
|
nativeParserAstFormatProfile('roslyn-csharp', {
|
|
443
455
|
aliases: ['roslyn', 'csharp-roslyn', 'c#-roslyn', 'microsoft-codeanalysis-csharp', 'csharp-syntax'],
|
|
444
456
|
kind: 'compiler-ast',
|
|
@@ -2958,6 +2970,78 @@ export function createJavaAstNativeImporterAdapter(options = {}) {
|
|
|
2958
2970
|
};
|
|
2959
2971
|
}
|
|
2960
2972
|
|
|
2973
|
+
export function createKotlinPsiNativeImporterAdapter(options = {}) {
|
|
2974
|
+
return {
|
|
2975
|
+
id: options.id ?? 'frontier.kotlin-psi-native-importer',
|
|
2976
|
+
language: options.language ?? 'kotlin',
|
|
2977
|
+
parser: options.parser ?? 'kotlin-psi',
|
|
2978
|
+
version: options.version,
|
|
2979
|
+
capabilities: uniqueStrings(['nativeAst', 'semanticIndex', 'sourceMaps', 'diagnostics', ...(options.capabilities ?? [])]),
|
|
2980
|
+
coverage: nativeImporterAdapterCoverage({
|
|
2981
|
+
exactness: 'exact-parser-ast',
|
|
2982
|
+
exactAst: true,
|
|
2983
|
+
tokens: true,
|
|
2984
|
+
trivia: true,
|
|
2985
|
+
diagnostics: true,
|
|
2986
|
+
sourceRanges: true,
|
|
2987
|
+
generatedRanges: false,
|
|
2988
|
+
semanticCoverage: declarationSemanticCoverage(),
|
|
2989
|
+
notes: [
|
|
2990
|
+
'Normalizes caller-owned Kotlin PSI/KtFile-shaped syntax trees into native AST nodes and declaration-level semantic index records.',
|
|
2991
|
+
'Kotlin PSI imports do not resolve Analysis API symbols, FIR/K2 types, overloads, nullability flow, expect/actual matching, compiler-plugin generated declarations, KSP/KAPT output, scripts, build variants, or control flow by themselves; attach host evidence for those claims.'
|
|
2992
|
+
]
|
|
2993
|
+
}, options.coverage),
|
|
2994
|
+
supportedExtensions: options.supportedExtensions ?? ['.kt', '.kts'],
|
|
2995
|
+
diagnostics: options.diagnostics,
|
|
2996
|
+
parse(input) {
|
|
2997
|
+
const parsed = input.options?.ast
|
|
2998
|
+
?? input.options?.nativeAst
|
|
2999
|
+
?? input.options?.ktFile
|
|
3000
|
+
?? input.options?.file
|
|
3001
|
+
?? input.options?.sourceFile
|
|
3002
|
+
?? input.options?.root
|
|
3003
|
+
?? options.ast
|
|
3004
|
+
?? options.ktFile
|
|
3005
|
+
?? options.file
|
|
3006
|
+
?? options.sourceFile
|
|
3007
|
+
?? options.root
|
|
3008
|
+
?? parseKotlinPsiSource(input, options);
|
|
3009
|
+
const root = kotlinPsiRoot(parsed);
|
|
3010
|
+
if (!root) {
|
|
3011
|
+
return missingInjectedParserResult(input, {
|
|
3012
|
+
parser: options.parser ?? 'kotlin-psi',
|
|
3013
|
+
adapterId: options.id ?? 'frontier.kotlin-psi-native-importer',
|
|
3014
|
+
message: 'createKotlinPsiNativeImporterAdapter requires an injected Kotlin PSI KtFile-shaped object, parserModule.parse function, parse function, or adapterOptions.ast.'
|
|
3015
|
+
});
|
|
3016
|
+
}
|
|
3017
|
+
const parseDiagnostics = normalizeParserErrors(parsed?.errors ?? parsed?.diagnostics ?? parsed?.parseDiagnostics, input, {
|
|
3018
|
+
parser: options.parser ?? 'kotlin-psi'
|
|
3019
|
+
});
|
|
3020
|
+
return createNativeImportFromKotlinPsi(root, input, {
|
|
3021
|
+
parser: options.parser ?? 'kotlin-psi',
|
|
3022
|
+
astFormat: 'kotlin-psi',
|
|
3023
|
+
maxNodes: options.maxNodes,
|
|
3024
|
+
diagnostics: parseDiagnostics,
|
|
3025
|
+
kotlinVersion: options.kotlinVersion ?? input.options?.kotlinVersion ?? parsed?.kotlinVersion,
|
|
3026
|
+
languageVersion: options.languageVersion ?? input.options?.languageVersion ?? parsed?.languageVersion,
|
|
3027
|
+
apiVersion: options.apiVersion ?? input.options?.apiVersion ?? parsed?.apiVersion,
|
|
3028
|
+
script: input.options?.script ?? options.script ?? parsed?.script ?? /\.kts$/i.test(input.sourcePath ?? ''),
|
|
3029
|
+
generated: input.options?.generated ?? options.generated ?? parsed?.generated ?? kotlinGeneratedSourcePath(input.sourcePath),
|
|
3030
|
+
analysisApiEvidence: input.options?.analysisApiEvidence ?? options.analysisApiEvidence ?? parsed?.analysisApiEvidence,
|
|
3031
|
+
firEvidence: input.options?.firEvidence ?? options.firEvidence ?? parsed?.firEvidence,
|
|
3032
|
+
compilerPluginEvidence: input.options?.compilerPluginEvidence ?? options.compilerPluginEvidence ?? parsed?.compilerPluginEvidence,
|
|
3033
|
+
kspEvidence: input.options?.kspEvidence ?? options.kspEvidence ?? parsed?.kspEvidence,
|
|
3034
|
+
kaptEvidence: input.options?.kaptEvidence ?? options.kaptEvidence ?? parsed?.kaptEvidence,
|
|
3035
|
+
multiplatformEvidence: input.options?.multiplatformEvidence ?? options.multiplatformEvidence ?? parsed?.multiplatformEvidence,
|
|
3036
|
+
buildVariantEvidence: input.options?.buildVariantEvidence ?? options.buildVariantEvidence ?? parsed?.buildVariantEvidence,
|
|
3037
|
+
positionResolver: input.options?.positionResolver ?? options.positionResolver,
|
|
3038
|
+
lineMap: input.options?.lineMap ?? options.lineMap ?? parsed?.lineMap,
|
|
3039
|
+
includeAnnotations: options.includeAnnotations ?? input.options?.includeAnnotations
|
|
3040
|
+
});
|
|
3041
|
+
}
|
|
3042
|
+
};
|
|
3043
|
+
}
|
|
3044
|
+
|
|
2961
3045
|
export function createCSharpRoslynNativeImporterAdapter(options = {}) {
|
|
2962
3046
|
return {
|
|
2963
3047
|
id: options.id ?? 'frontier.csharp-roslyn-native-importer',
|
|
@@ -7529,6 +7613,7 @@ function parserAstFormatIdForParser(parser) {
|
|
|
7529
7613
|
if (text.includes('clang') || text.includes('libclang')) return 'clang-ast-json';
|
|
7530
7614
|
if (text === 'go' || text.includes('go-parser') || text.includes('go-ast') || text.includes('go/parser') || text.includes('go/ast')) return 'go-ast';
|
|
7531
7615
|
if (text === 'java' || text.includes('javac') || text.includes('jdt') || text.includes('javaparser') || text.includes('java-parser') || text.includes('java-ast')) return 'java-ast';
|
|
7616
|
+
if (text === 'kotlin' || text === 'kt' || text.includes('kotlin-psi') || text.includes('kotlin-compiler') || text.includes('intellij-psi') || text.includes('kt-psi')) return 'kotlin-psi';
|
|
7532
7617
|
if (text === 'csharp' || text === 'c#' || text === 'cs' || text.includes('roslyn') || text.includes('microsoft-codeanalysis-csharp') || text.includes('csharp-syntax')) return 'roslyn-csharp';
|
|
7533
7618
|
if (text.includes('swift-syntax') || text.includes('swiftsyntax') || text.includes('swiftparser') || text.includes('swift-parser')) return 'swift-syntax';
|
|
7534
7619
|
if (text.includes('tree-sitter') || text.includes('treesitter')) return 'tree-sitter';
|
|
@@ -8629,6 +8714,23 @@ function parseJavaAstSource(input, options) {
|
|
|
8629
8714
|
return parse(input.sourceText, parserOptions);
|
|
8630
8715
|
}
|
|
8631
8716
|
|
|
8717
|
+
function parseKotlinPsiSource(input, options) {
|
|
8718
|
+
const parse = options.parse ?? options.parserModule?.parse ?? options.kotlinPsi?.parse ?? options.kotlinCompiler?.parse ?? options.intellijPsi?.parse;
|
|
8719
|
+
if (typeof parse !== 'function') return undefined;
|
|
8720
|
+
const parserOptions = {
|
|
8721
|
+
sourcePath: input.sourcePath,
|
|
8722
|
+
filename: input.sourcePath,
|
|
8723
|
+
kotlinVersion: options.kotlinVersion ?? input.options?.kotlinVersion,
|
|
8724
|
+
languageVersion: options.languageVersion ?? input.options?.languageVersion,
|
|
8725
|
+
apiVersion: options.apiVersion ?? input.options?.apiVersion,
|
|
8726
|
+
script: options.script ?? input.options?.script ?? /\.kts$/i.test(input.sourcePath ?? ''),
|
|
8727
|
+
includeAnnotations: options.includeAnnotations ?? input.options?.includeAnnotations,
|
|
8728
|
+
...(options.parserOptions ?? {}),
|
|
8729
|
+
...(input.options?.parserOptions ?? {})
|
|
8730
|
+
};
|
|
8731
|
+
return parse(input.sourceText, parserOptions);
|
|
8732
|
+
}
|
|
8733
|
+
|
|
8632
8734
|
function parseCSharpRoslynSource(input, options) {
|
|
8633
8735
|
const parse = options.parse ?? options.parserModule?.parse ?? options.roslyn?.parse ?? options.csharpRoslyn?.parse;
|
|
8634
8736
|
if (typeof parse !== 'function') return undefined;
|
|
@@ -8891,6 +8993,53 @@ function createNativeImportFromJavaAst(root, input, options) {
|
|
|
8891
8993
|
};
|
|
8892
8994
|
}
|
|
8893
8995
|
|
|
8996
|
+
function createNativeImportFromKotlinPsi(root, input, options) {
|
|
8997
|
+
const context = createAstNormalizationContext(input, options);
|
|
8998
|
+
visitKotlinPsiNode(root, context, 'root');
|
|
8999
|
+
if (context.truncated) {
|
|
9000
|
+
context.losses.push(truncatedAstLoss(input, context, options));
|
|
9001
|
+
}
|
|
9002
|
+
if (options.generated && !context.losses.some((loss) => loss.kind === 'generatedCode')) {
|
|
9003
|
+
context.losses.push(kotlinGeneratedCodeLoss(input, context.rootId, undefined, options));
|
|
9004
|
+
}
|
|
9005
|
+
if (options.script && !context.losses.some((loss) => loss.metadata?.script === true)) {
|
|
9006
|
+
context.losses.push(kotlinScriptLoss(input, context.rootId, undefined, options));
|
|
9007
|
+
}
|
|
9008
|
+
const semantic = semanticIndexFromNativeDeclarations(context.declarations, input, options);
|
|
9009
|
+
return {
|
|
9010
|
+
rootId: context.rootId,
|
|
9011
|
+
nodes: context.nodes,
|
|
9012
|
+
semanticIndex: semantic.semanticIndex,
|
|
9013
|
+
mappings: semantic.mappings,
|
|
9014
|
+
losses: mergeNativeLosses(context.losses, options.diagnostics?.map((diagnostic, index) => adapterDiagnosticToLoss(diagnostic, index, {
|
|
9015
|
+
id: input.adapterId,
|
|
9016
|
+
version: input.adapterVersion
|
|
9017
|
+
}, input)) ?? []),
|
|
9018
|
+
evidence: semantic.evidence,
|
|
9019
|
+
diagnostics: options.diagnostics,
|
|
9020
|
+
metadata: {
|
|
9021
|
+
astFormat: options.astFormat,
|
|
9022
|
+
parser: options.parser,
|
|
9023
|
+
kotlinVersion: options.kotlinVersion,
|
|
9024
|
+
languageVersion: options.languageVersion,
|
|
9025
|
+
apiVersion: options.apiVersion,
|
|
9026
|
+
script: Boolean(options.script),
|
|
9027
|
+
generated: options.generated,
|
|
9028
|
+
analysisApiEvidence: kotlinEvidenceSummary(options.analysisApiEvidence),
|
|
9029
|
+
firEvidence: kotlinEvidenceSummary(options.firEvidence),
|
|
9030
|
+
compilerPluginEvidence: kotlinEvidenceSummary(options.compilerPluginEvidence),
|
|
9031
|
+
kspEvidence: kotlinEvidenceSummary(options.kspEvidence),
|
|
9032
|
+
kaptEvidence: kotlinEvidenceSummary(options.kaptEvidence),
|
|
9033
|
+
multiplatformEvidence: kotlinEvidenceSummary(options.multiplatformEvidence),
|
|
9034
|
+
buildVariantEvidence: kotlinEvidenceSummary(options.buildVariantEvidence),
|
|
9035
|
+
includeAnnotations: Boolean(options.includeAnnotations),
|
|
9036
|
+
normalizedNodeCount: Object.keys(context.nodes).length,
|
|
9037
|
+
declarationCount: context.declarations.length,
|
|
9038
|
+
truncated: context.truncated
|
|
9039
|
+
}
|
|
9040
|
+
};
|
|
9041
|
+
}
|
|
9042
|
+
|
|
8894
9043
|
function createNativeImportFromCSharpRoslyn(root, input, options) {
|
|
8895
9044
|
const context = createAstNormalizationContext(input, options);
|
|
8896
9045
|
visitCSharpRoslynNode(root, context, 'root');
|
|
@@ -12348,6 +12497,658 @@ function javaBindingEvidenceSummary(value) {
|
|
|
12348
12497
|
return Object.keys(summary).length ? summary : { present: true };
|
|
12349
12498
|
}
|
|
12350
12499
|
|
|
12500
|
+
function kotlinPsiRoot(value) {
|
|
12501
|
+
if (!value || typeof value !== 'object') return undefined;
|
|
12502
|
+
if (isKotlinPsiNode(value)) return value;
|
|
12503
|
+
if (isKotlinPsiNode(value.ast)) return value.ast;
|
|
12504
|
+
if (isKotlinPsiNode(value.root)) return value.root;
|
|
12505
|
+
if (isKotlinPsiNode(value.rootNode)) return value.rootNode;
|
|
12506
|
+
if (isKotlinPsiNode(value.ktFile)) return value.ktFile;
|
|
12507
|
+
if (isKotlinPsiNode(value.file)) return value.file;
|
|
12508
|
+
if (isKotlinPsiNode(value.sourceFile)) return value.sourceFile;
|
|
12509
|
+
if (Array.isArray(value.declarations) || Array.isArray(value.imports) || value.packageDirective) {
|
|
12510
|
+
return { kind: 'KtFile', ...value };
|
|
12511
|
+
}
|
|
12512
|
+
return undefined;
|
|
12513
|
+
}
|
|
12514
|
+
|
|
12515
|
+
function isKotlinPsiNode(value) {
|
|
12516
|
+
return Boolean(value && typeof value === 'object' && typeof kotlinPsiKind(value) === 'string');
|
|
12517
|
+
}
|
|
12518
|
+
|
|
12519
|
+
function kotlinPsiKind(node) {
|
|
12520
|
+
if (!node || typeof node !== 'object') return undefined;
|
|
12521
|
+
const declared = node.kind ?? node.nodeType ?? node.elementType ?? node.psiKind ?? node._type ?? node.type;
|
|
12522
|
+
if (typeof declared === 'string') return normalizeKotlinPsiKind(declared);
|
|
12523
|
+
if (Array.isArray(node.declarations) || Array.isArray(node.imports) || node.packageDirective) return 'KtFile';
|
|
12524
|
+
if (node.fqName || node.packageFqName) return 'KtPackageDirective';
|
|
12525
|
+
if (node.importedFqName || node.importedReference) return 'KtImportDirective';
|
|
12526
|
+
if (node.classKind || node.primaryConstructor || node.superTypeListEntries) return 'KtClass';
|
|
12527
|
+
if (node.funKeyword || node.valueParameters || node.bodyExpression) return 'KtNamedFunction';
|
|
12528
|
+
if (node.valOrVarKeyword || node.delegateExpression || node.initializer) return 'KtProperty';
|
|
12529
|
+
return undefined;
|
|
12530
|
+
}
|
|
12531
|
+
|
|
12532
|
+
function normalizeKotlinPsiKind(kind) {
|
|
12533
|
+
const text = String(kind)
|
|
12534
|
+
.replace(/^org\.jetbrains\.kotlin\.psi\./, '')
|
|
12535
|
+
.replace(/^KtNodeTypes\./, '')
|
|
12536
|
+
.replace(/ElementType$/, '');
|
|
12537
|
+
const compact = text.replace(/[_\s.-]+/g, '').toLowerCase();
|
|
12538
|
+
const known = {
|
|
12539
|
+
kotlinfile: 'KtFile',
|
|
12540
|
+
ktfile: 'KtFile',
|
|
12541
|
+
file: 'KtFile',
|
|
12542
|
+
script: 'KtScript',
|
|
12543
|
+
ktscript: 'KtScript',
|
|
12544
|
+
packagedirective: 'KtPackageDirective',
|
|
12545
|
+
ktpackagedirective: 'KtPackageDirective',
|
|
12546
|
+
importdirective: 'KtImportDirective',
|
|
12547
|
+
ktimportdirective: 'KtImportDirective',
|
|
12548
|
+
class: 'KtClass',
|
|
12549
|
+
ktclass: 'KtClass',
|
|
12550
|
+
classorobject: 'KtClassOrObject',
|
|
12551
|
+
ktclassorobject: 'KtClassOrObject',
|
|
12552
|
+
objectdeclaration: 'KtObjectDeclaration',
|
|
12553
|
+
ktobjectdeclaration: 'KtObjectDeclaration',
|
|
12554
|
+
enumentry: 'KtEnumEntry',
|
|
12555
|
+
ktenumentry: 'KtEnumEntry',
|
|
12556
|
+
namedfunction: 'KtNamedFunction',
|
|
12557
|
+
ktnamedfunction: 'KtNamedFunction',
|
|
12558
|
+
function: 'KtNamedFunction',
|
|
12559
|
+
property: 'KtProperty',
|
|
12560
|
+
ktproperty: 'KtProperty',
|
|
12561
|
+
typealias: 'KtTypeAlias',
|
|
12562
|
+
kttypealias: 'KtTypeAlias',
|
|
12563
|
+
parameter: 'KtParameter',
|
|
12564
|
+
ktparameter: 'KtParameter',
|
|
12565
|
+
primaryconstructor: 'KtPrimaryConstructor',
|
|
12566
|
+
ktprimaryconstructor: 'KtPrimaryConstructor',
|
|
12567
|
+
secondaryconstructor: 'KtSecondaryConstructor',
|
|
12568
|
+
ktsecondaryconstructor: 'KtSecondaryConstructor',
|
|
12569
|
+
classinitializer: 'KtClassInitializer',
|
|
12570
|
+
ktclassinitializer: 'KtClassInitializer',
|
|
12571
|
+
annotationentry: 'KtAnnotationEntry',
|
|
12572
|
+
ktannotationentry: 'KtAnnotationEntry',
|
|
12573
|
+
contracteffect: 'KtContractEffect',
|
|
12574
|
+
ktcontracteffect: 'KtContractEffect',
|
|
12575
|
+
contractdescription: 'KtContractDescription',
|
|
12576
|
+
ktcontractdescription: 'KtContractDescription',
|
|
12577
|
+
error: 'PsiErrorElement',
|
|
12578
|
+
psierror: 'PsiErrorElement',
|
|
12579
|
+
psierrorelement: 'PsiErrorElement'
|
|
12580
|
+
};
|
|
12581
|
+
if (known[compact]) return known[compact];
|
|
12582
|
+
if (/^[A-Z0-9_]+$/.test(text)) return text.toLowerCase().split('_').map(upperFirst).join('');
|
|
12583
|
+
return text;
|
|
12584
|
+
}
|
|
12585
|
+
|
|
12586
|
+
function ignoredKotlinPsiField(key) {
|
|
12587
|
+
return key === '_type'
|
|
12588
|
+
|| key === 'type'
|
|
12589
|
+
|| key === 'kind'
|
|
12590
|
+
|| key === 'nodeType'
|
|
12591
|
+
|| key === 'elementType'
|
|
12592
|
+
|| key === 'psiKind'
|
|
12593
|
+
|| key === 'parent'
|
|
12594
|
+
|| key === 'parentKind'
|
|
12595
|
+
|| key === 'parentField'
|
|
12596
|
+
|| key === 'textRange'
|
|
12597
|
+
|| key === 'range'
|
|
12598
|
+
|| key === 'span'
|
|
12599
|
+
|| key === 'location'
|
|
12600
|
+
|| key === 'name'
|
|
12601
|
+
|| key === 'nameIdentifier'
|
|
12602
|
+
|| key === 'identifier'
|
|
12603
|
+
|| key === 'fqName'
|
|
12604
|
+
|| key === 'packageFqName'
|
|
12605
|
+
|| key === 'analysisSymbol'
|
|
12606
|
+
|| key === 'symbol'
|
|
12607
|
+
|| key === 'typeInfo'
|
|
12608
|
+
|| key === 'bindingContext'
|
|
12609
|
+
|| key === 'fir'
|
|
12610
|
+
|| key === 'ir';
|
|
12611
|
+
}
|
|
12612
|
+
|
|
12613
|
+
function visitKotlinPsiNode(node, context, propertyPath) {
|
|
12614
|
+
if (!isKotlinPsiNode(node) || context.truncated) return undefined;
|
|
12615
|
+
if (context.objectIds.has(node)) return context.objectIds.get(node);
|
|
12616
|
+
if (context.counter >= context.maxNodes) {
|
|
12617
|
+
context.truncated = true;
|
|
12618
|
+
return undefined;
|
|
12619
|
+
}
|
|
12620
|
+
const kind = kotlinPsiKind(node);
|
|
12621
|
+
const span = spanFromKotlinPsiNode(node, context.input, context.options);
|
|
12622
|
+
const id = nativeNodeId(context, kind, { start: { line: span?.startLine, column: span?.startColumn } }, propertyPath);
|
|
12623
|
+
context.objectIds.set(node, id);
|
|
12624
|
+
if (!context.rootId) context.rootId = id;
|
|
12625
|
+
const children = [];
|
|
12626
|
+
for (const [field, value] of kotlinPsiChildEntries(node, kind)) {
|
|
12627
|
+
if (Array.isArray(value)) {
|
|
12628
|
+
value.forEach((entry, index) => {
|
|
12629
|
+
const childId = visitKotlinPsiNode(entry, context, `${propertyPath}.${field}[${index}]`);
|
|
12630
|
+
if (childId) children.push(childId);
|
|
12631
|
+
});
|
|
12632
|
+
} else {
|
|
12633
|
+
const childId = visitKotlinPsiNode(value, context, `${propertyPath}.${field}`);
|
|
12634
|
+
if (childId) children.push(childId);
|
|
12635
|
+
}
|
|
12636
|
+
}
|
|
12637
|
+
const declarations = kotlinPsiDeclarations(node, kind, id, context.input);
|
|
12638
|
+
const declaration = declarations[0];
|
|
12639
|
+
const nativeNode = {
|
|
12640
|
+
id,
|
|
12641
|
+
kind,
|
|
12642
|
+
languageKind: `${context.input.language}.${kind}`,
|
|
12643
|
+
span,
|
|
12644
|
+
value: declaration?.name ?? kotlinPsiNodeValue(node),
|
|
12645
|
+
fields: primitiveKotlinPsiFields(node, kind),
|
|
12646
|
+
children,
|
|
12647
|
+
metadata: {
|
|
12648
|
+
astFormat: context.options.astFormat,
|
|
12649
|
+
propertyPath,
|
|
12650
|
+
positionKind: kotlinPsiPositionKind(node),
|
|
12651
|
+
parser: context.options.parser
|
|
12652
|
+
}
|
|
12653
|
+
};
|
|
12654
|
+
context.nodes[id] = nativeNode;
|
|
12655
|
+
for (const entry of declarations) {
|
|
12656
|
+
context.declarations.push({ ...entry, nativeNode });
|
|
12657
|
+
}
|
|
12658
|
+
if (kotlinPsiRecoveredKind(kind) || kotlinPsiProblemNode(node, kind)) {
|
|
12659
|
+
context.losses.push({
|
|
12660
|
+
id: `loss_${idFragment(id)}_kotlin_psi_recovered_node`,
|
|
12661
|
+
severity: 'error',
|
|
12662
|
+
phase: 'parse',
|
|
12663
|
+
sourceFormat: context.input.language,
|
|
12664
|
+
kind: 'unsupportedSyntax',
|
|
12665
|
+
message: 'Kotlin PSI reported an error or recovered syntax node; semantic import is partial until syntax errors are resolved.',
|
|
12666
|
+
span,
|
|
12667
|
+
nodeId: id,
|
|
12668
|
+
metadata: {
|
|
12669
|
+
parser: context.options.parser,
|
|
12670
|
+
astFormat: context.options.astFormat,
|
|
12671
|
+
nodeKind: kind
|
|
12672
|
+
}
|
|
12673
|
+
});
|
|
12674
|
+
}
|
|
12675
|
+
if (kotlinExpectActualNode(node, kind)) {
|
|
12676
|
+
context.losses.push(kotlinUnsupportedSemanticLoss(context.input, id, span, context.options, {
|
|
12677
|
+
nodeKind: kind,
|
|
12678
|
+
feature: 'expect-actual',
|
|
12679
|
+
message: 'Kotlin expect/actual syntax was imported; matching platform declarations requires multiplatform build evidence.'
|
|
12680
|
+
}));
|
|
12681
|
+
}
|
|
12682
|
+
if (kotlinCoroutineNode(node, kind)) {
|
|
12683
|
+
context.losses.push(kotlinUnsupportedSemanticLoss(context.input, id, span, context.options, {
|
|
12684
|
+
nodeKind: kind,
|
|
12685
|
+
feature: 'coroutine',
|
|
12686
|
+
message: 'Kotlin coroutine syntax was imported; suspend lowering, scheduling, and effect semantics require host compiler/runtime evidence.'
|
|
12687
|
+
}));
|
|
12688
|
+
}
|
|
12689
|
+
if (kotlinContractNode(kind)) {
|
|
12690
|
+
context.losses.push(kotlinUnsupportedSemanticLoss(context.input, id, span, context.options, {
|
|
12691
|
+
nodeKind: kind,
|
|
12692
|
+
feature: 'contract',
|
|
12693
|
+
message: 'Kotlin contract syntax was imported; data-flow effects require Analysis API or compiler evidence.'
|
|
12694
|
+
}));
|
|
12695
|
+
}
|
|
12696
|
+
if (kotlinCompilerPluginAnnotationNode(node, kind) && !context.options.compilerPluginEvidence) {
|
|
12697
|
+
context.losses.push({
|
|
12698
|
+
id: `loss_${idFragment(id)}_kotlin_compiler_plugin_semantics`,
|
|
12699
|
+
severity: 'warning',
|
|
12700
|
+
phase: 'parse',
|
|
12701
|
+
sourceFormat: context.input.language,
|
|
12702
|
+
kind: 'metaprogramming',
|
|
12703
|
+
message: 'Kotlin compiler-plugin-style annotation was imported; generated declarations and transformed semantics require compiler plugin evidence.',
|
|
12704
|
+
span,
|
|
12705
|
+
nodeId: id,
|
|
12706
|
+
metadata: {
|
|
12707
|
+
parser: context.options.parser,
|
|
12708
|
+
astFormat: context.options.astFormat,
|
|
12709
|
+
nodeKind: kind,
|
|
12710
|
+
annotations: kotlinPsiAnnotationNames(node)
|
|
12711
|
+
}
|
|
12712
|
+
});
|
|
12713
|
+
}
|
|
12714
|
+
if (kotlinGeneratedCodeMarker(node, kind)) {
|
|
12715
|
+
context.losses.push(kotlinGeneratedCodeLoss(context.input, id, span, context.options, { nodeKind: kind }));
|
|
12716
|
+
}
|
|
12717
|
+
return id;
|
|
12718
|
+
}
|
|
12719
|
+
|
|
12720
|
+
function primitiveKotlinPsiFields(node, kind) {
|
|
12721
|
+
const fields = { kind };
|
|
12722
|
+
const name = kotlinPsiDeclarationName(node, kind);
|
|
12723
|
+
if (name) fields.name = name;
|
|
12724
|
+
const importPath = kotlinPsiImportPath(node);
|
|
12725
|
+
if (importPath) fields.importPath = importPath;
|
|
12726
|
+
const packageName = kotlinPsiPackageName(node);
|
|
12727
|
+
if (packageName) fields.packageName = packageName;
|
|
12728
|
+
const type = kotlinPsiTypeName(node.typeReference ?? node.returnTypeRef ?? node.returnType ?? node.type);
|
|
12729
|
+
if (type) fields.type = type;
|
|
12730
|
+
const receiver = kotlinPsiTypeName(node.receiverTypeReference ?? node.receiverTypeRef);
|
|
12731
|
+
if (receiver) fields.receiverType = receiver;
|
|
12732
|
+
const modifiers = kotlinPsiModifiers(node);
|
|
12733
|
+
if (modifiers.length) fields.modifiers = modifiers.join(',');
|
|
12734
|
+
const annotations = kotlinPsiAnnotationNames(node);
|
|
12735
|
+
if (annotations.length) fields.annotations = annotations.join(',');
|
|
12736
|
+
if (node.generated === true || node.isGenerated === true) fields.generated = true;
|
|
12737
|
+
if (node.isScript === true || kind === 'KtScript') fields.script = true;
|
|
12738
|
+
if (Array.isArray(node.typeParameters ?? node.typeParameterList?.parameters)) fields.typeParameterCount = (node.typeParameters ?? node.typeParameterList?.parameters).length;
|
|
12739
|
+
if (Array.isArray(node.valueParameters ?? node.valueParameterList?.parameters ?? node.parameters)) fields.parameterCount = (node.valueParameters ?? node.valueParameterList?.parameters ?? node.parameters).length;
|
|
12740
|
+
if (Array.isArray(node.superTypeListEntries ?? node.superTypes)) fields.superTypeCount = (node.superTypeListEntries ?? node.superTypes).length;
|
|
12741
|
+
return fields;
|
|
12742
|
+
}
|
|
12743
|
+
|
|
12744
|
+
function spanFromKotlinPsiNode(node, input, options = {}) {
|
|
12745
|
+
const direct = spanFromKotlinLineFields(node, input);
|
|
12746
|
+
if (direct) return direct;
|
|
12747
|
+
const range = node.sourceRange ?? node.range ?? node.span ?? node.textRange;
|
|
12748
|
+
const fromRange = spanFromKotlinRange(range, input);
|
|
12749
|
+
if (fromRange) return fromRange;
|
|
12750
|
+
const start = kotlinPsiPosition(node.start ?? node.startOffset ?? range?.startOffset ?? range?.start, options);
|
|
12751
|
+
const end = kotlinPsiPosition(node.end ?? node.endOffset ?? range?.endOffset ?? range?.end, options);
|
|
12752
|
+
if (!start) return undefined;
|
|
12753
|
+
return {
|
|
12754
|
+
sourceId: input.sourceHash,
|
|
12755
|
+
path: start.path ?? end?.path ?? input.sourcePath,
|
|
12756
|
+
startLine: start.line,
|
|
12757
|
+
startColumn: start.column,
|
|
12758
|
+
endLine: end?.line,
|
|
12759
|
+
endColumn: end?.column
|
|
12760
|
+
};
|
|
12761
|
+
}
|
|
12762
|
+
|
|
12763
|
+
function spanFromKotlinLineFields(node, input) {
|
|
12764
|
+
const startLine = node.startLine ?? node.line ?? node.beginLine;
|
|
12765
|
+
if (typeof startLine !== 'number') return undefined;
|
|
12766
|
+
return {
|
|
12767
|
+
sourceId: input.sourceHash,
|
|
12768
|
+
path: node.path ?? node.filePath ?? node.file ?? input.sourcePath,
|
|
12769
|
+
startLine,
|
|
12770
|
+
startColumn: node.startColumn ?? node.column ?? node.beginColumn,
|
|
12771
|
+
endLine: node.endLine,
|
|
12772
|
+
endColumn: node.endColumn
|
|
12773
|
+
};
|
|
12774
|
+
}
|
|
12775
|
+
|
|
12776
|
+
function spanFromKotlinRange(range, input) {
|
|
12777
|
+
if (!range || typeof range !== 'object') return undefined;
|
|
12778
|
+
const start = range.start ?? range.startPosition ?? range.lowerBound ?? range.begin;
|
|
12779
|
+
const end = range.end ?? range.endPosition ?? range.upperBound;
|
|
12780
|
+
const line = start?.line ?? start?.Line;
|
|
12781
|
+
if (typeof line !== 'number') return undefined;
|
|
12782
|
+
const column = start.column ?? start.character ?? start.offset ?? start.Column;
|
|
12783
|
+
const endLine = end?.line ?? end?.Line;
|
|
12784
|
+
const endColumn = end?.column ?? end?.character ?? end?.offset ?? end?.Column;
|
|
12785
|
+
return {
|
|
12786
|
+
sourceId: input.sourceHash,
|
|
12787
|
+
path: range.path ?? range.filePath ?? range.file ?? input.sourcePath,
|
|
12788
|
+
startLine: line,
|
|
12789
|
+
startColumn: typeof column === 'number' ? column : undefined,
|
|
12790
|
+
endLine: typeof endLine === 'number' ? endLine : undefined,
|
|
12791
|
+
endColumn: typeof endColumn === 'number' ? endColumn : undefined
|
|
12792
|
+
};
|
|
12793
|
+
}
|
|
12794
|
+
|
|
12795
|
+
function kotlinPsiPosition(value, options = {}) {
|
|
12796
|
+
if (value === undefined || value === null) return undefined;
|
|
12797
|
+
if (typeof value === 'object') {
|
|
12798
|
+
const position = value.position ?? value.location ?? value;
|
|
12799
|
+
const line = position.line ?? position.Line;
|
|
12800
|
+
const column = position.column ?? position.character ?? position.Column;
|
|
12801
|
+
if (typeof line === 'number') {
|
|
12802
|
+
return {
|
|
12803
|
+
path: position.path ?? position.filePath ?? position.file,
|
|
12804
|
+
line,
|
|
12805
|
+
column: typeof column === 'number' ? column : undefined
|
|
12806
|
+
};
|
|
12807
|
+
}
|
|
12808
|
+
}
|
|
12809
|
+
const resolver = typeof options.positionResolver === 'function'
|
|
12810
|
+
? options.positionResolver
|
|
12811
|
+
: typeof options.lineMap?.position === 'function'
|
|
12812
|
+
? options.lineMap.position.bind(options.lineMap)
|
|
12813
|
+
: typeof options.lineMap?.getLineAndColumn === 'function'
|
|
12814
|
+
? options.lineMap.getLineAndColumn.bind(options.lineMap)
|
|
12815
|
+
: undefined;
|
|
12816
|
+
if (resolver) {
|
|
12817
|
+
const resolved = resolver(value);
|
|
12818
|
+
if (resolved !== value) return kotlinPsiPosition(resolved, options);
|
|
12819
|
+
}
|
|
12820
|
+
return undefined;
|
|
12821
|
+
}
|
|
12822
|
+
|
|
12823
|
+
function kotlinPsiPositionKind(node) {
|
|
12824
|
+
if (node.textRange || node.range) return 'text-range';
|
|
12825
|
+
if (typeof node.startOffset === 'number') return 'offset';
|
|
12826
|
+
if (typeof node.startLine === 'number' || typeof node.line === 'number') return 'line-column-fields';
|
|
12827
|
+
return undefined;
|
|
12828
|
+
}
|
|
12829
|
+
|
|
12830
|
+
function kotlinPsiDeclarations(node, kind, nativeNodeId, input) {
|
|
12831
|
+
if (kind === 'KtPackageDirective') {
|
|
12832
|
+
const name = kotlinPsiPackageName(node);
|
|
12833
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'namespace', 'definition')] : [];
|
|
12834
|
+
}
|
|
12835
|
+
if (kind === 'KtImportDirective') {
|
|
12836
|
+
const name = kotlinPsiImportPath(node);
|
|
12837
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'module', 'import')] : [];
|
|
12838
|
+
}
|
|
12839
|
+
if (kotlinPsiTypeDeclarationKind(kind)) {
|
|
12840
|
+
const name = kotlinPsiDeclarationName(node, kind);
|
|
12841
|
+
return name ? [declarationRecord(input, nativeNodeId, name, kotlinPsiTypeDeclarationSymbolKind(node, kind), 'definition')] : [];
|
|
12842
|
+
}
|
|
12843
|
+
if (kind === 'KtTypeAlias') {
|
|
12844
|
+
const name = kotlinPsiDeclarationName(node, kind);
|
|
12845
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'type', 'definition')] : [];
|
|
12846
|
+
}
|
|
12847
|
+
if (kind === 'KtNamedFunction') {
|
|
12848
|
+
const name = kotlinPsiDeclarationName(node, kind);
|
|
12849
|
+
return name ? [declarationRecord(input, nativeNodeId, name, node.parentKind && kotlinPsiTypeDeclarationKind(node.parentKind) ? 'method' : 'function', kotlinPsiHasBody(node) ? 'definition' : 'declaration')] : [];
|
|
12850
|
+
}
|
|
12851
|
+
if (kind === 'KtProperty') {
|
|
12852
|
+
return kotlinPsiVariableNames(node).map((name) => declarationRecord(input, nativeNodeId, name, 'property', 'definition'));
|
|
12853
|
+
}
|
|
12854
|
+
if (kind === 'KtParameter' && node.parentKind === 'KtPrimaryConstructor') {
|
|
12855
|
+
return kotlinPsiVariableNames(node).map((name) => declarationRecord(input, nativeNodeId, name, 'property', 'definition'));
|
|
12856
|
+
}
|
|
12857
|
+
if (kind === 'KtPrimaryConstructor' || kind === 'KtSecondaryConstructor') {
|
|
12858
|
+
return [declarationRecord(input, nativeNodeId, kotlinPsiDeclarationName(node, kind) ?? 'constructor', 'method', 'definition')];
|
|
12859
|
+
}
|
|
12860
|
+
if (kind === 'KtEnumEntry') {
|
|
12861
|
+
const name = kotlinPsiDeclarationName(node, kind);
|
|
12862
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'enumMember', 'definition')] : [];
|
|
12863
|
+
}
|
|
12864
|
+
return [];
|
|
12865
|
+
}
|
|
12866
|
+
|
|
12867
|
+
function kotlinPsiChildEntries(node, kind = kotlinPsiKind(node)) {
|
|
12868
|
+
const fieldNames = Object.keys(node).filter((key) => !ignoredKotlinPsiField(key));
|
|
12869
|
+
const entries = [];
|
|
12870
|
+
for (const field of fieldNames) {
|
|
12871
|
+
const value = node[field];
|
|
12872
|
+
if (Array.isArray(value)) {
|
|
12873
|
+
entries.push([field, value.map((entry) => kotlinPsiChildWithParent(entry, kind, field))]);
|
|
12874
|
+
continue;
|
|
12875
|
+
}
|
|
12876
|
+
if (value && typeof value === 'object') {
|
|
12877
|
+
entries.push([field, kotlinPsiChildWithParent(value, kind, field)]);
|
|
12878
|
+
}
|
|
12879
|
+
}
|
|
12880
|
+
return entries.filter(([, value]) => Array.isArray(value)
|
|
12881
|
+
? value.some(isKotlinPsiNode)
|
|
12882
|
+
: isKotlinPsiNode(value));
|
|
12883
|
+
}
|
|
12884
|
+
|
|
12885
|
+
function kotlinPsiChildWithParent(entry, parentKind, parentField) {
|
|
12886
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return entry;
|
|
12887
|
+
if (!isKotlinPsiNode(entry)) return entry;
|
|
12888
|
+
return { parentKind, parentField, ...entry };
|
|
12889
|
+
}
|
|
12890
|
+
|
|
12891
|
+
function kotlinPsiNodeValue(node) {
|
|
12892
|
+
return kotlinPsiDeclarationName(node, kotlinPsiKind(node))
|
|
12893
|
+
?? kotlinPsiImportPath(node)
|
|
12894
|
+
?? kotlinPsiPackageName(node)
|
|
12895
|
+
?? kotlinPsiTypeName(node.typeReference ?? node.returnTypeRef ?? node.type);
|
|
12896
|
+
}
|
|
12897
|
+
|
|
12898
|
+
function kotlinPsiDeclarationName(node, kind = kotlinPsiKind(node)) {
|
|
12899
|
+
if (!node || typeof node !== 'object') return undefined;
|
|
12900
|
+
if (kind === 'KtPrimaryConstructor' || kind === 'KtSecondaryConstructor') return 'constructor';
|
|
12901
|
+
if (kind === 'KtClassInitializer') return 'init';
|
|
12902
|
+
if (kind === 'KtObjectDeclaration' && node.isCompanion === true && !node.name && !node.nameIdentifier) return 'companion object';
|
|
12903
|
+
for (const key of ['nameIdentifier', 'identifier', 'name', 'simpleName', 'classId', 'fqName', 'id']) {
|
|
12904
|
+
const name = kotlinPsiName(node[key]);
|
|
12905
|
+
if (name) return name;
|
|
12906
|
+
}
|
|
12907
|
+
const variable = kotlinPsiVariableNames(node)[0];
|
|
12908
|
+
if (variable) return variable;
|
|
12909
|
+
return undefined;
|
|
12910
|
+
}
|
|
12911
|
+
|
|
12912
|
+
function kotlinPsiName(value) {
|
|
12913
|
+
if (!value) return undefined;
|
|
12914
|
+
if (typeof value === 'string') return value;
|
|
12915
|
+
if (typeof value.asString === 'string') return value.asString;
|
|
12916
|
+
if (typeof value.identifier === 'string') return value.identifier;
|
|
12917
|
+
if (typeof value.name === 'string') return value.name;
|
|
12918
|
+
if (typeof value.text === 'string') return value.text;
|
|
12919
|
+
if (typeof value.value === 'string') return value.value;
|
|
12920
|
+
if (typeof value.fqName === 'string') return value.fqName;
|
|
12921
|
+
if (value.shortName && value.shortName !== value) return kotlinPsiName(value.shortName);
|
|
12922
|
+
if (value.name && value.name !== value) return kotlinPsiName(value.name);
|
|
12923
|
+
if (value.identifier && value.identifier !== value) return kotlinPsiName(value.identifier);
|
|
12924
|
+
return undefined;
|
|
12925
|
+
}
|
|
12926
|
+
|
|
12927
|
+
function kotlinPsiImportPath(node) {
|
|
12928
|
+
if (!node || typeof node !== 'object') return undefined;
|
|
12929
|
+
const path = node.importedFqName ?? node.importedReference ?? node.importPath ?? node.path ?? node.name;
|
|
12930
|
+
if (typeof path === 'string') return path;
|
|
12931
|
+
if (path && typeof path === 'object') return kotlinPsiName(path.fqName ?? path.name ?? path);
|
|
12932
|
+
return undefined;
|
|
12933
|
+
}
|
|
12934
|
+
|
|
12935
|
+
function kotlinPsiPackageName(node) {
|
|
12936
|
+
if (!node || typeof node !== 'object') return undefined;
|
|
12937
|
+
const value = node.packageFqName ?? node.fqName ?? node.qualifiedName ?? node.packageName;
|
|
12938
|
+
if (typeof value === 'string') return value;
|
|
12939
|
+
if (value && typeof value === 'object') return kotlinPsiName(value);
|
|
12940
|
+
return undefined;
|
|
12941
|
+
}
|
|
12942
|
+
|
|
12943
|
+
function kotlinPsiVariableNames(node) {
|
|
12944
|
+
const variables = node.variables ?? node.entries ?? node.declarations;
|
|
12945
|
+
if (Array.isArray(variables)) return variables.map(kotlinPsiDeclarationName).filter(Boolean);
|
|
12946
|
+
const name = kotlinPsiName(node.nameIdentifier ?? node.identifier ?? node.name);
|
|
12947
|
+
return name ? [name] : [];
|
|
12948
|
+
}
|
|
12949
|
+
|
|
12950
|
+
function kotlinPsiTypeName(value) {
|
|
12951
|
+
if (!value) return undefined;
|
|
12952
|
+
if (typeof value === 'string') return value;
|
|
12953
|
+
if (typeof value.text === 'string') return value.text.trim();
|
|
12954
|
+
if (typeof value.name === 'string') return value.name;
|
|
12955
|
+
if (typeof value.fqName === 'string') return value.fqName;
|
|
12956
|
+
if (value.typeElement) return kotlinPsiTypeName(value.typeElement);
|
|
12957
|
+
if (value.typeReference) return kotlinPsiTypeName(value.typeReference);
|
|
12958
|
+
if (value.referencedName) return kotlinPsiName(value.referencedName);
|
|
12959
|
+
if (value.constructorReferenceExpression) return kotlinPsiTypeName(value.constructorReferenceExpression);
|
|
12960
|
+
if (Array.isArray(value.typeArguments) || Array.isArray(value.arguments)) {
|
|
12961
|
+
const base = kotlinPsiName(value.name ?? value.referencedName ?? value.constructorReferenceExpression);
|
|
12962
|
+
const args = (value.typeArguments ?? value.arguments).map((entry) => kotlinPsiTypeName(entry.typeReference ?? entry)).filter(Boolean);
|
|
12963
|
+
return base ? `${base}<${args.join(', ')}>` : undefined;
|
|
12964
|
+
}
|
|
12965
|
+
return kotlinPsiName(value);
|
|
12966
|
+
}
|
|
12967
|
+
|
|
12968
|
+
function kotlinPsiModifiers(node) {
|
|
12969
|
+
const raw = node.modifiers ?? node.modifierList?.modifiers ?? node.modifierList?.children;
|
|
12970
|
+
const names = [];
|
|
12971
|
+
if (Array.isArray(raw)) {
|
|
12972
|
+
for (const entry of raw) {
|
|
12973
|
+
const name = typeof entry === 'string' ? entry : kotlinPsiName(entry) ?? entry?.keyword ?? entry?.tokenType ?? entry?.text;
|
|
12974
|
+
if (name) names.push(String(name).toLowerCase());
|
|
12975
|
+
}
|
|
12976
|
+
} else if (typeof raw === 'string') {
|
|
12977
|
+
names.push(...raw.split(/\s+/).filter(Boolean).map((entry) => entry.toLowerCase()));
|
|
12978
|
+
} else if (raw && typeof raw === 'object') {
|
|
12979
|
+
for (const [key, enabled] of Object.entries(raw)) {
|
|
12980
|
+
if (enabled === true) names.push(key.toLowerCase());
|
|
12981
|
+
}
|
|
12982
|
+
}
|
|
12983
|
+
for (const key of ['suspend', 'expect', 'actual', 'inline', 'operator', 'infix', 'tailrec', 'external', 'override', 'data', 'sealed', 'value']) {
|
|
12984
|
+
if (node[key] === true || node[`is${upperFirst(key)}`] === true) names.push(key);
|
|
12985
|
+
}
|
|
12986
|
+
return uniqueStrings(names.map((entry) => entry.replace(/keyword$/i, '').replace(/_keyword$/i, '').replace(/[_\s-]+/g, '').toLowerCase()).filter(Boolean));
|
|
12987
|
+
}
|
|
12988
|
+
|
|
12989
|
+
function kotlinPsiAnnotationNames(node) {
|
|
12990
|
+
const entries = node.annotationEntries ?? node.annotations ?? node.modifierList?.annotationEntries;
|
|
12991
|
+
if (!entries) return [];
|
|
12992
|
+
if (Array.isArray(entries)) {
|
|
12993
|
+
return uniqueStrings(entries.map((entry) => typeof entry === 'string' ? entry : kotlinPsiName(entry.shortName ?? entry.calleeExpression ?? entry.typeReference ?? entry.name ?? entry)).filter(Boolean));
|
|
12994
|
+
}
|
|
12995
|
+
return [];
|
|
12996
|
+
}
|
|
12997
|
+
|
|
12998
|
+
function kotlinPsiTypeDeclarationKind(kind) {
|
|
12999
|
+
return kind === 'KtClass'
|
|
13000
|
+
|| kind === 'KtClassOrObject'
|
|
13001
|
+
|| kind === 'KtObjectDeclaration';
|
|
13002
|
+
}
|
|
13003
|
+
|
|
13004
|
+
function kotlinPsiTypeDeclarationSymbolKind(node, kind) {
|
|
13005
|
+
const classKind = String(node.classKind ?? node.kindKeyword ?? '').toLowerCase();
|
|
13006
|
+
if (kind === 'KtObjectDeclaration') return 'class';
|
|
13007
|
+
if (classKind.includes('interface')) return 'interface';
|
|
13008
|
+
if (classKind.includes('enum')) return 'enum';
|
|
13009
|
+
if (classKind.includes('annotation')) return 'type';
|
|
13010
|
+
return 'class';
|
|
13011
|
+
}
|
|
13012
|
+
|
|
13013
|
+
function kotlinPsiHasBody(node) {
|
|
13014
|
+
return Boolean(node.bodyExpression || node.bodyBlockExpression || node.body || Array.isArray(node.statements));
|
|
13015
|
+
}
|
|
13016
|
+
|
|
13017
|
+
function kotlinPsiRecoveredKind(kind) {
|
|
13018
|
+
return kind === 'PsiErrorElement'
|
|
13019
|
+
|| kind === 'KtErrorElement'
|
|
13020
|
+
|| /Error|Recovery|Incomplete|Missing|Skipped/.test(String(kind));
|
|
13021
|
+
}
|
|
13022
|
+
|
|
13023
|
+
function kotlinPsiProblemNode(node, kind) {
|
|
13024
|
+
return Boolean(
|
|
13025
|
+
node.hasError
|
|
13026
|
+
|| node.containsDiagnostics
|
|
13027
|
+
|| node.containsSkippedText
|
|
13028
|
+
|| node.isMissing
|
|
13029
|
+
|| kind === 'PsiErrorElement'
|
|
13030
|
+
|| kind === 'KtErrorElement'
|
|
13031
|
+
);
|
|
13032
|
+
}
|
|
13033
|
+
|
|
13034
|
+
function kotlinExpectActualNode(node) {
|
|
13035
|
+
const modifiers = kotlinPsiModifiers(node);
|
|
13036
|
+
return modifiers.includes('expect') || modifiers.includes('actual');
|
|
13037
|
+
}
|
|
13038
|
+
|
|
13039
|
+
function kotlinCoroutineNode(node, kind) {
|
|
13040
|
+
const modifiers = kotlinPsiModifiers(node);
|
|
13041
|
+
return modifiers.includes('suspend')
|
|
13042
|
+
|| /Coroutine|Suspend/i.test(String(kind))
|
|
13043
|
+
|| node.isSuspend === true
|
|
13044
|
+
|| node.suspend === true;
|
|
13045
|
+
}
|
|
13046
|
+
|
|
13047
|
+
function kotlinContractNode(kind) {
|
|
13048
|
+
return /Contract/i.test(String(kind));
|
|
13049
|
+
}
|
|
13050
|
+
|
|
13051
|
+
function kotlinCompilerPluginAnnotationNode(node) {
|
|
13052
|
+
const names = kotlinPsiAnnotationNames(node);
|
|
13053
|
+
return names.some((name) => /^(Composable|Serializable|Parcelize|Entity|Immutable|Stable|AutoService|AssistedInject|Hilt|Inject|Room|KSerializable)$/i.test(name.replace(/^.*\./, '')));
|
|
13054
|
+
}
|
|
13055
|
+
|
|
13056
|
+
function kotlinGeneratedCodeMarker(node) {
|
|
13057
|
+
if (node.generated || node.isGenerated) return true;
|
|
13058
|
+
const path = String(node.filePath ?? node.path ?? node.sourcePath ?? '');
|
|
13059
|
+
return kotlinGeneratedSourcePath(path);
|
|
13060
|
+
}
|
|
13061
|
+
|
|
13062
|
+
function kotlinGeneratedSourcePath(path) {
|
|
13063
|
+
return typeof path === 'string' && (/(\.g|\.generated)\.kts?$/i.test(path) || /[\/\\](build|generated|ksp|kapt)[\/\\]/i.test(path));
|
|
13064
|
+
}
|
|
13065
|
+
|
|
13066
|
+
function kotlinGeneratedCodeLoss(input, nodeId, span, options = {}, metadata = {}) {
|
|
13067
|
+
return {
|
|
13068
|
+
id: `loss_${idFragment(nodeId ?? input.sourcePath ?? 'kotlin')}_kotlin_generated_code`,
|
|
13069
|
+
severity: 'warning',
|
|
13070
|
+
phase: 'parse',
|
|
13071
|
+
sourceFormat: input.language,
|
|
13072
|
+
kind: 'generatedCode',
|
|
13073
|
+
message: 'Kotlin generated-source marker was imported; generated member provenance and source ownership require host evidence.',
|
|
13074
|
+
span,
|
|
13075
|
+
nodeId,
|
|
13076
|
+
metadata: {
|
|
13077
|
+
parser: options.parser,
|
|
13078
|
+
astFormat: options.astFormat,
|
|
13079
|
+
kspEvidence: kotlinEvidenceSummary(options.kspEvidence),
|
|
13080
|
+
kaptEvidence: kotlinEvidenceSummary(options.kaptEvidence),
|
|
13081
|
+
compilerPluginEvidence: kotlinEvidenceSummary(options.compilerPluginEvidence),
|
|
13082
|
+
...metadata
|
|
13083
|
+
}
|
|
13084
|
+
};
|
|
13085
|
+
}
|
|
13086
|
+
|
|
13087
|
+
function kotlinScriptLoss(input, nodeId, span, options = {}) {
|
|
13088
|
+
return {
|
|
13089
|
+
id: `loss_${idFragment(nodeId ?? input.sourcePath ?? 'kotlin')}_kotlin_script_semantics`,
|
|
13090
|
+
severity: 'warning',
|
|
13091
|
+
phase: 'parse',
|
|
13092
|
+
sourceFormat: input.language,
|
|
13093
|
+
kind: 'unsupportedSemantic',
|
|
13094
|
+
message: 'Kotlin script source was imported; script templates, implicit receivers, dependencies, and host execution environment require build/runtime evidence.',
|
|
13095
|
+
span,
|
|
13096
|
+
nodeId,
|
|
13097
|
+
metadata: {
|
|
13098
|
+
parser: options.parser,
|
|
13099
|
+
astFormat: options.astFormat,
|
|
13100
|
+
feature: 'script',
|
|
13101
|
+
unsupportedSemanticKind: 'kotlin.scriptContext',
|
|
13102
|
+
script: true,
|
|
13103
|
+
buildVariantEvidence: kotlinEvidenceSummary(options.buildVariantEvidence)
|
|
13104
|
+
}
|
|
13105
|
+
};
|
|
13106
|
+
}
|
|
13107
|
+
|
|
13108
|
+
function kotlinUnsupportedSemanticLoss(input, nodeId, span, options = {}, metadata = {}) {
|
|
13109
|
+
return {
|
|
13110
|
+
id: `loss_${idFragment(nodeId ?? input.sourcePath ?? 'kotlin')}_kotlin_${idFragment(metadata.feature ?? 'semantic')}`,
|
|
13111
|
+
severity: 'warning',
|
|
13112
|
+
phase: 'parse',
|
|
13113
|
+
sourceFormat: input.language,
|
|
13114
|
+
kind: 'unsupportedSemantic',
|
|
13115
|
+
message: metadata.message ?? 'Kotlin semantic feature requires host compiler evidence.',
|
|
13116
|
+
span,
|
|
13117
|
+
nodeId,
|
|
13118
|
+
metadata: {
|
|
13119
|
+
parser: options.parser,
|
|
13120
|
+
astFormat: options.astFormat,
|
|
13121
|
+
unsupportedSemanticKind: metadata.unsupportedSemanticKind ?? `kotlin.${idFragment(metadata.feature ?? 'semantic')}`,
|
|
13122
|
+
analysisApiEvidence: kotlinEvidenceSummary(options.analysisApiEvidence),
|
|
13123
|
+
firEvidence: kotlinEvidenceSummary(options.firEvidence),
|
|
13124
|
+
multiplatformEvidence: kotlinEvidenceSummary(options.multiplatformEvidence),
|
|
13125
|
+
...metadata
|
|
13126
|
+
}
|
|
13127
|
+
};
|
|
13128
|
+
}
|
|
13129
|
+
|
|
13130
|
+
function kotlinEvidenceSummary(value) {
|
|
13131
|
+
if (!value) return undefined;
|
|
13132
|
+
if (Array.isArray(value)) return { entryCount: value.length };
|
|
13133
|
+
if (typeof value === 'string') return { value };
|
|
13134
|
+
if (typeof value === 'object') {
|
|
13135
|
+
const summary = {};
|
|
13136
|
+
if (typeof value.hash === 'string') summary.hash = value.hash;
|
|
13137
|
+
if (typeof value.solver === 'string') summary.solver = value.solver;
|
|
13138
|
+
if (Array.isArray(value.entries)) summary.entryCount = value.entries.length;
|
|
13139
|
+
if (Array.isArray(value.symbols)) summary.symbolCount = value.symbols.length;
|
|
13140
|
+
if (Array.isArray(value.references)) summary.referenceCount = value.references.length;
|
|
13141
|
+
if (Array.isArray(value.types)) summary.typeCount = value.types.length;
|
|
13142
|
+
if (Array.isArray(value.diagnostics)) summary.diagnosticCount = value.diagnostics.length;
|
|
13143
|
+
if (Array.isArray(value.plugins)) summary.pluginCount = value.plugins.length;
|
|
13144
|
+
if (Array.isArray(value.generatedSources)) summary.generatedSourceCount = value.generatedSources.length;
|
|
13145
|
+
if (Array.isArray(value.platforms)) summary.platformCount = value.platforms.length;
|
|
13146
|
+
if (Array.isArray(value.variants)) summary.variantCount = value.variants.length;
|
|
13147
|
+
return Object.keys(summary).length ? summary : { present: true };
|
|
13148
|
+
}
|
|
13149
|
+
return { present: true };
|
|
13150
|
+
}
|
|
13151
|
+
|
|
12351
13152
|
function csharpRoslynRoot(value) {
|
|
12352
13153
|
if (!value || typeof value !== 'object') return undefined;
|
|
12353
13154
|
if (isCSharpRoslynNode(value)) return value;
|
package/package.json
CHANGED