diff options
Diffstat (limited to 'src/cmd/vet/taglit.go')
-rw-r--r-- | src/cmd/vet/taglit.go | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/src/cmd/vet/taglit.go b/src/cmd/vet/taglit.go index 0324e37b0..bcad2fe0a 100644 --- a/src/cmd/vet/taglit.go +++ b/src/cmd/vet/taglit.go @@ -9,32 +9,52 @@ package main import ( "flag" "go/ast" - "go/types" "strings" ) var compositeWhiteList = flag.Bool("compositewhitelist", true, "use composite white list; for testing only") -// checkUntaggedLiteral checks if a composite literal is an struct literal with +// checkUntaggedLiteral checks if a composite literal is a struct literal with // untagged fields. func (f *File) checkUntaggedLiteral(c *ast.CompositeLit) { if !vet("composites") { return } - // Check that the CompositeLit's type is a slice or array (which needs no tag), if possible. - typ := f.pkg.types[c] - if typ != nil { - // If it's a named type, pull out the underlying type. - if namedType, ok := typ.(*types.NamedType); ok { - typ = namedType.Underlying - } - switch typ.(type) { - case *types.Slice: - return - case *types.Array: - return + typ := c.Type + for { + if typ1, ok := c.Type.(*ast.ParenExpr); ok { + typ = typ1 + continue } + break + } + + switch typ.(type) { + case *ast.ArrayType: + return + case *ast.MapType: + return + case *ast.StructType: + return // a literal struct type does not need to use tags + case *ast.Ident: + // A simple type name like t or T does not need tags either, + // since it is almost certainly declared in the current package. + // (The exception is names being used via import . "pkg", but + // those are already breaking the Go 1 compatibility promise, + // so not reporting potential additional breakage seems okay.) + return + } + + // Otherwise the type is a selector like pkg.Name. + // We only care if pkg.Name is a struct, not if it's a map, array, or slice. + isStruct, typeString := f.pkg.isStruct(c) + if !isStruct { + return + } + + if typeString == "" { // isStruct doesn't know + typeString = f.gofmt(typ) } // It's a struct, or we can't tell it's not a struct because we don't have types. @@ -64,7 +84,7 @@ func (f *File) checkUntaggedLiteral(c *ast.CompositeLit) { // Convert the package name to an import path, and compare to a whitelist. path := pkgPath(f, pkg.Name) if path == "" { - f.Warnf(c.Pos(), "unresolvable package for %s.%s literal", pkg.Name, s.Sel.Name) + f.Badf(c.Pos(), "unresolvable package for %s.%s literal", pkg.Name, s.Sel.Name) return } typeName := path + "." + s.Sel.Name @@ -72,7 +92,7 @@ func (f *File) checkUntaggedLiteral(c *ast.CompositeLit) { return } - f.Warnf(c.Pos(), "%s composite literal uses untagged fields", typ) + f.Warn(c.Pos(), typeString+" composite literal uses untagged fields") } // pkgPath returns the import path "image/png" for the package name "png". @@ -119,8 +139,6 @@ var untaggedLiteralWhitelist = map[string]bool{ "encoding/xml.CharData": true, "encoding/xml.Comment": true, "encoding/xml.Directive": true, - "exp/norm.Decomposition": true, - "exp/types.ObjList": true, "go/scanner.ErrorList": true, "image/color.Palette": true, "net.HardwareAddr": true, |