Repository navigation
fix(go): variables declared in a var ( … ) block are indexed - #2682
Merged
Merged
Conversation
tree-sitter-go wraps the specs of a var group in a var_spec_list node, unlike a const group's, which sit directly in the declaration. Both extractors read only the specs directly inside a declaration, so every variable declared in a var ( ... ) block was missing from the graph: no node, no call or construction recorded from its initializer, and nothing for code that reads it, or for a call made through it, to point at. Each member of a var group is now a variable, as one declared on its own already was, with its own doc comment or the group's, and its initializer walked under it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Last follow-up from #2678, found while doing #2680. Variables declared in a Go
var ( … )block were not indexed at all. tree-sitter-go wraps a var group's specs in avar_spec_listnode, unlike aconst ( … )group's, which sit directly in the declaration. Both extractors read only the specs directly inside a declaration, so etcd, prometheus and gin had no node for any grouped variable. What followed from that:bsonBindinginvar ( BSON BindingBody = bsonBinding{} … ));fPointPool.Get()or etcd'sslowApplies.Inc(), was matched by its method name alone. fix(go): a call on a package-level variable or constant links through the type it is declared with #2667 reads a package-level variable's declared type, but only for variables that have a node.Change
extractVariablein TS,extract_variablein the kernel), the specs inside avar_spec_listare read like a declaration's own. Each member becomes a variable the file contains, with its initializer walked under it, as a variable declared on its own already is.a, b = 1, 2) still makes a node for the first name only. That limit is shared withconstand ungroupedvarand is not touched here.Verification
__tests__/go-var-groups.test.ts, kernel and wasm, each on LF and CRLF:containsedge, own or group doc, a call in an initializer recorded under its variable, and same-file reads becoming references.torture.goparity fixture gains a var group with a call and a function value in its values;kernel-tsjs-paritypasses 99/99. The Go doc tests from fix(go): a type declared on its own keeps its doc comment #2438, fix(go): a comment a blank line separates from a declaration is not its doc #2678, fix(go): a comment directive like //go:embed is not part of a declaration's doc #2679 and fix(go): a constant in a const ( … ) group keeps its own doc comment #2680 pass.CODEGRAPH_KERNEL_EXPECT=1(--maxWorkers=4 --minWorkers=1): 7,523 passed, 0 failed, 80 skipped (7,603 tests, 0 failed files).A/B on real repos
main 6e68a11 vs this branch. #2681, merged in by the sync, changes only TypeScript-family file discovery. Repos: etcd 6782f522, prometheus 0b57789d, gin 0f09c3a9.
Kernel and wasm indexes are byte-identical on both arms (nodes, edges, unresolved refs, files, docstrings). No node is removed; every new node is a grouped variable.
variablenodes (+containsedges)How each row was checked:
Value references (1,276 / 527 / 55, those from new nodes included): every one is same-file, and the reading function's body names the variable.
Calls landing on variables are calls of a function-valued variable, e.g. grpc-gateway's generated
forward_KV_Range_0(…)(= runtime.ForwardResponseMessage) and etcd tests'clusterTestCases(). Main already links calls to ungrouped function-valued variables the same way (9 in etcd).Resolved for the first time:
linuxTryLockFile(…)andopenWALFilesFn(…)reach the function their variable is set to (= flockTryLockFile,= openWALFiles);Meta.Name()reachesbackend.Bucket.Name;s.Write(…)withvar ( … s mvcc.KV )reachesmvcc.KV.Write;MsgPack.Bind(…)reachesBinding.Bind.Re-resolved, all from wrong to right:
fPointPool.Get()/.Put()(×6): azeropool.New(…)value, fromchunkenc.Pooltozeropool.Pool;testHistogram.Copy()(×2): fromFloatHistogram.CopytoHistogram.Copy.No longer linked, all wrong before (each a call through a grouped variable whose value or type comes from outside the project, which fix(go): a call on a package-level variable or constant links through the type it is declared with #2667 now reads):
.Inc()calls linked to v2store'sStats.Inc; async.Once's.Dolinked to the clientKV.Do; 3 cobra/text/template.Executelinked tomigrationPlan.Execute; aregexp's.Matchlinked toPrefix.Match;regexp.MatchStringlinked toFastRegexMatcher.MatchString; 9 Prometheus counter.Inc()/.Dec()linked tonoopMetric;fgprof.Handler()'s.ServeHTTPlinked toreadHandler.ServeHTTP.The function ref
tt.rangeLimitin an etcd test, a struct field, had been linked to thetxnpackage'srangeLimitfunction by name. A groupedrangeLimitvariable intools/benchmarknow shares that name, so the name-only guess no longer picks one.Edges from the new variables' values follow the resolver's existing rules. Composite literals instantiate their types, and calls reach
boolPtr,getGoGC,MustNewRegexp, theprompbconverters and others. A few inherit existing name guesses, which main already makes for the same calls in ordinary functions of the same files:testParser.ParseExpr(…)goes to a test type'sParseExpr, as main's three uses inrules/recording_test.godo;a.Flag(…).String()goes torwProtoMsgFlagParser.String, as 18 of main's do;txn.End()on akv.Read(…)result goes to lease'sTxnDelete.End, as main's three uses inkv_test.godo.Open PR fix(go): type receivers from package-qualified parameters and call results; no guess for outside types #1954 is on call-result typing, the gap behind these.
Dead code: the report (default kinds, and with exported symbols) is identical. Underneath, 21 / 3 / 11 symbols that had no incoming edge now have one from a grouped variable's value: gin's
bsonBinding,formBinding,headerBindingand the other binding structs,timeCodec; etcd'sNewIntegrationRunner/NewUnitRunner,GlobalFlags; prometheus'sgetGoGC. So impact on them now reaches the variables and their readers. The report's own text check had kept them off it.Kernel parity (
kernel-parity.mjs --lang go): 0 diffs on all three repos. etcd 1065/1105, the same 40 erroring files deferred as on main; prometheus 746/746; gin 99/99.Cost: indexing time unchanged within noise (etcd 10→11 s, prometheus 12→14 s, gin 2→3 s on this box).
🤖 Generated with Claude Code