@shapeshift-labs/frontier-lang-compiler 0.2.28 → 0.2.30

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
@@ -415,6 +415,30 @@ export const NativeParserAstFormatProfiles = Object.freeze([
415
415
  supportsErrorRecovery: false,
416
416
  notes: ['Clang JSON AST dumps expose compiler AST declarations and source ranges after preprocessing; compile commands, macros, inactive branches, type checking, and lossless formatting remain host-owned evidence.']
417
417
  }),
418
+ nativeParserAstFormatProfile('go-ast', {
419
+ aliases: ['go/parser', 'goast', 'golang-ast'],
420
+ kind: 'compiler-ast',
421
+ languages: ['go'],
422
+ parserAdapters: ['go/ast', 'go/parser', 'go-ast'],
423
+ exactness: 'exact-parser-ast',
424
+ sourceRangeModel: 'token-position',
425
+ preservesTokens: false,
426
+ preservesTrivia: false,
427
+ supportsErrorRecovery: true,
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
+ }),
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
+ }),
418
442
  nativeParserAstFormatProfile('tree-sitter', {
419
443
  kind: 'concrete-syntax-tree',
420
444
  languages: ['mixed'],
@@ -2781,6 +2805,133 @@ export function createClangAstNativeImporterAdapter(options = {}) {
2781
2805
  };
2782
2806
  }
2783
2807
 
2808
+ export function createGoAstNativeImporterAdapter(options = {}) {
2809
+ return {
2810
+ id: options.id ?? 'frontier.go-ast-native-importer',
2811
+ language: options.language ?? 'go',
2812
+ parser: options.parser ?? 'go/parser',
2813
+ version: options.version,
2814
+ capabilities: uniqueStrings(['nativeAst', 'semanticIndex', 'sourceMaps', 'diagnostics', ...(options.capabilities ?? [])]),
2815
+ coverage: nativeImporterAdapterCoverage({
2816
+ exactness: 'exact-parser-ast',
2817
+ exactAst: true,
2818
+ tokens: false,
2819
+ trivia: false,
2820
+ diagnostics: true,
2821
+ sourceRanges: true,
2822
+ generatedRanges: false,
2823
+ semanticCoverage: declarationSemanticCoverage(),
2824
+ notes: [
2825
+ 'Normalizes caller-owned Go go/ast-shaped File or Package trees into native AST nodes and declaration-level semantic index records.',
2826
+ 'Go AST imports do not resolve types, imports, build tags, generated code, or control flow by themselves; attach FileSet, go/types, go/packages, and build context evidence for those claims.'
2827
+ ]
2828
+ }, options.coverage),
2829
+ supportedExtensions: options.supportedExtensions ?? ['.go'],
2830
+ diagnostics: options.diagnostics,
2831
+ parse(input) {
2832
+ const parsed = input.options?.ast
2833
+ ?? input.options?.nativeAst
2834
+ ?? input.options?.file
2835
+ ?? input.options?.sourceFile
2836
+ ?? input.options?.package
2837
+ ?? options.ast
2838
+ ?? options.file
2839
+ ?? options.sourceFile
2840
+ ?? options.package
2841
+ ?? parseGoAstSource(input, options);
2842
+ const root = goAstRoot(parsed);
2843
+ if (!root) {
2844
+ return missingInjectedParserResult(input, {
2845
+ parser: options.parser ?? 'go/parser',
2846
+ adapterId: options.id ?? 'frontier.go-ast-native-importer',
2847
+ message: 'createGoAstNativeImporterAdapter requires an injected Go ast.File/Package-shaped object, parserModule.parse function, parse function, or adapterOptions.ast.'
2848
+ });
2849
+ }
2850
+ const parseDiagnostics = normalizeParserErrors(parsed?.errors ?? parsed?.diagnostics, input, {
2851
+ parser: options.parser ?? 'go/parser'
2852
+ });
2853
+ return createNativeImportFromGoAst(root, input, {
2854
+ parser: options.parser ?? 'go/parser',
2855
+ astFormat: 'go-ast',
2856
+ maxNodes: options.maxNodes,
2857
+ diagnostics: parseDiagnostics,
2858
+ goVersion: options.goVersion ?? input.options?.goVersion ?? parsed?.goVersion,
2859
+ packageName: options.packageName ?? input.options?.packageName ?? parsed?.packageName ?? root?.Name?.Name ?? root?.Name,
2860
+ fileSet: input.options?.fileSet ?? input.options?.fset ?? options.fileSet ?? options.fset ?? parsed?.fileSet ?? parsed?.fset,
2861
+ includeComments: options.includeComments ?? input.options?.includeComments,
2862
+ buildTags: input.options?.buildTags ?? options.buildTags ?? parsed?.buildTags,
2863
+ generated: input.options?.generated ?? options.generated ?? parsed?.generated,
2864
+ typeEvidence: input.options?.typeEvidence ?? options.typeEvidence ?? parsed?.typeEvidence
2865
+ });
2866
+ }
2867
+ };
2868
+ }
2869
+
2870
+ export function createJavaAstNativeImporterAdapter(options = {}) {
2871
+ return {
2872
+ id: options.id ?? 'frontier.java-ast-native-importer',
2873
+ language: options.language ?? 'java',
2874
+ parser: options.parser ?? 'javac',
2875
+ version: options.version,
2876
+ capabilities: uniqueStrings(['nativeAst', 'semanticIndex', 'sourceMaps', 'diagnostics', ...(options.capabilities ?? [])]),
2877
+ coverage: nativeImporterAdapterCoverage({
2878
+ exactness: 'exact-parser-ast',
2879
+ exactAst: true,
2880
+ tokens: false,
2881
+ trivia: false,
2882
+ diagnostics: true,
2883
+ sourceRanges: true,
2884
+ generatedRanges: false,
2885
+ semanticCoverage: declarationSemanticCoverage(),
2886
+ notes: [
2887
+ 'Normalizes caller-owned javac/JDT/JavaParser-shaped Java ASTs into native AST nodes and declaration-level semantic index records.',
2888
+ '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.'
2889
+ ]
2890
+ }, options.coverage),
2891
+ supportedExtensions: options.supportedExtensions ?? ['.java'],
2892
+ diagnostics: options.diagnostics,
2893
+ parse(input) {
2894
+ const parsed = input.options?.ast
2895
+ ?? input.options?.nativeAst
2896
+ ?? input.options?.compilationUnit
2897
+ ?? input.options?.unit
2898
+ ?? input.options?.sourceFile
2899
+ ?? options.ast
2900
+ ?? options.compilationUnit
2901
+ ?? options.unit
2902
+ ?? options.sourceFile
2903
+ ?? parseJavaAstSource(input, options);
2904
+ const root = javaAstRoot(parsed);
2905
+ if (!root) {
2906
+ return missingInjectedParserResult(input, {
2907
+ parser: options.parser ?? 'javac',
2908
+ adapterId: options.id ?? 'frontier.java-ast-native-importer',
2909
+ message: 'createJavaAstNativeImporterAdapter requires an injected Java AST object, parserModule.parse function, parse function, or adapterOptions.ast.'
2910
+ });
2911
+ }
2912
+ const parseDiagnostics = normalizeParserErrors(parsed?.errors ?? parsed?.diagnostics ?? parsed?.problems, input, {
2913
+ parser: options.parser ?? 'javac'
2914
+ });
2915
+ return createNativeImportFromJavaAst(root, input, {
2916
+ parser: options.parser ?? 'javac',
2917
+ astFormat: 'java-ast',
2918
+ maxNodes: options.maxNodes,
2919
+ diagnostics: parseDiagnostics,
2920
+ javaVersion: options.javaVersion ?? input.options?.javaVersion ?? parsed?.javaVersion,
2921
+ sourceLevel: options.sourceLevel ?? input.options?.sourceLevel ?? parsed?.sourceLevel,
2922
+ classPath: input.options?.classPath ?? options.classPath ?? parsed?.classPath,
2923
+ modulePath: input.options?.modulePath ?? options.modulePath ?? parsed?.modulePath,
2924
+ generated: input.options?.generated ?? options.generated ?? parsed?.generated,
2925
+ annotationProcessing: input.options?.annotationProcessing ?? options.annotationProcessing ?? parsed?.annotationProcessing,
2926
+ bindingEvidence: input.options?.bindingEvidence ?? options.bindingEvidence ?? parsed?.bindingEvidence,
2927
+ positionResolver: input.options?.positionResolver ?? options.positionResolver,
2928
+ lineMap: input.options?.lineMap ?? options.lineMap ?? parsed?.lineMap,
2929
+ includeAnnotations: options.includeAnnotations ?? input.options?.includeAnnotations
2930
+ });
2931
+ }
2932
+ };
2933
+ }
2934
+
2784
2935
  export function createTreeSitterNativeImporterAdapter(options = {}) {
2785
2936
  return {
2786
2937
  id: options.id ?? `frontier.tree-sitter-${idFragment(options.language ?? 'source')}-native-importer`,
@@ -7222,6 +7373,8 @@ function parserAstFormatIdForParser(parser) {
7222
7373
  if (text === 'syn' || text.includes('rust-syn')) return 'rust-syn';
7223
7374
  if (text.includes('rust-analyzer') || text.includes('rowan')) return 'rust-analyzer-rowan';
7224
7375
  if (text.includes('clang') || text.includes('libclang')) return 'clang-ast-json';
7376
+ if (text === 'go' || text.includes('go-parser') || text.includes('go-ast') || text.includes('go/parser') || text.includes('go/ast')) return 'go-ast';
7377
+ if (text === 'java' || text.includes('javac') || text.includes('jdt') || text.includes('javaparser') || text.includes('java-parser') || text.includes('java-ast')) return 'java-ast';
7225
7378
  if (text.includes('tree-sitter') || text.includes('treesitter')) return 'tree-sitter';
7226
7379
  if (text.includes('babel')) return 'babel';
7227
7380
  if (text.includes('estree')) return 'estree';
@@ -8287,6 +8440,39 @@ function parseClangAstSource(input, options) {
8287
8440
  return parse(input.sourceText, parserOptions);
8288
8441
  }
8289
8442
 
8443
+ function parseGoAstSource(input, options) {
8444
+ const parse = options.parse ?? options.parserModule?.parse ?? options.goAst?.parse ?? options.goParser?.parse;
8445
+ if (typeof parse !== 'function') return undefined;
8446
+ const parserOptions = {
8447
+ sourcePath: input.sourcePath,
8448
+ filename: input.sourcePath,
8449
+ mode: options.mode ?? input.options?.mode ?? 'ParseComments',
8450
+ goVersion: options.goVersion ?? input.options?.goVersion,
8451
+ packageName: options.packageName ?? input.options?.packageName,
8452
+ includeComments: options.includeComments ?? input.options?.includeComments,
8453
+ ...(options.parserOptions ?? {}),
8454
+ ...(input.options?.parserOptions ?? {})
8455
+ };
8456
+ return parse(input.sourceText, parserOptions);
8457
+ }
8458
+
8459
+ function parseJavaAstSource(input, options) {
8460
+ const parse = options.parse ?? options.parserModule?.parse ?? options.javac?.parse ?? options.jdt?.parse ?? options.javaParser?.parse;
8461
+ if (typeof parse !== 'function') return undefined;
8462
+ const parserOptions = {
8463
+ sourcePath: input.sourcePath,
8464
+ filename: input.sourcePath,
8465
+ javaVersion: options.javaVersion ?? input.options?.javaVersion,
8466
+ sourceLevel: options.sourceLevel ?? input.options?.sourceLevel,
8467
+ classPath: options.classPath ?? input.options?.classPath,
8468
+ modulePath: options.modulePath ?? input.options?.modulePath,
8469
+ includeAnnotations: options.includeAnnotations ?? input.options?.includeAnnotations,
8470
+ ...(options.parserOptions ?? {}),
8471
+ ...(input.options?.parserOptions ?? {})
8472
+ };
8473
+ return parse(input.sourceText, parserOptions);
8474
+ }
8475
+
8290
8476
  function createNativeImportFromSyntaxAst(ast, input, options) {
8291
8477
  const root = normalizeSyntaxAstRoot(ast, options.astFormat);
8292
8478
  if (!root) {
@@ -8443,6 +8629,80 @@ function createNativeImportFromClangAst(root, input, options) {
8443
8629
  };
8444
8630
  }
8445
8631
 
8632
+ function createNativeImportFromGoAst(root, input, options) {
8633
+ const context = createAstNormalizationContext(input, options);
8634
+ visitGoAstNode(root, context, 'root');
8635
+ if (context.truncated) {
8636
+ context.losses.push(truncatedAstLoss(input, context, options));
8637
+ }
8638
+ const semantic = semanticIndexFromNativeDeclarations(context.declarations, input, options);
8639
+ return {
8640
+ rootId: context.rootId,
8641
+ nodes: context.nodes,
8642
+ semanticIndex: semantic.semanticIndex,
8643
+ mappings: semantic.mappings,
8644
+ losses: mergeNativeLosses(context.losses, options.diagnostics?.map((diagnostic, index) => adapterDiagnosticToLoss(diagnostic, index, {
8645
+ id: input.adapterId,
8646
+ version: input.adapterVersion
8647
+ }, input)) ?? []),
8648
+ evidence: semantic.evidence,
8649
+ diagnostics: options.diagnostics,
8650
+ metadata: {
8651
+ astFormat: options.astFormat,
8652
+ parser: options.parser,
8653
+ goVersion: options.goVersion,
8654
+ packageName: options.packageName,
8655
+ includeComments: Boolean(options.includeComments),
8656
+ buildTags: Array.isArray(options.buildTags) ? options.buildTags.slice() : options.buildTags,
8657
+ generated: options.generated,
8658
+ fileSetEvidence: Boolean(options.fileSet),
8659
+ typeEvidence: goTypeEvidenceSummary(options.typeEvidence),
8660
+ normalizedNodeCount: Object.keys(context.nodes).length,
8661
+ declarationCount: context.declarations.length,
8662
+ truncated: context.truncated
8663
+ }
8664
+ };
8665
+ }
8666
+
8667
+ function createNativeImportFromJavaAst(root, input, options) {
8668
+ const context = createAstNormalizationContext(input, options);
8669
+ visitJavaAstNode(root, context, 'root');
8670
+ if (context.truncated) {
8671
+ context.losses.push(truncatedAstLoss(input, context, options));
8672
+ }
8673
+ if (options.generated && !context.losses.some((loss) => loss.kind === 'generatedCode')) {
8674
+ context.losses.push(javaGeneratedCodeLoss(input, context.rootId, undefined, options));
8675
+ }
8676
+ const semantic = semanticIndexFromNativeDeclarations(context.declarations, input, options);
8677
+ return {
8678
+ rootId: context.rootId,
8679
+ nodes: context.nodes,
8680
+ semanticIndex: semantic.semanticIndex,
8681
+ mappings: semantic.mappings,
8682
+ losses: mergeNativeLosses(context.losses, options.diagnostics?.map((diagnostic, index) => adapterDiagnosticToLoss(diagnostic, index, {
8683
+ id: input.adapterId,
8684
+ version: input.adapterVersion
8685
+ }, input)) ?? []),
8686
+ evidence: semantic.evidence,
8687
+ diagnostics: options.diagnostics,
8688
+ metadata: {
8689
+ astFormat: options.astFormat,
8690
+ parser: options.parser,
8691
+ javaVersion: options.javaVersion,
8692
+ sourceLevel: options.sourceLevel,
8693
+ classPathEvidence: javaPathEvidenceSummary(options.classPath),
8694
+ modulePathEvidence: javaPathEvidenceSummary(options.modulePath),
8695
+ annotationProcessing: javaAnnotationProcessingSummary(options.annotationProcessing),
8696
+ bindingEvidence: javaBindingEvidenceSummary(options.bindingEvidence),
8697
+ generated: options.generated,
8698
+ includeAnnotations: Boolean(options.includeAnnotations),
8699
+ normalizedNodeCount: Object.keys(context.nodes).length,
8700
+ declarationCount: context.declarations.length,
8701
+ truncated: context.truncated
8702
+ }
8703
+ };
8704
+ }
8705
+
8446
8706
  function createNativeImportFromTreeSitter(root, input, options) {
8447
8707
  const context = createAstNormalizationContext(input, options);
8448
8708
  visitTreeSitterNode(root, context, 'root');
@@ -8748,117 +9008,287 @@ function visitClangAstNode(node, context, propertyPath) {
8748
9008
  return id;
8749
9009
  }
8750
9010
 
8751
- function visitTreeSitterNode(node, context, propertyPath) {
8752
- if (!node || typeof node !== 'object' || context.truncated) return undefined;
9011
+ function visitGoAstNode(node, context, propertyPath) {
9012
+ if (!isGoAstNode(node) || context.truncated) return undefined;
8753
9013
  if (context.objectIds.has(node)) return context.objectIds.get(node);
8754
9014
  if (context.counter >= context.maxNodes) {
8755
9015
  context.truncated = true;
8756
9016
  return undefined;
8757
9017
  }
8758
- const kind = String(node.type ?? node.kind ?? 'node');
8759
- const span = spanFromTreeSitterNode(node, context.input);
9018
+ const kind = goAstKind(node);
9019
+ const span = spanFromGoAstNode(node, context.input, context.options);
8760
9020
  const id = nativeNodeId(context, kind, { start: { line: span?.startLine, column: span?.startColumn } }, propertyPath);
8761
9021
  context.objectIds.set(node, id);
8762
9022
  if (!context.rootId) context.rootId = id;
8763
9023
  const children = [];
8764
- const rawChildren = Array.isArray(node.namedChildren)
8765
- ? node.namedChildren
8766
- : Array.isArray(node.children)
8767
- ? node.children
8768
- : [];
8769
- rawChildren.forEach((child, index) => {
8770
- const childId = visitTreeSitterNode(child, context, `${propertyPath}.children[${index}]`);
8771
- if (childId) children.push(childId);
8772
- });
8773
- const declaration = treeSitterDeclaration(node, kind, id, context.input, context.options);
9024
+ for (const [field, value] of goAstChildEntries(node)) {
9025
+ if (Array.isArray(value)) {
9026
+ value.forEach((entry, index) => {
9027
+ const childId = visitGoAstNode(entry, context, `${propertyPath}.${field}[${index}]`);
9028
+ if (childId) children.push(childId);
9029
+ });
9030
+ } else {
9031
+ const childId = visitGoAstNode(value, context, `${propertyPath}.${field}`);
9032
+ if (childId) children.push(childId);
9033
+ }
9034
+ }
9035
+ const declarations = goAstDeclarations(node, kind, id, context.input);
9036
+ const declaration = declarations[0];
8774
9037
  const nativeNode = {
8775
9038
  id,
8776
9039
  kind,
8777
9040
  languageKind: `${context.input.language}.${kind}`,
8778
9041
  span,
8779
- value: declaration?.name ?? shortNodeText(node),
8780
- fields: {
8781
- named: Boolean(node.isNamed ?? node.named),
8782
- missing: Boolean(node.isMissing),
8783
- error: Boolean(node.hasError || kind === 'ERROR')
8784
- },
9042
+ value: declaration?.name ?? goAstNodeValue(node),
9043
+ fields: primitiveGoAstFields(node, kind),
8785
9044
  children,
8786
9045
  metadata: {
8787
9046
  astFormat: context.options.astFormat,
8788
9047
  propertyPath,
8789
- startIndex: numberOrUndefined(node.startIndex),
8790
- endIndex: numberOrUndefined(node.endIndex)
9048
+ positionKind: goAstPositionKind(node),
9049
+ packageName: context.options.packageName
8791
9050
  }
8792
9051
  };
8793
9052
  context.nodes[id] = nativeNode;
8794
- if (declaration) context.declarations.push({ ...declaration, nativeNode });
8795
- if (node.hasError || kind === 'ERROR') {
9053
+ for (const entry of declarations) {
9054
+ context.declarations.push({ ...entry, nativeNode });
9055
+ }
9056
+ if (goBadAstKind(kind)) {
8796
9057
  context.losses.push({
8797
- id: `loss_${idFragment(id)}_tree_sitter_error`,
9058
+ id: `loss_${idFragment(id)}_go_bad_node`,
8798
9059
  severity: 'error',
8799
9060
  phase: 'parse',
8800
9061
  sourceFormat: context.input.language,
8801
9062
  kind: 'unsupportedSyntax',
8802
- message: 'Tree-sitter reported a parse error node.',
9063
+ message: 'Go parser recovered a BadDecl/BadExpr/BadStmt node; semantic import is partial until syntax errors are resolved.',
8803
9064
  span,
8804
- nodeId: id
9065
+ nodeId: id,
9066
+ metadata: {
9067
+ parser: context.options.parser,
9068
+ astFormat: context.options.astFormat,
9069
+ nodeKind: kind
9070
+ }
8805
9071
  });
8806
9072
  }
8807
- return id;
8808
- }
8809
-
8810
- function semanticIndexFromNativeDeclarations(declarations, input, options) {
8811
- const documentId = `doc_${idFragment(input.sourcePath ?? input.language)}_${idFragment(input.sourceHash)}`;
8812
- const evidenceId = `evidence_${idFragment(input.sourcePath ?? input.language)}_${idFragment(options.astFormat ?? options.parser)}_import`;
8813
- const symbols = [];
8814
- const occurrences = [];
8815
- const relations = [];
8816
- const facts = [];
8817
- const mappings = [];
8818
- for (const declaration of declarations) {
8819
- const symbolId = declaration.symbolId ?? `symbol:${input.language}:${declaration.role === 'import' ? 'import:' : ''}${idFragment(declaration.name)}`;
8820
- const occurrenceId = `occ_${idFragment(declaration.nativeNode.id)}_${declaration.role ?? 'definition'}`;
8821
- const ownershipRegion = semanticOwnershipRegionForDeclaration(input, {
8822
- ...declaration,
8823
- nodeId: declaration.nativeNode.id,
8824
- kind: declaration.nativeNode.kind,
8825
- languageKind: declaration.nativeNode.languageKind,
8826
- span: declaration.nativeNode.span,
8827
- symbolId
8828
- }, documentId);
8829
- declaration.nativeNode.metadata = {
8830
- ...declaration.nativeNode.metadata,
8831
- ownershipRegionId: ownershipRegion.id,
8832
- ownershipRegionKey: ownershipRegion.key,
8833
- ownershipRegionKind: ownershipRegion.regionKind
8834
- };
8835
- symbols.push({
8836
- id: symbolId,
8837
- scheme: 'frontier',
8838
- name: declaration.name,
8839
- kind: declaration.symbolKind,
8840
- language: input.language,
8841
- nativeAstNodeId: declaration.nativeNode.id,
8842
- signatureHash: hashSemanticValue([input.language, declaration.nativeNode.kind, declaration.name, declaration.nativeNode.fields ?? {}]),
8843
- definitionSpan: declaration.nativeNode.span,
9073
+ if (kind === 'FuncDecl' && goReceiverFieldCount(node) > 1) {
9074
+ context.losses.push({
9075
+ id: `loss_${idFragment(id)}_go_multiple_receivers`,
9076
+ severity: 'warning',
9077
+ phase: 'parse',
9078
+ sourceFormat: context.input.language,
9079
+ kind: 'unsupportedSyntax',
9080
+ message: 'Go parser accepted multiple receiver fields; valid method ownership requires a single receiver.',
9081
+ span,
9082
+ nodeId: id,
8844
9083
  metadata: {
8845
- ownershipRegionId: ownershipRegion.id,
8846
- ownershipRegionKey: ownershipRegion.key,
8847
- ownershipRegionKind: ownershipRegion.regionKind
9084
+ parser: context.options.parser,
9085
+ astFormat: context.options.astFormat,
9086
+ receiverFieldCount: goReceiverFieldCount(node)
8848
9087
  }
8849
9088
  });
8850
- occurrences.push({
8851
- id: occurrenceId,
8852
- documentId,
8853
- symbolId,
8854
- role: declaration.role ?? 'definition',
8855
- span: declaration.nativeNode.span,
8856
- nativeAstNodeId: declaration.nativeNode.id
8857
- });
8858
- relations.push({
8859
- id: `rel_${idFragment(documentId)}_${idFragment(declaration.nativeNode.id)}`,
8860
- sourceId: documentId,
8861
- predicate: relationPredicateForDeclaration(declaration),
9089
+ }
9090
+ if (goGeneratedCodeMarker(node, kind)) {
9091
+ context.losses.push({
9092
+ id: `loss_${idFragment(id)}_go_generated_code`,
9093
+ severity: 'warning',
9094
+ phase: 'parse',
9095
+ sourceFormat: context.input.language,
9096
+ kind: 'generatedCode',
9097
+ message: 'Go generated-code marker was imported; regeneration provenance and source ownership require host evidence.',
9098
+ span,
9099
+ nodeId: id,
9100
+ metadata: {
9101
+ parser: context.options.parser,
9102
+ astFormat: context.options.astFormat
9103
+ }
9104
+ });
9105
+ }
9106
+ return id;
9107
+ }
9108
+
9109
+ function visitJavaAstNode(node, context, propertyPath) {
9110
+ if (!isJavaAstNode(node) || context.truncated) return undefined;
9111
+ if (context.objectIds.has(node)) return context.objectIds.get(node);
9112
+ if (context.counter >= context.maxNodes) {
9113
+ context.truncated = true;
9114
+ return undefined;
9115
+ }
9116
+ const kind = javaAstKind(node);
9117
+ const span = spanFromJavaAstNode(node, context.input, context.options);
9118
+ const id = nativeNodeId(context, kind, { start: { line: span?.startLine, column: span?.startColumn } }, propertyPath);
9119
+ context.objectIds.set(node, id);
9120
+ if (!context.rootId) context.rootId = id;
9121
+ const children = [];
9122
+ for (const [field, value] of javaAstChildEntries(node, kind)) {
9123
+ if (Array.isArray(value)) {
9124
+ value.forEach((entry, index) => {
9125
+ const childId = visitJavaAstNode(entry, context, `${propertyPath}.${field}[${index}]`);
9126
+ if (childId) children.push(childId);
9127
+ });
9128
+ } else {
9129
+ const childId = visitJavaAstNode(value, context, `${propertyPath}.${field}`);
9130
+ if (childId) children.push(childId);
9131
+ }
9132
+ }
9133
+ const declarations = javaAstDeclarations(node, kind, id, context.input);
9134
+ const declaration = declarations[0];
9135
+ const nativeNode = {
9136
+ id,
9137
+ kind,
9138
+ languageKind: `${context.input.language}.${kind}`,
9139
+ span,
9140
+ value: declaration?.name ?? javaAstNodeValue(node),
9141
+ fields: primitiveJavaAstFields(node, kind),
9142
+ children,
9143
+ metadata: {
9144
+ astFormat: context.options.astFormat,
9145
+ propertyPath,
9146
+ positionKind: javaAstPositionKind(node),
9147
+ parser: context.options.parser
9148
+ }
9149
+ };
9150
+ context.nodes[id] = nativeNode;
9151
+ for (const entry of declarations) {
9152
+ context.declarations.push({ ...entry, nativeNode });
9153
+ }
9154
+ if (javaRecoveredAstKind(kind) || javaProblemNode(node, kind)) {
9155
+ context.losses.push({
9156
+ id: `loss_${idFragment(id)}_java_recovered_node`,
9157
+ severity: 'error',
9158
+ phase: 'parse',
9159
+ sourceFormat: context.input.language,
9160
+ kind: 'unsupportedSyntax',
9161
+ message: 'Java parser reported a recovered, erroneous, malformed, or problem node; semantic import is partial until syntax errors are resolved.',
9162
+ span,
9163
+ nodeId: id,
9164
+ metadata: {
9165
+ parser: context.options.parser,
9166
+ astFormat: context.options.astFormat,
9167
+ nodeKind: kind
9168
+ }
9169
+ });
9170
+ }
9171
+ if (javaGeneratedCodeMarker(node, kind) || javaLombokAnnotationMarker(node, kind)) {
9172
+ context.losses.push(javaGeneratedCodeLoss(context.input, id, span, context.options, {
9173
+ nodeKind: kind,
9174
+ generatedMarker: javaGeneratedCodeMarker(node, kind),
9175
+ lombokMarker: javaLombokAnnotationMarker(node, kind)
9176
+ }));
9177
+ }
9178
+ return id;
9179
+ }
9180
+
9181
+ function visitTreeSitterNode(node, context, propertyPath) {
9182
+ if (!node || typeof node !== 'object' || context.truncated) return undefined;
9183
+ if (context.objectIds.has(node)) return context.objectIds.get(node);
9184
+ if (context.counter >= context.maxNodes) {
9185
+ context.truncated = true;
9186
+ return undefined;
9187
+ }
9188
+ const kind = String(node.type ?? node.kind ?? 'node');
9189
+ const span = spanFromTreeSitterNode(node, context.input);
9190
+ const id = nativeNodeId(context, kind, { start: { line: span?.startLine, column: span?.startColumn } }, propertyPath);
9191
+ context.objectIds.set(node, id);
9192
+ if (!context.rootId) context.rootId = id;
9193
+ const children = [];
9194
+ const rawChildren = Array.isArray(node.namedChildren)
9195
+ ? node.namedChildren
9196
+ : Array.isArray(node.children)
9197
+ ? node.children
9198
+ : [];
9199
+ rawChildren.forEach((child, index) => {
9200
+ const childId = visitTreeSitterNode(child, context, `${propertyPath}.children[${index}]`);
9201
+ if (childId) children.push(childId);
9202
+ });
9203
+ const declaration = treeSitterDeclaration(node, kind, id, context.input, context.options);
9204
+ const nativeNode = {
9205
+ id,
9206
+ kind,
9207
+ languageKind: `${context.input.language}.${kind}`,
9208
+ span,
9209
+ value: declaration?.name ?? shortNodeText(node),
9210
+ fields: {
9211
+ named: Boolean(node.isNamed ?? node.named),
9212
+ missing: Boolean(node.isMissing),
9213
+ error: Boolean(node.hasError || kind === 'ERROR')
9214
+ },
9215
+ children,
9216
+ metadata: {
9217
+ astFormat: context.options.astFormat,
9218
+ propertyPath,
9219
+ startIndex: numberOrUndefined(node.startIndex),
9220
+ endIndex: numberOrUndefined(node.endIndex)
9221
+ }
9222
+ };
9223
+ context.nodes[id] = nativeNode;
9224
+ if (declaration) context.declarations.push({ ...declaration, nativeNode });
9225
+ if (node.hasError || kind === 'ERROR') {
9226
+ context.losses.push({
9227
+ id: `loss_${idFragment(id)}_tree_sitter_error`,
9228
+ severity: 'error',
9229
+ phase: 'parse',
9230
+ sourceFormat: context.input.language,
9231
+ kind: 'unsupportedSyntax',
9232
+ message: 'Tree-sitter reported a parse error node.',
9233
+ span,
9234
+ nodeId: id
9235
+ });
9236
+ }
9237
+ return id;
9238
+ }
9239
+
9240
+ function semanticIndexFromNativeDeclarations(declarations, input, options) {
9241
+ const documentId = `doc_${idFragment(input.sourcePath ?? input.language)}_${idFragment(input.sourceHash)}`;
9242
+ const evidenceId = `evidence_${idFragment(input.sourcePath ?? input.language)}_${idFragment(options.astFormat ?? options.parser)}_import`;
9243
+ const symbols = [];
9244
+ const occurrences = [];
9245
+ const relations = [];
9246
+ const facts = [];
9247
+ const mappings = [];
9248
+ for (const declaration of declarations) {
9249
+ const symbolId = declaration.symbolId ?? `symbol:${input.language}:${declaration.role === 'import' ? 'import:' : ''}${idFragment(declaration.name)}`;
9250
+ const occurrenceId = `occ_${idFragment(declaration.nativeNode.id)}_${declaration.role ?? 'definition'}`;
9251
+ const ownershipRegion = semanticOwnershipRegionForDeclaration(input, {
9252
+ ...declaration,
9253
+ nodeId: declaration.nativeNode.id,
9254
+ kind: declaration.nativeNode.kind,
9255
+ languageKind: declaration.nativeNode.languageKind,
9256
+ span: declaration.nativeNode.span,
9257
+ symbolId
9258
+ }, documentId);
9259
+ declaration.nativeNode.metadata = {
9260
+ ...declaration.nativeNode.metadata,
9261
+ ownershipRegionId: ownershipRegion.id,
9262
+ ownershipRegionKey: ownershipRegion.key,
9263
+ ownershipRegionKind: ownershipRegion.regionKind
9264
+ };
9265
+ symbols.push({
9266
+ id: symbolId,
9267
+ scheme: 'frontier',
9268
+ name: declaration.name,
9269
+ kind: declaration.symbolKind,
9270
+ language: input.language,
9271
+ nativeAstNodeId: declaration.nativeNode.id,
9272
+ signatureHash: hashSemanticValue([input.language, declaration.nativeNode.kind, declaration.name, declaration.nativeNode.fields ?? {}]),
9273
+ definitionSpan: declaration.nativeNode.span,
9274
+ metadata: {
9275
+ ownershipRegionId: ownershipRegion.id,
9276
+ ownershipRegionKey: ownershipRegion.key,
9277
+ ownershipRegionKind: ownershipRegion.regionKind
9278
+ }
9279
+ });
9280
+ occurrences.push({
9281
+ id: occurrenceId,
9282
+ documentId,
9283
+ symbolId,
9284
+ role: declaration.role ?? 'definition',
9285
+ span: declaration.nativeNode.span,
9286
+ nativeAstNodeId: declaration.nativeNode.id
9287
+ });
9288
+ relations.push({
9289
+ id: `rel_${idFragment(documentId)}_${idFragment(declaration.nativeNode.id)}`,
9290
+ sourceId: documentId,
9291
+ predicate: relationPredicateForDeclaration(declaration),
8862
9292
  targetId: symbolId
8863
9293
  });
8864
9294
  facts.push({
@@ -10657,6 +11087,815 @@ function serializableIncludeGraphSummary(value) {
10657
11087
  return Object.keys(summary).length ? summary : { present: true };
10658
11088
  }
10659
11089
 
11090
+ function goAstRoot(value) {
11091
+ if (!value || typeof value !== 'object') return undefined;
11092
+ if (isGoAstNode(value)) return value;
11093
+ if (isGoAstNode(value.ast)) return value.ast;
11094
+ if (isGoAstNode(value.file)) return value.file;
11095
+ if (isGoAstNode(value.sourceFile)) return value.sourceFile;
11096
+ if (isGoAstNode(value.root)) return value.root;
11097
+ if (isGoAstNode(value.package)) return value.package;
11098
+ if (value.files && typeof value.files === 'object') return { kind: 'Package', Name: value.name ?? value.packageName, Files: value.files };
11099
+ return undefined;
11100
+ }
11101
+
11102
+ function isGoAstNode(value) {
11103
+ return Boolean(value && typeof value === 'object' && typeof goAstKind(value) === 'string');
11104
+ }
11105
+
11106
+ function goAstKind(node) {
11107
+ if (!node || typeof node !== 'object') return undefined;
11108
+ const declared = node.kind ?? node._type ?? node.type ?? node.nodeType ?? node.astKind;
11109
+ if (typeof declared === 'string') return normalizeGoAstKind(declared);
11110
+ if (Array.isArray(node.Decls) || Array.isArray(node.decls)) return 'File';
11111
+ if (node.Files || node.files) return 'Package';
11112
+ if (node.Name && node.Type && (node.Body || node.Recv !== undefined || node.recv !== undefined)) return 'FuncDecl';
11113
+ if (node.Tok && (node.Specs || node.specs)) return 'GenDecl';
11114
+ if (node.Path && (node.Name !== undefined || node.EndPos !== undefined)) return 'ImportSpec';
11115
+ if (node.Names && node.Type !== undefined) return 'ValueSpec';
11116
+ if (node.Name && node.Type !== undefined) return 'TypeSpec';
11117
+ if (node.List && (node.Opening !== undefined || node.Closing !== undefined)) return 'FieldList';
11118
+ return undefined;
11119
+ }
11120
+
11121
+ function normalizeGoAstKind(kind) {
11122
+ const text = String(kind).replace(/^(?:ast\.)?\*/, '').replace(/^(?:go\/ast\.)/, '');
11123
+ if (/^file$/i.test(text)) return 'File';
11124
+ if (/^package$/i.test(text)) return 'Package';
11125
+ if (/^funcdecl$/i.test(text) || /^func_decl$/i.test(text)) return 'FuncDecl';
11126
+ if (/^gendecl$/i.test(text) || /^gen_decl$/i.test(text)) return 'GenDecl';
11127
+ if (/^importspec$/i.test(text) || /^import_spec$/i.test(text)) return 'ImportSpec';
11128
+ if (/^typespec$/i.test(text) || /^type_spec$/i.test(text)) return 'TypeSpec';
11129
+ if (/^valuespec$/i.test(text) || /^value_spec$/i.test(text)) return 'ValueSpec';
11130
+ if (/^structtype$/i.test(text) || /^struct_type$/i.test(text)) return 'StructType';
11131
+ if (/^interfacetype$/i.test(text) || /^interface_type$/i.test(text)) return 'InterfaceType';
11132
+ if (/^fieldlist$/i.test(text) || /^field_list$/i.test(text)) return 'FieldList';
11133
+ return text;
11134
+ }
11135
+
11136
+ function ignoredGoAstField(key) {
11137
+ return key === '_type'
11138
+ || key === 'type'
11139
+ || key === 'kind'
11140
+ || key === 'nodeType'
11141
+ || key === 'astKind'
11142
+ || key === 'parent'
11143
+ || key === 'Obj'
11144
+ || key === 'object'
11145
+ || key === 'Scope'
11146
+ || key === 'scope'
11147
+ || key === 'Unresolved'
11148
+ || key === 'unresolved'
11149
+ || key === 'FileStart'
11150
+ || key === 'FileEnd'
11151
+ || key === 'Package'
11152
+ || key === 'Name'
11153
+ || key === 'Path'
11154
+ || key === 'Pos'
11155
+ || key === 'End'
11156
+ || key === 'pos'
11157
+ || key === 'end';
11158
+ }
11159
+
11160
+ function primitiveGoAstFields(node, kind) {
11161
+ const fields = { kind };
11162
+ const name = goAstDeclarationName(node);
11163
+ if (name) fields.name = name;
11164
+ const type = goAstTypeName(node.Type ?? node.type);
11165
+ if (type) fields.type = type;
11166
+ const tok = goAstTokenName(node.Tok ?? node.tok);
11167
+ if (tok) fields.token = tok;
11168
+ const importPath = goAstImportPath(node);
11169
+ if (importPath) fields.importPath = importPath;
11170
+ const receiver = goAstReceiverName(node);
11171
+ if (receiver) fields.receiver = receiver;
11172
+ for (const key of ['Incomplete', 'Doc', 'Comment']) {
11173
+ const value = node[key] ?? node[key[0].toLowerCase() + key.slice(1)];
11174
+ if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || value === null) fields[key[0].toLowerCase() + key.slice(1)] = value;
11175
+ }
11176
+ if (Array.isArray(node.Names ?? node.names)) {
11177
+ fields.names = (node.Names ?? node.names).map(goAstIdentName).filter(Boolean).join(',');
11178
+ }
11179
+ return fields;
11180
+ }
11181
+
11182
+ function spanFromGoAstNode(node, input, options = {}) {
11183
+ const start = goAstPosition(node.Pos ?? node.pos ?? node.Name?.NamePos ?? node.name?.namePos ?? node.Package, options);
11184
+ const end = goAstPosition(node.End ?? node.end ?? node.EndPos ?? node.endPos, options);
11185
+ if (!start) return undefined;
11186
+ return {
11187
+ sourceId: input.sourceHash,
11188
+ path: start.path ?? end?.path ?? input.sourcePath,
11189
+ startLine: start.line,
11190
+ startColumn: start.column,
11191
+ endLine: end?.line,
11192
+ endColumn: end?.column
11193
+ };
11194
+ }
11195
+
11196
+ function goAstPosition(value, options = {}) {
11197
+ if (!value) return undefined;
11198
+ if (typeof value === 'object') {
11199
+ const position = value.position ?? value.Position ?? value.pos ?? value.Pos ?? value;
11200
+ const line = position.Line ?? position.line;
11201
+ const column = position.Column ?? position.column ?? position.Col ?? position.col;
11202
+ if (typeof line === 'number') {
11203
+ return {
11204
+ path: position.Filename ?? position.filename ?? position.file ?? position.path,
11205
+ line,
11206
+ column: typeof column === 'number' ? column : undefined
11207
+ };
11208
+ }
11209
+ }
11210
+ const fileSet = options.fileSet ?? options.fset;
11211
+ const positionFor = typeof fileSet?.PositionFor === 'function'
11212
+ ? fileSet.PositionFor.bind(fileSet)
11213
+ : typeof fileSet?.positionFor === 'function'
11214
+ ? fileSet.positionFor.bind(fileSet)
11215
+ : typeof fileSet?.Position === 'function'
11216
+ ? fileSet.Position.bind(fileSet)
11217
+ : typeof fileSet?.position === 'function'
11218
+ ? fileSet.position.bind(fileSet)
11219
+ : undefined;
11220
+ if (positionFor) {
11221
+ const resolved = positionFor(value, true);
11222
+ return goAstPosition(resolved, options);
11223
+ }
11224
+ return undefined;
11225
+ }
11226
+
11227
+ function goAstPositionKind(node) {
11228
+ const pos = node.Pos ?? node.pos ?? node.Name?.NamePos ?? node.name?.namePos;
11229
+ if (!pos) return undefined;
11230
+ if (typeof pos === 'object') return 'token.Position';
11231
+ return 'token.Pos';
11232
+ }
11233
+
11234
+ function goAstDeclarations(node, kind, nativeNodeId, input) {
11235
+ if (kind === 'ImportSpec') {
11236
+ const name = goAstImportPath(node);
11237
+ return name ? [declarationRecord(input, nativeNodeId, name, 'module', 'import')] : [];
11238
+ }
11239
+ if (kind === 'FuncDecl') {
11240
+ const name = goAstDeclarationName(node);
11241
+ if (!name) return [];
11242
+ const receiver = goAstReceiverName(node);
11243
+ return [declarationRecord(input, nativeNodeId, receiver ? `${receiver}.${name}` : name, receiver ? 'method' : 'function', node.Body || node.body ? 'definition' : 'declaration')];
11244
+ }
11245
+ if (kind === 'TypeSpec') {
11246
+ const name = goAstDeclarationName(node);
11247
+ return name ? [declarationRecord(input, nativeNodeId, name, goAstTypeSpecSymbolKind(node), 'definition')] : [];
11248
+ }
11249
+ if (kind === 'ValueSpec') {
11250
+ const names = goAstValueSpecNames(node);
11251
+ const token = goAstTokenName(node.parentTok ?? node.Tok ?? node.tok);
11252
+ return names.map((name) => declarationRecord(input, nativeNodeId, name, token === 'CONST' || token === 'const' ? 'constant' : 'variable', 'definition'));
11253
+ }
11254
+ if (kind === 'Field') {
11255
+ return goAstValueSpecNames(node).map((name) => declarationRecord(input, nativeNodeId, name, 'property', 'definition'));
11256
+ }
11257
+ if (kind === 'Package' || kind === 'File') {
11258
+ const name = goAstPackageName(node);
11259
+ return name ? [declarationRecord(input, nativeNodeId, name, 'module', 'definition')] : [];
11260
+ }
11261
+ return [];
11262
+ }
11263
+
11264
+ function goAstChildEntries(node) {
11265
+ const fieldNames = Object.keys(node).filter((key) => !ignoredGoAstField(key));
11266
+ const entries = [];
11267
+ for (const field of fieldNames) {
11268
+ const value = node[field];
11269
+ if (field === 'Files' || field === 'files') {
11270
+ if (value && typeof value === 'object') entries.push([field, Array.isArray(value) ? value : Object.values(value)]);
11271
+ continue;
11272
+ }
11273
+ if (field === 'Specs' || field === 'specs') {
11274
+ const token = goAstTokenName(node.Tok ?? node.tok);
11275
+ entries.push([field, Array.isArray(value)
11276
+ ? value.map((entry) => entry && typeof entry === 'object' ? { parentTok: token, ...entry } : entry)
11277
+ : value]);
11278
+ continue;
11279
+ }
11280
+ entries.push([field, value]);
11281
+ }
11282
+ return entries.filter(([, value]) => Array.isArray(value)
11283
+ ? value.some(isGoAstNode)
11284
+ : isGoAstNode(value));
11285
+ }
11286
+
11287
+ function goAstNodeValue(node) {
11288
+ return goAstDeclarationName(node)
11289
+ ?? goAstImportPath(node)
11290
+ ?? goAstTypeName(node.Type ?? node.type)
11291
+ ?? goAstLiteralValue(node);
11292
+ }
11293
+
11294
+ function goAstDeclarationName(node) {
11295
+ if (!node || typeof node !== 'object') return undefined;
11296
+ return goAstIdentName(node.Name ?? node.name)
11297
+ ?? goAstIdentName(node.Ident ?? node.ident)
11298
+ ?? goAstIdentName(node.Sel ?? node.sel)
11299
+ ?? (typeof node.Name === 'string' ? node.Name : undefined)
11300
+ ?? (typeof node.name === 'string' ? node.name : undefined);
11301
+ }
11302
+
11303
+ function goAstPackageName(node) {
11304
+ if (!node || typeof node !== 'object') return undefined;
11305
+ return goAstIdentName(node.Name ?? node.name) ?? node.PackageName ?? node.packageName;
11306
+ }
11307
+
11308
+ function goAstIdentName(value) {
11309
+ if (!value) return undefined;
11310
+ if (typeof value === 'string') return value;
11311
+ return value.Name ?? value.name ?? value.Value ?? value.value;
11312
+ }
11313
+
11314
+ function goAstImportPath(node) {
11315
+ if (!node || typeof node !== 'object') return undefined;
11316
+ const path = node.Path ?? node.path;
11317
+ const raw = typeof path === 'string' ? path : path?.Value ?? path?.value ?? path?.Kind;
11318
+ if (typeof raw !== 'string') return undefined;
11319
+ return raw.replace(/^"|"$/g, '').replace(/^`|`$/g, '');
11320
+ }
11321
+
11322
+ function goAstReceiverName(node) {
11323
+ const recv = node?.Recv ?? node?.recv;
11324
+ const list = recv?.List ?? recv?.list;
11325
+ if (!Array.isArray(list) || !list.length) return undefined;
11326
+ const first = list[0];
11327
+ return goAstTypeName(first?.Type ?? first?.type);
11328
+ }
11329
+
11330
+ function goAstValueSpecName(node) {
11331
+ return goAstValueSpecNames(node)[0];
11332
+ }
11333
+
11334
+ function goAstValueSpecNames(node) {
11335
+ const names = node.Names ?? node.names;
11336
+ if (Array.isArray(names)) return names.map(goAstIdentName).filter(Boolean);
11337
+ const name = goAstDeclarationName(node);
11338
+ return name ? [name] : [];
11339
+ }
11340
+
11341
+ function goAstTypeSpecSymbolKind(node) {
11342
+ const type = node.Type ?? node.type;
11343
+ const kind = goAstKind(type);
11344
+ if (kind === 'InterfaceType') return 'interface';
11345
+ if (kind === 'StructType') return 'class';
11346
+ return 'type';
11347
+ }
11348
+
11349
+ function goAstTypeName(value) {
11350
+ if (!value) return undefined;
11351
+ if (typeof value === 'string') return value;
11352
+ const kind = goAstKind(value);
11353
+ if (kind === 'Ident') return goAstIdentName(value);
11354
+ if (kind === 'StarExpr') {
11355
+ const inner = goAstTypeName(value.X ?? value.x);
11356
+ return inner ? `*${inner}` : '*';
11357
+ }
11358
+ if (kind === 'SelectorExpr') {
11359
+ const left = goAstTypeName(value.X ?? value.x);
11360
+ const right = goAstIdentName(value.Sel ?? value.sel);
11361
+ return [left, right].filter(Boolean).join('.');
11362
+ }
11363
+ if (kind === 'ArrayType') {
11364
+ const inner = goAstTypeName(value.Elt ?? value.elt);
11365
+ return `[]${inner ?? 'unknown'}`;
11366
+ }
11367
+ if (kind === 'MapType') {
11368
+ return `map[${goAstTypeName(value.Key ?? value.key) ?? 'unknown'}]${goAstTypeName(value.Value ?? value.value) ?? 'unknown'}`;
11369
+ }
11370
+ if (kind === 'StructType') return 'struct';
11371
+ if (kind === 'InterfaceType') return 'interface';
11372
+ if (kind === 'FuncType') return 'func';
11373
+ return goAstDeclarationName(value);
11374
+ }
11375
+
11376
+ function goAstTokenName(value) {
11377
+ if (!value) return undefined;
11378
+ if (typeof value === 'string') return value;
11379
+ if (typeof value === 'number') return String(value);
11380
+ return value.String ?? value.string ?? value.Name ?? value.name;
11381
+ }
11382
+
11383
+ function goAstLiteralValue(node) {
11384
+ const value = node.Value ?? node.value;
11385
+ if (value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') return value;
11386
+ return undefined;
11387
+ }
11388
+
11389
+ function goGeneratedCodeMarker(node, kind) {
11390
+ if (kind !== 'File') return false;
11391
+ if (node.Generated || node.generated) return true;
11392
+ const comments = node.Comments ?? node.comments;
11393
+ if (!Array.isArray(comments)) return false;
11394
+ return comments.some((group) => JSON.stringify(group).includes('Code generated') && JSON.stringify(group).includes('DO NOT EDIT'));
11395
+ }
11396
+
11397
+ function goBadAstKind(kind) {
11398
+ return kind === 'BadDecl' || kind === 'BadExpr' || kind === 'BadStmt';
11399
+ }
11400
+
11401
+ function goReceiverFieldCount(node) {
11402
+ const list = (node?.Recv ?? node?.recv)?.List ?? (node?.Recv ?? node?.recv)?.list;
11403
+ return Array.isArray(list) ? list.length : 0;
11404
+ }
11405
+
11406
+ function goTypeEvidenceSummary(value) {
11407
+ if (!value || typeof value !== 'object') return undefined;
11408
+ const summary = {};
11409
+ if (typeof value.packagePath === 'string') summary.packagePath = value.packagePath;
11410
+ if (typeof value.hash === 'string') summary.hash = value.hash;
11411
+ if (Array.isArray(value.types)) summary.typeCount = value.types.length;
11412
+ if (Array.isArray(value.references)) summary.referenceCount = value.references.length;
11413
+ return Object.keys(summary).length ? summary : { present: true };
11414
+ }
11415
+
11416
+ function javaAstRoot(value) {
11417
+ if (!value || typeof value !== 'object') return undefined;
11418
+ if (isJavaAstNode(value)) return value;
11419
+ if (isJavaAstNode(value.ast)) return value.ast;
11420
+ if (isJavaAstNode(value.root)) return value.root;
11421
+ if (isJavaAstNode(value.compilationUnit)) return value.compilationUnit;
11422
+ if (isJavaAstNode(value.unit)) return value.unit;
11423
+ if (isJavaAstNode(value.sourceFile)) return value.sourceFile;
11424
+ if (Array.isArray(value.types) || Array.isArray(value.imports) || value.packageDeclaration || value.package) {
11425
+ return { kind: 'CompilationUnit', ...value };
11426
+ }
11427
+ return undefined;
11428
+ }
11429
+
11430
+ function isJavaAstNode(value) {
11431
+ return Boolean(value && typeof value === 'object' && typeof javaAstKind(value) === 'string');
11432
+ }
11433
+
11434
+ function javaAstKind(node) {
11435
+ if (!node || typeof node !== 'object') return undefined;
11436
+ const declared = node.kind ?? node._type ?? node.type ?? node.nodeType ?? node.astKind ?? node.treeKind ?? node.nodeKind;
11437
+ if (typeof declared === 'string') return normalizeJavaAstKind(declared);
11438
+ if (Array.isArray(node.imports) || Array.isArray(node.types) || node.packageDeclaration || node.package) return 'CompilationUnit';
11439
+ if (node.name && (node.members || node.bodyDeclarations || node.extends || node.implements || node.permittedTypes)) return 'ClassDeclaration';
11440
+ if (node.name && (node.returnType || node.parameters || node.body) && (node.modifiers || node.thrownExceptions || node.throws)) return 'MethodDeclaration';
11441
+ if (node.variables || node.fragments) return 'FieldDeclaration';
11442
+ if (node.name && node.type && (node.initializer !== undefined || node.extraDimensions !== undefined)) return 'VariableDeclarator';
11443
+ return undefined;
11444
+ }
11445
+
11446
+ function normalizeJavaAstKind(kind) {
11447
+ const text = String(kind).replace(/^(?:com\.sun\.source\.tree\.|org\.eclipse\.jdt\.core\.dom\.|com\.github\.javaparser\.ast\.)/, '');
11448
+ const compact = text.replace(/[_\s.-]+/g, '').replace(/Tree$/, '').toLowerCase();
11449
+ if (compact === 'compilationunit' || compact === 'compilationunitnode') return 'CompilationUnit';
11450
+ if (compact === 'package' || compact === 'packagedeclaration' || compact === 'packageclause') return 'PackageDeclaration';
11451
+ if (compact === 'import' || compact === 'importdeclaration') return 'ImportDeclaration';
11452
+ if (compact === 'class' || compact === 'classdeclaration' || compact === 'normalclassdeclaration' || compact === 'classorinterfacedeclaration') return 'ClassDeclaration';
11453
+ if (compact === 'interface' || compact === 'interfacedeclaration' || compact === 'normalinterfacedeclaration') return 'InterfaceDeclaration';
11454
+ if (compact === 'enum' || compact === 'enumdeclaration') return 'EnumDeclaration';
11455
+ if (compact === 'record' || compact === 'recorddeclaration') return 'RecordDeclaration';
11456
+ if (compact === 'annotation' || compact === 'annotationdeclaration' || compact === 'annotationtypedeclaration' || compact === 'annotationinterface') return 'AnnotationDeclaration';
11457
+ if (compact === 'method' || compact === 'methoddeclaration') return 'MethodDeclaration';
11458
+ if (compact === 'constructor' || compact === 'constructordeclaration') return 'ConstructorDeclaration';
11459
+ if (compact === 'variable' || compact === 'variabledeclaration' || compact === 'variabledeclarator' || compact === 'variabletree') return 'VariableDeclarator';
11460
+ if (compact === 'field' || compact === 'fielddeclaration') return 'FieldDeclaration';
11461
+ if (compact === 'enumconstant' || compact === 'enumconstantdeclaration') return 'EnumConstantDeclaration';
11462
+ if (compact === 'parameter' || compact === 'formalparameter' || compact === 'receiverparameter') return 'Parameter';
11463
+ if (compact === 'modifiers' || compact === 'modifier') return 'Modifiers';
11464
+ if (compact === 'markerannotationexpr' || compact === 'singlememberannotationexpr' || compact === 'normalannotationexpr' || compact === 'annotationexpr') return 'Annotation';
11465
+ if (compact === 'erroneous' || compact === 'erroneoustree' || compact === 'malformed' || compact === 'error' || compact === 'errornode' || compact === 'problem' || compact === 'problemtree' || compact === 'recovered') return 'Erroneous';
11466
+ if (/^[A-Z0-9_]+$/.test(text)) return text.toLowerCase().split('_').map(upperFirst).join('');
11467
+ return text;
11468
+ }
11469
+
11470
+ function ignoredJavaAstField(key) {
11471
+ return key === '_type'
11472
+ || key === 'type'
11473
+ || key === 'kind'
11474
+ || key === 'nodeType'
11475
+ || key === 'astKind'
11476
+ || key === 'treeKind'
11477
+ || key === 'nodeKind'
11478
+ || key === 'parent'
11479
+ || key === 'parentKind'
11480
+ || key === 'parentField'
11481
+ || key === 'binding'
11482
+ || key === 'resolvedBinding'
11483
+ || key === 'symbol'
11484
+ || key === 'scope'
11485
+ || key === 'range'
11486
+ || key === 'loc'
11487
+ || key === 'location'
11488
+ || key === 'pos'
11489
+ || key === 'end'
11490
+ || key === 'start'
11491
+ || key === 'endPosition'
11492
+ || key === 'startPosition'
11493
+ || key === 'length'
11494
+ || key === 'name'
11495
+ || key === 'identifier'
11496
+ || key === 'simpleName'
11497
+ || key === 'qualifiedName';
11498
+ }
11499
+
11500
+ function primitiveJavaAstFields(node, kind) {
11501
+ const fields = { kind };
11502
+ const name = javaAstDeclarationName(node);
11503
+ if (name) fields.name = name;
11504
+ const importPath = javaAstImportPath(node);
11505
+ if (importPath) fields.importPath = importPath;
11506
+ const type = javaAstTypeName(node.type ?? node.typeName ?? node.returnType ?? node.elementType);
11507
+ if (type) fields.type = type;
11508
+ const packageName = javaAstPackageName(node);
11509
+ if (packageName) fields.packageName = packageName;
11510
+ const modifiers = javaAstModifierNames(node);
11511
+ if (modifiers.length) fields.modifiers = modifiers.join(',');
11512
+ if (node.static === true || node.isStatic === true) fields.static = true;
11513
+ if (node.default === true || node.isDefault === true) fields.default = true;
11514
+ if (node.generated === true || node.Generated === true) fields.generated = true;
11515
+ if (typeof node.binaryName === 'string') fields.binaryName = node.binaryName;
11516
+ if (typeof node.qualifiedName === 'string') fields.qualifiedName = node.qualifiedName;
11517
+ if (Array.isArray(node.parameters)) fields.parameterCount = node.parameters.length;
11518
+ if (Array.isArray(node.throws ?? node.thrownExceptions)) fields.throwsCount = (node.throws ?? node.thrownExceptions).length;
11519
+ return fields;
11520
+ }
11521
+
11522
+ function spanFromJavaAstNode(node, input, options = {}) {
11523
+ const direct = spanFromJavaRange(node.range ?? node.loc ?? node.location, input)
11524
+ ?? spanFromJavaLineFields(node, input);
11525
+ if (direct) return direct;
11526
+ const start = javaAstPosition(
11527
+ node.begin ?? node.start ?? node.pos ?? node.position ?? node.startPosition ?? node.name?.range?.begin ?? node.name?.loc?.start,
11528
+ options
11529
+ );
11530
+ const end = javaAstPosition(
11531
+ node.end ?? node.endPosition ?? node.stopPosition ?? node.finishPosition ?? node.name?.range?.end ?? node.name?.loc?.end,
11532
+ options
11533
+ );
11534
+ const sourceRange = node.sourceRange ?? node.rangeInfo;
11535
+ const sourceStart = javaAstPosition(
11536
+ sourceRange?.start ?? sourceRange?.offset ?? sourceRange?.startPosition,
11537
+ options
11538
+ );
11539
+ const sourceEnd = javaAstPosition(
11540
+ typeof sourceRange?.offset === 'number' && typeof sourceRange?.length === 'number'
11541
+ ? sourceRange.offset + sourceRange.length
11542
+ : sourceRange?.end ?? sourceRange?.endPosition,
11543
+ options
11544
+ );
11545
+ const resolvedStart = start ?? sourceStart;
11546
+ const resolvedEnd = end ?? sourceEnd;
11547
+ if (!resolvedStart) return undefined;
11548
+ return {
11549
+ sourceId: input.sourceHash,
11550
+ path: resolvedStart.path ?? resolvedEnd?.path ?? input.sourcePath,
11551
+ startLine: resolvedStart.line,
11552
+ startColumn: resolvedStart.column,
11553
+ endLine: resolvedEnd?.line,
11554
+ endColumn: resolvedEnd?.column
11555
+ };
11556
+ }
11557
+
11558
+ function spanFromJavaRange(range, input) {
11559
+ if (!range || typeof range !== 'object') return undefined;
11560
+ const start = range.begin ?? range.start;
11561
+ const end = range.end ?? range.stop;
11562
+ if (start && typeof start === 'object') {
11563
+ const startLine = start.line ?? start.Line;
11564
+ const startColumn = start.column ?? start.col ?? start.Column ?? start.character;
11565
+ const endLine = end?.line ?? end?.Line;
11566
+ const endColumn = end?.column ?? end?.col ?? end?.Column ?? end?.character;
11567
+ if (typeof startLine === 'number') {
11568
+ return {
11569
+ sourceId: input.sourceHash,
11570
+ path: start.path ?? start.file ?? end?.path ?? end?.file ?? input.sourcePath,
11571
+ startLine,
11572
+ startColumn,
11573
+ endLine,
11574
+ endColumn
11575
+ };
11576
+ }
11577
+ }
11578
+ return undefined;
11579
+ }
11580
+
11581
+ function spanFromJavaLineFields(node, input) {
11582
+ const startLine = node.startLine ?? node.line ?? node.beginLine ?? node.lineno;
11583
+ if (typeof startLine !== 'number') return undefined;
11584
+ return {
11585
+ sourceId: input.sourceHash,
11586
+ path: node.path ?? node.file ?? node.filename ?? input.sourcePath,
11587
+ startLine,
11588
+ startColumn: node.startColumn ?? node.column ?? node.beginColumn ?? node.col,
11589
+ endLine: node.endLine ?? node.end_lineno,
11590
+ endColumn: node.endColumn ?? node.end_col_offset
11591
+ };
11592
+ }
11593
+
11594
+ function javaAstPosition(value, options = {}) {
11595
+ if (value === undefined || value === null) return undefined;
11596
+ if (typeof value === 'object') {
11597
+ const position = value.position ?? value.Position ?? value.pos ?? value.start ?? value;
11598
+ const line = position.line ?? position.Line ?? position.lineno;
11599
+ const column = position.column ?? position.Column ?? position.col ?? position.character;
11600
+ if (typeof line === 'number') {
11601
+ return {
11602
+ path: position.path ?? position.file ?? position.filename ?? position.Filename,
11603
+ line,
11604
+ column: typeof column === 'number' ? column : undefined
11605
+ };
11606
+ }
11607
+ }
11608
+ const resolver = typeof options.positionResolver === 'function'
11609
+ ? options.positionResolver
11610
+ : typeof options.lineMap?.position === 'function'
11611
+ ? options.lineMap.position.bind(options.lineMap)
11612
+ : typeof options.lineMap?.getPosition === 'function'
11613
+ ? options.lineMap.getPosition.bind(options.lineMap)
11614
+ : typeof options.lineMap?.getLineNumber === 'function'
11615
+ ? (offset) => ({
11616
+ line: options.lineMap.getLineNumber(offset),
11617
+ column: typeof options.lineMap.getColumnNumber === 'function' ? options.lineMap.getColumnNumber(offset) : undefined
11618
+ })
11619
+ : undefined;
11620
+ if (resolver) {
11621
+ const resolved = resolver(value);
11622
+ if (resolved !== value) return javaAstPosition(resolved, options);
11623
+ }
11624
+ return undefined;
11625
+ }
11626
+
11627
+ function javaAstPositionKind(node) {
11628
+ if (node.range?.begin || node.loc?.start) return 'line-column-range';
11629
+ if (typeof node.startLine === 'number' || typeof node.line === 'number') return 'line-column-fields';
11630
+ if (node.pos !== undefined || node.startPosition !== undefined) return 'offset-position';
11631
+ if (node.sourceRange) return 'source-range';
11632
+ return undefined;
11633
+ }
11634
+
11635
+ function javaAstDeclarations(node, kind, nativeNodeId, input) {
11636
+ if (kind === 'PackageDeclaration') {
11637
+ const name = javaAstPackageName(node) ?? javaAstDeclarationName(node);
11638
+ return name ? [declarationRecord(input, nativeNodeId, name, 'module', 'definition')] : [];
11639
+ }
11640
+ if (kind === 'ImportDeclaration') {
11641
+ const name = javaAstImportPath(node);
11642
+ return name ? [declarationRecord(input, nativeNodeId, name, 'module', 'import')] : [];
11643
+ }
11644
+ if (javaTypeDeclarationKind(kind)) {
11645
+ const name = javaAstDeclarationName(node);
11646
+ return name ? [declarationRecord(input, nativeNodeId, name, javaTypeDeclarationSymbolKind(kind), 'definition')] : [];
11647
+ }
11648
+ if (kind === 'MethodDeclaration' || kind === 'ConstructorDeclaration') {
11649
+ const name = javaAstDeclarationName(node);
11650
+ if (!name) return [];
11651
+ return [declarationRecord(input, nativeNodeId, name, 'method', javaAstHasBody(node) ? 'definition' : 'declaration')];
11652
+ }
11653
+ if (kind === 'FieldDeclaration') {
11654
+ return javaAstFieldNames(node).map((name) => declarationRecord(input, nativeNodeId, name, 'property', 'definition'));
11655
+ }
11656
+ if (kind === 'VariableDeclarator') {
11657
+ if (node.parentField === 'parameters' || node.parentKind === 'MethodDeclaration' || node.parentKind === 'ConstructorDeclaration') return [];
11658
+ const name = javaAstDeclarationName(node);
11659
+ if (!name) return [];
11660
+ const symbolKind = node.parentKind === 'FieldDeclaration' || javaTypeDeclarationKind(node.parentKind) ? 'property' : 'variable';
11661
+ return [declarationRecord(input, nativeNodeId, name, symbolKind, 'definition')];
11662
+ }
11663
+ if (kind === 'EnumConstantDeclaration') {
11664
+ const name = javaAstDeclarationName(node);
11665
+ return name ? [declarationRecord(input, nativeNodeId, name, 'enumMember', 'definition')] : [];
11666
+ }
11667
+ return [];
11668
+ }
11669
+
11670
+ function javaAstChildEntries(node, kind = javaAstKind(node)) {
11671
+ const fieldNames = Object.keys(node).filter((key) => !ignoredJavaAstField(key));
11672
+ const entries = [];
11673
+ for (const field of fieldNames) {
11674
+ const value = node[field];
11675
+ if (Array.isArray(value)) {
11676
+ entries.push([field, value.map((entry) => javaAstChildWithParent(entry, kind, field))]);
11677
+ continue;
11678
+ }
11679
+ if (value && typeof value === 'object') {
11680
+ entries.push([field, javaAstChildWithParent(value, kind, field)]);
11681
+ }
11682
+ }
11683
+ return entries.filter(([, value]) => Array.isArray(value)
11684
+ ? value.some(isJavaAstNode)
11685
+ : isJavaAstNode(value));
11686
+ }
11687
+
11688
+ function javaAstChildWithParent(entry, parentKind, parentField) {
11689
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return entry;
11690
+ if (!isJavaAstNode(entry)) return entry;
11691
+ return { parentKind, parentField, ...entry };
11692
+ }
11693
+
11694
+ function javaAstNodeValue(node) {
11695
+ return javaAstDeclarationName(node)
11696
+ ?? javaAstImportPath(node)
11697
+ ?? javaAstPackageName(node)
11698
+ ?? javaAstTypeName(node.type ?? node.returnType ?? node.elementType)
11699
+ ?? javaAstLiteralValue(node);
11700
+ }
11701
+
11702
+ function javaAstDeclarationName(node) {
11703
+ if (!node || typeof node !== 'object') return undefined;
11704
+ for (const key of ['name', 'identifier', 'simpleName', 'qualifiedName', 'id']) {
11705
+ const value = node[key];
11706
+ const name = javaAstName(value);
11707
+ if (name) return name;
11708
+ }
11709
+ if (node.declaration && typeof node.declaration === 'object') return javaAstDeclarationName(node.declaration);
11710
+ return undefined;
11711
+ }
11712
+
11713
+ function javaAstName(value) {
11714
+ if (!value) return undefined;
11715
+ if (typeof value === 'string') return value;
11716
+ if (typeof value.identifier === 'string') return value.identifier;
11717
+ if (typeof value.name === 'string') return value.name;
11718
+ if (typeof value.simpleName === 'string') return value.simpleName;
11719
+ if (typeof value.qualifiedName === 'string') return value.qualifiedName;
11720
+ if (typeof value.fullyQualifiedName === 'string') return value.fullyQualifiedName;
11721
+ if (typeof value.id === 'string') return value.id;
11722
+ if (typeof value.value === 'string') return value.value;
11723
+ if (value.name && value.name !== value) return javaAstName(value.name);
11724
+ if (value.identifier && value.identifier !== value) return javaAstName(value.identifier);
11725
+ return undefined;
11726
+ }
11727
+
11728
+ function javaAstPackageName(node) {
11729
+ if (!node || typeof node !== 'object') return undefined;
11730
+ return javaAstName(node.packageName ?? node.packageDeclaration ?? node.package ?? node.name);
11731
+ }
11732
+
11733
+ function javaAstImportPath(node) {
11734
+ if (!node || typeof node !== 'object') return undefined;
11735
+ const candidate = node.qualifiedIdentifier ?? node.qualifiedName ?? node.path ?? node.name ?? node.identifier;
11736
+ const path = javaAstName(candidate);
11737
+ if (!path) return undefined;
11738
+ return node.asterisk || node.wildcard || node.onDemand || node.isAsterisk ? `${path.replace(/\.\*$/, '')}.*` : path;
11739
+ }
11740
+
11741
+ function javaAstFieldNames(node) {
11742
+ const fragments = node.variables ?? node.fragments ?? node.declarators ?? node.variableDeclarators;
11743
+ if (Array.isArray(fragments)) return fragments.map(javaAstDeclarationName).filter(Boolean);
11744
+ const name = javaAstDeclarationName(node);
11745
+ return name ? [name] : [];
11746
+ }
11747
+
11748
+ function javaAstTypeName(value) {
11749
+ if (!value) return undefined;
11750
+ if (typeof value === 'string') return value;
11751
+ if (typeof value.name === 'string') return value.name;
11752
+ if (typeof value.typeName === 'string') return value.typeName;
11753
+ if (typeof value.qualifiedName === 'string') return value.qualifiedName;
11754
+ if (value.elementType) {
11755
+ const inner = javaAstTypeName(value.elementType);
11756
+ return inner ? `${inner}[]` : '[]';
11757
+ }
11758
+ if (value.componentType) {
11759
+ const inner = javaAstTypeName(value.componentType);
11760
+ return inner ? `${inner}[]` : '[]';
11761
+ }
11762
+ if (Array.isArray(value.typeArguments)) {
11763
+ const base = javaAstName(value.name) ?? javaAstName(value);
11764
+ const args = value.typeArguments.map(javaAstTypeName).filter(Boolean);
11765
+ return base ? `${base}<${args.join(', ')}>` : undefined;
11766
+ }
11767
+ return javaAstName(value);
11768
+ }
11769
+
11770
+ function javaAstModifierNames(node) {
11771
+ const modifiers = node.modifiers ?? node.Modifiers ?? node.flags;
11772
+ if (!modifiers) return [];
11773
+ if (Array.isArray(modifiers)) {
11774
+ return uniqueStrings(modifiers.map((entry) => typeof entry === 'string' ? entry : javaAstName(entry) ?? entry.keyword ?? entry.kind).filter(Boolean));
11775
+ }
11776
+ if (typeof modifiers === 'string') return uniqueStrings(modifiers.split(/\s+/).filter(Boolean));
11777
+ if (typeof modifiers === 'object') {
11778
+ return uniqueStrings(Object.entries(modifiers)
11779
+ .filter(([, enabled]) => enabled === true)
11780
+ .map(([key]) => key));
11781
+ }
11782
+ return [];
11783
+ }
11784
+
11785
+ function javaTypeDeclarationKind(kind) {
11786
+ return kind === 'ClassDeclaration'
11787
+ || kind === 'InterfaceDeclaration'
11788
+ || kind === 'EnumDeclaration'
11789
+ || kind === 'RecordDeclaration'
11790
+ || kind === 'AnnotationDeclaration';
11791
+ }
11792
+
11793
+ function javaTypeDeclarationSymbolKind(kind) {
11794
+ if (kind === 'InterfaceDeclaration' || kind === 'AnnotationDeclaration') return 'interface';
11795
+ if (kind === 'ClassDeclaration') return 'class';
11796
+ return 'type';
11797
+ }
11798
+
11799
+ function javaAstHasBody(node) {
11800
+ return Boolean(node.body || node.block || node.statements || node.defaultValue || Array.isArray(node.bodyDeclarations));
11801
+ }
11802
+
11803
+ function javaAstLiteralValue(node) {
11804
+ const value = node.value ?? node.literal ?? node.token;
11805
+ if (value === null || typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') return value;
11806
+ return undefined;
11807
+ }
11808
+
11809
+ function javaRecoveredAstKind(kind) {
11810
+ return kind === 'Erroneous'
11811
+ || /Error|Erroneous|Malformed|Recovered|Problem|Missing/.test(String(kind));
11812
+ }
11813
+
11814
+ function javaProblemNode(node, kind) {
11815
+ return Boolean(node.problem || node.error || node.malformed || node.recovered || node.hasError || node.hasErrors || kind === 'Erroneous');
11816
+ }
11817
+
11818
+ function javaGeneratedCodeMarker(node, kind) {
11819
+ if (node.generated || node.Generated || node.isGenerated) return true;
11820
+ if (kind === 'Annotation') {
11821
+ const name = javaAstDeclarationName(node);
11822
+ if (name && /(^|\.)(Generated|GeneratedValue)$/.test(name)) return true;
11823
+ }
11824
+ const annotations = node.annotations ?? node.modifiers?.annotations ?? node.modifiers;
11825
+ if (Array.isArray(annotations)) {
11826
+ return annotations.some((annotation) => {
11827
+ const name = javaAstDeclarationName(annotation) ?? javaAstName(annotation);
11828
+ return Boolean(name && /(^|\.)(Generated|GeneratedValue)$/.test(name));
11829
+ });
11830
+ }
11831
+ return false;
11832
+ }
11833
+
11834
+ function javaLombokAnnotationMarker(node, kind) {
11835
+ if (kind !== 'Annotation') return false;
11836
+ const name = javaAstDeclarationName(node);
11837
+ return Boolean(name && /^(lombok\.|Data$|Value$|Builder$|Getter$|Setter$|AllArgsConstructor$|NoArgsConstructor$|RequiredArgsConstructor$)/.test(name));
11838
+ }
11839
+
11840
+ function javaGeneratedCodeLoss(input, nodeId, span, options = {}, metadata = {}) {
11841
+ return {
11842
+ id: `loss_${idFragment(nodeId ?? input.sourcePath ?? 'java')}_java_generated_code`,
11843
+ severity: 'warning',
11844
+ phase: 'parse',
11845
+ sourceFormat: input.language,
11846
+ kind: 'generatedCode',
11847
+ message: 'Java generated-source, annotation-generated, or Lombok-derived code marker was imported; regenerated members and source ownership require host evidence.',
11848
+ span,
11849
+ nodeId,
11850
+ metadata: {
11851
+ parser: options.parser,
11852
+ astFormat: options.astFormat,
11853
+ annotationProcessing: javaAnnotationProcessingSummary(options.annotationProcessing),
11854
+ ...metadata
11855
+ }
11856
+ };
11857
+ }
11858
+
11859
+ function javaPathEvidenceSummary(value) {
11860
+ if (!value) return undefined;
11861
+ if (Array.isArray(value)) return { entryCount: value.length };
11862
+ if (typeof value === 'string') return { entryCount: value.split(/[:;]/).filter(Boolean).length };
11863
+ if (typeof value === 'object') {
11864
+ const summary = {};
11865
+ if (typeof value.hash === 'string') summary.hash = value.hash;
11866
+ if (Array.isArray(value.entries)) summary.entryCount = value.entries.length;
11867
+ if (Array.isArray(value.roots)) summary.rootCount = value.roots.length;
11868
+ if (typeof value.source === 'string') summary.source = value.source;
11869
+ return Object.keys(summary).length ? summary : { present: true };
11870
+ }
11871
+ return { present: true };
11872
+ }
11873
+
11874
+ function javaAnnotationProcessingSummary(value) {
11875
+ if (!value) return undefined;
11876
+ if (Array.isArray(value)) return { processorCount: value.length };
11877
+ if (typeof value === 'object') {
11878
+ const summary = {};
11879
+ if (typeof value.hash === 'string') summary.hash = value.hash;
11880
+ if (typeof value.enabled === 'boolean') summary.enabled = value.enabled;
11881
+ if (Array.isArray(value.processors)) summary.processorCount = value.processors.length;
11882
+ if (Array.isArray(value.generatedSources)) summary.generatedSourceCount = value.generatedSources.length;
11883
+ return Object.keys(summary).length ? summary : { present: true };
11884
+ }
11885
+ return { present: Boolean(value) };
11886
+ }
11887
+
11888
+ function javaBindingEvidenceSummary(value) {
11889
+ if (!value || typeof value !== 'object') return undefined;
11890
+ const summary = {};
11891
+ if (typeof value.hash === 'string') summary.hash = value.hash;
11892
+ if (Array.isArray(value.bindings)) summary.bindingCount = value.bindings.length;
11893
+ if (Array.isArray(value.types)) summary.typeCount = value.types.length;
11894
+ if (Array.isArray(value.references)) summary.referenceCount = value.references.length;
11895
+ if (typeof value.solver === 'string') summary.solver = value.solver;
11896
+ return Object.keys(summary).length ? summary : { present: true };
11897
+ }
11898
+
10660
11899
  function declarationRecord(input, nativeNodeId, name, symbolKind, role = 'definition') {
10661
11900
  return {
10662
11901
  name: String(name),