feat: add exhaustruct
linter (#2667)
Co-authored-by: Fernandez Ludovic <ldez@users.noreply.github.com>
This commit is contained in:
parent
acceecf661
commit
380699a099
@ -285,6 +285,16 @@ linters-settings:
|
|||||||
- '*.Test'
|
- '*.Test'
|
||||||
- 'example.com/package.ExampleStruct'
|
- 'example.com/package.ExampleStruct'
|
||||||
|
|
||||||
|
exhaustruct:
|
||||||
|
# List of regular expressions to match struct packages and names.
|
||||||
|
# If this list is empty, all structs are tested.
|
||||||
|
include:
|
||||||
|
- '.*\.Test'
|
||||||
|
- 'example\.com/package\.ExampleStruct[\d]{1,2}'
|
||||||
|
# List of regular expressions to exclude struct packages and names from check.
|
||||||
|
exclude:
|
||||||
|
- 'cobra\.Command$'
|
||||||
|
|
||||||
forbidigo:
|
forbidigo:
|
||||||
# Forbid the following identifiers (list of regexp).
|
# Forbid the following identifiers (list of regexp).
|
||||||
forbid:
|
forbid:
|
||||||
|
1
go.mod
1
go.mod
@ -8,6 +8,7 @@ require (
|
|||||||
github.com/Antonboom/nilnil v0.1.1
|
github.com/Antonboom/nilnil v0.1.1
|
||||||
github.com/BurntSushi/toml v1.1.0
|
github.com/BurntSushi/toml v1.1.0
|
||||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24
|
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24
|
||||||
|
github.com/GaijinEntertainment/go-exhaustruct/v2 v2.1.0
|
||||||
github.com/OpenPeeDeeP/depguard v1.1.0
|
github.com/OpenPeeDeeP/depguard v1.1.0
|
||||||
github.com/alexkohler/prealloc v1.0.0
|
github.com/alexkohler/prealloc v1.0.0
|
||||||
github.com/ashanbrown/forbidigo v1.3.0
|
github.com/ashanbrown/forbidigo v1.3.0
|
||||||
|
2
go.sum
generated
2
go.sum
generated
@ -62,6 +62,8 @@ github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbi
|
|||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM=
|
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM=
|
||||||
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
|
github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs=
|
||||||
|
github.com/GaijinEntertainment/go-exhaustruct/v2 v2.1.0 h1:LAPPhJ4KR5Z8aKVZF5S48csJkxL5RMKmE/98fMs1u5M=
|
||||||
|
github.com/GaijinEntertainment/go-exhaustruct/v2 v2.1.0/go.mod h1:LGOGuvEgCfCQsy3JF2tRmpGDpzA53iZfyGEWSPwQ6/4=
|
||||||
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||||
|
@ -123,6 +123,7 @@ type LintersSettings struct {
|
|||||||
ErrorLint ErrorLintSettings
|
ErrorLint ErrorLintSettings
|
||||||
Exhaustive ExhaustiveSettings
|
Exhaustive ExhaustiveSettings
|
||||||
ExhaustiveStruct ExhaustiveStructSettings
|
ExhaustiveStruct ExhaustiveStructSettings
|
||||||
|
Exhaustruct ExhaustructSettings
|
||||||
Forbidigo ForbidigoSettings
|
Forbidigo ForbidigoSettings
|
||||||
Funlen FunlenSettings
|
Funlen FunlenSettings
|
||||||
Gci GciSettings
|
Gci GciSettings
|
||||||
@ -255,6 +256,11 @@ type ExhaustiveStructSettings struct {
|
|||||||
StructPatterns []string `mapstructure:"struct-patterns"`
|
StructPatterns []string `mapstructure:"struct-patterns"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ExhaustructSettings struct {
|
||||||
|
Include []string `mapstructure:"include"`
|
||||||
|
Exclude []string `mapstructure:"exclude"`
|
||||||
|
}
|
||||||
|
|
||||||
type ForbidigoSettings struct {
|
type ForbidigoSettings struct {
|
||||||
Forbid []string `mapstructure:"forbid"`
|
Forbid []string `mapstructure:"forbid"`
|
||||||
ExcludeGodocExamples bool `mapstructure:"exclude-godoc-examples"`
|
ExcludeGodocExamples bool `mapstructure:"exclude-godoc-examples"`
|
||||||
|
6
pkg/golinters/commons.go
Normal file
6
pkg/golinters/commons.go
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package golinters
|
||||||
|
|
||||||
|
import "github.com/golangci/golangci-lint/pkg/logutils"
|
||||||
|
|
||||||
|
// linterLogger must be use only when the context logger is not available.
|
||||||
|
var linterLogger = logutils.NewStderrLog("linter")
|
26
pkg/golinters/exhaustruct.go
Normal file
26
pkg/golinters/exhaustruct.go
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
package golinters
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/GaijinEntertainment/go-exhaustruct/v2/pkg/analyzer"
|
||||||
|
"golang.org/x/tools/go/analysis"
|
||||||
|
|
||||||
|
"github.com/golangci/golangci-lint/pkg/config"
|
||||||
|
"github.com/golangci/golangci-lint/pkg/golinters/goanalysis"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewExhaustruct(settings *config.ExhaustructSettings) *goanalysis.Linter {
|
||||||
|
var include, exclude []string
|
||||||
|
|
||||||
|
if settings != nil {
|
||||||
|
include = settings.Include
|
||||||
|
exclude = settings.Exclude
|
||||||
|
}
|
||||||
|
|
||||||
|
a, err := analyzer.NewAnalyzer(include, exclude)
|
||||||
|
if err != nil {
|
||||||
|
linterLogger.Fatalf("exhaustruct configuration: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return goanalysis.NewLinter(a.Name, a.Doc, []*analysis.Analyzer{a}, nil).
|
||||||
|
WithLoadMode(goanalysis.LoadModeTypesInfo)
|
||||||
|
}
|
@ -107,6 +107,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
|||||||
var errorlintCfg *config.ErrorLintSettings
|
var errorlintCfg *config.ErrorLintSettings
|
||||||
var exhaustiveCfg *config.ExhaustiveSettings
|
var exhaustiveCfg *config.ExhaustiveSettings
|
||||||
var exhaustiveStructCfg *config.ExhaustiveStructSettings
|
var exhaustiveStructCfg *config.ExhaustiveStructSettings
|
||||||
|
var exhaustructCfg *config.ExhaustructSettings
|
||||||
var gciCfg *config.GciSettings
|
var gciCfg *config.GciSettings
|
||||||
var goModDirectivesCfg *config.GoModDirectivesSettings
|
var goModDirectivesCfg *config.GoModDirectivesSettings
|
||||||
var goMndCfg *config.GoMndSettings
|
var goMndCfg *config.GoMndSettings
|
||||||
@ -140,6 +141,7 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
|||||||
errorlintCfg = &m.cfg.LintersSettings.ErrorLint
|
errorlintCfg = &m.cfg.LintersSettings.ErrorLint
|
||||||
exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
|
exhaustiveCfg = &m.cfg.LintersSettings.Exhaustive
|
||||||
exhaustiveStructCfg = &m.cfg.LintersSettings.ExhaustiveStruct
|
exhaustiveStructCfg = &m.cfg.LintersSettings.ExhaustiveStruct
|
||||||
|
exhaustructCfg = &m.cfg.LintersSettings.Exhaustruct
|
||||||
gciCfg = &m.cfg.LintersSettings.Gci
|
gciCfg = &m.cfg.LintersSettings.Gci
|
||||||
goModDirectivesCfg = &m.cfg.LintersSettings.GoModDirectives
|
goModDirectivesCfg = &m.cfg.LintersSettings.GoModDirectives
|
||||||
goMndCfg = &m.cfg.LintersSettings.Gomnd
|
goMndCfg = &m.cfg.LintersSettings.Gomnd
|
||||||
@ -281,7 +283,14 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
|
|||||||
WithSince("v1.32.0").
|
WithSince("v1.32.0").
|
||||||
WithPresets(linter.PresetStyle, linter.PresetTest).
|
WithPresets(linter.PresetStyle, linter.PresetTest).
|
||||||
WithLoadForGoAnalysis().
|
WithLoadForGoAnalysis().
|
||||||
WithURL("https://github.com/mbilski/exhaustivestruct"),
|
WithURL("https://github.com/mbilski/exhaustivestruct").
|
||||||
|
Deprecated("The owner seems to have abandoned the linter.", "v1.46.0", "exhaustruct"),
|
||||||
|
|
||||||
|
linter.NewConfig(golinters.NewExhaustruct(exhaustructCfg)).
|
||||||
|
WithSince("v1.46.0").
|
||||||
|
WithPresets(linter.PresetStyle, linter.PresetTest).
|
||||||
|
WithLoadForGoAnalysis().
|
||||||
|
WithURL("https://github.com/GaijinEntertainment/go-exhaustruct"),
|
||||||
|
|
||||||
linter.NewConfig(golinters.NewExportLoopRef()).
|
linter.NewConfig(golinters.NewExportLoopRef()).
|
||||||
WithSince("v1.28.0").
|
WithSince("v1.28.0").
|
||||||
|
5
test/testdata/configs/exhaustivestruct.yml
vendored
Normal file
5
test/testdata/configs/exhaustivestruct.yml
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
linters-settings:
|
||||||
|
exhaustivestruct:
|
||||||
|
struct-patterns:
|
||||||
|
- '*.ExhaustiveStructCustom'
|
||||||
|
- '*.ExhaustiveStructCustom2'
|
6
test/testdata/configs/exhaustruct.yml
vendored
Normal file
6
test/testdata/configs/exhaustruct.yml
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
linters-settings:
|
||||||
|
exhaustruct:
|
||||||
|
include:
|
||||||
|
- .*\.ExhaustructCustom
|
||||||
|
exclude:
|
||||||
|
- .*\.ExhaustructCustom[\d]{1,2}
|
56
test/testdata/exhaustivestruct.go
vendored
56
test/testdata/exhaustivestruct.go
vendored
@ -1,9 +1,9 @@
|
|||||||
//args: -Eexhaustivestruct
|
// args: -Eexhaustivestruct --internal-cmd-test
|
||||||
package testdata
|
package testdata
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type Test struct {
|
type ExhaustiveStruct struct {
|
||||||
A string
|
A string
|
||||||
B int
|
B int
|
||||||
c bool // private field inside the same package are not ignored
|
c bool // private field inside the same package are not ignored
|
||||||
@ -11,30 +11,36 @@ type Test struct {
|
|||||||
E time.Time
|
E time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
var pass = Test{
|
func exhaustiveStruct() {
|
||||||
A: "a",
|
// pass
|
||||||
B: 0,
|
_ = ExhaustiveStruct{
|
||||||
c: false,
|
A: "a",
|
||||||
D: 1.0,
|
B: 0,
|
||||||
E: time.Now(),
|
c: false,
|
||||||
}
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
var failPrivate = Test{ // ERROR "c is missing in Test"
|
// failPrivate
|
||||||
A: "a",
|
_ = ExhaustiveStruct{ // ERROR "c is missing in ExhaustiveStruct"
|
||||||
B: 0,
|
A: "a",
|
||||||
D: 1.0,
|
B: 0,
|
||||||
E: time.Now(),
|
D: 1.0,
|
||||||
}
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
var fail = Test{ // ERROR "B is missing in Test"
|
// fail
|
||||||
A: "a",
|
_ = ExhaustiveStruct{ // ERROR "B is missing in ExhaustiveStruct"
|
||||||
c: false,
|
A: "a",
|
||||||
D: 1.0,
|
c: false,
|
||||||
E: time.Now(),
|
D: 1.0,
|
||||||
}
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
var failMultiple = Test{ // ERROR "B, D are missing in Test"
|
// failMultiple
|
||||||
A: "a",
|
_ = ExhaustiveStruct{ // ERROR "B, D are missing in ExhaustiveStruct"
|
||||||
c: false,
|
A: "a",
|
||||||
E: time.Now(),
|
c: false,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
176
test/testdata/exhaustivestruct_custom.go
vendored
176
test/testdata/exhaustivestruct_custom.go
vendored
@ -1,10 +1,10 @@
|
|||||||
//args: -Eexhaustivestruct
|
// args: -Eexhaustivestruct --internal-cmd-test
|
||||||
//config: linters-settings.exhaustivestruct.struct-patterns=*.Test1,*.Test3
|
// config_path: testdata/configs/exhaustivestruct.yml
|
||||||
package testdata
|
package testdata
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type Test1 struct {
|
type ExhaustiveStructCustom struct {
|
||||||
A string
|
A string
|
||||||
B int
|
B int
|
||||||
c bool // private field inside the same package are not ignored
|
c bool // private field inside the same package are not ignored
|
||||||
@ -12,35 +12,42 @@ type Test1 struct {
|
|||||||
E time.Time
|
E time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
var passTest1 = Test1{
|
func exhaustiveStructCustom() {
|
||||||
A: "a",
|
// pass
|
||||||
B: 0,
|
_ = ExhaustiveStructCustom{
|
||||||
c: false,
|
A: "a",
|
||||||
D: 1.0,
|
B: 0,
|
||||||
E: time.Now(),
|
c: false,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// fail
|
||||||
|
_ = ExhaustiveStructCustom{ // ERROR "B is missing in ExhaustiveStructCustom"
|
||||||
|
A: "a",
|
||||||
|
c: false,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// failMultiple
|
||||||
|
_ = ExhaustiveStructCustom{ // ERROR "B, D are missing in ExhaustiveStructCustom"
|
||||||
|
A: "a",
|
||||||
|
c: false,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// failPrivate
|
||||||
|
_ = ExhaustiveStructCustom{ // ERROR "c is missing in ExhaustiveStructCustom"
|
||||||
|
A: "a",
|
||||||
|
B: 0,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var failTest1 = Test1{ // ERROR "B is missing in Test"
|
type ExhaustiveStructCustom1 struct {
|
||||||
A: "a",
|
|
||||||
c: false,
|
|
||||||
D: 1.0,
|
|
||||||
E: time.Now(),
|
|
||||||
}
|
|
||||||
|
|
||||||
var failMultipleTest1 = Test1{ // ERROR "B, D are missing in Test"
|
|
||||||
A: "a",
|
|
||||||
c: false,
|
|
||||||
E: time.Now(),
|
|
||||||
}
|
|
||||||
|
|
||||||
var failPrivateTest1 = Test1{ // ERROR "c is missing in Test"
|
|
||||||
A: "a",
|
|
||||||
B: 0,
|
|
||||||
D: 1.0,
|
|
||||||
E: time.Now(),
|
|
||||||
}
|
|
||||||
|
|
||||||
type Test2 struct {
|
|
||||||
A string
|
A string
|
||||||
B int
|
B int
|
||||||
c bool // private field inside the same package are not ignored
|
c bool // private field inside the same package are not ignored
|
||||||
@ -48,35 +55,37 @@ type Test2 struct {
|
|||||||
E time.Time
|
E time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
var passTest2 = Test1{
|
func exhaustiveStructCustom1() {
|
||||||
A: "a",
|
_ = ExhaustiveStructCustom1{
|
||||||
B: 0,
|
A: "a",
|
||||||
c: false,
|
B: 0,
|
||||||
D: 1.0,
|
c: false,
|
||||||
E: time.Now(),
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = ExhaustiveStructCustom1{
|
||||||
|
A: "a",
|
||||||
|
c: false,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = ExhaustiveStructCustom1{
|
||||||
|
A: "a",
|
||||||
|
c: false,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = ExhaustiveStructCustom1{
|
||||||
|
A: "a",
|
||||||
|
B: 0,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var failTest2 = Test2{
|
type ExhaustiveStructCustom2 struct {
|
||||||
A: "a",
|
|
||||||
c: false,
|
|
||||||
D: 1.0,
|
|
||||||
E: time.Now(),
|
|
||||||
}
|
|
||||||
|
|
||||||
var failMultipleTest2 = Test2{
|
|
||||||
A: "a",
|
|
||||||
c: false,
|
|
||||||
E: time.Now(),
|
|
||||||
}
|
|
||||||
|
|
||||||
var failPrivateTest2 = Test2{
|
|
||||||
A: "a",
|
|
||||||
B: 0,
|
|
||||||
D: 1.0,
|
|
||||||
E: time.Now(),
|
|
||||||
}
|
|
||||||
|
|
||||||
type Test3 struct {
|
|
||||||
A string
|
A string
|
||||||
B int
|
B int
|
||||||
c bool // private field inside the same package are not ignored
|
c bool // private field inside the same package are not ignored
|
||||||
@ -84,30 +93,37 @@ type Test3 struct {
|
|||||||
E time.Time
|
E time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
var passTest3 = Test3{
|
func exhaustiveStructCustom2() {
|
||||||
A: "a",
|
// pass
|
||||||
B: 0,
|
_ = ExhaustiveStructCustom2{
|
||||||
c: false,
|
A: "a",
|
||||||
D: 1.0,
|
B: 0,
|
||||||
E: time.Now(),
|
c: false,
|
||||||
}
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
var failTest3 = Test3{ // ERROR "B is missing in Test"
|
// fail
|
||||||
A: "a",
|
_ = ExhaustiveStructCustom2{ // ERROR "B is missing in ExhaustiveStructCustom2"
|
||||||
c: false,
|
A: "a",
|
||||||
D: 1.0,
|
c: false,
|
||||||
E: time.Now(),
|
D: 1.0,
|
||||||
}
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
var failMultipleTest3 = Test3{ // ERROR "B, D are missing in Test"
|
// failMultiple
|
||||||
A: "a",
|
_ = ExhaustiveStructCustom2{ // ERROR "B, D are missing in ExhaustiveStructCustom2"
|
||||||
c: false,
|
A: "a",
|
||||||
E: time.Now(),
|
c: false,
|
||||||
}
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// failPrivate
|
||||||
|
_ = ExhaustiveStructCustom2{ // ERROR "c is missing in ExhaustiveStructCustom2"
|
||||||
|
A: "a",
|
||||||
|
B: 0,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
var failPrivateTest3 = Test3{ // ERROR "c is missing in Test"
|
|
||||||
A: "a",
|
|
||||||
B: 0,
|
|
||||||
D: 1.0,
|
|
||||||
E: time.Now(),
|
|
||||||
}
|
}
|
||||||
|
47
test/testdata/exhaustruct.go
vendored
Normal file
47
test/testdata/exhaustruct.go
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// args: -Eexhaustruct
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type Exhaustruct struct {
|
||||||
|
A string
|
||||||
|
B int
|
||||||
|
c bool // private field inside the same package are not ignored
|
||||||
|
D float64
|
||||||
|
E time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func exhaustruct() {
|
||||||
|
// pass
|
||||||
|
_ = Exhaustruct{
|
||||||
|
A: "a",
|
||||||
|
B: 0,
|
||||||
|
c: false,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// failPrivate
|
||||||
|
_ = Exhaustruct{ // ERROR "c is missing in Exhaustruct"
|
||||||
|
A: "a",
|
||||||
|
B: 0,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// fail
|
||||||
|
_ = Exhaustruct{ // ERROR "B is missing in Exhaustruct"
|
||||||
|
A: "a",
|
||||||
|
c: false,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// failMultiple
|
||||||
|
_ = Exhaustruct{ // ERROR "B, D are missing in Exhaustruct"
|
||||||
|
A: "a",
|
||||||
|
c: false,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
133
test/testdata/exhaustruct_custom.go
vendored
Normal file
133
test/testdata/exhaustruct_custom.go
vendored
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
// args: -Eexhaustruct
|
||||||
|
// config_path: testdata/configs/exhaustruct.yml
|
||||||
|
package testdata
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type ExhaustructCustom struct {
|
||||||
|
A string
|
||||||
|
B int
|
||||||
|
c bool // private field inside the same package are not ignored
|
||||||
|
D float64
|
||||||
|
E time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func exhaustructCustom() {
|
||||||
|
// pass
|
||||||
|
_ = ExhaustructCustom{
|
||||||
|
A: "a",
|
||||||
|
B: 0,
|
||||||
|
c: false,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// fail
|
||||||
|
_ = ExhaustructCustom{ // ERROR "B is missing in ExhaustructCustom"
|
||||||
|
A: "a",
|
||||||
|
c: false,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// failMultiple
|
||||||
|
_ = ExhaustructCustom{ // ERROR "B, D are missing in ExhaustructCustom"
|
||||||
|
A: "a",
|
||||||
|
c: false,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// failPrivate
|
||||||
|
_ = ExhaustructCustom{ // ERROR "c is missing in ExhaustructCustom"
|
||||||
|
A: "a",
|
||||||
|
B: 0,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExhaustructCustom1 struct {
|
||||||
|
A string
|
||||||
|
B int
|
||||||
|
c bool // private field inside the same package are not ignored
|
||||||
|
D float64
|
||||||
|
E time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func exhaustructCustom1() {
|
||||||
|
// pass
|
||||||
|
_ = ExhaustructCustom{
|
||||||
|
A: "a",
|
||||||
|
B: 0,
|
||||||
|
c: false,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// fail
|
||||||
|
_ = ExhaustructCustom1{
|
||||||
|
A: "a",
|
||||||
|
c: false,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// failMultiple
|
||||||
|
_ = ExhaustructCustom1{
|
||||||
|
A: "a",
|
||||||
|
c: false,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// failPrivate
|
||||||
|
_ = ExhaustructCustom1{
|
||||||
|
A: "a",
|
||||||
|
B: 0,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
type ExhaustructCustom2 struct {
|
||||||
|
A string
|
||||||
|
B int
|
||||||
|
c bool // private field inside the same package are not ignored
|
||||||
|
D float64
|
||||||
|
E time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func exhaustructCustom2() {
|
||||||
|
// pass
|
||||||
|
_ = ExhaustructCustom2{
|
||||||
|
A: "a",
|
||||||
|
B: 0,
|
||||||
|
c: false,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// fail
|
||||||
|
_ = ExhaustructCustom2{
|
||||||
|
A: "a",
|
||||||
|
c: false,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// failMultiple
|
||||||
|
_ = ExhaustructCustom2{
|
||||||
|
A: "a",
|
||||||
|
c: false,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
|
||||||
|
// failPrivate
|
||||||
|
_ = ExhaustructCustom2{
|
||||||
|
A: "a",
|
||||||
|
B: 0,
|
||||||
|
D: 1.0,
|
||||||
|
E: time.Now(),
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user