From 5f37d325ff648e4517e71462d1a76ceff6e8f91a Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Wed, 14 Aug 2024 14:26:26 +0200 Subject: [PATCH 1/4] staticcheck: propagate Go version --- pkg/goanalysis/runner.go | 10 +++++++--- pkg/goanalysis/runner_loadingpackage.go | 2 ++ pkg/goanalysis/runners.go | 7 ++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/pkg/goanalysis/runner.go b/pkg/goanalysis/runner.go index c1274ec09a7c..1f5931992625 100644 --- a/pkg/goanalysis/runner.go +++ b/pkg/goanalysis/runner.go @@ -15,6 +15,7 @@ import ( "go/token" "runtime" "sort" + "strings" "sync" "golang.org/x/exp/maps" @@ -58,11 +59,12 @@ type runner struct { passToPkg map[*analysis.Pass]*packages.Package passToPkgGuard sync.Mutex sw *timeutils.Stopwatch + goVersion string // TODO(ldez) temporary workaround } -func newRunner(prefix string, logger logutils.Log, pkgCache *pkgcache.Cache, loadGuard *load.Guard, - loadMode LoadMode, sw *timeutils.Stopwatch, -) *runner { +func newRunner(prefix string, logger logutils.Log, + pkgCache *pkgcache.Cache, loadGuard *load.Guard, loadMode LoadMode, + sw *timeutils.Stopwatch, goVersion string) *runner { return &runner{ prefix: prefix, log: logger, @@ -71,6 +73,7 @@ func newRunner(prefix string, logger logutils.Log, pkgCache *pkgcache.Cache, loa loadMode: loadMode, passToPkg: map[*analysis.Pass]*packages.Package{}, sw: sw, + goVersion: goVersion, } } @@ -247,6 +250,7 @@ func (r *runner) analyze(pkgs []*packages.Package, analyzers []*analysis.Analyze loadingPackages[pkg] = &loadingPackage{ pkg: pkg, + goVersion: "go" + strings.TrimPrefix(r.goVersion, "go"), imports: imports, isInitial: initialPkgs[pkg], log: r.log, diff --git a/pkg/goanalysis/runner_loadingpackage.go b/pkg/goanalysis/runner_loadingpackage.go index c54357eb6794..cabd83c03b5b 100644 --- a/pkg/goanalysis/runner_loadingpackage.go +++ b/pkg/goanalysis/runner_loadingpackage.go @@ -23,6 +23,7 @@ const unsafePkgName = "unsafe" type loadingPackage struct { pkg *packages.Package + goVersion string // TODO(ldez) temporary workaround imports map[string]*loadingPackage isInitial bool log logutils.Log @@ -155,6 +156,7 @@ func (lp *loadingPackage) loadFromSource(loadMode LoadMode) error { Error: func(err error) { pkg.Errors = append(pkg.Errors, lp.convertError(err)...) }, + GoVersion: lp.goVersion, // TODO(ldez) temporary workaround } _ = types.NewChecker(tc, pkg.Fset, pkg.Types, pkg.TypesInfo).Files(pkg.Syntax) // Don't handle error here: errors are adding by tc.Error function. diff --git a/pkg/goanalysis/runners.go b/pkg/goanalysis/runners.go index c02d33b79757..6f2c9dac28fc 100644 --- a/pkg/goanalysis/runners.go +++ b/pkg/goanalysis/runners.go @@ -36,7 +36,12 @@ func runAnalyzers(cfg runAnalyzersConfig, lintCtx *linter.Context) ([]result.Iss const stagesToPrint = 10 defer sw.PrintTopStages(stagesToPrint) - runner := newRunner(cfg.getName(), log, lintCtx.PkgCache, lintCtx.LoadGuard, cfg.getLoadMode(), sw) + var goVersion string + if lintCtx.Cfg != nil { + goVersion = lintCtx.Cfg.Run.Go + } + + runner := newRunner(cfg.getName(), log, lintCtx.PkgCache, lintCtx.LoadGuard, cfg.getLoadMode(), sw, goVersion) pkgs := lintCtx.Packages if cfg.useOriginalPackages() { From 10d0ae289d49b6b50b32de872a69bcabc87980f4 Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Wed, 14 Aug 2024 14:37:19 +0200 Subject: [PATCH 2/4] chore: remove dead code --- pkg/golinters/gosimple/gosimple.go | 2 +- pkg/golinters/internal/staticcheck_common.go | 16 +--------------- pkg/golinters/staticcheck/staticcheck.go | 2 +- pkg/golinters/stylecheck/stylecheck.go | 2 +- pkg/golinters/unused/unused.go | 5 +---- pkg/lint/lintersdb/builder_linter.go | 2 +- 6 files changed, 6 insertions(+), 23 deletions(-) diff --git a/pkg/golinters/gosimple/gosimple.go b/pkg/golinters/gosimple/gosimple.go index 6a0d967232ab..c03871adf9b5 100644 --- a/pkg/golinters/gosimple/gosimple.go +++ b/pkg/golinters/gosimple/gosimple.go @@ -11,7 +11,7 @@ import ( func New(settings *config.StaticCheckSettings) *goanalysis.Linter { cfg := internal.StaticCheckConfig(settings) - analyzers := internal.SetupStaticCheckAnalyzers(simple.Analyzers, internal.GetGoVersion(settings), cfg.Checks) + analyzers := internal.SetupStaticCheckAnalyzers(simple.Analyzers, cfg.Checks) return goanalysis.NewLinter( "gosimple", diff --git a/pkg/golinters/internal/staticcheck_common.go b/pkg/golinters/internal/staticcheck_common.go index 5b5812c318a2..958013d0df2c 100644 --- a/pkg/golinters/internal/staticcheck_common.go +++ b/pkg/golinters/internal/staticcheck_common.go @@ -14,20 +14,7 @@ import ( var debugf = logutils.Debug(logutils.DebugKeyMegacheck) -func GetGoVersion(settings *config.StaticCheckSettings) string { - var goVersion string - if settings != nil { - goVersion = settings.GoVersion - } - - if goVersion != "" { - return goVersion - } - - return "1.17" -} - -func SetupStaticCheckAnalyzers(src []*lint.Analyzer, goVersion string, checks []string) []*analysis.Analyzer { +func SetupStaticCheckAnalyzers(src []*lint.Analyzer, checks []string) []*analysis.Analyzer { var names []string for _, a := range src { names = append(names, a.Analyzer.Name) @@ -38,7 +25,6 @@ func SetupStaticCheckAnalyzers(src []*lint.Analyzer, goVersion string, checks [] var ret []*analysis.Analyzer for _, a := range src { if filter[a.Analyzer.Name] { - SetAnalyzerGoVersion(a.Analyzer, goVersion) ret = append(ret, a.Analyzer) } } diff --git a/pkg/golinters/staticcheck/staticcheck.go b/pkg/golinters/staticcheck/staticcheck.go index 0c0534539ea5..79394bdb7f8a 100644 --- a/pkg/golinters/staticcheck/staticcheck.go +++ b/pkg/golinters/staticcheck/staticcheck.go @@ -10,7 +10,7 @@ import ( func New(settings *config.StaticCheckSettings) *goanalysis.Linter { cfg := internal.StaticCheckConfig(settings) - analyzers := internal.SetupStaticCheckAnalyzers(staticcheck.Analyzers, internal.GetGoVersion(settings), cfg.Checks) + analyzers := internal.SetupStaticCheckAnalyzers(staticcheck.Analyzers, cfg.Checks) return goanalysis.NewLinter( "staticcheck", diff --git a/pkg/golinters/stylecheck/stylecheck.go b/pkg/golinters/stylecheck/stylecheck.go index b8fc8fe547d1..60859f28afc3 100644 --- a/pkg/golinters/stylecheck/stylecheck.go +++ b/pkg/golinters/stylecheck/stylecheck.go @@ -20,7 +20,7 @@ func New(settings *config.StaticCheckSettings) *goanalysis.Linter { return cfg, nil } - analyzers := internal.SetupStaticCheckAnalyzers(stylecheck.Analyzers, internal.GetGoVersion(settings), cfg.Checks) + analyzers := internal.SetupStaticCheckAnalyzers(stylecheck.Analyzers, cfg.Checks) return goanalysis.NewLinter( "stylecheck", diff --git a/pkg/golinters/unused/unused.go b/pkg/golinters/unused/unused.go index 19cf7476fc03..7b2b478fc943 100644 --- a/pkg/golinters/unused/unused.go +++ b/pkg/golinters/unused/unused.go @@ -12,14 +12,13 @@ import ( "github.com/golangci/golangci-lint/pkg/config" "github.com/golangci/golangci-lint/pkg/goanalysis" - "github.com/golangci/golangci-lint/pkg/golinters/internal" "github.com/golangci/golangci-lint/pkg/lint/linter" "github.com/golangci/golangci-lint/pkg/result" ) const linterName = "unused" -func New(settings *config.UnusedSettings, scSettings *config.StaticCheckSettings) *goanalysis.Linter { +func New(settings *config.UnusedSettings) *goanalysis.Linter { var mu sync.Mutex var resIssues []goanalysis.Issue @@ -41,8 +40,6 @@ func New(settings *config.UnusedSettings, scSettings *config.StaticCheckSettings }, } - internal.SetAnalyzerGoVersion(analyzer, internal.GetGoVersion(scSettings)) - return goanalysis.NewLinter( linterName, "Checks Go code for unused constants, variables, functions and types", diff --git a/pkg/lint/lintersdb/builder_linter.go b/pkg/lint/lintersdb/builder_linter.go index 7b83a81530a7..3a46cbf88e5e 100644 --- a/pkg/lint/lintersdb/builder_linter.go +++ b/pkg/lint/lintersdb/builder_linter.go @@ -774,7 +774,7 @@ func (LinterBuilder) Build(cfg *config.Config) ([]*linter.Config, error) { WithLoadForGoAnalysis(). WithURL("https://github.com/mvdan/unparam"), - linter.NewConfig(unused.New(&cfg.LintersSettings.Unused, &cfg.LintersSettings.Staticcheck)). + linter.NewConfig(unused.New(&cfg.LintersSettings.Unused)). WithEnabledByDefault(). WithSince("v1.20.0"). WithLoadForGoAnalysis(). From 1ba44a047fee8ca249b7e1a658d24addf782319d Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Wed, 14 Aug 2024 14:41:47 +0200 Subject: [PATCH 3/4] chore: fix tests --- pkg/golinters/spancheck/testdata/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/golinters/spancheck/testdata/go.mod b/pkg/golinters/spancheck/testdata/go.mod index de347098a901..f35f25df4589 100644 --- a/pkg/golinters/spancheck/testdata/go.mod +++ b/pkg/golinters/spancheck/testdata/go.mod @@ -1,6 +1,6 @@ module spancheck -go 1.20 +go 1.21 require ( go.opentelemetry.io/otel v1.21.0 From 28fc300f4b2c3e3f7bbe7599b17875369d3dcefe Mon Sep 17 00:00:00 2001 From: Fernandez Ludovic Date: Wed, 14 Aug 2024 18:12:11 +0200 Subject: [PATCH 4/4] fix: workaround to avoid high memory consumption --- pkg/goanalysis/runner.go | 10 +++------- pkg/goanalysis/runner_loadingpackage.go | 21 +++++++++++++++++++-- pkg/goanalysis/runners.go | 7 +------ 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/pkg/goanalysis/runner.go b/pkg/goanalysis/runner.go index 1f5931992625..c1274ec09a7c 100644 --- a/pkg/goanalysis/runner.go +++ b/pkg/goanalysis/runner.go @@ -15,7 +15,6 @@ import ( "go/token" "runtime" "sort" - "strings" "sync" "golang.org/x/exp/maps" @@ -59,12 +58,11 @@ type runner struct { passToPkg map[*analysis.Pass]*packages.Package passToPkgGuard sync.Mutex sw *timeutils.Stopwatch - goVersion string // TODO(ldez) temporary workaround } -func newRunner(prefix string, logger logutils.Log, - pkgCache *pkgcache.Cache, loadGuard *load.Guard, loadMode LoadMode, - sw *timeutils.Stopwatch, goVersion string) *runner { +func newRunner(prefix string, logger logutils.Log, pkgCache *pkgcache.Cache, loadGuard *load.Guard, + loadMode LoadMode, sw *timeutils.Stopwatch, +) *runner { return &runner{ prefix: prefix, log: logger, @@ -73,7 +71,6 @@ func newRunner(prefix string, logger logutils.Log, loadMode: loadMode, passToPkg: map[*analysis.Pass]*packages.Package{}, sw: sw, - goVersion: goVersion, } } @@ -250,7 +247,6 @@ func (r *runner) analyze(pkgs []*packages.Package, analyzers []*analysis.Analyze loadingPackages[pkg] = &loadingPackage{ pkg: pkg, - goVersion: "go" + strings.TrimPrefix(r.goVersion, "go"), imports: imports, isInitial: initialPkgs[pkg], log: r.log, diff --git a/pkg/goanalysis/runner_loadingpackage.go b/pkg/goanalysis/runner_loadingpackage.go index cabd83c03b5b..ad546fcc756f 100644 --- a/pkg/goanalysis/runner_loadingpackage.go +++ b/pkg/goanalysis/runner_loadingpackage.go @@ -9,6 +9,8 @@ import ( "go/types" "os" "reflect" + "runtime" + "strings" "sync" "sync/atomic" @@ -23,7 +25,6 @@ const unsafePkgName = "unsafe" type loadingPackage struct { pkg *packages.Package - goVersion string // TODO(ldez) temporary workaround imports map[string]*loadingPackage isInitial bool log logutils.Log @@ -151,13 +152,15 @@ func (lp *loadingPackage) loadFromSource(loadMode LoadMode) error { } return imp.Types, nil } + tc := &types.Config{ Importer: importerFunc(importer), Error: func(err error) { pkg.Errors = append(pkg.Errors, lp.convertError(err)...) }, - GoVersion: lp.goVersion, // TODO(ldez) temporary workaround + GoVersion: getGoVersion(), } + _ = types.NewChecker(tc, pkg.Fset, pkg.Types, pkg.TypesInfo).Files(pkg.Syntax) // Don't handle error here: errors are adding by tc.Error function. @@ -499,3 +502,17 @@ func sizeOfReflectValueTreeBytes(rv reflect.Value, visitedPtrs map[uintptr]struc panic("unknown rv of type " + rv.String()) } } + +// TODO(ldez) temporary workaround +func getGoVersion() string { + goVersion := runtime.Version() + + parts := strings.Fields(goVersion) + + if len(parts) == 0 { + return goVersion + } + + // When using GOEXPERIMENT, the version returned might look something like "go1.23.0 X:boringcrypto". + return parts[0] +} diff --git a/pkg/goanalysis/runners.go b/pkg/goanalysis/runners.go index 6f2c9dac28fc..c02d33b79757 100644 --- a/pkg/goanalysis/runners.go +++ b/pkg/goanalysis/runners.go @@ -36,12 +36,7 @@ func runAnalyzers(cfg runAnalyzersConfig, lintCtx *linter.Context) ([]result.Iss const stagesToPrint = 10 defer sw.PrintTopStages(stagesToPrint) - var goVersion string - if lintCtx.Cfg != nil { - goVersion = lintCtx.Cfg.Run.Go - } - - runner := newRunner(cfg.getName(), log, lintCtx.PkgCache, lintCtx.LoadGuard, cfg.getLoadMode(), sw, goVersion) + runner := newRunner(cfg.getName(), log, lintCtx.PkgCache, lintCtx.LoadGuard, cfg.getLoadMode(), sw) pkgs := lintCtx.Packages if cfg.useOriginalPackages() {