mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-29 14:49:36 +08:00
fix(go): a local's scope ends at its case clause, and a func-typed result's parameters are not locals (#2597)
Main's gate for a Go call to a local func value or parameter that shadows a package function (PR 2658) reads scopes through the Go scope reader, and two of its readings were too wide. A name declared in one case of a switch or select stayed in scope in the clauses after it, and the parameter names inside a func-typed result, like func() func(run string), *func(...) or chan<- func(...), were read as the function's own. Either made a later call to the package function look shadowed and drop its link. The PR's own earlier shadowing check is left out: the gate already covers every case its tests pin. Go A/B on gin, cobra, etcd, prometheus and hugo is byte-identical. Fixes issue 2580. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
23ff26be68
commit
e3f23cc4bc
@@ -2743,9 +2743,10 @@ function readGoScopes(code: string): GoScopeIndex {
|
||||
}
|
||||
}
|
||||
// Each `func`'s receiver, parameters and results, bound in its body. A
|
||||
// `[]func(…)` or `chan func(…)` is a type, whatever brace follows it.
|
||||
// `[]func(…)` or `chan func(…)` is a type, whatever brace follows it, and
|
||||
// so is a `func(…)` result type after a signature's `)` (#2580).
|
||||
for (const m of code.matchAll(/(?<![\w.])func\b/g)) {
|
||||
if (/(?:\]|\bchan)[ \t]*$/.test(code.slice(Math.max(0, m.index! - 8), m.index!))) continue;
|
||||
if (/(?:[\]*)]|\bchan(?:[ \t]*<-)?)[ \t]*$/.test(code.slice(Math.max(0, m.index! - 8), m.index!))) continue;
|
||||
const sig = goSignature(code, m.index! + 4);
|
||||
if (!sig) continue;
|
||||
for (const [from, to] of sig.groups) {
|
||||
@@ -2928,7 +2929,8 @@ function goScopesOf(index: GoScopeIndex, name: string): Array<[number, number, G
|
||||
}
|
||||
const from = goStatementEnd(index.code, d.at);
|
||||
let to = block[1];
|
||||
if (d.kind === 'case') {
|
||||
// A `case` clause's names, header or body, end at the next clause.
|
||||
{
|
||||
const clause = /\n[ \t]*(?:case\b|default[ \t]*:)/g;
|
||||
clause.lastIndex = from;
|
||||
for (let m = clause.exec(index.code); m && m.index < to; m = clause.exec(index.code)) {
|
||||
|
||||
Reference in New Issue
Block a user