Skip to content

unused: support passing in options #4086

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

Merged
merged 3 commits into from
Oct 9, 2023
Merged
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
23 changes: 23 additions & 0 deletions .golangci.reference.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2016,6 +2016,29 @@ linters-settings:
# Default: false
check-exported: true

unused:
# Mark all struct fields that have been written to as used.
# Default: true
field-writes-are-uses: false
# Treat IncDec statement (e.g. `i++` or `i--`) as both read and write operation instead of just write.
# Default: false
post-statements-are-reads: true
# Mark all exported identifiers as used.
# Default: true
exported-is-used: false
# Mark all exported fields as used.
# default: true
exported-fields-are-used: false
# Mark all function parameters as used.
# default: true
parameters-are-used: false
# Mark all local variables as used.
# default: true
local-variables-are-used: false
# Mark all identifiers inside generated files as used.
# Default: true
generated-is-used: false

varcheck:
# Check usage of exported fields and variables.
# Default: false
Expand Down
20 changes: 20 additions & 0 deletions pkg/config/linters_settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,15 @@ var defaultLintersSettings = LintersSettings{
Unparam: UnparamSettings{
Algo: "cha",
},
Unused: UnusedSettings{
FieldWritesAreUses: true,
PostStatementsAreReads: false,
ExportedIsUsed: true,
ExportedFieldsAreUsed: true,
ParametersAreUsed: true,
LocalVariablesAreUsed: true,
GeneratedIsUsed: true,
},
UseStdlibVars: UseStdlibVarsSettings{
HTTPMethod: true,
HTTPStatusCode: true,
Expand Down Expand Up @@ -223,6 +232,7 @@ type LintersSettings struct {
Testpackage TestpackageSettings
Thelper ThelperSettings
Unparam UnparamSettings
Unused UnusedSettings
UseStdlibVars UseStdlibVarsSettings
Varcheck VarCheckSettings
Varnamelen VarnamelenSettings
Expand Down Expand Up @@ -794,6 +804,16 @@ type UnparamSettings struct {
Algo string
}

type UnusedSettings struct {
FieldWritesAreUses bool `mapstructure:"field-writes-are-uses"`
PostStatementsAreReads bool `mapstructure:"post-statements-are-reads"`
ExportedIsUsed bool `mapstructure:"exported-is-used"`
ExportedFieldsAreUsed bool `mapstructure:"exported-fields-are-used"`
ParametersAreUsed bool `mapstructure:"parameters-are-used"`
LocalVariablesAreUsed bool `mapstructure:"local-variables-are-used"`
GeneratedIsUsed bool `mapstructure:"generated-is-used"`
}

type VarCheckSettings struct {
CheckExportedFields bool `mapstructure:"exported-fields"`
}
Expand Down
56 changes: 37 additions & 19 deletions pkg/golinters/unused.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import (
"sync"

"golang.org/x/tools/go/analysis"
"honnef.co/go/tools/analysis/facts/directives"
"honnef.co/go/tools/analysis/facts/generated"
"honnef.co/go/tools/analysis/lint"
"honnef.co/go/tools/unused"

"github.com/golangci/golangci-lint/pkg/config"
Expand All @@ -15,11 +18,7 @@ import (

const unusedName = "unused"

type UnusedSettings struct {
GoVersion string
}

func NewUnused(settings *config.StaticCheckSettings) *goanalysis.Linter {
func NewUnused(settings *config.UnusedSettings, scSettings *config.StaticCheckSettings) *goanalysis.Linter {
var mu sync.Mutex
var resIssues []goanalysis.Issue

Expand All @@ -28,11 +27,7 @@ func NewUnused(settings *config.StaticCheckSettings) *goanalysis.Linter {
Doc: unused.Analyzer.Analyzer.Doc,
Requires: unused.Analyzer.Analyzer.Requires,
Run: func(pass *analysis.Pass) (any, error) {
issues, err := runUnused(pass)
if err != nil {
return nil, err
}

issues := runUnused(pass, settings)
if len(issues) == 0 {
return nil, nil
}
Expand All @@ -45,7 +40,7 @@ func NewUnused(settings *config.StaticCheckSettings) *goanalysis.Linter {
},
}

setAnalyzerGoVersion(analyzer, getGoVersion(settings))
setAnalyzerGoVersion(analyzer, getGoVersion(scSettings))

return goanalysis.NewLinter(
unusedName,
Expand All @@ -57,21 +52,18 @@ func NewUnused(settings *config.StaticCheckSettings) *goanalysis.Linter {
}).WithLoadMode(goanalysis.LoadModeTypesInfo)
}

func runUnused(pass *analysis.Pass) ([]goanalysis.Issue, error) {
res, err := unused.Analyzer.Analyzer.Run(pass)
if err != nil {
return nil, err
}
func runUnused(pass *analysis.Pass, cfg *config.UnusedSettings) []goanalysis.Issue {
res := getUnusedResults(pass, cfg)

used := make(map[string]bool)
for _, obj := range res.(unused.Result).Used {
for _, obj := range res.Used {
used[fmt.Sprintf("%s %d %s", obj.Position.Filename, obj.Position.Line, obj.Name)] = true
}

var issues []goanalysis.Issue

// Inspired by https://github.com/dominikh/go-tools/blob/d694aadcb1f50c2d8ac0a1dd06217ebb9f654764/lintcmd/lint.go#L177-L197
for _, object := range res.(unused.Result).Unused {
for _, object := range res.Unused {
if object.Kind == "type param" {
continue
}
Expand All @@ -90,5 +82,31 @@ func runUnused(pass *analysis.Pass) ([]goanalysis.Issue, error) {
issues = append(issues, issue)
}

return issues, nil
return issues
}

func getUnusedResults(pass *analysis.Pass, settings *config.UnusedSettings) unused.Result {
opts := unused.Options{
FieldWritesAreUses: settings.FieldWritesAreUses,
PostStatementsAreReads: settings.PostStatementsAreReads,
ExportedIsUsed: settings.ExportedIsUsed,
ExportedFieldsAreUsed: settings.ExportedFieldsAreUsed,
ParametersAreUsed: settings.ParametersAreUsed,
LocalVariablesAreUsed: settings.LocalVariablesAreUsed,
GeneratedIsUsed: settings.GeneratedIsUsed,
}

// ref: https://github.com/dominikh/go-tools/blob/4ec1f474ca6c0feb8e10a8fcca4ab95f5b5b9881/internal/cmd/unused/unused.go#L68
nodes := unused.Graph(pass.Fset,
pass.Files,
pass.Pkg,
pass.TypesInfo,
pass.ResultOf[directives.Analyzer].([]lint.Directive),
pass.ResultOf[generated.Analyzer].(map[string]generated.Generator),
opts,
)

sg := unused.SerializedGraph{}
sg.Merge(nodes)
return sg.Results()
}
9 changes: 3 additions & 6 deletions pkg/lint/lintersdb/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
testpackageCfg *config.TestpackageSettings
thelperCfg *config.ThelperSettings
unparamCfg *config.UnparamSettings
unusedCfg *config.StaticCheckSettings
unusedCfg *config.UnusedSettings
usestdlibvars *config.UseStdlibVarsSettings
varcheckCfg *config.VarCheckSettings
varnamelenCfg *config.VarnamelenSettings
Expand Down Expand Up @@ -218,7 +218,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
testpackageCfg = &m.cfg.LintersSettings.Testpackage
thelperCfg = &m.cfg.LintersSettings.Thelper
unparamCfg = &m.cfg.LintersSettings.Unparam
unusedCfg = new(config.StaticCheckSettings)
unusedCfg = &m.cfg.LintersSettings.Unused
usestdlibvars = &m.cfg.LintersSettings.UseStdlibVars
varcheckCfg = &m.cfg.LintersSettings.Varcheck
varnamelenCfg = &m.cfg.LintersSettings.Varnamelen
Expand Down Expand Up @@ -247,9 +247,6 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
if stylecheckCfg != nil && stylecheckCfg.GoVersion != "" {
stylecheckCfg.GoVersion = trimGoVersion(m.cfg.Run.Go)
}
if unusedCfg != nil && unusedCfg.GoVersion == "" {
unusedCfg.GoVersion = trimGoVersion(m.cfg.Run.Go)
}
}

const megacheckName = "megacheck"
Expand Down Expand Up @@ -833,7 +830,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
WithLoadForGoAnalysis().
WithURL("https://github.com/mvdan/unparam"),

linter.NewConfig(golinters.NewUnused(unusedCfg)).
linter.NewConfig(golinters.NewUnused(unusedCfg, staticcheckCfg)).
WithEnabledByDefault().
WithSince("v1.20.0").
WithLoadForGoAnalysis().
Expand Down