Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve compilation errors output #1859

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/golinters/makezero.go
Expand Up @@ -56,5 +56,5 @@ func NewMakezero() *goanalysis.Linter {
}
}).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue {
return resIssues
}).WithLoadMode(goanalysis.LoadModeSyntax | goanalysis.LoadModeTypesInfo)
}).WithLoadMode(goanalysis.LoadModeTypesInfo)
}
8 changes: 7 additions & 1 deletion pkg/golinters/typecheck.go
Expand Up @@ -8,19 +8,25 @@ import (

func NewTypecheck() *goanalysis.Linter {
const linterName = "typecheck"

analyzer := &analysis.Analyzer{
Name: linterName,
Doc: goanalysis.TheOnlyanalyzerDoc,
Run: func(pass *analysis.Pass) (interface{}, error) {
return nil, nil
},
}

// Note: typecheck doesn't require the LoadModeWholeProgram
// but it's a hack to force this linter to be the first linter in all the cases.
linter := goanalysis.NewLinter(
linterName,
"Like the front-end of a Go compiler, parses and type-checks Go code",
[]*analysis.Analyzer{analyzer},
nil,
).WithLoadMode(goanalysis.LoadModeTypesInfo)
).WithLoadMode(goanalysis.LoadModeWholeProgram)

linter.SetTypecheckMode()

return linter
}
2 changes: 1 addition & 1 deletion pkg/golinters/unused.go
Expand Up @@ -59,7 +59,7 @@ func NewUnused() *goanalysis.Linter {
nil,
).WithIssuesReporter(func(lintCtx *linter.Context) []goanalysis.Issue {
return resIssues
}).WithLoadMode(goanalysis.LoadModeSyntax | goanalysis.LoadModeTypesInfo)
}).WithLoadMode(goanalysis.LoadModeWholeProgram)

return lnt
}
8 changes: 8 additions & 0 deletions pkg/lint/linter/config.go
Expand Up @@ -20,6 +20,14 @@ const (
PresetUnused = "unused" // Related to the detection of unused code.
)

const (
// typecheck must be first because it checks the compiling errors.
FirstLinter = "typecheck"

// nolintlint must be last because it looks at the results of all the previous linters for unused nolint directives.
LastLinter = "nolintlint"
)

type Deprecation struct {
Since string
Message string
Expand Down
22 changes: 21 additions & 1 deletion pkg/lint/lintersdb/enabled_set.go
Expand Up @@ -111,6 +111,15 @@ func (es EnabledSet) GetOptimizedLinters() ([]*linter.Config, error) {
// Make order of execution of linters (go/analysis metalinter and unused) stable.
sort.Slice(resultLinters, func(i, j int) bool {
a, b := resultLinters[i], resultLinters[j]

if a.Name() == linter.FirstLinter || b.Name() == linter.LastLinter {
return true
}

if a.Name() == linter.LastLinter || b.Name() == linter.FirstLinter {
return false
}

if a.DoesChangeTypes != b.DoesChangeTypes {
return b.DoesChangeTypes // move type-changing linters to the end to optimize speed
}
Expand Down Expand Up @@ -149,8 +158,19 @@ func (es EnabledSet) combineGoAnalysisLinters(linters map[string]*linter.Config)

// Make order of execution of go/analysis analyzers stable.
sort.Slice(goanalysisLinters, func(i, j int) bool {
return strings.Compare(goanalysisLinters[i].Name(), goanalysisLinters[j].Name()) <= 0
a, b := goanalysisLinters[i], goanalysisLinters[j]

if a.Name() == linter.FirstLinter || b.Name() == linter.LastLinter {
return true
}

if a.Name() == linter.LastLinter || b.Name() == linter.FirstLinter {
return false
}

return strings.Compare(a.Name(), b.Name()) <= 0
})

ml := goanalysis.NewMetaLinter(goanalysisLinters)

var presets []string
Expand Down
11 changes: 6 additions & 5 deletions pkg/lint/lintersdb/manager.go
Expand Up @@ -131,6 +131,12 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
const megacheckName = "megacheck"

lcs := []*linter.Config{
linter.NewConfig(golinters.NewTypecheck()).
WithSince("v1.3.0").
WithLoadForGoAnalysis().
WithPresets(linter.PresetBugs).
WithURL(""),

linter.NewConfig(golinters.NewGovet(govetCfg)).
WithSince("v1.0.0").
WithLoadForGoAnalysis().
Expand Down Expand Up @@ -247,11 +253,6 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithSince("v1.20.0").
WithPresets(linter.PresetComplexity).
WithURL("https://github.com/uudashr/gocognit"),
linter.NewConfig(golinters.NewTypecheck()).
WithSince("v1.3.0").
WithLoadForGoAnalysis().
WithPresets(linter.PresetBugs).
WithURL(""),
linter.NewConfig(golinters.NewAsciicheck()).
WithSince("v1.26.0").
WithPresets(linter.PresetBugs, linter.PresetStyle).
Expand Down
6 changes: 5 additions & 1 deletion pkg/lint/runner.go
Expand Up @@ -200,7 +200,7 @@ func (r Runner) Run(ctx context.Context, linters []*linter.Config, lintCtx *lint
sw.TrackStage(lc.Name(), func() {
linterIssues, err := r.runLinterSafe(ctx, lintCtx, lc)
if err != nil {
r.Log.Warnf("Can't run linter %s: %s", lc.Linter.Name(), err)
r.Log.Warnf("Can't run linter %s: %v", lc.Linter.Name(), err)
if os.Getenv("GOLANGCI_COM_RUN") == "" {
// Don't stop all linters on one linter failure for golangci.com.
runErr = err
Expand All @@ -209,6 +209,10 @@ func (r Runner) Run(ctx context.Context, linters []*linter.Config, lintCtx *lint
}
issues = append(issues, linterIssues...)
})

if lc.Name() == linter.FirstLinter && len(issues) > 0 {
return r.processLintResults(issues), nil
}
}

return r.processLintResults(issues), runErr
Expand Down