diff --git a/comment.go b/comment.go index 0f641ee..9df598c 100644 --- a/comment.go +++ b/comment.go @@ -3,42 +3,9 @@ package exhaustive import ( "go/ast" "go/token" - "regexp" "strings" ) -// For definition of generated file see: -// http://golang.org/s/generatedcode - -var generatedCodeRe = regexp.MustCompile(`^// Code generated .* DO NOT EDIT\.$`) - -func isGeneratedFile(file *ast.File) bool { - // NOTE: file.Comments includes file.Doc as well, so no need - // to separately check file.Doc. - for _, c := range file.Comments { - for _, cc := range c.List { - // This check handles the "must appear before the first - // non-comment, non-blank text in the file" requirement. - // - // According to https://golang.org/ref/spec#Source_file_organization - // the package clause is the first element in a file, which - // should make it the first non-comment, non-blank text. - if c.Pos() >= file.Package { - return false - } - // According to the docs: - // '\r' has been removed. - // '\n' has been removed for //-style comments - // This has also been manually verified. - if generatedCodeRe.MatchString(cc.Text) { - return true - } - } - } - - return false -} - const ( ignoreComment = "//exhaustive:ignore" enforceComment = "//exhaustive:enforce" diff --git a/comment_go121.go b/comment_go121.go new file mode 100644 index 0000000..a7bbc88 --- /dev/null +++ b/comment_go121.go @@ -0,0 +1,11 @@ +//go:build go1.21 + +package exhaustive + +import ( + "go/ast" +) + +func isGeneratedFile(file *ast.File) bool { + return ast.IsGenerated(file) +} diff --git a/comment_pre_go121.go b/comment_pre_go121.go new file mode 100644 index 0000000..28d2ed4 --- /dev/null +++ b/comment_pre_go121.go @@ -0,0 +1,27 @@ +//go:build !go1.21 + +package exhaustive + +import ( + "go/ast" + "regexp" +) + +// For definition of generated file see: +// http://golang.org/s/generatedcode + +var generatedCodeRe = regexp.MustCompile(`^// Code generated .* DO NOT EDIT\.$`) + +func isGeneratedFile(file *ast.File) bool { + for _, c := range file.Comments { + for _, cc := range c.List { + if cc.Pos() > file.Package { + break + } + if generatedCodeRe.MatchString(cc.Text) { + return true + } + } + } + return false +} diff --git a/doc.go b/doc.go index 8435e5d..a745247 100644 --- a/doc.go +++ b/doc.go @@ -10,8 +10,8 @@ The Go [language spec] does not have an explicit definition for enums. For the purpose of this analyzer, and by convention, an enum type is any named type that: - - has underlying type float, string, or integer (includes byte and rune); - and + - has an [underlying type] of float, string, or integer (includes byte + and rune); and - has at least one constant of its type defined in the same [block]. In the example below, Biome is an enum type. The three constants are its @@ -209,6 +209,7 @@ To ignore specific types, specify the -ignore-enum-types flag: exhaustive -ignore-enum-types '^time\.Duration$|^example\.org/measure\.Unit$' [language spec]: https://golang.org/ref/spec +[underlying type]: https://golang.org/ref/spec#Underlying_types [block]: https://golang.org/ref/spec#Blocks [BasicKind]: https://pkg.go.dev/go/types#BasicKind */