From 905d338e602d7cb79a803c783081036d80620690 Mon Sep 17 00:00:00 2001 From: "wangzekun.zekin" Date: Tue, 21 Apr 2026 20:13:44 +0800 Subject: [PATCH] fix(golang): continue parsing chained selector method calls Allow selector traversal to keep visiting chained method calls instead of returning early, so downstream calls can still be collected during Go parsing. --- .github/workflows/regression.yml | 5 +++-- lang/golang/parser/file.go | 19 +++---------------- lang/lsp/clients_test.go | 4 +++- testdata/go/0_golang/pkg/entity/entity.go | 8 ++++++++ 4 files changed, 17 insertions(+), 19 deletions(-) diff --git a/.github/workflows/regression.yml b/.github/workflows/regression.yml index 5185e699..f1d40ce2 100644 --- a/.github/workflows/regression.yml +++ b/.github/workflows/regression.yml @@ -82,13 +82,14 @@ jobs: run: | # HACK: auto installation uses the published version, not our local version (cd ./main_repo/ts-parser && npm install && npm run build && npm install -g .) - OUTDIR=out_old ABCEXE=./abcoder_old ./main_repo/script/run_testdata.sh first + OUTDIR=out_old ABCEXE=./abcoder_old ./pr_repo/script/run_testdata.sh first # avoid wasting time install a new jdtls echo "JDTLS_ROOT_PATH=$(realpath ./main_repo/lang/java/lsp/jdtls/jdt-language-server-*)" >> $GITHUB_ENV - name: Run OLD abcoder run: - OUTDIR=out_old ABCEXE=./abcoder_old ./main_repo/script/run_testdata.sh all + # we run the old abcoder on the new data to compare the outputs + OUTDIR=out_old ABCEXE=./abcoder_old ./pr_repo/script/run_testdata.sh all - name: Reset dependencies run: | diff --git a/lang/golang/parser/file.go b/lang/golang/parser/file.go index d4b9e092..4631e4ac 100644 --- a/lang/golang/parser/file.go +++ b/lang/golang/parser/file.go @@ -354,21 +354,6 @@ func (p *GoParser) parseSelector(ctx *fileContext, expr *ast.SelectorExpr, infos } else if sel, ok := expr.X.(*ast.SelectorExpr); ok { // recurse call cont = p.parseSelector(ctx, sel, infos) - } else { - // try to get type info of field first - if ti := ctx.GetTypeInfo(expr); ti.Ty != nil { - if _, ok := ti.Ty.(*types.Signature); ok { - // collect method call - // method call - rev := ctx.GetTypeInfo(expr.X) - if !rev.IsStdOrBuiltin { - id := NewIdentity(rev.Id.ModPath, rev.Id.PkgPath, rev.Id.Name+"."+expr.Sel.Name) - dep := NewDependency(id, ctx.FileLine(expr.Sel)) - infos.methodCalls = InsertDependency(infos.methodCalls, dep) - } - } - } - return true } // method calls @@ -400,7 +385,9 @@ func (p *GoParser) parseSelector(ctx *fileContext, expr *ast.SelectorExpr, infos } infos.methodCalls = InsertDependency(infos.methodCalls, dep) } - return false + + // 此处应该是 true,用于处理 chained method call,让 visit 可以继续处理 + return true } return cont diff --git a/lang/lsp/clients_test.go b/lang/lsp/clients_test.go index eb23b92f..083dcaa5 100644 --- a/lang/lsp/clients_test.go +++ b/lang/lsp/clients_test.go @@ -63,7 +63,9 @@ func TestGolangLSP(t *testing.T) { uri := NewURI(goTestCase + "/pkg/entity/entity.go") // documentSymbol - expectedSymNames := `(MyStruct).String + expectedSymNames := `(*MyStruct).Return0 +(*MyStruct).Return4 +(MyStruct).String (MyStructC).String (MyStructD).DFunction (MyStructD).String diff --git a/testdata/go/0_golang/pkg/entity/entity.go b/testdata/go/0_golang/pkg/entity/entity.go index d17f8197..297c00be 100644 --- a/testdata/go/0_golang/pkg/entity/entity.go +++ b/testdata/go/0_golang/pkg/entity/entity.go @@ -61,3 +61,11 @@ const G1 = 1 type Integer int var V1 = Integer(1) + +func (a *MyStruct) Return0() *MyStruct { + return a +} + +func (a *MyStruct) Return4() string { + return a.Return0().DFunction() +}