From d24c10485aebc9e4c6fa31c2d44551f0d7f34978 Mon Sep 17 00:00:00 2001 From: "wangzekun.zekin" Date: Mon, 1 Jun 2026 11:45:08 +0800 Subject: [PATCH] fix(go): fill File-level metadata for pre-parsed packages When a package was pre-parsed via cross-module referCodes, only Functions were populated but File.Package/Imports were left empty. This broke downstream reachability analysis based on the package import graph. Now we still fill File-level metadata for such packages while skipping duplicate function-body parsing. Co-Authored-By: Claude Opus 4.6 (1M context) --- lang/golang/parser/pkg.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/lang/golang/parser/pkg.go b/lang/golang/parser/pkg.go index 32ae1303..ba9404f9 100644 --- a/lang/golang/parser/pkg.go +++ b/lang/golang/parser/pkg.go @@ -217,11 +217,18 @@ func (p *GoParser) loadPackages(mod *Module, dir string, pkgPath PkgPath) (err e fmt.Fprintf(os.Stderr, "[loadPackages] mod: %s, dir: %s, pkgPath: %s, hasCGO: %v\n", mod.Name, dir, pkgPath, hasCGO) for _, pkg := range pkgs { + // The package may have been pre-parsed by referCodes for cross-module + // references (only Functions populated, no File-level Package/Imports). + // We must not skip entirely: otherwise File.Package and File.Imports + // remain empty, breaking downstream reachability analysis based on + // the package import graph. Instead, still fill File-level metadata + // but skip duplicate function body parsing and package-level finalization. + alreadyParsed := false if mm := p.repo.Modules[mod.Name]; mm != nil && (*mm).Packages[pkg.ID] != nil { - continue + alreadyParsed = true } if pp, ok := mod.Packages[pkg.ID]; ok && pp != nil { - continue + alreadyParsed = true } for idx, file := range pkg.Syntax { var filePath string @@ -278,10 +285,17 @@ func (p *GoParser) loadPackages(mod *Module, dir string, pkgPath PkgPath) (err e f.Package = pkg.ID f.Imports = imports.Origins } + // Skip duplicate function body parsing when package was pre-parsed. + if alreadyParsed { + continue + } if err := p.parseFile(ctx, file); err != nil { return err } } + if alreadyParsed { + continue + } if obj := mod.Packages[pkg.ID]; obj != nil { // obj.Dependencies = make([]PkgPath, 0, len(pkg.Imports)) // for _, imp := range pkg.Imports {