diff --git a/pkg/commands/run.go b/pkg/commands/run.go index 0f1f6551..7e733de8 100644 --- a/pkg/commands/run.go +++ b/pkg/commands/run.go @@ -190,6 +190,30 @@ func discoverGoRoot() (string, error) { return strings.TrimSpace(string(output)), nil } +// separateNotCompilingPackages moves not compiling packages into separate slices: +// a lot of linters crash on such packages. Leave them only for those linters +// which can work with them. +func separateNotCompilingPackages(lintCtx *golinters.Context) { + prog := lintCtx.Program + + compilingCreated := make([]*loader.PackageInfo, 0, len(prog.Created)) + for _, info := range prog.Created { + if len(info.Errors) != 0 { + lintCtx.NotCompilingPackages = append(lintCtx.NotCompilingPackages, info) + } else { + compilingCreated = append(compilingCreated, info) + } + } + prog.Created = compilingCreated + + for k, info := range prog.Imported { + if len(info.Errors) != 0 { + lintCtx.NotCompilingPackages = append(lintCtx.NotCompilingPackages, info) + delete(prog.Imported, k) + } + } +} + func buildLintCtx(ctx context.Context, linters []pkg.Linter, cfg *config.Config) (*golinters.Context, error) { // Set GOROOT to have working cross-compilation: cross-compiled binaries // have invalid GOROOT. XXX: can't use runtime.GOROOT(). @@ -228,14 +252,18 @@ func buildLintCtx(ctx context.Context, linters []pkg.Linter, cfg *config.Config) astCache = astcache.LoadFromFiles(paths.Files) } - return &golinters.Context{ + ret := &golinters.Context{ Paths: paths, Cfg: cfg, Program: prog, SSAProgram: ssaProg, LoaderConfig: loaderConfig, ASTCache: astCache, - }, nil + } + + separateNotCompilingPackages(ret) + + return ret, nil } func (e *Executor) runAnalysis(ctx context.Context, args []string) (<-chan result.Issue, error) { diff --git a/pkg/golinters/context.go b/pkg/golinters/context.go index 749debed..fbe31b7e 100644 --- a/pkg/golinters/context.go +++ b/pkg/golinters/context.go @@ -9,12 +9,13 @@ import ( ) type Context struct { - Paths *fsutils.ProjectPaths - Cfg *config.Config - Program *loader.Program - SSAProgram *ssa.Program - LoaderConfig *loader.Config - ASTCache *astcache.Cache + Paths *fsutils.ProjectPaths + Cfg *config.Config + Program *loader.Program + SSAProgram *ssa.Program + LoaderConfig *loader.Config + ASTCache *astcache.Cache + NotCompilingPackages []*loader.PackageInfo } func (c *Context) Settings() *config.LintersSettings { diff --git a/pkg/golinters/typecheck.go b/pkg/golinters/typecheck.go index 7954004c..b16f1050 100644 --- a/pkg/golinters/typecheck.go +++ b/pkg/golinters/typecheck.go @@ -63,7 +63,7 @@ func (lint TypeCheck) parseError(err error) *result.Issue { func (lint TypeCheck) Run(ctx context.Context, lintCtx *Context) ([]result.Issue, error) { var res []result.Issue - for _, pkg := range lintCtx.Program.InitialPackages() { + for _, pkg := range lintCtx.NotCompilingPackages { for _, err := range pkg.Errors { i := lint.parseError(err) if i != nil {