cmd/vet: backport of https://go-review.googlesource.com/#/c/10777/3
Change-Id: I8d63575f2053eda2d7f0a63f3ff862bf0de88d31 Reviewed-on: https://go-review.googlesource.com/10807 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
ac303766f5
commit
a6d2a4254e
|
@ -19,8 +19,8 @@ var imports = make(map[string]*types.Package)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
errorType *types.Interface
|
errorType *types.Interface
|
||||||
stringerType *types.Interface
|
stringerType *types.Interface // possibly nil
|
||||||
formatterType *types.Interface
|
formatterType *types.Interface // possibly nil
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -37,13 +37,12 @@ func init() {
|
||||||
|
|
||||||
// importType returns the type denoted by the qualified identifier
|
// importType returns the type denoted by the qualified identifier
|
||||||
// path.name, and adds the respective package to the imports map
|
// path.name, and adds the respective package to the imports map
|
||||||
// as a side effect.
|
// as a side effect. In case of an error, importType returns nil.
|
||||||
func importType(path, name string) types.Type {
|
func importType(path, name string) types.Type {
|
||||||
pkg, err := types.DefaultImport(imports, path)
|
pkg, err := types.DefaultImport(imports, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// This can happen if fmt hasn't been compiled yet.
|
// This can happen if the package at path hasn't been compiled yet.
|
||||||
// Since nothing uses formatterType anyway, don't complain.
|
warnf("import failed: %v", err)
|
||||||
//warnf("import failed: %v", err)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if obj, ok := pkg.Scope().Lookup(name).(*types.TypeName); ok {
|
if obj, ok := pkg.Scope().Lookup(name).(*types.TypeName); ok {
|
||||||
|
@ -136,16 +135,13 @@ func (f *File) matchArgTypeInternal(t printfArgType, typ types.Type, arg ast.Exp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If the type implements fmt.Formatter, we have nothing to check.
|
// If the type implements fmt.Formatter, we have nothing to check.
|
||||||
// But (see issue 6259) that's not easy to verify, so instead we see
|
// formatterTyp may be nil - be conservative and check for Format method in that case.
|
||||||
// if its method set contains a Format function. We could do better,
|
if formatterType != nil && types.Implements(typ, formatterType) || f.hasMethod(typ, "Format") {
|
||||||
// even now, but we don't need to be 100% accurate. Wait for 6259 to
|
|
||||||
// be fixed instead. TODO.
|
|
||||||
if f.hasMethod(typ, "Format") {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
// If we can use a string, might arg (dynamically) implement the Stringer or Error interface?
|
// If we can use a string, might arg (dynamically) implement the Stringer or Error interface?
|
||||||
if t&argString != 0 {
|
if t&argString != 0 {
|
||||||
if types.AssertableTo(errorType, typ) || types.AssertableTo(stringerType, typ) {
|
if types.AssertableTo(errorType, typ) || stringerType != nil && types.AssertableTo(stringerType, typ) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,7 +315,9 @@ func (f *File) isErrorMethodCall(call *ast.CallExpr) bool {
|
||||||
if typ != nil {
|
if typ != nil {
|
||||||
// We know it's called "Error", so just check the function signature
|
// We know it's called "Error", so just check the function signature
|
||||||
// (stringerType has exactly one method, String).
|
// (stringerType has exactly one method, String).
|
||||||
return types.Identical(f.pkg.types[call.Fun].Type, stringerType.Method(0).Type())
|
if stringerType != nil && stringerType.NumMethods() == 1 {
|
||||||
|
return types.Identical(f.pkg.types[call.Fun].Type, stringerType.Method(0).Type())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Without types, we can still check by hand.
|
// Without types, we can still check by hand.
|
||||||
// Is it a selector expression? Otherwise it's a function call, not a method call.
|
// Is it a selector expression? Otherwise it's a function call, not a method call.
|
||||||
|
|
Loading…
Reference in New Issue