Skip to content

Improve compilation errors output #1859

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

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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/golinters/makezero.go
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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