@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/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 visitTreeSitterNode(node, context, propertyPath) {
8976
- if (!node || typeof node !== 'object' || context.truncated) return undefined;
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 = String(node.type ?? node.kind ?? 'node');
8983
- const span = spanFromTreeSitterNode(node, context.input);
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 rawChildren = Array.isArray(node.namedChildren)
8989
- ? node.namedChildren
8990
- : Array.isArray(node.children)
8991
- ? node.children
8992
- : [];
8993
- rawChildren.forEach((child, index) => {
8994
- const childId = visitTreeSitterNode(child, context, `${propertyPath}.children[${index}]`);
8995
- if (childId) children.push(childId);
8996
- });
8997
- const declaration = treeSitterDeclaration(node, kind, id, context.input, context.options);
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 ?? shortNodeText(node),
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
- startIndex: numberOrUndefined(node.startIndex),
9014
- endIndex: numberOrUndefined(node.endIndex)
9282
+ positionKind: javaAstPositionKind(node),
9283
+ parser: context.options.parser
9015
9284
  }
9016
9285
  };
9017
9286
  context.nodes[id] = nativeNode;
9018
- if (declaration) context.declarations.push({ ...declaration, nativeNode });
9019
- if (node.hasError || kind === 'ERROR') {
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)}_tree_sitter_error`,
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: 'Tree-sitter reported a parse error node.',
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 semanticIndexFromNativeDeclarations(declarations, input, options) {
9035
- const documentId = `doc_${idFragment(input.sourcePath ?? input.language)}_${idFragment(input.sourceHash)}`;
9036
- const evidenceId = `evidence_${idFragment(input.sourcePath ?? input.language)}_${idFragment(options.astFormat ?? options.parser)}_import`;
9037
- const symbols = [];
9038
- const occurrences = [];
9039
- const relations = [];
9040
- const facts = [];
9041
- const mappings = [];
9042
- for (const declaration of declarations) {
9043
- const symbolId = declaration.symbolId ?? `symbol:${input.language}:${declaration.role === 'import' ? 'import:' : ''}${idFragment(declaration.name)}`;
9044
- const occurrenceId = `occ_${idFragment(declaration.nativeNode.id)}_${declaration.role ?? 'definition'}`;
9045
- const ownershipRegion = semanticOwnershipRegionForDeclaration(input, {
9046
- ...declaration,
9047
- nodeId: declaration.nativeNode.id,
9048
- kind: declaration.nativeNode.kind,
9049
- languageKind: declaration.nativeNode.languageKind,
9050
- span: declaration.nativeNode.span,
9051
- symbolId
9052
- }, documentId);
9053
- declaration.nativeNode.metadata = {
9054
- ...declaration.nativeNode.metadata,
9055
- ownershipRegionId: ownershipRegion.id,
9056
- ownershipRegionKey: ownershipRegion.key,
9057
- ownershipRegionKind: ownershipRegion.regionKind
9058
- };
9059
- symbols.push({
9060
- id: symbolId,
9061
- scheme: 'frontier',
9062
- name: declaration.name,
9063
- kind: declaration.symbolKind,
9064
- language: input.language,
9065
- nativeAstNodeId: declaration.nativeNode.id,
9066
- signatureHash: hashSemanticValue([input.language, declaration.nativeNode.kind, declaration.name, declaration.nativeNode.fields ?? {}]),
9067
- definitionSpan: declaration.nativeNode.span,
9068
- metadata: {
9069
- ownershipRegionId: ownershipRegion.id,
9070
- ownershipRegionKey: ownershipRegion.key,
9071
- ownershipRegionKind: ownershipRegion.regionKind
9072
- }
9073
- });
9074
- occurrences.push({
9075
- id: occurrenceId,
9076
- documentId,
9077
- symbolId,
9078
- role: declaration.role ?? 'definition',
9079
- span: declaration.nativeNode.span,
9080
- nativeAstNodeId: declaration.nativeNode.id
9081
- });
9082
- relations.push({
9083
- id: `rel_${idFragment(documentId)}_${idFragment(declaration.nativeNode.id)}`,
9084
- sourceId: documentId,
9085
- predicate: relationPredicateForDeclaration(declaration),
9086
- targetId: symbolId
9087
- });
9088
- facts.push({
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),