Skip to content
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

dev: refactor regexp usage #24

Merged
merged 6 commits into from Feb 17, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
61 changes: 37 additions & 24 deletions wrapcheck/wrapcheck.go
@@ -1,6 +1,7 @@
package wrapcheck

import (
"fmt"
"go/ast"
"go/token"
"go/types"
Expand All @@ -13,18 +14,16 @@ import (
"golang.org/x/tools/go/analysis"
)

var (
DefaultIgnoreSigs = []string{
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack(",
}
)
var DefaultIgnoreSigs = []string{
".Errorf(",
"errors.New(",
"errors.Unwrap(",
".Wrap(",
".Wrapf(",
".WithMessage(",
".WithMessagef(",
".WithStack(",
}

// WrapcheckConfig is the set of configuration values which configure the
// behaviour of the linter.
Expand Down Expand Up @@ -72,6 +71,9 @@ type WrapcheckConfig struct {
// ignorePackageGlobs:
// - encoding/*
IgnorePackageGlobs []string `mapstructure:"ignorePackageGlobs" yaml:"ignorePackageGlobs"`

// ignoreSigRegexpCompiled use to hold compiled results of the IgnoreSigRegexps
ignoreSigRegexpCompiled []*regexp.Regexp
}

func NewDefaultConfig() WrapcheckConfig {
Expand All @@ -91,7 +93,24 @@ func NewAnalyzer(cfg WrapcheckConfig) *analysis.Analyzer {
}

func run(cfg WrapcheckConfig) func(*analysis.Pass) (interface{}, error) {
var Err error

for i := range cfg.IgnoreSigRegexps {
butuzov marked this conversation as resolved.
Show resolved Hide resolved
re, err := regexp.Compile(cfg.IgnoreSigRegexps[i])
if err != nil {
Err = fmt.Errorf("unable to parse regexp: %v at %s\n", err, cfg.IgnoreSigRegexps[i])
log.Printf(Err.Error())
break
}
cfg.ignoreSigRegexpCompiled = append(cfg.ignoreSigRegexpCompiled, re)
butuzov marked this conversation as resolved.
Show resolved Hide resolved
}

return func(pass *analysis.Pass) (interface{}, error) {
// handling load errors.
if Err != nil {
return nil, Err
}

for _, file := range pass.Files {
ast.Inspect(file, func(n ast.Node) bool {
ret, ok := n.(*ast.ReturnStmt)
Expand All @@ -112,6 +131,7 @@ func run(cfg WrapcheckConfig) func(*analysis.Pass) (interface{}, error) {
// If the return type of the function is a single error. This will not
// match an error within multiple return values, for that, the below
// tuple check is required.

if isError(pass.TypesInfo.TypeOf(expr)) {
reportUnwrapped(pass, retFn, retFn.Pos(), cfg)
return true
Expand Down Expand Up @@ -146,9 +166,7 @@ func run(cfg WrapcheckConfig) func(*analysis.Pass) (interface{}, error) {
return true
}

var (
call *ast.CallExpr
)
var call *ast.CallExpr

// Attempt to find the most recent short assign
if shortAss := prevErrAssign(pass, file, ident); shortAss != nil {
Expand Down Expand Up @@ -216,9 +234,10 @@ func reportUnwrapped(pass *analysis.Pass, call *ast.CallExpr, tokenPos token.Pos

// Check for ignored signatures
fnSig := pass.TypesInfo.ObjectOf(sel.Sel).String()

if contains(cfg.IgnoreSigs, fnSig) {
return
} else if containsMatch(cfg.IgnoreSigRegexps, fnSig) {
} else if containsMatch(cfg.ignoreSigRegexpCompiled, fnSig) {
return
}

Expand Down Expand Up @@ -331,14 +350,8 @@ func contains(slice []string, el string) bool {
return false
}

func containsMatch(slice []string, el string) bool {
for _, s := range slice {
re, err := regexp.Compile(s)
if err != nil {
log.Printf("unable to parse regexp: %s\n", s)
os.Exit(1)
}

func containsMatch(regexps []*regexp.Regexp, el string) bool {
for _, re := range regexps {
if re.MatchString(el) {
return true
}
Expand Down