diff --git a/gitnexus-shared/src/scope-resolution/finalize-algorithm.ts b/gitnexus-shared/src/scope-resolution/finalize-algorithm.ts index df27a8511..a94012a0b 100644 --- a/gitnexus-shared/src/scope-resolution/finalize-algorithm.ts +++ b/gitnexus-shared/src/scope-resolution/finalize-algorithm.ts @@ -127,20 +127,22 @@ export interface FinalizedScc { /** * Counters reported by `finalize`. * - * **Counting granularity** — all edge counters are **per-`ParsedImport`**, - * not per-materialized-`ImportEdge`. A single `wildcard` ParsedImport that - * expands to N exports counts as one linked edge in these stats; the - * materialized output (`FinalizeOutput.imports`) will have N edges for - * that input. `dynamic-unresolved` ParsedImports count as linked (they - * pass through with no `linkStatus`), so `linkedEdges` ≠ "has a + * **Counting granularity** — `totalEdges` is **per-generated-`ImportEdgeDraft`**, + * which may exceed the number of `ParsedImport` records when + * `resolveImportTarget` returns a multi-file array (e.g. Go package-scoped + * imports fan out to every `.go` file in the target directory). A single + * `wildcard` ParsedImport that expands to N exports also counts as one + * linked edge here; the materialized output (`FinalizeOutput.imports`) will + * have N edges for that input. `dynamic-unresolved` ParsedImports count as + * linked (they pass through with no `linkStatus`), so `linkedEdges` ≠ "has a * BindingRef" — use the `bindings` map for that. * - * In other words: `totalEdges === input.parsedImports.length` summed + * In other words: `totalEdges >= input.parsedImports.length` summed * across files, and `linkedEdges + unresolvedEdges === totalEdges`. */ export interface FinalizeStats { readonly totalFiles: number; - /** Total `ParsedImport` records seen across all files. */ + /** Total `ImportEdgeDraft` records generated (≥ ParsedImport count). */ readonly totalEdges: number; /** * `ParsedImport`s whose finalized edge does NOT carry diff --git a/gitnexus/src/core/ingestion/languages/go/captures.ts b/gitnexus/src/core/ingestion/languages/go/captures.ts index baffa9210..8065341b3 100644 --- a/gitnexus/src/core/ingestion/languages/go/captures.ts +++ b/gitnexus/src/core/ingestion/languages/go/captures.ts @@ -8,6 +8,31 @@ import { synthesizeGoReceiverBinding } from './receiver-binding.js'; import { synthesizeGoTypeBindings } from './type-binding.js'; import { getTreeSitterBufferSize } from '../../constants.js'; +/** Go builtin types that must not be qualified with a package prefix. */ +const GO_BUILTIN_TYPES = new Set([ + 'bool', + 'byte', + 'complex128', + 'complex64', + 'error', + 'float32', + 'float64', + 'int', + 'int16', + 'int32', + 'int64', + 'int8', + 'rune', + 'string', + 'uint', + 'uint16', + 'uint32', + 'uint64', + 'uint8', + 'uintptr', + 'any', +]); + function inferPackageName(sourceText: string): string | null { const match = sourceText.match(/^\s*package\s+([A-Za-z_][A-Za-z0-9_]*)/m); return match?.[1] ?? null; @@ -155,8 +180,8 @@ export function emitGoScopeCaptures( let raw = typeCap.text.trim(); while (raw.startsWith('*')) raw = raw.slice(1).trim(); if (raw.startsWith('[]')) raw = raw.slice(2).trim(); - // Not a builtin or generic — safe to qualify. if (raw.includes('.') || raw.startsWith('func(') || raw.startsWith('map[')) continue; + if (GO_BUILTIN_TYPES.has(raw)) continue; const idx = raw.indexOf('['); if (idx !== -1) raw = raw.slice(0, idx); out[i] = { diff --git a/gitnexus/src/core/ingestion/languages/go/range-binding.ts b/gitnexus/src/core/ingestion/languages/go/range-binding.ts index d4a7b828a..4ba63f46b 100644 --- a/gitnexus/src/core/ingestion/languages/go/range-binding.ts +++ b/gitnexus/src/core/ingestion/languages/go/range-binding.ts @@ -96,6 +96,7 @@ function findEnclosingFunctionScope( _node: unknown, _scopeMap: ReadonlyMap, ): Scope | null { - // V1 simplified: return null, use module scope as fallback + // V1 simplified: return null, use module scope as fallback. + // TODO(#1239): walk up tree-sitter AST to find enclosing func/method declaration. return null; }