Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ignorePackageGlobs:
- encoding/*
19 changes: 19 additions & 0 deletions wrapcheck/testdata/config_ignorePackageGlobs_interface/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package main

import (
"encoding/json"
"time"
)

func main() {
do(&time.Time{})
}

func do(fn json.Unmarshaler) error {
err := fn.UnmarshalJSON([]byte{})
if err != nil {
return err
}

return nil
}
19 changes: 15 additions & 4 deletions wrapcheck/wrapcheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,15 +234,23 @@ func run(cfg WrapcheckConfig) func(*analysis.Pass) (interface{}, error) {

// Report unwrapped takes a call expression and an identifier and reports
// if the call is unwrapped.
func reportUnwrapped(pass *analysis.Pass, call *ast.CallExpr, tokenPos token.Pos, cfg WrapcheckConfig, regexpsSig []*regexp.Regexp, regexpsInter []*regexp.Regexp, pkgGlobs []glob.Glob) {
func reportUnwrapped(
pass *analysis.Pass,
call *ast.CallExpr,
tokenPos token.Pos,
cfg WrapcheckConfig,
regexpsSig []*regexp.Regexp,
regexpsInter []*regexp.Regexp,
pkgGlobs []glob.Glob,
) {

sel, ok := call.Fun.(*ast.SelectorExpr)
if !ok {
return
}

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

if contains(cfg.IgnoreSigs, fnSig) {
return
} else if containsMatch(regexpsSig, fnSig) {
Expand All @@ -253,9 +261,9 @@ func reportUnwrapped(pass *analysis.Pass, call *ast.CallExpr, tokenPos token.Pos
// errors returned from interface types should be wrapped, unless ignored
// as per `ignoreInterfaceRegexps`
if isInterface(pass, sel) {
pkgPath := pass.TypesInfo.ObjectOf(sel.Sel).Pkg().Path()
name := types.TypeString(pass.TypesInfo.TypeOf(sel.X), func(p *types.Package) string { return p.Name() })
if containsMatch(regexpsInter, name) {
} else {
if !containsMatch(regexpsInter, name) && !containsMatchGlob(pkgGlobs, pkgPath) {
pass.Reportf(tokenPos, "error returned from interface method should be wrapped: sig: %s", fnSig)
return
}
Expand Down Expand Up @@ -318,6 +326,7 @@ func prevErrAssign(pass *analysis.Pass, file *ast.File, returnIdent *ast.Ident)
if !isError(pass.TypesInfo.TypeOf(expr)) {
continue
}

if assIdent, ok := expr.(*ast.Ident); ok {
if assIdent.Obj == nil || returnIdent.Obj == nil {
// If we can't find the Obj for one of the identifiers, just skip
Expand All @@ -341,6 +350,7 @@ func prevErrAssign(pass *analysis.Pass, file *ast.File, returnIdent *ast.Ident)
if ass.Pos() > returnIdent.Pos() {
break
}

mostRecentAssign = ass
}

Expand Down Expand Up @@ -373,6 +383,7 @@ func containsMatchGlob(globs []glob.Glob, el string) bool {
return true
}
}

return false
}

Expand Down