mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-11-15 05:59:11 +08:00
fix(go): a package-level var or const named in uppercase is exported (#3043)
Both extractors created a Go var/const node from its var_spec or const_spec without exportedness: the TS Go branch passed no isExported (the declaration-level value is read off the var_declaration, which has no name), and the kernel's extract_variable set none. Every such node was unexported, so findGoPackageMember, which looks up pkg.Name among the package's exported declarations, skipped it: a call through `var Hook = func...` from another package linked to nothing, though the same call inside the package linked to the variable. Both engines now mark the node exported by its own name's case, read from the spec through goExtractor.isExported / is_exported, as functions, methods and types already were. Validation: - __tests__/go-package-value-exported.test.ts, 16 tests (extraction on the kernel and wasm, LF and CRLF; cross-package calls on both paths): 12 fail on the base main, 6 with only the TS half (the kernel checks), all pass with the fix. - A/B, main vs fix, kernel path: gin 108 var/const flags, 0 edges; prometheus 625 flags, 0 edges; etcd 806 flags and 12 new calls, all right (e2e.GetVersionFromBinary x11 and model.NonDeterministicModel, both `var X = func(...)`); flask and express byte-identical. The fix's kernel and wasm graphs are byte-identical on all three Go repos, and the wasm A/B matches. - kernel-parity --lang go: gin 99/99, prometheus 755/755, etcd 1065/1105 with 40 deferred on main too; 0 diffs. - etcd index time, median of 3 interleaved: 13.4 s main, 12.6 s fix. Reimplements PR #1521 by ericquan8. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
c12a7b6a74
commit
37052b1825
@@ -216,8 +216,10 @@ export const goExtractor: LanguageExtractor = {
|
||||
},
|
||||
isExported: (node, source) => {
|
||||
// Go: a symbol is exported when its identifier starts with an uppercase letter.
|
||||
// Look at the `name` field directly (works for function_declaration,
|
||||
// method_declaration, type_spec, and var_spec / const_spec via extractor flow).
|
||||
// Look at the `name` field directly: function_declaration,
|
||||
// method_declaration, type_spec, and a var_spec / const_spec, whose first
|
||||
// name is the one the extractor gives a node (never the declaration
|
||||
// around a spec, which has no name).
|
||||
const nameNode = getChildByField(node, 'name');
|
||||
if (nameNode) {
|
||||
const text = getNodeText(nameNode, source);
|
||||
|
||||
@@ -4149,9 +4149,14 @@ export class TreeSitterExtractor {
|
||||
|
||||
// A member of a `const ( … )` or `var ( … )` group has its own doc
|
||||
// comment beside it in the parentheses; one without keeps the group's.
|
||||
// Exported by its own name's case, read from the spec: the
|
||||
// declaration around it has no name, so `var Hook = …` and
|
||||
// `const Limit = 3` read as unexported and `a.Hook()` from another
|
||||
// package linked to nothing.
|
||||
varNode = this.createNode(node.type === 'const_declaration' ? 'constant' : 'variable', name, spec, {
|
||||
docstring: this.docstringFor(spec) ?? docstring,
|
||||
signature: initSignature,
|
||||
isExported: this.extractor.isExported?.(spec, this.source),
|
||||
});
|
||||
}
|
||||
// Walk the initializer so composite literals and calls in a
|
||||
|
||||
Reference in New Issue
Block a user