Skip to content

Commit

Permalink
Allow applying ignore directives to type declarations
Browse files Browse the repository at this point in the history
Adds support for the syntax:

```go
//exhaustive:ignore
type DeclTypeIgnoredEnum int

const (
	DeclTypeIgnoredMamberA DeclTypeIgnoredEnum = 1
	DeclTypeIgnoredMamberB DeclTypeIgnoredEnum = 2
)
```
  • Loading branch information
iwahbe committed Apr 19, 2024
1 parent d9dc665 commit fc6d38d
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 16 deletions.
56 changes: 55 additions & 1 deletion enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ func (em *enumMembers) factString() string {
func findEnums(pass *analysis.Pass, pkgScopeOnly bool, pkg *types.Package, inspect *inspector.Inspector, info *types.Info) map[enumType]enumMembers {
result := make(map[enumType]enumMembers)

ignoredTypes := findIgnoredTypes(pass, inspect, info)

inspect.Preorder([]ast.Node{&ast.GenDecl{}}, func(n ast.Node) {
gen := n.(*ast.GenDecl)
if gen.Tok != token.CONST {
Expand All @@ -84,7 +86,23 @@ func findEnums(pass *analysis.Pass, pkgScopeOnly bool, pkg *types.Package, inspe
}

for _, s := range gen.Specs {
for _, name := range s.(*ast.ValueSpec).Names {
s := s.(*ast.ValueSpec)
dirs, err := parseDirectives([]*ast.CommentGroup{s.Doc})
if err != nil {
pass.Report(makeInvalidDirectiveDiagnostic(s, err))
return
}

if dirs.has(ignoreDirective) {
return
}

for _, name := range s.Names {

if _, ignored := ignoredTypes[info.Defs[name].Type()]; ignored {
continue
}

enumTyp, memberName, val, ok := possibleEnumMember(name, info)
if !ok {
continue
Expand Down Expand Up @@ -152,6 +170,42 @@ func possibleEnumMember(constName *ast.Ident, info *types.Info) (et enumType, na
return enumType{tn}, obj.Name(), determineConstVal(constName, info), true
}

func findIgnoredTypes(pass *analysis.Pass, inspect *inspector.Inspector, info *types.Info) map[types.Type]struct{} {
ignoredTypes := map[types.Type]struct{}{}

inspect.Preorder([]ast.Node{&ast.GenDecl{}}, func(n ast.Node) {
gen := n.(*ast.GenDecl)
if gen.Tok != token.TYPE {
return
}

dirs, err := parseDirectives([]*ast.CommentGroup{gen.Doc})
if err != nil {
pass.Report(makeInvalidDirectiveDiagnostic(gen, err))
return
}

doIgnoreDecl := dirs.has(ignoreDirective)

for _, s := range gen.Specs {
t := s.(*ast.TypeSpec)
dirs, err := parseDirectives([]*ast.CommentGroup{t.Doc})
if err != nil {
pass.Report(makeInvalidDirectiveDiagnostic(t, err))
continue
}
doIgnoreSpec := doIgnoreDecl || dirs.has(ignoreDirective)
if !doIgnoreSpec {
continue
}

ignoredTypes[info.Defs[t.Name].Type()] = struct{}{}
}
})

return ignoredTypes
}

func determineConstVal(name *ast.Ident, info *types.Info) constantValue {
c := info.ObjectOf(name).(*types.Const)
return constantValue(c.Val().ExactString())
Expand Down
40 changes: 32 additions & 8 deletions enum_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -367,27 +367,51 @@ func checkEnums(t *testing.T, got []checkEnum, pkgOnly bool) {
},
}},
{"DeclGroupIgnoredEnum", enumMembers{
[]string{"DeclGroupIgnoredMamberC"},
[]string{"DeclGroupIgnoredMemberC"},
map[string]token.Pos{
"DeclGroupIgnoredMamberC": 0,
"DeclGroupIgnoredMemberC": 0,
},
map[string]constantValue{
"DeclGroupIgnoredMamberC": `3`,
"DeclGroupIgnoredMemberC": `3`,
},
map[constantValue][]string{
`3`: {"DeclGroupIgnoredMamberC"},
`3`: {"DeclGroupIgnoredMemberC"},
},
}},
{"DeclIgnoredEnum", enumMembers{
[]string{"DeclIgnoredMamberB"},
[]string{"DeclIgnoredMemberB"},
map[string]token.Pos{
"DeclIgnoredMamberB": 0,
"DeclIgnoredMemberB": 0,
},
map[string]constantValue{
"DeclIgnoredMamberB": `2`,
"DeclIgnoredMemberB": `2`,
},
map[constantValue][]string{
`2`: {"DeclIgnoredMamberB"},
`2`: {"DeclIgnoredMemberB"},
},
}},
{"DeclTypeInnerNotIgnore", enumMembers{
[]string{"DeclTypeInnerNotIgnoreMember"},
map[string]token.Pos{
"DeclTypeInnerNotIgnoreMember": 0,
},
map[string]constantValue{
"DeclTypeInnerNotIgnoreMember": `5`,
},
map[constantValue][]string{
`5`: {"DeclTypeInnerNotIgnoreMember"},
},
}},
{"DeclTypeIgnoredValue", enumMembers{
[]string{"DeclTypeNotIgnoredValue"},
map[string]token.Pos{
"DeclTypeNotIgnoredValue": 0,
},
map[string]constantValue{
"DeclTypeNotIgnoredValue": `1`,
},
map[constantValue][]string{
`1`: {"DeclTypeNotIgnoredValue"},
},
}},
}
Expand Down
42 changes: 35 additions & 7 deletions testdata/src/enum/enum.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,19 +87,47 @@ const (

func (WithMethod) String() string { return "whatever" }

type DeclGroupIgnoredEnum int // want DeclGroupIgnoredEnum:"^DeclGroupIgnoredMamberC$"
type DeclGroupIgnoredEnum int // want DeclGroupIgnoredEnum:"^DeclGroupIgnoredMemberC$"

//exhaustive:ignore
const (
DeclGroupIgnoredMamberA DeclGroupIgnoredEnum = 1
DeclGroupIgnoredMamberB DeclGroupIgnoredEnum = 2
DeclGroupIgnoredMemberA DeclGroupIgnoredEnum = 1
DeclGroupIgnoredMemberB DeclGroupIgnoredEnum = 2
)

const DeclGroupIgnoredMamberC DeclGroupIgnoredEnum = 3
const DeclGroupIgnoredMemberC DeclGroupIgnoredEnum = 3

type DeclIgnoredEnum int // want DeclIgnoredEnum:"^DeclIgnoredMamberB$"
type DeclIgnoredEnum int // want DeclIgnoredEnum:"^DeclIgnoredMemberB$"

//exhaustive:ignore
const DeclIgnoredMamberA DeclIgnoredEnum = 1
const DeclIgnoredMemberA DeclIgnoredEnum = 1

const DeclIgnoredMamberB DeclIgnoredEnum = 2
const DeclIgnoredMemberB DeclIgnoredEnum = 2

//exhaustive:ignore
type DeclTypeIgnoredEnum int

const (
DeclTypeIgnoredMemberA DeclTypeIgnoredEnum = 1
DeclTypeIgnoredMemberB DeclTypeIgnoredEnum = 2
)

type (
//exhaustive:ignore
DeclTypeInnerIgnore int
DeclTypeInnerNotIgnore int // want DeclTypeInnerNotIgnore:"^DeclTypeInnerNotIgnoreMember$"
)

const (
DeclTypeInnerIgnoreMemberA DeclTypeInnerIgnore = 3
DeclTypeInnerIgnoreMemberB DeclTypeInnerIgnore = 4
DeclTypeInnerNotIgnoreMember DeclTypeInnerNotIgnore = 5
)

type DeclTypeIgnoredValue int // want DeclTypeIgnoredValue:"^DeclTypeNotIgnoredValue$"

const (
DeclTypeNotIgnoredValue DeclTypeIgnoredValue = 1
//exhaustive:ignore
DeclTypeIsIgnoredValue DeclTypeIgnoredValue = 2
)

0 comments on commit fc6d38d

Please sign in to comment.