@shapeshift-labs/frontier-lang-compiler 0.2.29 → 0.2.31
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 +18 -2
- package/bench/smoke.mjs +3 -1
- package/dist/index.d.ts +68 -0
- package/dist/index.js +1484 -82
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -427,6 +427,31 @@ export const NativeParserAstFormatProfiles = Object.freeze([
|
|
|
427
427
|
supportsErrorRecovery: true,
|
|
428
428
|
notes: ['Go go/ast trees expose parser syntax nodes and token positions; FileSet, build tags, generated-code classification, package loading, go/types, comments/trivia, and control-flow evidence remain host-owned.']
|
|
429
429
|
}),
|
|
430
|
+
nativeParserAstFormatProfile('java-ast', {
|
|
431
|
+
aliases: ['javac', 'javac-tree', 'jdt', 'eclipse-jdt', 'javaparser', 'java-parser'],
|
|
432
|
+
kind: 'compiler-ast',
|
|
433
|
+
languages: ['java'],
|
|
434
|
+
parserAdapters: ['javac', 'jdt', 'javaparser', 'java-ast'],
|
|
435
|
+
exactness: 'exact-parser-ast',
|
|
436
|
+
sourceRangeModel: 'java-source-range',
|
|
437
|
+
preservesTokens: false,
|
|
438
|
+
preservesTrivia: false,
|
|
439
|
+
supportsErrorRecovery: true,
|
|
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
|
+
}),
|
|
442
|
+
nativeParserAstFormatProfile('roslyn-csharp', {
|
|
443
|
+
aliases: ['roslyn', 'csharp-roslyn', 'c#-roslyn', 'microsoft-codeanalysis-csharp', 'csharp-syntax'],
|
|
444
|
+
kind: 'compiler-ast',
|
|
445
|
+
languages: ['csharp'],
|
|
446
|
+
parserAdapters: ['roslyn', 'microsoft.codeanalysis.csharp', 'csharp-roslyn'],
|
|
447
|
+
exactness: 'exact-parser-ast',
|
|
448
|
+
sourceRangeModel: 'text-span-line-position-span',
|
|
449
|
+
preservesTokens: true,
|
|
450
|
+
preservesTrivia: true,
|
|
451
|
+
supportsIncremental: true,
|
|
452
|
+
supportsErrorRecovery: true,
|
|
453
|
+
notes: ['Roslyn C# syntax trees expose immutable nodes, tokens, trivia, spans, diagnostics, directives, and skipped text; SemanticModel symbols, nullable analysis, generated sources, partial type stitching, analyzer results, and project references remain host-owned evidence.']
|
|
454
|
+
}),
|
|
430
455
|
nativeParserAstFormatProfile('tree-sitter', {
|
|
431
456
|
kind: 'concrete-syntax-tree',
|
|
432
457
|
languages: ['mixed'],
|
|
@@ -2855,6 +2880,138 @@ export function createGoAstNativeImporterAdapter(options = {}) {
|
|
|
2855
2880
|
};
|
|
2856
2881
|
}
|
|
2857
2882
|
|
|
2883
|
+
export function createJavaAstNativeImporterAdapter(options = {}) {
|
|
2884
|
+
return {
|
|
2885
|
+
id: options.id ?? 'frontier.java-ast-native-importer',
|
|
2886
|
+
language: options.language ?? 'java',
|
|
2887
|
+
parser: options.parser ?? 'javac',
|
|
2888
|
+
version: options.version,
|
|
2889
|
+
capabilities: uniqueStrings(['nativeAst', 'semanticIndex', 'sourceMaps', 'diagnostics', ...(options.capabilities ?? [])]),
|
|
2890
|
+
coverage: nativeImporterAdapterCoverage({
|
|
2891
|
+
exactness: 'exact-parser-ast',
|
|
2892
|
+
exactAst: true,
|
|
2893
|
+
tokens: false,
|
|
2894
|
+
trivia: false,
|
|
2895
|
+
diagnostics: true,
|
|
2896
|
+
sourceRanges: true,
|
|
2897
|
+
generatedRanges: false,
|
|
2898
|
+
semanticCoverage: declarationSemanticCoverage(),
|
|
2899
|
+
notes: [
|
|
2900
|
+
'Normalizes caller-owned javac/JDT/JavaParser-shaped Java ASTs into native AST nodes and declaration-level semantic index records.',
|
|
2901
|
+
'Java AST imports do not resolve overloads, bindings, annotation processors, generated Lombok code, classpaths, modules, bytecode, comments/trivia, or control flow by themselves; attach host evidence for those claims.'
|
|
2902
|
+
]
|
|
2903
|
+
}, options.coverage),
|
|
2904
|
+
supportedExtensions: options.supportedExtensions ?? ['.java'],
|
|
2905
|
+
diagnostics: options.diagnostics,
|
|
2906
|
+
parse(input) {
|
|
2907
|
+
const parsed = input.options?.ast
|
|
2908
|
+
?? input.options?.nativeAst
|
|
2909
|
+
?? input.options?.compilationUnit
|
|
2910
|
+
?? input.options?.unit
|
|
2911
|
+
?? input.options?.sourceFile
|
|
2912
|
+
?? options.ast
|
|
2913
|
+
?? options.compilationUnit
|
|
2914
|
+
?? options.unit
|
|
2915
|
+
?? options.sourceFile
|
|
2916
|
+
?? parseJavaAstSource(input, options);
|
|
2917
|
+
const root = javaAstRoot(parsed);
|
|
2918
|
+
if (!root) {
|
|
2919
|
+
return missingInjectedParserResult(input, {
|
|
2920
|
+
parser: options.parser ?? 'javac',
|
|
2921
|
+
adapterId: options.id ?? 'frontier.java-ast-native-importer',
|
|
2922
|
+
message: 'createJavaAstNativeImporterAdapter requires an injected Java AST object, parserModule.parse function, parse function, or adapterOptions.ast.'
|
|
2923
|
+
});
|
|
2924
|
+
}
|
|
2925
|
+
const parseDiagnostics = normalizeParserErrors(parsed?.errors ?? parsed?.diagnostics ?? parsed?.problems, input, {
|
|
2926
|
+
parser: options.parser ?? 'javac'
|
|
2927
|
+
});
|
|
2928
|
+
return createNativeImportFromJavaAst(root, input, {
|
|
2929
|
+
parser: options.parser ?? 'javac',
|
|
2930
|
+
astFormat: 'java-ast',
|
|
2931
|
+
maxNodes: options.maxNodes,
|
|
2932
|
+
diagnostics: parseDiagnostics,
|
|
2933
|
+
javaVersion: options.javaVersion ?? input.options?.javaVersion ?? parsed?.javaVersion,
|
|
2934
|
+
sourceLevel: options.sourceLevel ?? input.options?.sourceLevel ?? parsed?.sourceLevel,
|
|
2935
|
+
classPath: input.options?.classPath ?? options.classPath ?? parsed?.classPath,
|
|
2936
|
+
modulePath: input.options?.modulePath ?? options.modulePath ?? parsed?.modulePath,
|
|
2937
|
+
generated: input.options?.generated ?? options.generated ?? parsed?.generated,
|
|
2938
|
+
annotationProcessing: input.options?.annotationProcessing ?? options.annotationProcessing ?? parsed?.annotationProcessing,
|
|
2939
|
+
bindingEvidence: input.options?.bindingEvidence ?? options.bindingEvidence ?? parsed?.bindingEvidence,
|
|
2940
|
+
positionResolver: input.options?.positionResolver ?? options.positionResolver,
|
|
2941
|
+
lineMap: input.options?.lineMap ?? options.lineMap ?? parsed?.lineMap,
|
|
2942
|
+
includeAnnotations: options.includeAnnotations ?? input.options?.includeAnnotations
|
|
2943
|
+
});
|
|
2944
|
+
}
|
|
2945
|
+
};
|
|
2946
|
+
}
|
|
2947
|
+
|
|
2948
|
+
export function createCSharpRoslynNativeImporterAdapter(options = {}) {
|
|
2949
|
+
return {
|
|
2950
|
+
id: options.id ?? 'frontier.csharp-roslyn-native-importer',
|
|
2951
|
+
language: options.language ?? 'csharp',
|
|
2952
|
+
parser: options.parser ?? 'roslyn',
|
|
2953
|
+
version: options.version,
|
|
2954
|
+
capabilities: uniqueStrings(['nativeAst', 'semanticIndex', 'sourceMaps', 'diagnostics', ...(options.capabilities ?? [])]),
|
|
2955
|
+
coverage: nativeImporterAdapterCoverage({
|
|
2956
|
+
exactness: 'exact-parser-ast',
|
|
2957
|
+
exactAst: true,
|
|
2958
|
+
tokens: true,
|
|
2959
|
+
trivia: true,
|
|
2960
|
+
diagnostics: true,
|
|
2961
|
+
sourceRanges: true,
|
|
2962
|
+
generatedRanges: false,
|
|
2963
|
+
semanticCoverage: declarationSemanticCoverage(),
|
|
2964
|
+
notes: [
|
|
2965
|
+
'Normalizes caller-owned Roslyn C# SyntaxTree/SyntaxNode-shaped objects into native AST nodes and declaration-level semantic index records.',
|
|
2966
|
+
'Roslyn syntax imports do not resolve SemanticModel symbols, overloads, nullable flow, source generators, partial types, project references, or analyzer results by themselves; attach host evidence for those claims.'
|
|
2967
|
+
]
|
|
2968
|
+
}, options.coverage),
|
|
2969
|
+
supportedExtensions: options.supportedExtensions ?? ['.cs'],
|
|
2970
|
+
diagnostics: options.diagnostics,
|
|
2971
|
+
parse(input) {
|
|
2972
|
+
const parsed = input.options?.ast
|
|
2973
|
+
?? input.options?.nativeAst
|
|
2974
|
+
?? input.options?.syntaxTree
|
|
2975
|
+
?? input.options?.tree
|
|
2976
|
+
?? input.options?.root
|
|
2977
|
+
?? input.options?.compilationUnit
|
|
2978
|
+
?? options.ast
|
|
2979
|
+
?? options.syntaxTree
|
|
2980
|
+
?? options.tree
|
|
2981
|
+
?? options.root
|
|
2982
|
+
?? options.compilationUnit
|
|
2983
|
+
?? parseCSharpRoslynSource(input, options);
|
|
2984
|
+
const root = csharpRoslynRoot(parsed);
|
|
2985
|
+
if (!root) {
|
|
2986
|
+
return missingInjectedParserResult(input, {
|
|
2987
|
+
parser: options.parser ?? 'roslyn',
|
|
2988
|
+
adapterId: options.id ?? 'frontier.csharp-roslyn-native-importer',
|
|
2989
|
+
message: 'createCSharpRoslynNativeImporterAdapter requires an injected Roslyn SyntaxTree/SyntaxNode object, parserModule.parse function, parse function, or adapterOptions.ast.'
|
|
2990
|
+
});
|
|
2991
|
+
}
|
|
2992
|
+
const parseDiagnostics = normalizeParserErrors(parsed?.errors ?? parsed?.diagnostics ?? parsed?.parseDiagnostics, input, {
|
|
2993
|
+
parser: options.parser ?? 'roslyn'
|
|
2994
|
+
});
|
|
2995
|
+
return createNativeImportFromCSharpRoslyn(root, input, {
|
|
2996
|
+
parser: options.parser ?? 'roslyn',
|
|
2997
|
+
astFormat: 'roslyn-csharp',
|
|
2998
|
+
maxNodes: options.maxNodes,
|
|
2999
|
+
diagnostics: parseDiagnostics,
|
|
3000
|
+
csharpVersion: options.csharpVersion ?? input.options?.csharpVersion ?? parsed?.csharpVersion,
|
|
3001
|
+
languageVersion: options.languageVersion ?? input.options?.languageVersion ?? parsed?.languageVersion,
|
|
3002
|
+
nullableContext: input.options?.nullableContext ?? options.nullableContext ?? parsed?.nullableContext,
|
|
3003
|
+
generated: input.options?.generated ?? options.generated ?? parsed?.generated ?? csharpGeneratedSourcePath(input.sourcePath),
|
|
3004
|
+
projectReferences: input.options?.projectReferences ?? options.projectReferences ?? parsed?.projectReferences,
|
|
3005
|
+
analyzerDiagnostics: input.options?.analyzerDiagnostics ?? options.analyzerDiagnostics ?? parsed?.analyzerDiagnostics,
|
|
3006
|
+
semanticModelEvidence: input.options?.semanticModelEvidence ?? options.semanticModelEvidence ?? parsed?.semanticModelEvidence,
|
|
3007
|
+
sourceGeneratorEvidence: input.options?.sourceGeneratorEvidence ?? options.sourceGeneratorEvidence ?? parsed?.sourceGeneratorEvidence,
|
|
3008
|
+
positionResolver: input.options?.positionResolver ?? options.positionResolver,
|
|
3009
|
+
lineMap: input.options?.lineMap ?? options.lineMap ?? parsed?.lineMap
|
|
3010
|
+
});
|
|
3011
|
+
}
|
|
3012
|
+
};
|
|
3013
|
+
}
|
|
3014
|
+
|
|
2858
3015
|
export function createTreeSitterNativeImporterAdapter(options = {}) {
|
|
2859
3016
|
return {
|
|
2860
3017
|
id: options.id ?? `frontier.tree-sitter-${idFragment(options.language ?? 'source')}-native-importer`,
|
|
@@ -7297,6 +7454,8 @@ function parserAstFormatIdForParser(parser) {
|
|
|
7297
7454
|
if (text.includes('rust-analyzer') || text.includes('rowan')) return 'rust-analyzer-rowan';
|
|
7298
7455
|
if (text.includes('clang') || text.includes('libclang')) return 'clang-ast-json';
|
|
7299
7456
|
if (text === 'go' || text.includes('go-parser') || text.includes('go-ast') || text.includes('go/parser') || text.includes('go/ast')) return 'go-ast';
|
|
7457
|
+
if (text === 'java' || text.includes('javac') || text.includes('jdt') || text.includes('javaparser') || text.includes('java-parser') || text.includes('java-ast')) return 'java-ast';
|
|
7458
|
+
if (text === 'csharp' || text === 'c#' || text === 'cs' || text.includes('roslyn') || text.includes('microsoft-codeanalysis-csharp') || text.includes('csharp-syntax')) return 'roslyn-csharp';
|
|
7300
7459
|
if (text.includes('tree-sitter') || text.includes('treesitter')) return 'tree-sitter';
|
|
7301
7460
|
if (text.includes('babel')) return 'babel';
|
|
7302
7461
|
if (text.includes('estree')) return 'estree';
|
|
@@ -8378,6 +8537,39 @@ function parseGoAstSource(input, options) {
|
|
|
8378
8537
|
return parse(input.sourceText, parserOptions);
|
|
8379
8538
|
}
|
|
8380
8539
|
|
|
8540
|
+
function parseJavaAstSource(input, options) {
|
|
8541
|
+
const parse = options.parse ?? options.parserModule?.parse ?? options.javac?.parse ?? options.jdt?.parse ?? options.javaParser?.parse;
|
|
8542
|
+
if (typeof parse !== 'function') return undefined;
|
|
8543
|
+
const parserOptions = {
|
|
8544
|
+
sourcePath: input.sourcePath,
|
|
8545
|
+
filename: input.sourcePath,
|
|
8546
|
+
javaVersion: options.javaVersion ?? input.options?.javaVersion,
|
|
8547
|
+
sourceLevel: options.sourceLevel ?? input.options?.sourceLevel,
|
|
8548
|
+
classPath: options.classPath ?? input.options?.classPath,
|
|
8549
|
+
modulePath: options.modulePath ?? input.options?.modulePath,
|
|
8550
|
+
includeAnnotations: options.includeAnnotations ?? input.options?.includeAnnotations,
|
|
8551
|
+
...(options.parserOptions ?? {}),
|
|
8552
|
+
...(input.options?.parserOptions ?? {})
|
|
8553
|
+
};
|
|
8554
|
+
return parse(input.sourceText, parserOptions);
|
|
8555
|
+
}
|
|
8556
|
+
|
|
8557
|
+
function parseCSharpRoslynSource(input, options) {
|
|
8558
|
+
const parse = options.parse ?? options.parserModule?.parse ?? options.roslyn?.parse ?? options.csharpRoslyn?.parse;
|
|
8559
|
+
if (typeof parse !== 'function') return undefined;
|
|
8560
|
+
const parserOptions = {
|
|
8561
|
+
sourcePath: input.sourcePath,
|
|
8562
|
+
filename: input.sourcePath,
|
|
8563
|
+
languageVersion: options.languageVersion ?? input.options?.languageVersion,
|
|
8564
|
+
csharpVersion: options.csharpVersion ?? input.options?.csharpVersion,
|
|
8565
|
+
nullableContext: options.nullableContext ?? input.options?.nullableContext,
|
|
8566
|
+
kind: options.sourceCodeKind ?? input.options?.sourceCodeKind,
|
|
8567
|
+
...(options.parserOptions ?? {}),
|
|
8568
|
+
...(input.options?.parserOptions ?? {})
|
|
8569
|
+
};
|
|
8570
|
+
return parse(input.sourceText, parserOptions);
|
|
8571
|
+
}
|
|
8572
|
+
|
|
8381
8573
|
function createNativeImportFromSyntaxAst(ast, input, options) {
|
|
8382
8574
|
const root = normalizeSyntaxAstRoot(ast, options.astFormat);
|
|
8383
8575
|
if (!root) {
|
|
@@ -8569,6 +8761,84 @@ function createNativeImportFromGoAst(root, input, options) {
|
|
|
8569
8761
|
};
|
|
8570
8762
|
}
|
|
8571
8763
|
|
|
8764
|
+
function createNativeImportFromJavaAst(root, input, options) {
|
|
8765
|
+
const context = createAstNormalizationContext(input, options);
|
|
8766
|
+
visitJavaAstNode(root, context, 'root');
|
|
8767
|
+
if (context.truncated) {
|
|
8768
|
+
context.losses.push(truncatedAstLoss(input, context, options));
|
|
8769
|
+
}
|
|
8770
|
+
if (options.generated && !context.losses.some((loss) => loss.kind === 'generatedCode')) {
|
|
8771
|
+
context.losses.push(javaGeneratedCodeLoss(input, context.rootId, undefined, options));
|
|
8772
|
+
}
|
|
8773
|
+
const semantic = semanticIndexFromNativeDeclarations(context.declarations, input, options);
|
|
8774
|
+
return {
|
|
8775
|
+
rootId: context.rootId,
|
|
8776
|
+
nodes: context.nodes,
|
|
8777
|
+
semanticIndex: semantic.semanticIndex,
|
|
8778
|
+
mappings: semantic.mappings,
|
|
8779
|
+
losses: mergeNativeLosses(context.losses, options.diagnostics?.map((diagnostic, index) => adapterDiagnosticToLoss(diagnostic, index, {
|
|
8780
|
+
id: input.adapterId,
|
|
8781
|
+
version: input.adapterVersion
|
|
8782
|
+
}, input)) ?? []),
|
|
8783
|
+
evidence: semantic.evidence,
|
|
8784
|
+
diagnostics: options.diagnostics,
|
|
8785
|
+
metadata: {
|
|
8786
|
+
astFormat: options.astFormat,
|
|
8787
|
+
parser: options.parser,
|
|
8788
|
+
javaVersion: options.javaVersion,
|
|
8789
|
+
sourceLevel: options.sourceLevel,
|
|
8790
|
+
classPathEvidence: javaPathEvidenceSummary(options.classPath),
|
|
8791
|
+
modulePathEvidence: javaPathEvidenceSummary(options.modulePath),
|
|
8792
|
+
annotationProcessing: javaAnnotationProcessingSummary(options.annotationProcessing),
|
|
8793
|
+
bindingEvidence: javaBindingEvidenceSummary(options.bindingEvidence),
|
|
8794
|
+
generated: options.generated,
|
|
8795
|
+
includeAnnotations: Boolean(options.includeAnnotations),
|
|
8796
|
+
normalizedNodeCount: Object.keys(context.nodes).length,
|
|
8797
|
+
declarationCount: context.declarations.length,
|
|
8798
|
+
truncated: context.truncated
|
|
8799
|
+
}
|
|
8800
|
+
};
|
|
8801
|
+
}
|
|
8802
|
+
|
|
8803
|
+
function createNativeImportFromCSharpRoslyn(root, input, options) {
|
|
8804
|
+
const context = createAstNormalizationContext(input, options);
|
|
8805
|
+
visitCSharpRoslynNode(root, context, 'root');
|
|
8806
|
+
if (context.truncated) {
|
|
8807
|
+
context.losses.push(truncatedAstLoss(input, context, options));
|
|
8808
|
+
}
|
|
8809
|
+
if (options.generated && !context.losses.some((loss) => loss.kind === 'generatedCode')) {
|
|
8810
|
+
context.losses.push(csharpGeneratedCodeLoss(input, context.rootId, undefined, options));
|
|
8811
|
+
}
|
|
8812
|
+
const semantic = semanticIndexFromNativeDeclarations(context.declarations, input, options);
|
|
8813
|
+
return {
|
|
8814
|
+
rootId: context.rootId,
|
|
8815
|
+
nodes: context.nodes,
|
|
8816
|
+
semanticIndex: semantic.semanticIndex,
|
|
8817
|
+
mappings: semantic.mappings,
|
|
8818
|
+
losses: mergeNativeLosses(context.losses, options.diagnostics?.map((diagnostic, index) => adapterDiagnosticToLoss(diagnostic, index, {
|
|
8819
|
+
id: input.adapterId,
|
|
8820
|
+
version: input.adapterVersion
|
|
8821
|
+
}, input)) ?? []),
|
|
8822
|
+
evidence: semantic.evidence,
|
|
8823
|
+
diagnostics: options.diagnostics,
|
|
8824
|
+
metadata: {
|
|
8825
|
+
astFormat: options.astFormat,
|
|
8826
|
+
parser: options.parser,
|
|
8827
|
+
csharpVersion: options.csharpVersion,
|
|
8828
|
+
languageVersion: options.languageVersion,
|
|
8829
|
+
nullableContext: options.nullableContext,
|
|
8830
|
+
generated: options.generated,
|
|
8831
|
+
projectReferences: csharpEvidenceSummary(options.projectReferences),
|
|
8832
|
+
analyzerDiagnostics: csharpEvidenceSummary(options.analyzerDiagnostics),
|
|
8833
|
+
semanticModelEvidence: csharpEvidenceSummary(options.semanticModelEvidence),
|
|
8834
|
+
sourceGeneratorEvidence: csharpEvidenceSummary(options.sourceGeneratorEvidence),
|
|
8835
|
+
normalizedNodeCount: Object.keys(context.nodes).length,
|
|
8836
|
+
declarationCount: context.declarations.length,
|
|
8837
|
+
truncated: context.truncated
|
|
8838
|
+
}
|
|
8839
|
+
};
|
|
8840
|
+
}
|
|
8841
|
+
|
|
8572
8842
|
function createNativeImportFromTreeSitter(root, input, options) {
|
|
8573
8843
|
const context = createAstNormalizationContext(input, options);
|
|
8574
8844
|
visitTreeSitterNode(root, context, 'root');
|
|
@@ -8972,120 +9242,278 @@ function visitGoAstNode(node, context, propertyPath) {
|
|
|
8972
9242
|
return id;
|
|
8973
9243
|
}
|
|
8974
9244
|
|
|
8975
|
-
function
|
|
8976
|
-
if (!node ||
|
|
9245
|
+
function visitJavaAstNode(node, context, propertyPath) {
|
|
9246
|
+
if (!isJavaAstNode(node) || context.truncated) return undefined;
|
|
8977
9247
|
if (context.objectIds.has(node)) return context.objectIds.get(node);
|
|
8978
9248
|
if (context.counter >= context.maxNodes) {
|
|
8979
9249
|
context.truncated = true;
|
|
8980
9250
|
return undefined;
|
|
8981
9251
|
}
|
|
8982
|
-
const kind =
|
|
8983
|
-
const span =
|
|
9252
|
+
const kind = javaAstKind(node);
|
|
9253
|
+
const span = spanFromJavaAstNode(node, context.input, context.options);
|
|
8984
9254
|
const id = nativeNodeId(context, kind, { start: { line: span?.startLine, column: span?.startColumn } }, propertyPath);
|
|
8985
9255
|
context.objectIds.set(node, id);
|
|
8986
9256
|
if (!context.rootId) context.rootId = id;
|
|
8987
9257
|
const children = [];
|
|
8988
|
-
const
|
|
8989
|
-
|
|
8990
|
-
|
|
8991
|
-
|
|
8992
|
-
|
|
8993
|
-
|
|
8994
|
-
|
|
8995
|
-
|
|
8996
|
-
|
|
8997
|
-
|
|
9258
|
+
for (const [field, value] of javaAstChildEntries(node, kind)) {
|
|
9259
|
+
if (Array.isArray(value)) {
|
|
9260
|
+
value.forEach((entry, index) => {
|
|
9261
|
+
const childId = visitJavaAstNode(entry, context, `${propertyPath}.${field}[${index}]`);
|
|
9262
|
+
if (childId) children.push(childId);
|
|
9263
|
+
});
|
|
9264
|
+
} else {
|
|
9265
|
+
const childId = visitJavaAstNode(value, context, `${propertyPath}.${field}`);
|
|
9266
|
+
if (childId) children.push(childId);
|
|
9267
|
+
}
|
|
9268
|
+
}
|
|
9269
|
+
const declarations = javaAstDeclarations(node, kind, id, context.input);
|
|
9270
|
+
const declaration = declarations[0];
|
|
8998
9271
|
const nativeNode = {
|
|
8999
9272
|
id,
|
|
9000
9273
|
kind,
|
|
9001
9274
|
languageKind: `${context.input.language}.${kind}`,
|
|
9002
9275
|
span,
|
|
9003
|
-
value: declaration?.name ??
|
|
9004
|
-
fields:
|
|
9005
|
-
named: Boolean(node.isNamed ?? node.named),
|
|
9006
|
-
missing: Boolean(node.isMissing),
|
|
9007
|
-
error: Boolean(node.hasError || kind === 'ERROR')
|
|
9008
|
-
},
|
|
9276
|
+
value: declaration?.name ?? javaAstNodeValue(node),
|
|
9277
|
+
fields: primitiveJavaAstFields(node, kind),
|
|
9009
9278
|
children,
|
|
9010
9279
|
metadata: {
|
|
9011
9280
|
astFormat: context.options.astFormat,
|
|
9012
9281
|
propertyPath,
|
|
9013
|
-
|
|
9014
|
-
|
|
9282
|
+
positionKind: javaAstPositionKind(node),
|
|
9283
|
+
parser: context.options.parser
|
|
9015
9284
|
}
|
|
9016
9285
|
};
|
|
9017
9286
|
context.nodes[id] = nativeNode;
|
|
9018
|
-
|
|
9019
|
-
|
|
9287
|
+
for (const entry of declarations) {
|
|
9288
|
+
context.declarations.push({ ...entry, nativeNode });
|
|
9289
|
+
}
|
|
9290
|
+
if (javaRecoveredAstKind(kind) || javaProblemNode(node, kind)) {
|
|
9020
9291
|
context.losses.push({
|
|
9021
|
-
id: `loss_${idFragment(id)}
|
|
9292
|
+
id: `loss_${idFragment(id)}_java_recovered_node`,
|
|
9022
9293
|
severity: 'error',
|
|
9023
9294
|
phase: 'parse',
|
|
9024
9295
|
sourceFormat: context.input.language,
|
|
9025
9296
|
kind: 'unsupportedSyntax',
|
|
9026
|
-
message: '
|
|
9297
|
+
message: 'Java parser reported a recovered, erroneous, malformed, or problem node; semantic import is partial until syntax errors are resolved.',
|
|
9027
9298
|
span,
|
|
9028
|
-
nodeId: id
|
|
9299
|
+
nodeId: id,
|
|
9300
|
+
metadata: {
|
|
9301
|
+
parser: context.options.parser,
|
|
9302
|
+
astFormat: context.options.astFormat,
|
|
9303
|
+
nodeKind: kind
|
|
9304
|
+
}
|
|
9029
9305
|
});
|
|
9030
9306
|
}
|
|
9307
|
+
if (javaGeneratedCodeMarker(node, kind) || javaLombokAnnotationMarker(node, kind)) {
|
|
9308
|
+
context.losses.push(javaGeneratedCodeLoss(context.input, id, span, context.options, {
|
|
9309
|
+
nodeKind: kind,
|
|
9310
|
+
generatedMarker: javaGeneratedCodeMarker(node, kind),
|
|
9311
|
+
lombokMarker: javaLombokAnnotationMarker(node, kind)
|
|
9312
|
+
}));
|
|
9313
|
+
}
|
|
9031
9314
|
return id;
|
|
9032
9315
|
}
|
|
9033
9316
|
|
|
9034
|
-
function
|
|
9035
|
-
|
|
9036
|
-
|
|
9037
|
-
|
|
9038
|
-
|
|
9039
|
-
|
|
9040
|
-
|
|
9041
|
-
const
|
|
9042
|
-
|
|
9043
|
-
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9062
|
-
|
|
9063
|
-
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
-
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
|
|
9083
|
-
|
|
9084
|
-
|
|
9085
|
-
|
|
9086
|
-
|
|
9087
|
-
|
|
9088
|
-
|
|
9317
|
+
function visitCSharpRoslynNode(node, context, propertyPath) {
|
|
9318
|
+
if (!isCSharpRoslynNode(node) || context.truncated) return undefined;
|
|
9319
|
+
if (context.objectIds.has(node)) return context.objectIds.get(node);
|
|
9320
|
+
if (context.counter >= context.maxNodes) {
|
|
9321
|
+
context.truncated = true;
|
|
9322
|
+
return undefined;
|
|
9323
|
+
}
|
|
9324
|
+
const kind = csharpRoslynKind(node);
|
|
9325
|
+
const span = spanFromCSharpRoslynNode(node, context.input, context.options);
|
|
9326
|
+
const id = nativeNodeId(context, kind, { start: { line: span?.startLine, column: span?.startColumn } }, propertyPath);
|
|
9327
|
+
context.objectIds.set(node, id);
|
|
9328
|
+
if (!context.rootId) context.rootId = id;
|
|
9329
|
+
const children = [];
|
|
9330
|
+
for (const [field, value] of csharpRoslynChildEntries(node, kind)) {
|
|
9331
|
+
if (Array.isArray(value)) {
|
|
9332
|
+
value.forEach((entry, index) => {
|
|
9333
|
+
const childId = visitCSharpRoslynNode(entry, context, `${propertyPath}.${field}[${index}]`);
|
|
9334
|
+
if (childId) children.push(childId);
|
|
9335
|
+
});
|
|
9336
|
+
} else {
|
|
9337
|
+
const childId = visitCSharpRoslynNode(value, context, `${propertyPath}.${field}`);
|
|
9338
|
+
if (childId) children.push(childId);
|
|
9339
|
+
}
|
|
9340
|
+
}
|
|
9341
|
+
const declarations = csharpRoslynDeclarations(node, kind, id, context.input);
|
|
9342
|
+
const declaration = declarations[0];
|
|
9343
|
+
const nativeNode = {
|
|
9344
|
+
id,
|
|
9345
|
+
kind,
|
|
9346
|
+
languageKind: `${context.input.language}.${kind}`,
|
|
9347
|
+
span,
|
|
9348
|
+
value: declaration?.name ?? csharpRoslynNodeValue(node),
|
|
9349
|
+
fields: primitiveCSharpRoslynFields(node, kind),
|
|
9350
|
+
children,
|
|
9351
|
+
metadata: {
|
|
9352
|
+
astFormat: context.options.astFormat,
|
|
9353
|
+
propertyPath,
|
|
9354
|
+
rawKind: numberOrUndefined(node.rawKind ?? node.RawKind),
|
|
9355
|
+
positionKind: csharpRoslynPositionKind(node),
|
|
9356
|
+
parser: context.options.parser
|
|
9357
|
+
}
|
|
9358
|
+
};
|
|
9359
|
+
context.nodes[id] = nativeNode;
|
|
9360
|
+
for (const entry of declarations) {
|
|
9361
|
+
context.declarations.push({ ...entry, nativeNode });
|
|
9362
|
+
}
|
|
9363
|
+
if (csharpRoslynRecoveredKind(kind) || csharpRoslynProblemNode(node, kind)) {
|
|
9364
|
+
context.losses.push({
|
|
9365
|
+
id: `loss_${idFragment(id)}_csharp_roslyn_recovered_node`,
|
|
9366
|
+
severity: 'error',
|
|
9367
|
+
phase: 'parse',
|
|
9368
|
+
sourceFormat: context.input.language,
|
|
9369
|
+
kind: 'unsupportedSyntax',
|
|
9370
|
+
message: 'Roslyn reported skipped text, missing syntax, or syntax diagnostics; semantic import is partial until syntax errors are resolved.',
|
|
9371
|
+
span,
|
|
9372
|
+
nodeId: id,
|
|
9373
|
+
metadata: {
|
|
9374
|
+
parser: context.options.parser,
|
|
9375
|
+
astFormat: context.options.astFormat,
|
|
9376
|
+
nodeKind: kind
|
|
9377
|
+
}
|
|
9378
|
+
});
|
|
9379
|
+
}
|
|
9380
|
+
if (csharpRoslynDirectiveKind(kind)) {
|
|
9381
|
+
context.losses.push({
|
|
9382
|
+
id: `loss_${idFragment(id)}_csharp_preprocessor`,
|
|
9383
|
+
severity: 'warning',
|
|
9384
|
+
phase: 'parse',
|
|
9385
|
+
sourceFormat: context.input.language,
|
|
9386
|
+
kind: 'preprocessor',
|
|
9387
|
+
message: 'C# preprocessor directive was imported as syntax; conditional compilation state and inactive branches require host evidence.',
|
|
9388
|
+
span,
|
|
9389
|
+
nodeId: id,
|
|
9390
|
+
metadata: {
|
|
9391
|
+
parser: context.options.parser,
|
|
9392
|
+
astFormat: context.options.astFormat,
|
|
9393
|
+
nodeKind: kind
|
|
9394
|
+
}
|
|
9395
|
+
});
|
|
9396
|
+
}
|
|
9397
|
+
if (csharpGeneratedCodeMarker(node, kind)) {
|
|
9398
|
+
context.losses.push(csharpGeneratedCodeLoss(context.input, id, span, context.options, { nodeKind: kind }));
|
|
9399
|
+
}
|
|
9400
|
+
return id;
|
|
9401
|
+
}
|
|
9402
|
+
|
|
9403
|
+
function visitTreeSitterNode(node, context, propertyPath) {
|
|
9404
|
+
if (!node || typeof node !== 'object' || context.truncated) return undefined;
|
|
9405
|
+
if (context.objectIds.has(node)) return context.objectIds.get(node);
|
|
9406
|
+
if (context.counter >= context.maxNodes) {
|
|
9407
|
+
context.truncated = true;
|
|
9408
|
+
return undefined;
|
|
9409
|
+
}
|
|
9410
|
+
const kind = String(node.type ?? node.kind ?? 'node');
|
|
9411
|
+
const span = spanFromTreeSitterNode(node, context.input);
|
|
9412
|
+
const id = nativeNodeId(context, kind, { start: { line: span?.startLine, column: span?.startColumn } }, propertyPath);
|
|
9413
|
+
context.objectIds.set(node, id);
|
|
9414
|
+
if (!context.rootId) context.rootId = id;
|
|
9415
|
+
const children = [];
|
|
9416
|
+
const rawChildren = Array.isArray(node.namedChildren)
|
|
9417
|
+
? node.namedChildren
|
|
9418
|
+
: Array.isArray(node.children)
|
|
9419
|
+
? node.children
|
|
9420
|
+
: [];
|
|
9421
|
+
rawChildren.forEach((child, index) => {
|
|
9422
|
+
const childId = visitTreeSitterNode(child, context, `${propertyPath}.children[${index}]`);
|
|
9423
|
+
if (childId) children.push(childId);
|
|
9424
|
+
});
|
|
9425
|
+
const declaration = treeSitterDeclaration(node, kind, id, context.input, context.options);
|
|
9426
|
+
const nativeNode = {
|
|
9427
|
+
id,
|
|
9428
|
+
kind,
|
|
9429
|
+
languageKind: `${context.input.language}.${kind}`,
|
|
9430
|
+
span,
|
|
9431
|
+
value: declaration?.name ?? shortNodeText(node),
|
|
9432
|
+
fields: {
|
|
9433
|
+
named: Boolean(node.isNamed ?? node.named),
|
|
9434
|
+
missing: Boolean(node.isMissing),
|
|
9435
|
+
error: Boolean(node.hasError || kind === 'ERROR')
|
|
9436
|
+
},
|
|
9437
|
+
children,
|
|
9438
|
+
metadata: {
|
|
9439
|
+
astFormat: context.options.astFormat,
|
|
9440
|
+
propertyPath,
|
|
9441
|
+
startIndex: numberOrUndefined(node.startIndex),
|
|
9442
|
+
endIndex: numberOrUndefined(node.endIndex)
|
|
9443
|
+
}
|
|
9444
|
+
};
|
|
9445
|
+
context.nodes[id] = nativeNode;
|
|
9446
|
+
if (declaration) context.declarations.push({ ...declaration, nativeNode });
|
|
9447
|
+
if (node.hasError || kind === 'ERROR') {
|
|
9448
|
+
context.losses.push({
|
|
9449
|
+
id: `loss_${idFragment(id)}_tree_sitter_error`,
|
|
9450
|
+
severity: 'error',
|
|
9451
|
+
phase: 'parse',
|
|
9452
|
+
sourceFormat: context.input.language,
|
|
9453
|
+
kind: 'unsupportedSyntax',
|
|
9454
|
+
message: 'Tree-sitter reported a parse error node.',
|
|
9455
|
+
span,
|
|
9456
|
+
nodeId: id
|
|
9457
|
+
});
|
|
9458
|
+
}
|
|
9459
|
+
return id;
|
|
9460
|
+
}
|
|
9461
|
+
|
|
9462
|
+
function semanticIndexFromNativeDeclarations(declarations, input, options) {
|
|
9463
|
+
const documentId = `doc_${idFragment(input.sourcePath ?? input.language)}_${idFragment(input.sourceHash)}`;
|
|
9464
|
+
const evidenceId = `evidence_${idFragment(input.sourcePath ?? input.language)}_${idFragment(options.astFormat ?? options.parser)}_import`;
|
|
9465
|
+
const symbols = [];
|
|
9466
|
+
const occurrences = [];
|
|
9467
|
+
const relations = [];
|
|
9468
|
+
const facts = [];
|
|
9469
|
+
const mappings = [];
|
|
9470
|
+
for (const declaration of declarations) {
|
|
9471
|
+
const symbolId = declaration.symbolId ?? `symbol:${input.language}:${declaration.role === 'import' ? 'import:' : ''}${idFragment(declaration.name)}`;
|
|
9472
|
+
const occurrenceId = `occ_${idFragment(declaration.nativeNode.id)}_${declaration.role ?? 'definition'}`;
|
|
9473
|
+
const ownershipRegion = semanticOwnershipRegionForDeclaration(input, {
|
|
9474
|
+
...declaration,
|
|
9475
|
+
nodeId: declaration.nativeNode.id,
|
|
9476
|
+
kind: declaration.nativeNode.kind,
|
|
9477
|
+
languageKind: declaration.nativeNode.languageKind,
|
|
9478
|
+
span: declaration.nativeNode.span,
|
|
9479
|
+
symbolId
|
|
9480
|
+
}, documentId);
|
|
9481
|
+
declaration.nativeNode.metadata = {
|
|
9482
|
+
...declaration.nativeNode.metadata,
|
|
9483
|
+
ownershipRegionId: ownershipRegion.id,
|
|
9484
|
+
ownershipRegionKey: ownershipRegion.key,
|
|
9485
|
+
ownershipRegionKind: ownershipRegion.regionKind
|
|
9486
|
+
};
|
|
9487
|
+
symbols.push({
|
|
9488
|
+
id: symbolId,
|
|
9489
|
+
scheme: 'frontier',
|
|
9490
|
+
name: declaration.name,
|
|
9491
|
+
kind: declaration.symbolKind,
|
|
9492
|
+
language: input.language,
|
|
9493
|
+
nativeAstNodeId: declaration.nativeNode.id,
|
|
9494
|
+
signatureHash: hashSemanticValue([input.language, declaration.nativeNode.kind, declaration.name, declaration.nativeNode.fields ?? {}]),
|
|
9495
|
+
definitionSpan: declaration.nativeNode.span,
|
|
9496
|
+
metadata: {
|
|
9497
|
+
ownershipRegionId: ownershipRegion.id,
|
|
9498
|
+
ownershipRegionKey: ownershipRegion.key,
|
|
9499
|
+
ownershipRegionKind: ownershipRegion.regionKind
|
|
9500
|
+
}
|
|
9501
|
+
});
|
|
9502
|
+
occurrences.push({
|
|
9503
|
+
id: occurrenceId,
|
|
9504
|
+
documentId,
|
|
9505
|
+
symbolId,
|
|
9506
|
+
role: declaration.role ?? 'definition',
|
|
9507
|
+
span: declaration.nativeNode.span,
|
|
9508
|
+
nativeAstNodeId: declaration.nativeNode.id
|
|
9509
|
+
});
|
|
9510
|
+
relations.push({
|
|
9511
|
+
id: `rel_${idFragment(documentId)}_${idFragment(declaration.nativeNode.id)}`,
|
|
9512
|
+
sourceId: documentId,
|
|
9513
|
+
predicate: relationPredicateForDeclaration(declaration),
|
|
9514
|
+
targetId: symbolId
|
|
9515
|
+
});
|
|
9516
|
+
facts.push({
|
|
9089
9517
|
id: `fact_${idFragment(declaration.nativeNode.id)}_kind`,
|
|
9090
9518
|
predicate: 'nativeKind',
|
|
9091
9519
|
subjectId: symbolId,
|
|
@@ -11207,6 +11635,980 @@ function goTypeEvidenceSummary(value) {
|
|
|
11207
11635
|
return Object.keys(summary).length ? summary : { present: true };
|
|
11208
11636
|
}
|
|
11209
11637
|
|
|
11638
|
+
function javaAstRoot(value) {
|
|
11639
|
+
if (!value || typeof value !== 'object') return undefined;
|
|
11640
|
+
if (isJavaAstNode(value)) return value;
|
|
11641
|
+
if (isJavaAstNode(value.ast)) return value.ast;
|
|
11642
|
+
if (isJavaAstNode(value.root)) return value.root;
|
|
11643
|
+
if (isJavaAstNode(value.compilationUnit)) return value.compilationUnit;
|
|
11644
|
+
if (isJavaAstNode(value.unit)) return value.unit;
|
|
11645
|
+
if (isJavaAstNode(value.sourceFile)) return value.sourceFile;
|
|
11646
|
+
if (Array.isArray(value.types) || Array.isArray(value.imports) || value.packageDeclaration || value.package) {
|
|
11647
|
+
return { kind: 'CompilationUnit', ...value };
|
|
11648
|
+
}
|
|
11649
|
+
return undefined;
|
|
11650
|
+
}
|
|
11651
|
+
|
|
11652
|
+
function isJavaAstNode(value) {
|
|
11653
|
+
return Boolean(value && typeof value === 'object' && typeof javaAstKind(value) === 'string');
|
|
11654
|
+
}
|
|
11655
|
+
|
|
11656
|
+
function javaAstKind(node) {
|
|
11657
|
+
if (!node || typeof node !== 'object') return undefined;
|
|
11658
|
+
const declared = node.kind ?? node._type ?? node.type ?? node.nodeType ?? node.astKind ?? node.treeKind ?? node.nodeKind;
|
|
11659
|
+
if (typeof declared === 'string') return normalizeJavaAstKind(declared);
|
|
11660
|
+
if (Array.isArray(node.imports) || Array.isArray(node.types) || node.packageDeclaration || node.package) return 'CompilationUnit';
|
|
11661
|
+
if (node.name && (node.members || node.bodyDeclarations || node.extends || node.implements || node.permittedTypes)) return 'ClassDeclaration';
|
|
11662
|
+
if (node.name && (node.returnType || node.parameters || node.body) && (node.modifiers || node.thrownExceptions || node.throws)) return 'MethodDeclaration';
|
|
11663
|
+
if (node.variables || node.fragments) return 'FieldDeclaration';
|
|
11664
|
+
if (node.name && node.type && (node.initializer !== undefined || node.extraDimensions !== undefined)) return 'VariableDeclarator';
|
|
11665
|
+
return undefined;
|
|
11666
|
+
}
|
|
11667
|
+
|
|
11668
|
+
function normalizeJavaAstKind(kind) {
|
|
11669
|
+
const text = String(kind).replace(/^(?:com\.sun\.source\.tree\.|org\.eclipse\.jdt\.core\.dom\.|com\.github\.javaparser\.ast\.)/, '');
|
|
11670
|
+
const compact = text.replace(/[_\s.-]+/g, '').replace(/Tree$/, '').toLowerCase();
|
|
11671
|
+
if (compact === 'compilationunit' || compact === 'compilationunitnode') return 'CompilationUnit';
|
|
11672
|
+
if (compact === 'package' || compact === 'packagedeclaration' || compact === 'packageclause') return 'PackageDeclaration';
|
|
11673
|
+
if (compact === 'import' || compact === 'importdeclaration') return 'ImportDeclaration';
|
|
11674
|
+
if (compact === 'class' || compact === 'classdeclaration' || compact === 'normalclassdeclaration' || compact === 'classorinterfacedeclaration') return 'ClassDeclaration';
|
|
11675
|
+
if (compact === 'interface' || compact === 'interfacedeclaration' || compact === 'normalinterfacedeclaration') return 'InterfaceDeclaration';
|
|
11676
|
+
if (compact === 'enum' || compact === 'enumdeclaration') return 'EnumDeclaration';
|
|
11677
|
+
if (compact === 'record' || compact === 'recorddeclaration') return 'RecordDeclaration';
|
|
11678
|
+
if (compact === 'annotation' || compact === 'annotationdeclaration' || compact === 'annotationtypedeclaration' || compact === 'annotationinterface') return 'AnnotationDeclaration';
|
|
11679
|
+
if (compact === 'method' || compact === 'methoddeclaration') return 'MethodDeclaration';
|
|
11680
|
+
if (compact === 'constructor' || compact === 'constructordeclaration') return 'ConstructorDeclaration';
|
|
11681
|
+
if (compact === 'variable' || compact === 'variabledeclaration' || compact === 'variabledeclarator' || compact === 'variabletree') return 'VariableDeclarator';
|
|
11682
|
+
if (compact === 'field' || compact === 'fielddeclaration') return 'FieldDeclaration';
|
|
11683
|
+
if (compact === 'enumconstant' || compact === 'enumconstantdeclaration') return 'EnumConstantDeclaration';
|
|
11684
|
+
if (compact === 'parameter' || compact === 'formalparameter' || compact === 'receiverparameter') return 'Parameter';
|
|
11685
|
+
if (compact === 'modifiers' || compact === 'modifier') return 'Modifiers';
|
|
11686
|
+
if (compact === 'markerannotationexpr' || compact === 'singlememberannotationexpr' || compact === 'normalannotationexpr' || compact === 'annotationexpr') return 'Annotation';
|
|
11687
|
+
if (compact === 'erroneous' || compact === 'erroneoustree' || compact === 'malformed' || compact === 'error' || compact === 'errornode' || compact === 'problem' || compact === 'problemtree' || compact === 'recovered') return 'Erroneous';
|
|
11688
|
+
if (/^[A-Z0-9_]+$/.test(text)) return text.toLowerCase().split('_').map(upperFirst).join('');
|
|
11689
|
+
return text;
|
|
11690
|
+
}
|
|
11691
|
+
|
|
11692
|
+
function ignoredJavaAstField(key) {
|
|
11693
|
+
return key === '_type'
|
|
11694
|
+
|| key === 'type'
|
|
11695
|
+
|| key === 'kind'
|
|
11696
|
+
|| key === 'nodeType'
|
|
11697
|
+
|| key === 'astKind'
|
|
11698
|
+
|| key === 'treeKind'
|
|
11699
|
+
|| key === 'nodeKind'
|
|
11700
|
+
|| key === 'parent'
|
|
11701
|
+
|| key === 'parentKind'
|
|
11702
|
+
|| key === 'parentField'
|
|
11703
|
+
|| key === 'binding'
|
|
11704
|
+
|| key === 'resolvedBinding'
|
|
11705
|
+
|| key === 'symbol'
|
|
11706
|
+
|| key === 'scope'
|
|
11707
|
+
|| key === 'range'
|
|
11708
|
+
|| key === 'loc'
|
|
11709
|
+
|| key === 'location'
|
|
11710
|
+
|| key === 'pos'
|
|
11711
|
+
|| key === 'end'
|
|
11712
|
+
|| key === 'start'
|
|
11713
|
+
|| key === 'endPosition'
|
|
11714
|
+
|| key === 'startPosition'
|
|
11715
|
+
|| key === 'length'
|
|
11716
|
+
|| key === 'name'
|
|
11717
|
+
|| key === 'identifier'
|
|
11718
|
+
|| key === 'simpleName'
|
|
11719
|
+
|| key === 'qualifiedName';
|
|
11720
|
+
}
|
|
11721
|
+
|
|
11722
|
+
function primitiveJavaAstFields(node, kind) {
|
|
11723
|
+
const fields = { kind };
|
|
11724
|
+
const name = javaAstDeclarationName(node);
|
|
11725
|
+
if (name) fields.name = name;
|
|
11726
|
+
const importPath = javaAstImportPath(node);
|
|
11727
|
+
if (importPath) fields.importPath = importPath;
|
|
11728
|
+
const type = javaAstTypeName(node.type ?? node.typeName ?? node.returnType ?? node.elementType);
|
|
11729
|
+
if (type) fields.type = type;
|
|
11730
|
+
const packageName = javaAstPackageName(node);
|
|
11731
|
+
if (packageName) fields.packageName = packageName;
|
|
11732
|
+
const modifiers = javaAstModifierNames(node);
|
|
11733
|
+
if (modifiers.length) fields.modifiers = modifiers.join(',');
|
|
11734
|
+
if (node.static === true || node.isStatic === true) fields.static = true;
|
|
11735
|
+
if (node.default === true || node.isDefault === true) fields.default = true;
|
|
11736
|
+
if (node.generated === true || node.Generated === true) fields.generated = true;
|
|
11737
|
+
if (typeof node.binaryName === 'string') fields.binaryName = node.binaryName;
|
|
11738
|
+
if (typeof node.qualifiedName === 'string') fields.qualifiedName = node.qualifiedName;
|
|
11739
|
+
if (Array.isArray(node.parameters)) fields.parameterCount = node.parameters.length;
|
|
11740
|
+
if (Array.isArray(node.throws ?? node.thrownExceptions)) fields.throwsCount = (node.throws ?? node.thrownExceptions).length;
|
|
11741
|
+
return fields;
|
|
11742
|
+
}
|
|
11743
|
+
|
|
11744
|
+
function spanFromJavaAstNode(node, input, options = {}) {
|
|
11745
|
+
const direct = spanFromJavaRange(node.range ?? node.loc ?? node.location, input)
|
|
11746
|
+
?? spanFromJavaLineFields(node, input);
|
|
11747
|
+
if (direct) return direct;
|
|
11748
|
+
const start = javaAstPosition(
|
|
11749
|
+
node.begin ?? node.start ?? node.pos ?? node.position ?? node.startPosition ?? node.name?.range?.begin ?? node.name?.loc?.start,
|
|
11750
|
+
options
|
|
11751
|
+
);
|
|
11752
|
+
const end = javaAstPosition(
|
|
11753
|
+
node.end ?? node.endPosition ?? node.stopPosition ?? node.finishPosition ?? node.name?.range?.end ?? node.name?.loc?.end,
|
|
11754
|
+
options
|
|
11755
|
+
);
|
|
11756
|
+
const sourceRange = node.sourceRange ?? node.rangeInfo;
|
|
11757
|
+
const sourceStart = javaAstPosition(
|
|
11758
|
+
sourceRange?.start ?? sourceRange?.offset ?? sourceRange?.startPosition,
|
|
11759
|
+
options
|
|
11760
|
+
);
|
|
11761
|
+
const sourceEnd = javaAstPosition(
|
|
11762
|
+
typeof sourceRange?.offset === 'number' && typeof sourceRange?.length === 'number'
|
|
11763
|
+
? sourceRange.offset + sourceRange.length
|
|
11764
|
+
: sourceRange?.end ?? sourceRange?.endPosition,
|
|
11765
|
+
options
|
|
11766
|
+
);
|
|
11767
|
+
const resolvedStart = start ?? sourceStart;
|
|
11768
|
+
const resolvedEnd = end ?? sourceEnd;
|
|
11769
|
+
if (!resolvedStart) return undefined;
|
|
11770
|
+
return {
|
|
11771
|
+
sourceId: input.sourceHash,
|
|
11772
|
+
path: resolvedStart.path ?? resolvedEnd?.path ?? input.sourcePath,
|
|
11773
|
+
startLine: resolvedStart.line,
|
|
11774
|
+
startColumn: resolvedStart.column,
|
|
11775
|
+
endLine: resolvedEnd?.line,
|
|
11776
|
+
endColumn: resolvedEnd?.column
|
|
11777
|
+
};
|
|
11778
|
+
}
|
|
11779
|
+
|
|
11780
|
+
function spanFromJavaRange(range, input) {
|
|
11781
|
+
if (!range || typeof range !== 'object') return undefined;
|
|
11782
|
+
const start = range.begin ?? range.start;
|
|
11783
|
+
const end = range.end ?? range.stop;
|
|
11784
|
+
if (start && typeof start === 'object') {
|
|
11785
|
+
const startLine = start.line ?? start.Line;
|
|
11786
|
+
const startColumn = start.column ?? start.col ?? start.Column ?? start.character;
|
|
11787
|
+
const endLine = end?.line ?? end?.Line;
|
|
11788
|
+
const endColumn = end?.column ?? end?.col ?? end?.Column ?? end?.character;
|
|
11789
|
+
if (typeof startLine === 'number') {
|
|
11790
|
+
return {
|
|
11791
|
+
sourceId: input.sourceHash,
|
|
11792
|
+
path: start.path ?? start.file ?? end?.path ?? end?.file ?? input.sourcePath,
|
|
11793
|
+
startLine,
|
|
11794
|
+
startColumn,
|
|
11795
|
+
endLine,
|
|
11796
|
+
endColumn
|
|
11797
|
+
};
|
|
11798
|
+
}
|
|
11799
|
+
}
|
|
11800
|
+
return undefined;
|
|
11801
|
+
}
|
|
11802
|
+
|
|
11803
|
+
function spanFromJavaLineFields(node, input) {
|
|
11804
|
+
const startLine = node.startLine ?? node.line ?? node.beginLine ?? node.lineno;
|
|
11805
|
+
if (typeof startLine !== 'number') return undefined;
|
|
11806
|
+
return {
|
|
11807
|
+
sourceId: input.sourceHash,
|
|
11808
|
+
path: node.path ?? node.file ?? node.filename ?? input.sourcePath,
|
|
11809
|
+
startLine,
|
|
11810
|
+
startColumn: node.startColumn ?? node.column ?? node.beginColumn ?? node.col,
|
|
11811
|
+
endLine: node.endLine ?? node.end_lineno,
|
|
11812
|
+
endColumn: node.endColumn ?? node.end_col_offset
|
|
11813
|
+
};
|
|
11814
|
+
}
|
|
11815
|
+
|
|
11816
|
+
function javaAstPosition(value, options = {}) {
|
|
11817
|
+
if (value === undefined || value === null) return undefined;
|
|
11818
|
+
if (typeof value === 'object') {
|
|
11819
|
+
const position = value.position ?? value.Position ?? value.pos ?? value.start ?? value;
|
|
11820
|
+
const line = position.line ?? position.Line ?? position.lineno;
|
|
11821
|
+
const column = position.column ?? position.Column ?? position.col ?? position.character;
|
|
11822
|
+
if (typeof line === 'number') {
|
|
11823
|
+
return {
|
|
11824
|
+
path: position.path ?? position.file ?? position.filename ?? position.Filename,
|
|
11825
|
+
line,
|
|
11826
|
+
column: typeof column === 'number' ? column : undefined
|
|
11827
|
+
};
|
|
11828
|
+
}
|
|
11829
|
+
}
|
|
11830
|
+
const resolver = typeof options.positionResolver === 'function'
|
|
11831
|
+
? options.positionResolver
|
|
11832
|
+
: typeof options.lineMap?.position === 'function'
|
|
11833
|
+
? options.lineMap.position.bind(options.lineMap)
|
|
11834
|
+
: typeof options.lineMap?.getPosition === 'function'
|
|
11835
|
+
? options.lineMap.getPosition.bind(options.lineMap)
|
|
11836
|
+
: typeof options.lineMap?.getLineNumber === 'function'
|
|
11837
|
+
? (offset) => ({
|
|
11838
|
+
line: options.lineMap.getLineNumber(offset),
|
|
11839
|
+
column: typeof options.lineMap.getColumnNumber === 'function' ? options.lineMap.getColumnNumber(offset) : undefined
|
|
11840
|
+
})
|
|
11841
|
+
: undefined;
|
|
11842
|
+
if (resolver) {
|
|
11843
|
+
const resolved = resolver(value);
|
|
11844
|
+
if (resolved !== value) return javaAstPosition(resolved, options);
|
|
11845
|
+
}
|
|
11846
|
+
return undefined;
|
|
11847
|
+
}
|
|
11848
|
+
|
|
11849
|
+
function javaAstPositionKind(node) {
|
|
11850
|
+
if (node.range?.begin || node.loc?.start) return 'line-column-range';
|
|
11851
|
+
if (typeof node.startLine === 'number' || typeof node.line === 'number') return 'line-column-fields';
|
|
11852
|
+
if (node.pos !== undefined || node.startPosition !== undefined) return 'offset-position';
|
|
11853
|
+
if (node.sourceRange) return 'source-range';
|
|
11854
|
+
return undefined;
|
|
11855
|
+
}
|
|
11856
|
+
|
|
11857
|
+
function javaAstDeclarations(node, kind, nativeNodeId, input) {
|
|
11858
|
+
if (kind === 'PackageDeclaration') {
|
|
11859
|
+
const name = javaAstPackageName(node) ?? javaAstDeclarationName(node);
|
|
11860
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'module', 'definition')] : [];
|
|
11861
|
+
}
|
|
11862
|
+
if (kind === 'ImportDeclaration') {
|
|
11863
|
+
const name = javaAstImportPath(node);
|
|
11864
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'module', 'import')] : [];
|
|
11865
|
+
}
|
|
11866
|
+
if (javaTypeDeclarationKind(kind)) {
|
|
11867
|
+
const name = javaAstDeclarationName(node);
|
|
11868
|
+
return name ? [declarationRecord(input, nativeNodeId, name, javaTypeDeclarationSymbolKind(kind), 'definition')] : [];
|
|
11869
|
+
}
|
|
11870
|
+
if (kind === 'MethodDeclaration' || kind === 'ConstructorDeclaration') {
|
|
11871
|
+
const name = javaAstDeclarationName(node);
|
|
11872
|
+
if (!name) return [];
|
|
11873
|
+
return [declarationRecord(input, nativeNodeId, name, 'method', javaAstHasBody(node) ? 'definition' : 'declaration')];
|
|
11874
|
+
}
|
|
11875
|
+
if (kind === 'FieldDeclaration') {
|
|
11876
|
+
return javaAstFieldNames(node).map((name) => declarationRecord(input, nativeNodeId, name, 'property', 'definition'));
|
|
11877
|
+
}
|
|
11878
|
+
if (kind === 'VariableDeclarator') {
|
|
11879
|
+
if (node.parentField === 'parameters' || node.parentKind === 'MethodDeclaration' || node.parentKind === 'ConstructorDeclaration') return [];
|
|
11880
|
+
const name = javaAstDeclarationName(node);
|
|
11881
|
+
if (!name) return [];
|
|
11882
|
+
const symbolKind = node.parentKind === 'FieldDeclaration' || javaTypeDeclarationKind(node.parentKind) ? 'property' : 'variable';
|
|
11883
|
+
return [declarationRecord(input, nativeNodeId, name, symbolKind, 'definition')];
|
|
11884
|
+
}
|
|
11885
|
+
if (kind === 'EnumConstantDeclaration') {
|
|
11886
|
+
const name = javaAstDeclarationName(node);
|
|
11887
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'enumMember', 'definition')] : [];
|
|
11888
|
+
}
|
|
11889
|
+
return [];
|
|
11890
|
+
}
|
|
11891
|
+
|
|
11892
|
+
function javaAstChildEntries(node, kind = javaAstKind(node)) {
|
|
11893
|
+
const fieldNames = Object.keys(node).filter((key) => !ignoredJavaAstField(key));
|
|
11894
|
+
const entries = [];
|
|
11895
|
+
for (const field of fieldNames) {
|
|
11896
|
+
const value = node[field];
|
|
11897
|
+
if (Array.isArray(value)) {
|
|
11898
|
+
entries.push([field, value.map((entry) => javaAstChildWithParent(entry, kind, field))]);
|
|
11899
|
+
continue;
|
|
11900
|
+
}
|
|
11901
|
+
if (value && typeof value === 'object') {
|
|
11902
|
+
entries.push([field, javaAstChildWithParent(value, kind, field)]);
|
|
11903
|
+
}
|
|
11904
|
+
}
|
|
11905
|
+
return entries.filter(([, value]) => Array.isArray(value)
|
|
11906
|
+
? value.some(isJavaAstNode)
|
|
11907
|
+
: isJavaAstNode(value));
|
|
11908
|
+
}
|
|
11909
|
+
|
|
11910
|
+
function javaAstChildWithParent(entry, parentKind, parentField) {
|
|
11911
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return entry;
|
|
11912
|
+
if (!isJavaAstNode(entry)) return entry;
|
|
11913
|
+
return { parentKind, parentField, ...entry };
|
|
11914
|
+
}
|
|
11915
|
+
|
|
11916
|
+
function javaAstNodeValue(node) {
|
|
11917
|
+
return javaAstDeclarationName(node)
|
|
11918
|
+
?? javaAstImportPath(node)
|
|
11919
|
+
?? javaAstPackageName(node)
|
|
11920
|
+
?? javaAstTypeName(node.type ?? node.returnType ?? node.elementType)
|
|
11921
|
+
?? javaAstLiteralValue(node);
|
|
11922
|
+
}
|
|
11923
|
+
|
|
11924
|
+
function javaAstDeclarationName(node) {
|
|
11925
|
+
if (!node || typeof node !== 'object') return undefined;
|
|
11926
|
+
for (const key of ['name', 'identifier', 'simpleName', 'qualifiedName', 'id']) {
|
|
11927
|
+
const value = node[key];
|
|
11928
|
+
const name = javaAstName(value);
|
|
11929
|
+
if (name) return name;
|
|
11930
|
+
}
|
|
11931
|
+
if (node.declaration && typeof node.declaration === 'object') return javaAstDeclarationName(node.declaration);
|
|
11932
|
+
return undefined;
|
|
11933
|
+
}
|
|
11934
|
+
|
|
11935
|
+
function javaAstName(value) {
|
|
11936
|
+
if (!value) return undefined;
|
|
11937
|
+
if (typeof value === 'string') return value;
|
|
11938
|
+
if (typeof value.identifier === 'string') return value.identifier;
|
|
11939
|
+
if (typeof value.name === 'string') return value.name;
|
|
11940
|
+
if (typeof value.simpleName === 'string') return value.simpleName;
|
|
11941
|
+
if (typeof value.qualifiedName === 'string') return value.qualifiedName;
|
|
11942
|
+
if (typeof value.fullyQualifiedName === 'string') return value.fullyQualifiedName;
|
|
11943
|
+
if (typeof value.id === 'string') return value.id;
|
|
11944
|
+
if (typeof value.value === 'string') return value.value;
|
|
11945
|
+
if (value.name && value.name !== value) return javaAstName(value.name);
|
|
11946
|
+
if (value.identifier && value.identifier !== value) return javaAstName(value.identifier);
|
|
11947
|
+
return undefined;
|
|
11948
|
+
}
|
|
11949
|
+
|
|
11950
|
+
function javaAstPackageName(node) {
|
|
11951
|
+
if (!node || typeof node !== 'object') return undefined;
|
|
11952
|
+
return javaAstName(node.packageName ?? node.packageDeclaration ?? node.package ?? node.name);
|
|
11953
|
+
}
|
|
11954
|
+
|
|
11955
|
+
function javaAstImportPath(node) {
|
|
11956
|
+
if (!node || typeof node !== 'object') return undefined;
|
|
11957
|
+
const candidate = node.qualifiedIdentifier ?? node.qualifiedName ?? node.path ?? node.name ?? node.identifier;
|
|
11958
|
+
const path = javaAstName(candidate);
|
|
11959
|
+
if (!path) return undefined;
|
|
11960
|
+
return node.asterisk || node.wildcard || node.onDemand || node.isAsterisk ? `${path.replace(/\.\*$/, '')}.*` : path;
|
|
11961
|
+
}
|
|
11962
|
+
|
|
11963
|
+
function javaAstFieldNames(node) {
|
|
11964
|
+
const fragments = node.variables ?? node.fragments ?? node.declarators ?? node.variableDeclarators;
|
|
11965
|
+
if (Array.isArray(fragments)) return fragments.map(javaAstDeclarationName).filter(Boolean);
|
|
11966
|
+
const name = javaAstDeclarationName(node);
|
|
11967
|
+
return name ? [name] : [];
|
|
11968
|
+
}
|
|
11969
|
+
|
|
11970
|
+
function javaAstTypeName(value) {
|
|
11971
|
+
if (!value) return undefined;
|
|
11972
|
+
if (typeof value === 'string') return value;
|
|
11973
|
+
if (typeof value.name === 'string') return value.name;
|
|
11974
|
+
if (typeof value.typeName === 'string') return value.typeName;
|
|
11975
|
+
if (typeof value.qualifiedName === 'string') return value.qualifiedName;
|
|
11976
|
+
if (value.elementType) {
|
|
11977
|
+
const inner = javaAstTypeName(value.elementType);
|
|
11978
|
+
return inner ? `${inner}[]` : '[]';
|
|
11979
|
+
}
|
|
11980
|
+
if (value.componentType) {
|
|
11981
|
+
const inner = javaAstTypeName(value.componentType);
|
|
11982
|
+
return inner ? `${inner}[]` : '[]';
|
|
11983
|
+
}
|
|
11984
|
+
if (Array.isArray(value.typeArguments)) {
|
|
11985
|
+
const base = javaAstName(value.name) ?? javaAstName(value);
|
|
11986
|
+
const args = value.typeArguments.map(javaAstTypeName).filter(Boolean);
|
|
11987
|
+
return base ? `${base}<${args.join(', ')}>` : undefined;
|
|
11988
|
+
}
|
|
11989
|
+
return javaAstName(value);
|
|
11990
|
+
}
|
|
11991
|
+
|
|
11992
|
+
function javaAstModifierNames(node) {
|
|
11993
|
+
const modifiers = node.modifiers ?? node.Modifiers ?? node.flags;
|
|
11994
|
+
if (!modifiers) return [];
|
|
11995
|
+
if (Array.isArray(modifiers)) {
|
|
11996
|
+
return uniqueStrings(modifiers.map((entry) => typeof entry === 'string' ? entry : javaAstName(entry) ?? entry.keyword ?? entry.kind).filter(Boolean));
|
|
11997
|
+
}
|
|
11998
|
+
if (typeof modifiers === 'string') return uniqueStrings(modifiers.split(/\s+/).filter(Boolean));
|
|
11999
|
+
if (typeof modifiers === 'object') {
|
|
12000
|
+
return uniqueStrings(Object.entries(modifiers)
|
|
12001
|
+
.filter(([, enabled]) => enabled === true)
|
|
12002
|
+
.map(([key]) => key));
|
|
12003
|
+
}
|
|
12004
|
+
return [];
|
|
12005
|
+
}
|
|
12006
|
+
|
|
12007
|
+
function javaTypeDeclarationKind(kind) {
|
|
12008
|
+
return kind === 'ClassDeclaration'
|
|
12009
|
+
|| kind === 'InterfaceDeclaration'
|
|
12010
|
+
|| kind === 'EnumDeclaration'
|
|
12011
|
+
|| kind === 'RecordDeclaration'
|
|
12012
|
+
|| kind === 'AnnotationDeclaration';
|
|
12013
|
+
}
|
|
12014
|
+
|
|
12015
|
+
function javaTypeDeclarationSymbolKind(kind) {
|
|
12016
|
+
if (kind === 'InterfaceDeclaration' || kind === 'AnnotationDeclaration') return 'interface';
|
|
12017
|
+
if (kind === 'ClassDeclaration') return 'class';
|
|
12018
|
+
return 'type';
|
|
12019
|
+
}
|
|
12020
|
+
|
|
12021
|
+
function javaAstHasBody(node) {
|
|
12022
|
+
return Boolean(node.body || node.block || node.statements || node.defaultValue || Array.isArray(node.bodyDeclarations));
|
|
12023
|
+
}
|
|
12024
|
+
|
|
12025
|
+
function javaAstLiteralValue(node) {
|
|
12026
|
+
const value = node.value ?? node.literal ?? node.token;
|
|
12027
|
+
if (value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') return value;
|
|
12028
|
+
return undefined;
|
|
12029
|
+
}
|
|
12030
|
+
|
|
12031
|
+
function javaRecoveredAstKind(kind) {
|
|
12032
|
+
return kind === 'Erroneous'
|
|
12033
|
+
|| /Error|Erroneous|Malformed|Recovered|Problem|Missing/.test(String(kind));
|
|
12034
|
+
}
|
|
12035
|
+
|
|
12036
|
+
function javaProblemNode(node, kind) {
|
|
12037
|
+
return Boolean(node.problem || node.error || node.malformed || node.recovered || node.hasError || node.hasErrors || kind === 'Erroneous');
|
|
12038
|
+
}
|
|
12039
|
+
|
|
12040
|
+
function javaGeneratedCodeMarker(node, kind) {
|
|
12041
|
+
if (node.generated || node.Generated || node.isGenerated) return true;
|
|
12042
|
+
if (kind === 'Annotation') {
|
|
12043
|
+
const name = javaAstDeclarationName(node);
|
|
12044
|
+
if (name && /(^|\.)(Generated|GeneratedValue)$/.test(name)) return true;
|
|
12045
|
+
}
|
|
12046
|
+
const annotations = node.annotations ?? node.modifiers?.annotations ?? node.modifiers;
|
|
12047
|
+
if (Array.isArray(annotations)) {
|
|
12048
|
+
return annotations.some((annotation) => {
|
|
12049
|
+
const name = javaAstDeclarationName(annotation) ?? javaAstName(annotation);
|
|
12050
|
+
return Boolean(name && /(^|\.)(Generated|GeneratedValue)$/.test(name));
|
|
12051
|
+
});
|
|
12052
|
+
}
|
|
12053
|
+
return false;
|
|
12054
|
+
}
|
|
12055
|
+
|
|
12056
|
+
function javaLombokAnnotationMarker(node, kind) {
|
|
12057
|
+
if (kind !== 'Annotation') return false;
|
|
12058
|
+
const name = javaAstDeclarationName(node);
|
|
12059
|
+
return Boolean(name && /^(lombok\.|Data$|Value$|Builder$|Getter$|Setter$|AllArgsConstructor$|NoArgsConstructor$|RequiredArgsConstructor$)/.test(name));
|
|
12060
|
+
}
|
|
12061
|
+
|
|
12062
|
+
function javaGeneratedCodeLoss(input, nodeId, span, options = {}, metadata = {}) {
|
|
12063
|
+
return {
|
|
12064
|
+
id: `loss_${idFragment(nodeId ?? input.sourcePath ?? 'java')}_java_generated_code`,
|
|
12065
|
+
severity: 'warning',
|
|
12066
|
+
phase: 'parse',
|
|
12067
|
+
sourceFormat: input.language,
|
|
12068
|
+
kind: 'generatedCode',
|
|
12069
|
+
message: 'Java generated-source, annotation-generated, or Lombok-derived code marker was imported; regenerated members and source ownership require host evidence.',
|
|
12070
|
+
span,
|
|
12071
|
+
nodeId,
|
|
12072
|
+
metadata: {
|
|
12073
|
+
parser: options.parser,
|
|
12074
|
+
astFormat: options.astFormat,
|
|
12075
|
+
annotationProcessing: javaAnnotationProcessingSummary(options.annotationProcessing),
|
|
12076
|
+
...metadata
|
|
12077
|
+
}
|
|
12078
|
+
};
|
|
12079
|
+
}
|
|
12080
|
+
|
|
12081
|
+
function javaPathEvidenceSummary(value) {
|
|
12082
|
+
if (!value) return undefined;
|
|
12083
|
+
if (Array.isArray(value)) return { entryCount: value.length };
|
|
12084
|
+
if (typeof value === 'string') return { entryCount: value.split(/[:;]/).filter(Boolean).length };
|
|
12085
|
+
if (typeof value === 'object') {
|
|
12086
|
+
const summary = {};
|
|
12087
|
+
if (typeof value.hash === 'string') summary.hash = value.hash;
|
|
12088
|
+
if (Array.isArray(value.entries)) summary.entryCount = value.entries.length;
|
|
12089
|
+
if (Array.isArray(value.roots)) summary.rootCount = value.roots.length;
|
|
12090
|
+
if (typeof value.source === 'string') summary.source = value.source;
|
|
12091
|
+
return Object.keys(summary).length ? summary : { present: true };
|
|
12092
|
+
}
|
|
12093
|
+
return { present: true };
|
|
12094
|
+
}
|
|
12095
|
+
|
|
12096
|
+
function javaAnnotationProcessingSummary(value) {
|
|
12097
|
+
if (!value) return undefined;
|
|
12098
|
+
if (Array.isArray(value)) return { processorCount: value.length };
|
|
12099
|
+
if (typeof value === 'object') {
|
|
12100
|
+
const summary = {};
|
|
12101
|
+
if (typeof value.hash === 'string') summary.hash = value.hash;
|
|
12102
|
+
if (typeof value.enabled === 'boolean') summary.enabled = value.enabled;
|
|
12103
|
+
if (Array.isArray(value.processors)) summary.processorCount = value.processors.length;
|
|
12104
|
+
if (Array.isArray(value.generatedSources)) summary.generatedSourceCount = value.generatedSources.length;
|
|
12105
|
+
return Object.keys(summary).length ? summary : { present: true };
|
|
12106
|
+
}
|
|
12107
|
+
return { present: Boolean(value) };
|
|
12108
|
+
}
|
|
12109
|
+
|
|
12110
|
+
function javaBindingEvidenceSummary(value) {
|
|
12111
|
+
if (!value || typeof value !== 'object') return undefined;
|
|
12112
|
+
const summary = {};
|
|
12113
|
+
if (typeof value.hash === 'string') summary.hash = value.hash;
|
|
12114
|
+
if (Array.isArray(value.bindings)) summary.bindingCount = value.bindings.length;
|
|
12115
|
+
if (Array.isArray(value.types)) summary.typeCount = value.types.length;
|
|
12116
|
+
if (Array.isArray(value.references)) summary.referenceCount = value.references.length;
|
|
12117
|
+
if (typeof value.solver === 'string') summary.solver = value.solver;
|
|
12118
|
+
return Object.keys(summary).length ? summary : { present: true };
|
|
12119
|
+
}
|
|
12120
|
+
|
|
12121
|
+
function csharpRoslynRoot(value) {
|
|
12122
|
+
if (!value || typeof value !== 'object') return undefined;
|
|
12123
|
+
if (isCSharpRoslynNode(value)) return value;
|
|
12124
|
+
if (isCSharpRoslynNode(value.ast)) return value.ast;
|
|
12125
|
+
if (isCSharpRoslynNode(value.root)) return value.root;
|
|
12126
|
+
if (isCSharpRoslynNode(value.rootNode)) return value.rootNode;
|
|
12127
|
+
if (isCSharpRoslynNode(value.compilationUnit)) return value.compilationUnit;
|
|
12128
|
+
if (isCSharpRoslynNode(value.syntaxTree)) return csharpRoslynRoot(value.syntaxTree);
|
|
12129
|
+
if (isCSharpRoslynNode(value.tree)) return csharpRoslynRoot(value.tree);
|
|
12130
|
+
if (Array.isArray(value.members) || Array.isArray(value.usings) || Array.isArray(value.externs)) {
|
|
12131
|
+
return { kind: 'CompilationUnit', ...value };
|
|
12132
|
+
}
|
|
12133
|
+
return undefined;
|
|
12134
|
+
}
|
|
12135
|
+
|
|
12136
|
+
function isCSharpRoslynNode(value) {
|
|
12137
|
+
return Boolean(value && typeof value === 'object' && typeof csharpRoslynKind(value) === 'string');
|
|
12138
|
+
}
|
|
12139
|
+
|
|
12140
|
+
function csharpRoslynKind(node) {
|
|
12141
|
+
if (!node || typeof node !== 'object') return undefined;
|
|
12142
|
+
const declared = node.kind ?? node.Kind ?? node._type ?? node.type ?? node.nodeType ?? node.syntaxKind ?? node.SyntaxKind;
|
|
12143
|
+
if (typeof declared === 'string') return normalizeCSharpRoslynKind(declared);
|
|
12144
|
+
if (Array.isArray(node.members) || Array.isArray(node.usings) || Array.isArray(node.externs)) return 'CompilationUnit';
|
|
12145
|
+
if (node.identifier && (node.members || node.baseList || node.parameterList || node.modifiers)) return 'ClassDeclaration';
|
|
12146
|
+
if (node.declaration && (node.eventKeyword || node.eventField)) return 'EventFieldDeclaration';
|
|
12147
|
+
if (node.declaration && Array.isArray(node.declaration.variables)) return 'FieldDeclaration';
|
|
12148
|
+
return undefined;
|
|
12149
|
+
}
|
|
12150
|
+
|
|
12151
|
+
function normalizeCSharpRoslynKind(kind) {
|
|
12152
|
+
const text = String(kind)
|
|
12153
|
+
.replace(/^(?:Microsoft\.CodeAnalysis\.CSharp\.Syntax\.|Microsoft\.CodeAnalysis\.CSharp\.)/, '')
|
|
12154
|
+
.replace(/Syntax$/, '');
|
|
12155
|
+
const compact = text.replace(/[_\s.-]+/g, '').toLowerCase();
|
|
12156
|
+
if (compact === 'compilationunit') return 'CompilationUnit';
|
|
12157
|
+
if (compact === 'usingdirective') return 'UsingDirective';
|
|
12158
|
+
if (compact === 'namespacedeclaration') return 'NamespaceDeclaration';
|
|
12159
|
+
if (compact === 'filescopednamespacedeclaration') return 'FileScopedNamespaceDeclaration';
|
|
12160
|
+
if (compact === 'classdeclaration') return 'ClassDeclaration';
|
|
12161
|
+
if (compact === 'interfacedeclaration') return 'InterfaceDeclaration';
|
|
12162
|
+
if (compact === 'structdeclaration') return 'StructDeclaration';
|
|
12163
|
+
if (compact === 'recorddeclaration') return 'RecordDeclaration';
|
|
12164
|
+
if (compact === 'recordstructdeclaration') return 'RecordStructDeclaration';
|
|
12165
|
+
if (compact === 'enumdeclaration') return 'EnumDeclaration';
|
|
12166
|
+
if (compact === 'methoddeclaration') return 'MethodDeclaration';
|
|
12167
|
+
if (compact === 'constructordeclaration') return 'ConstructorDeclaration';
|
|
12168
|
+
if (compact === 'destructordeclaration') return 'DestructorDeclaration';
|
|
12169
|
+
if (compact === 'operatordeclaration') return 'OperatorDeclaration';
|
|
12170
|
+
if (compact === 'conversionoperatordeclaration') return 'ConversionOperatorDeclaration';
|
|
12171
|
+
if (compact === 'propertydeclaration') return 'PropertyDeclaration';
|
|
12172
|
+
if (compact === 'indexerdeclaration') return 'IndexerDeclaration';
|
|
12173
|
+
if (compact === 'fielddeclaration') return 'FieldDeclaration';
|
|
12174
|
+
if (compact === 'variabledeclarator') return 'VariableDeclarator';
|
|
12175
|
+
if (compact === 'eventdeclaration') return 'EventDeclaration';
|
|
12176
|
+
if (compact === 'eventfielddeclaration') return 'EventFieldDeclaration';
|
|
12177
|
+
if (compact === 'delegatedeclaration') return 'DelegateDeclaration';
|
|
12178
|
+
if (compact === 'enummemberdeclaration') return 'EnumMemberDeclaration';
|
|
12179
|
+
if (compact === 'attributelist') return 'AttributeList';
|
|
12180
|
+
if (compact === 'attribute') return 'Attribute';
|
|
12181
|
+
if (compact === 'parameter') return 'Parameter';
|
|
12182
|
+
if (compact === 'incompletemember') return 'IncompleteMember';
|
|
12183
|
+
if (compact === 'skippedtokenstrivia' || compact === 'skippedtokens') return 'SkippedTokensTrivia';
|
|
12184
|
+
if (compact.endsWith('directivetrivia')) return `${upperFirst(compact.slice(0, -'directivetrivia'.length))}DirectiveTrivia`;
|
|
12185
|
+
if (/^[A-Z0-9_]+$/.test(text)) return text.toLowerCase().split('_').map(upperFirst).join('');
|
|
12186
|
+
return text;
|
|
12187
|
+
}
|
|
12188
|
+
|
|
12189
|
+
function ignoredCSharpRoslynField(key) {
|
|
12190
|
+
return key === '_type'
|
|
12191
|
+
|| key === 'type'
|
|
12192
|
+
|| key === 'kind'
|
|
12193
|
+
|| key === 'Kind'
|
|
12194
|
+
|| key === 'nodeType'
|
|
12195
|
+
|| key === 'syntaxKind'
|
|
12196
|
+
|| key === 'SyntaxKind'
|
|
12197
|
+
|| key === 'rawKind'
|
|
12198
|
+
|| key === 'RawKind'
|
|
12199
|
+
|| key === 'parent'
|
|
12200
|
+
|| key === 'parentKind'
|
|
12201
|
+
|| key === 'parentField'
|
|
12202
|
+
|| key === 'span'
|
|
12203
|
+
|| key === 'Span'
|
|
12204
|
+
|| key === 'fullSpan'
|
|
12205
|
+
|| key === 'FullSpan'
|
|
12206
|
+
|| key === 'lineSpan'
|
|
12207
|
+
|| key === 'location'
|
|
12208
|
+
|| key === 'locations'
|
|
12209
|
+
|| key === 'identifier'
|
|
12210
|
+
|| key === 'name'
|
|
12211
|
+
|| key === 'simpleName'
|
|
12212
|
+
|| key === 'qualifiedName'
|
|
12213
|
+
|| key === 'semanticModel'
|
|
12214
|
+
|| key === 'symbol'
|
|
12215
|
+
|| key === 'declaredSymbol'
|
|
12216
|
+
|| key === 'typeInfo'
|
|
12217
|
+
|| key === 'conversion'
|
|
12218
|
+
|| key === 'constantValue';
|
|
12219
|
+
}
|
|
12220
|
+
|
|
12221
|
+
function primitiveCSharpRoslynFields(node, kind) {
|
|
12222
|
+
const fields = { kind };
|
|
12223
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12224
|
+
if (name) fields.name = name;
|
|
12225
|
+
const importPath = csharpRoslynUsingPath(node);
|
|
12226
|
+
if (importPath) fields.importPath = importPath;
|
|
12227
|
+
const type = csharpRoslynTypeName(node.type ?? node.Type ?? node.returnType ?? node.ReturnType);
|
|
12228
|
+
if (type) fields.type = type;
|
|
12229
|
+
const modifiers = csharpRoslynModifierNames(node);
|
|
12230
|
+
if (modifiers.length) fields.modifiers = modifiers.join(',');
|
|
12231
|
+
const alias = csharpRoslynName(node.alias ?? node.Alias);
|
|
12232
|
+
if (alias) fields.alias = alias;
|
|
12233
|
+
if (node.static === true || node.isStatic === true) fields.static = true;
|
|
12234
|
+
if (node.global === true || node.isGlobal === true) fields.global = true;
|
|
12235
|
+
if (node.generated === true || node.Generated === true) fields.generated = true;
|
|
12236
|
+
if (node.containsDiagnostics === true || node.ContainsDiagnostics === true) fields.containsDiagnostics = true;
|
|
12237
|
+
if (node.containsSkippedText === true || node.ContainsSkippedText === true) fields.containsSkippedText = true;
|
|
12238
|
+
if (node.isMissing === true || node.IsMissing === true) fields.isMissing = true;
|
|
12239
|
+
if (Array.isArray(node.parameterList?.parameters ?? node.parameters)) fields.parameterCount = (node.parameterList?.parameters ?? node.parameters).length;
|
|
12240
|
+
if (Array.isArray(node.attributeLists)) fields.attributeListCount = node.attributeLists.length;
|
|
12241
|
+
return fields;
|
|
12242
|
+
}
|
|
12243
|
+
|
|
12244
|
+
function spanFromCSharpRoslynNode(node, input, options = {}) {
|
|
12245
|
+
const lineSpan = node.lineSpan ?? node.location?.lineSpan ?? node.location?.LineSpan ?? node.FileLinePositionSpan;
|
|
12246
|
+
const fromLineSpan = spanFromCSharpLineSpan(lineSpan, input);
|
|
12247
|
+
if (fromLineSpan) return fromLineSpan;
|
|
12248
|
+
const direct = spanFromCSharpLineFields(node, input);
|
|
12249
|
+
if (direct) return direct;
|
|
12250
|
+
const start = csharpRoslynPosition(node.start ?? node.Start ?? node.span?.start ?? node.Span?.Start ?? node.position, options);
|
|
12251
|
+
const end = csharpRoslynPosition(node.end ?? node.End ?? node.span?.end ?? node.Span?.End, options);
|
|
12252
|
+
if (!start) return undefined;
|
|
12253
|
+
return {
|
|
12254
|
+
sourceId: input.sourceHash,
|
|
12255
|
+
path: start.path ?? end?.path ?? input.sourcePath,
|
|
12256
|
+
startLine: start.line,
|
|
12257
|
+
startColumn: start.column,
|
|
12258
|
+
endLine: end?.line,
|
|
12259
|
+
endColumn: end?.column
|
|
12260
|
+
};
|
|
12261
|
+
}
|
|
12262
|
+
|
|
12263
|
+
function spanFromCSharpLineSpan(lineSpan, input) {
|
|
12264
|
+
if (!lineSpan || typeof lineSpan !== 'object') return undefined;
|
|
12265
|
+
const start = lineSpan.startLinePosition ?? lineSpan.StartLinePosition ?? lineSpan.start ?? lineSpan.Start;
|
|
12266
|
+
const end = lineSpan.endLinePosition ?? lineSpan.EndLinePosition ?? lineSpan.end ?? lineSpan.End;
|
|
12267
|
+
const line = start?.line ?? start?.Line;
|
|
12268
|
+
if (typeof line !== 'number') return undefined;
|
|
12269
|
+
const character = start.character ?? start.Character ?? start.column ?? start.Column;
|
|
12270
|
+
const endLine = end?.line ?? end?.Line;
|
|
12271
|
+
const endCharacter = end?.character ?? end?.Character ?? end?.column ?? end?.Column;
|
|
12272
|
+
return {
|
|
12273
|
+
sourceId: input.sourceHash,
|
|
12274
|
+
path: lineSpan.path ?? lineSpan.filePath ?? lineSpan.FilePath ?? input.sourcePath,
|
|
12275
|
+
startLine: line + 1,
|
|
12276
|
+
startColumn: typeof character === 'number' ? character + 1 : undefined,
|
|
12277
|
+
endLine: typeof endLine === 'number' ? endLine + 1 : undefined,
|
|
12278
|
+
endColumn: typeof endCharacter === 'number' ? endCharacter + 1 : undefined
|
|
12279
|
+
};
|
|
12280
|
+
}
|
|
12281
|
+
|
|
12282
|
+
function spanFromCSharpLineFields(node, input) {
|
|
12283
|
+
const startLine = node.startLine ?? node.line ?? node.beginLine;
|
|
12284
|
+
if (typeof startLine !== 'number') return undefined;
|
|
12285
|
+
return {
|
|
12286
|
+
sourceId: input.sourceHash,
|
|
12287
|
+
path: node.path ?? node.filePath ?? node.file ?? input.sourcePath,
|
|
12288
|
+
startLine,
|
|
12289
|
+
startColumn: node.startColumn ?? node.column ?? node.beginColumn,
|
|
12290
|
+
endLine: node.endLine,
|
|
12291
|
+
endColumn: node.endColumn
|
|
12292
|
+
};
|
|
12293
|
+
}
|
|
12294
|
+
|
|
12295
|
+
function csharpRoslynPosition(value, options = {}) {
|
|
12296
|
+
if (value === undefined || value === null) return undefined;
|
|
12297
|
+
if (typeof value === 'object') {
|
|
12298
|
+
const position = value.position ?? value.Position ?? value;
|
|
12299
|
+
const line = position.line ?? position.Line;
|
|
12300
|
+
const column = position.column ?? position.Column ?? position.character ?? position.Character;
|
|
12301
|
+
if (typeof line === 'number') {
|
|
12302
|
+
return {
|
|
12303
|
+
path: position.path ?? position.filePath ?? position.FilePath ?? position.file,
|
|
12304
|
+
line,
|
|
12305
|
+
column: typeof column === 'number' ? column : undefined
|
|
12306
|
+
};
|
|
12307
|
+
}
|
|
12308
|
+
}
|
|
12309
|
+
const resolver = typeof options.positionResolver === 'function'
|
|
12310
|
+
? options.positionResolver
|
|
12311
|
+
: typeof options.lineMap?.position === 'function'
|
|
12312
|
+
? options.lineMap.position.bind(options.lineMap)
|
|
12313
|
+
: typeof options.lineMap?.getLinePosition === 'function'
|
|
12314
|
+
? options.lineMap.getLinePosition.bind(options.lineMap)
|
|
12315
|
+
: undefined;
|
|
12316
|
+
if (resolver) {
|
|
12317
|
+
const resolved = resolver(value);
|
|
12318
|
+
if (resolved !== value) return csharpRoslynPosition(resolved, options);
|
|
12319
|
+
}
|
|
12320
|
+
return undefined;
|
|
12321
|
+
}
|
|
12322
|
+
|
|
12323
|
+
function csharpRoslynPositionKind(node) {
|
|
12324
|
+
if (node.lineSpan || node.location?.lineSpan) return 'line-position-span';
|
|
12325
|
+
if (node.span || node.Span) return 'text-span';
|
|
12326
|
+
if (typeof node.startLine === 'number' || typeof node.line === 'number') return 'line-column-fields';
|
|
12327
|
+
return undefined;
|
|
12328
|
+
}
|
|
12329
|
+
|
|
12330
|
+
function csharpRoslynDeclarations(node, kind, nativeNodeId, input) {
|
|
12331
|
+
if (kind === 'UsingDirective') {
|
|
12332
|
+
const name = csharpRoslynUsingPath(node);
|
|
12333
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'module', 'import')] : [];
|
|
12334
|
+
}
|
|
12335
|
+
if (kind === 'NamespaceDeclaration' || kind === 'FileScopedNamespaceDeclaration') {
|
|
12336
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12337
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'namespace', 'definition')] : [];
|
|
12338
|
+
}
|
|
12339
|
+
if (csharpRoslynTypeDeclarationKind(kind)) {
|
|
12340
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12341
|
+
return name ? [declarationRecord(input, nativeNodeId, name, csharpRoslynTypeDeclarationSymbolKind(kind), 'definition')] : [];
|
|
12342
|
+
}
|
|
12343
|
+
if (kind === 'DelegateDeclaration') {
|
|
12344
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12345
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'type', 'definition')] : [];
|
|
12346
|
+
}
|
|
12347
|
+
if (csharpRoslynMethodLikeKind(kind)) {
|
|
12348
|
+
const name = csharpRoslynDeclarationName(node) ?? csharpRoslynOperatorName(node, kind);
|
|
12349
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'method', csharpRoslynHasBody(node) ? 'definition' : 'declaration')] : [];
|
|
12350
|
+
}
|
|
12351
|
+
if (kind === 'PropertyDeclaration' || kind === 'IndexerDeclaration') {
|
|
12352
|
+
const name = csharpRoslynDeclarationName(node) ?? (kind === 'IndexerDeclaration' ? 'this[]' : undefined);
|
|
12353
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'property', 'definition')] : [];
|
|
12354
|
+
}
|
|
12355
|
+
if (kind === 'FieldDeclaration') {
|
|
12356
|
+
return csharpRoslynVariableNames(node).map((name) => declarationRecord(input, nativeNodeId, name, 'property', 'definition'));
|
|
12357
|
+
}
|
|
12358
|
+
if (kind === 'EventDeclaration') {
|
|
12359
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12360
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'event', 'definition')] : [];
|
|
12361
|
+
}
|
|
12362
|
+
if (kind === 'EventFieldDeclaration') {
|
|
12363
|
+
return csharpRoslynVariableNames(node).map((name) => declarationRecord(input, nativeNodeId, name, 'event', 'definition'));
|
|
12364
|
+
}
|
|
12365
|
+
if (kind === 'VariableDeclarator') {
|
|
12366
|
+
if (node.parentKind === 'FieldDeclaration') {
|
|
12367
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12368
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'property', 'definition')] : [];
|
|
12369
|
+
}
|
|
12370
|
+
if (node.parentKind === 'EventFieldDeclaration') {
|
|
12371
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12372
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'event', 'definition')] : [];
|
|
12373
|
+
}
|
|
12374
|
+
return [];
|
|
12375
|
+
}
|
|
12376
|
+
if (kind === 'EnumMemberDeclaration') {
|
|
12377
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12378
|
+
return name ? [declarationRecord(input, nativeNodeId, name, 'enumMember', 'definition')] : [];
|
|
12379
|
+
}
|
|
12380
|
+
return [];
|
|
12381
|
+
}
|
|
12382
|
+
|
|
12383
|
+
function csharpRoslynChildEntries(node, kind = csharpRoslynKind(node)) {
|
|
12384
|
+
const fieldNames = Object.keys(node).filter((key) => !ignoredCSharpRoslynField(key));
|
|
12385
|
+
const entries = [];
|
|
12386
|
+
for (const field of fieldNames) {
|
|
12387
|
+
const value = node[field];
|
|
12388
|
+
if (Array.isArray(value)) {
|
|
12389
|
+
entries.push([field, value.map((entry) => csharpRoslynChildWithParent(entry, kind, field))]);
|
|
12390
|
+
continue;
|
|
12391
|
+
}
|
|
12392
|
+
if (value && typeof value === 'object') {
|
|
12393
|
+
entries.push([field, csharpRoslynChildWithParent(value, kind, field)]);
|
|
12394
|
+
}
|
|
12395
|
+
}
|
|
12396
|
+
return entries.filter(([, value]) => Array.isArray(value)
|
|
12397
|
+
? value.some(isCSharpRoslynNode)
|
|
12398
|
+
: isCSharpRoslynNode(value));
|
|
12399
|
+
}
|
|
12400
|
+
|
|
12401
|
+
function csharpRoslynChildWithParent(entry, parentKind, parentField) {
|
|
12402
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return entry;
|
|
12403
|
+
if (!isCSharpRoslynNode(entry)) return entry;
|
|
12404
|
+
return { parentKind, parentField, ...entry };
|
|
12405
|
+
}
|
|
12406
|
+
|
|
12407
|
+
function csharpRoslynNodeValue(node) {
|
|
12408
|
+
return csharpRoslynDeclarationName(node)
|
|
12409
|
+
?? csharpRoslynUsingPath(node)
|
|
12410
|
+
?? csharpRoslynTypeName(node.type ?? node.returnType)
|
|
12411
|
+
?? csharpRoslynLiteralValue(node);
|
|
12412
|
+
}
|
|
12413
|
+
|
|
12414
|
+
function csharpRoslynDeclarationName(node) {
|
|
12415
|
+
if (!node || typeof node !== 'object') return undefined;
|
|
12416
|
+
for (const key of ['identifier', 'name', 'simpleName', 'qualifiedName', 'id']) {
|
|
12417
|
+
const value = node[key];
|
|
12418
|
+
const name = csharpRoslynName(value);
|
|
12419
|
+
if (name) return name;
|
|
12420
|
+
}
|
|
12421
|
+
if (node.declaration && typeof node.declaration === 'object') return csharpRoslynDeclarationName(node.declaration);
|
|
12422
|
+
return undefined;
|
|
12423
|
+
}
|
|
12424
|
+
|
|
12425
|
+
function csharpRoslynName(value) {
|
|
12426
|
+
if (!value) return undefined;
|
|
12427
|
+
if (typeof value === 'string') return value;
|
|
12428
|
+
if (typeof value.text === 'string') return value.text;
|
|
12429
|
+
if (typeof value.valueText === 'string') return value.valueText;
|
|
12430
|
+
if (typeof value.identifier === 'string') return value.identifier;
|
|
12431
|
+
if (typeof value.name === 'string') return value.name;
|
|
12432
|
+
if (typeof value.qualifiedName === 'string') return value.qualifiedName;
|
|
12433
|
+
if (typeof value.value === 'string') return value.value;
|
|
12434
|
+
if (value.identifier && value.identifier !== value) return csharpRoslynName(value.identifier);
|
|
12435
|
+
if (value.name && value.name !== value) return csharpRoslynName(value.name);
|
|
12436
|
+
return undefined;
|
|
12437
|
+
}
|
|
12438
|
+
|
|
12439
|
+
function csharpRoslynUsingPath(node) {
|
|
12440
|
+
if (!node || typeof node !== 'object') return undefined;
|
|
12441
|
+
return csharpRoslynName(node.name ?? node.Name ?? node.qualifiedName ?? node.path);
|
|
12442
|
+
}
|
|
12443
|
+
|
|
12444
|
+
function csharpRoslynVariableNames(node) {
|
|
12445
|
+
const variables = node.variables
|
|
12446
|
+
?? node.declaration?.variables
|
|
12447
|
+
?? node.Declaration?.Variables
|
|
12448
|
+
?? node.variableDeclarators;
|
|
12449
|
+
if (Array.isArray(variables)) return variables.map(csharpRoslynDeclarationName).filter(Boolean);
|
|
12450
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12451
|
+
return name ? [name] : [];
|
|
12452
|
+
}
|
|
12453
|
+
|
|
12454
|
+
function csharpRoslynTypeName(value) {
|
|
12455
|
+
if (!value) return undefined;
|
|
12456
|
+
if (typeof value === 'string') return value;
|
|
12457
|
+
if (typeof value.name === 'string') return value.name;
|
|
12458
|
+
if (typeof value.text === 'string') return value.text;
|
|
12459
|
+
if (typeof value.valueText === 'string') return value.valueText;
|
|
12460
|
+
if (typeof value.qualifiedName === 'string') return value.qualifiedName;
|
|
12461
|
+
if (value.elementType) {
|
|
12462
|
+
const inner = csharpRoslynTypeName(value.elementType);
|
|
12463
|
+
return inner ? `${inner}[]` : '[]';
|
|
12464
|
+
}
|
|
12465
|
+
if (Array.isArray(value.typeArgumentList?.arguments ?? value.typeArguments)) {
|
|
12466
|
+
const base = csharpRoslynName(value.name) ?? csharpRoslynName(value);
|
|
12467
|
+
const args = (value.typeArgumentList?.arguments ?? value.typeArguments).map(csharpRoslynTypeName).filter(Boolean);
|
|
12468
|
+
return base ? `${base}<${args.join(', ')}>` : undefined;
|
|
12469
|
+
}
|
|
12470
|
+
return csharpRoslynName(value);
|
|
12471
|
+
}
|
|
12472
|
+
|
|
12473
|
+
function csharpRoslynModifierNames(node) {
|
|
12474
|
+
const modifiers = node.modifiers ?? node.Modifiers;
|
|
12475
|
+
if (!modifiers) return [];
|
|
12476
|
+
if (Array.isArray(modifiers)) {
|
|
12477
|
+
return uniqueStrings(modifiers.map((entry) => typeof entry === 'string' ? entry : csharpRoslynName(entry) ?? entry.kind).filter(Boolean));
|
|
12478
|
+
}
|
|
12479
|
+
if (typeof modifiers === 'string') return uniqueStrings(modifiers.split(/\s+/).filter(Boolean));
|
|
12480
|
+
if (typeof modifiers === 'object') {
|
|
12481
|
+
return uniqueStrings(Object.entries(modifiers)
|
|
12482
|
+
.filter(([, enabled]) => enabled === true)
|
|
12483
|
+
.map(([key]) => key));
|
|
12484
|
+
}
|
|
12485
|
+
return [];
|
|
12486
|
+
}
|
|
12487
|
+
|
|
12488
|
+
function csharpRoslynTypeDeclarationKind(kind) {
|
|
12489
|
+
return kind === 'ClassDeclaration'
|
|
12490
|
+
|| kind === 'InterfaceDeclaration'
|
|
12491
|
+
|| kind === 'StructDeclaration'
|
|
12492
|
+
|| kind === 'RecordDeclaration'
|
|
12493
|
+
|| kind === 'RecordStructDeclaration'
|
|
12494
|
+
|| kind === 'EnumDeclaration';
|
|
12495
|
+
}
|
|
12496
|
+
|
|
12497
|
+
function csharpRoslynTypeDeclarationSymbolKind(kind) {
|
|
12498
|
+
if (kind === 'ClassDeclaration' || kind === 'RecordDeclaration') return 'class';
|
|
12499
|
+
if (kind === 'InterfaceDeclaration') return 'interface';
|
|
12500
|
+
return 'type';
|
|
12501
|
+
}
|
|
12502
|
+
|
|
12503
|
+
function csharpRoslynMethodLikeKind(kind) {
|
|
12504
|
+
return kind === 'MethodDeclaration'
|
|
12505
|
+
|| kind === 'ConstructorDeclaration'
|
|
12506
|
+
|| kind === 'DestructorDeclaration'
|
|
12507
|
+
|| kind === 'OperatorDeclaration'
|
|
12508
|
+
|| kind === 'ConversionOperatorDeclaration';
|
|
12509
|
+
}
|
|
12510
|
+
|
|
12511
|
+
function csharpRoslynHasBody(node) {
|
|
12512
|
+
return Boolean(node.body || node.expressionBody || node.accessorList || Array.isArray(node.statements));
|
|
12513
|
+
}
|
|
12514
|
+
|
|
12515
|
+
function csharpRoslynOperatorName(node, kind) {
|
|
12516
|
+
if (kind === 'ConstructorDeclaration') return csharpRoslynDeclarationName(node);
|
|
12517
|
+
if (kind === 'DestructorDeclaration') return `~${csharpRoslynDeclarationName(node) ?? 'destructor'}`;
|
|
12518
|
+
if (kind === 'OperatorDeclaration') return `operator ${csharpRoslynName(node.operatorToken) ?? csharpRoslynName(node.operatorKeyword) ?? 'operator'}`;
|
|
12519
|
+
if (kind === 'ConversionOperatorDeclaration') return `operator ${csharpRoslynTypeName(node.type) ?? 'conversion'}`;
|
|
12520
|
+
return undefined;
|
|
12521
|
+
}
|
|
12522
|
+
|
|
12523
|
+
function csharpRoslynLiteralValue(node) {
|
|
12524
|
+
const value = node.value ?? node.literal;
|
|
12525
|
+
if (value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') return value;
|
|
12526
|
+
return undefined;
|
|
12527
|
+
}
|
|
12528
|
+
|
|
12529
|
+
function csharpRoslynRecoveredKind(kind) {
|
|
12530
|
+
return kind === 'IncompleteMember'
|
|
12531
|
+
|| kind === 'SkippedTokensTrivia'
|
|
12532
|
+
|| /Skipped|Missing|Bad|Incomplete/.test(String(kind));
|
|
12533
|
+
}
|
|
12534
|
+
|
|
12535
|
+
function csharpRoslynProblemNode(node, kind) {
|
|
12536
|
+
return Boolean(
|
|
12537
|
+
node.containsDiagnostics
|
|
12538
|
+
|| node.ContainsDiagnostics
|
|
12539
|
+
|| node.containsSkippedText
|
|
12540
|
+
|| node.ContainsSkippedText
|
|
12541
|
+
|| node.isMissing
|
|
12542
|
+
|| node.IsMissing
|
|
12543
|
+
|| node.hasDiagnostics
|
|
12544
|
+
|| node.HasDiagnostics
|
|
12545
|
+
|| kind === 'IncompleteMember'
|
|
12546
|
+
|| kind === 'SkippedTokensTrivia'
|
|
12547
|
+
);
|
|
12548
|
+
}
|
|
12549
|
+
|
|
12550
|
+
function csharpRoslynDirectiveKind(kind) {
|
|
12551
|
+
return /DirectiveTrivia$/.test(String(kind)) || /^(IfDirective|ElifDirective|ElseDirective|EndIfDirective|DefineDirective|UndefDirective|NullableDirective|RegionDirective|EndRegionDirective|PragmaWarningDirective|LineDirective|ErrorDirective|WarningDirective|LoadDirective|ReferenceDirective)/.test(String(kind));
|
|
12552
|
+
}
|
|
12553
|
+
|
|
12554
|
+
function csharpGeneratedCodeMarker(node, kind) {
|
|
12555
|
+
if (node.generated || node.Generated || node.isGenerated) return true;
|
|
12556
|
+
const path = String(node.filePath ?? node.path ?? node.sourcePath ?? '');
|
|
12557
|
+
if (csharpGeneratedSourcePath(path)) return true;
|
|
12558
|
+
if (kind === 'Attribute') {
|
|
12559
|
+
const name = csharpRoslynDeclarationName(node);
|
|
12560
|
+
if (name && /(^|\.)(GeneratedCode|CompilerGenerated|DebuggerNonUserCode)Attribute?$/.test(name)) return true;
|
|
12561
|
+
}
|
|
12562
|
+
const attributes = node.attributeLists ?? node.attributes;
|
|
12563
|
+
if (Array.isArray(attributes)) {
|
|
12564
|
+
return JSON.stringify(attributes).includes('GeneratedCode')
|
|
12565
|
+
|| JSON.stringify(attributes).includes('CompilerGenerated');
|
|
12566
|
+
}
|
|
12567
|
+
return false;
|
|
12568
|
+
}
|
|
12569
|
+
|
|
12570
|
+
function csharpGeneratedSourcePath(path) {
|
|
12571
|
+
return typeof path === 'string' && /\.(g|generated|designer)\.cs$/i.test(path);
|
|
12572
|
+
}
|
|
12573
|
+
|
|
12574
|
+
function csharpGeneratedCodeLoss(input, nodeId, span, options = {}, metadata = {}) {
|
|
12575
|
+
return {
|
|
12576
|
+
id: `loss_${idFragment(nodeId ?? input.sourcePath ?? 'csharp')}_csharp_generated_code`,
|
|
12577
|
+
severity: 'warning',
|
|
12578
|
+
phase: 'parse',
|
|
12579
|
+
sourceFormat: input.language,
|
|
12580
|
+
kind: 'generatedCode',
|
|
12581
|
+
message: 'C# generated-source or source-generator marker was imported; generated member provenance and source ownership require host evidence.',
|
|
12582
|
+
span,
|
|
12583
|
+
nodeId,
|
|
12584
|
+
metadata: {
|
|
12585
|
+
parser: options.parser,
|
|
12586
|
+
astFormat: options.astFormat,
|
|
12587
|
+
sourceGeneratorEvidence: csharpEvidenceSummary(options.sourceGeneratorEvidence),
|
|
12588
|
+
...metadata
|
|
12589
|
+
}
|
|
12590
|
+
};
|
|
12591
|
+
}
|
|
12592
|
+
|
|
12593
|
+
function csharpEvidenceSummary(value) {
|
|
12594
|
+
if (!value) return undefined;
|
|
12595
|
+
if (Array.isArray(value)) return { entryCount: value.length };
|
|
12596
|
+
if (typeof value === 'string') return { value };
|
|
12597
|
+
if (typeof value === 'object') {
|
|
12598
|
+
const summary = {};
|
|
12599
|
+
if (typeof value.hash === 'string') summary.hash = value.hash;
|
|
12600
|
+
if (typeof value.solver === 'string') summary.solver = value.solver;
|
|
12601
|
+
if (Array.isArray(value.entries)) summary.entryCount = value.entries.length;
|
|
12602
|
+
if (Array.isArray(value.references)) summary.referenceCount = value.references.length;
|
|
12603
|
+
if (Array.isArray(value.symbols)) summary.symbolCount = value.symbols.length;
|
|
12604
|
+
if (Array.isArray(value.diagnostics)) summary.diagnosticCount = value.diagnostics.length;
|
|
12605
|
+
if (Array.isArray(value.generators)) summary.generatorCount = value.generators.length;
|
|
12606
|
+
if (Array.isArray(value.projects)) summary.projectCount = value.projects.length;
|
|
12607
|
+
return Object.keys(summary).length ? summary : { present: true };
|
|
12608
|
+
}
|
|
12609
|
+
return { present: true };
|
|
12610
|
+
}
|
|
12611
|
+
|
|
11210
12612
|
function declarationRecord(input, nativeNodeId, name, symbolKind, role = 'definition') {
|
|
11211
12613
|
return {
|
|
11212
12614
|
name: String(name),
|