go.tools/cmd/vet: the composite test is about keys, not tags
Fix the confusion. No semantic change, just some renamings. Fixes golang/go#6017. R=golang-dev, dsymonds CC=golang-dev https://golang.org/cl/12394043
This commit is contained in:
parent
3209d6ad73
commit
aecec2f502
|
|
@ -2,7 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
// This file contains the test for untagged struct literals.
|
// This file contains the test for unkeyed struct literals.
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|
@ -14,9 +14,9 @@ import (
|
||||||
|
|
||||||
var compositeWhiteList = flag.Bool("compositewhitelist", true, "use composite white list; for testing only")
|
var compositeWhiteList = flag.Bool("compositewhitelist", true, "use composite white list; for testing only")
|
||||||
|
|
||||||
// checkUntaggedLiteral checks if a composite literal is a struct literal with
|
// checkUnkeyedLiteral checks if a composite literal is a struct literal with
|
||||||
// untagged fields.
|
// unkeyed fields.
|
||||||
func (f *File) checkUntaggedLiteral(c *ast.CompositeLit) {
|
func (f *File) checkUnkeyedLiteral(c *ast.CompositeLit) {
|
||||||
if !vet("composites") {
|
if !vet("composites") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -36,9 +36,9 @@ func (f *File) checkUntaggedLiteral(c *ast.CompositeLit) {
|
||||||
case *ast.MapType:
|
case *ast.MapType:
|
||||||
return
|
return
|
||||||
case *ast.StructType:
|
case *ast.StructType:
|
||||||
return // a literal struct type does not need to use tags
|
return // a literal struct type does not need to use keys
|
||||||
case *ast.Ident:
|
case *ast.Ident:
|
||||||
// A simple type name like t or T does not need tags either,
|
// A simple type name like t or T does not need keys either,
|
||||||
// since it is almost certainly declared in the current package.
|
// since it is almost certainly declared in the current package.
|
||||||
// (The exception is names being used via import . "pkg", but
|
// (The exception is names being used via import . "pkg", but
|
||||||
// those are already breaking the Go 1 compatibility promise,
|
// those are already breaking the Go 1 compatibility promise,
|
||||||
|
|
@ -59,7 +59,7 @@ func (f *File) checkUntaggedLiteral(c *ast.CompositeLit) {
|
||||||
|
|
||||||
// It's a struct, or we can't tell it's not a struct because we don't have types.
|
// It's a struct, or we can't tell it's not a struct because we don't have types.
|
||||||
|
|
||||||
// Check if the CompositeLit contains an untagged field.
|
// Check if the CompositeLit contains an unkeyed field.
|
||||||
allKeyValue := true
|
allKeyValue := true
|
||||||
for _, e := range c.Elts {
|
for _, e := range c.Elts {
|
||||||
if _, ok := e.(*ast.KeyValueExpr); !ok {
|
if _, ok := e.(*ast.KeyValueExpr); !ok {
|
||||||
|
|
@ -88,11 +88,11 @@ func (f *File) checkUntaggedLiteral(c *ast.CompositeLit) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
typeName := path + "." + s.Sel.Name
|
typeName := path + "." + s.Sel.Name
|
||||||
if *compositeWhiteList && untaggedLiteralWhitelist[typeName] {
|
if *compositeWhiteList && unkeyedLiteralWhitelist[typeName] {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
f.Warn(c.Pos(), typeString+" composite literal uses untagged fields")
|
f.Warn(c.Pos(), typeString+" composite literal uses unkeyed fields")
|
||||||
}
|
}
|
||||||
|
|
||||||
// pkgPath returns the import path "image/png" for the package name "png".
|
// pkgPath returns the import path "image/png" for the package name "png".
|
||||||
|
|
@ -118,7 +118,7 @@ func pkgPath(f *File, pkgName string) (path string) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
var untaggedLiteralWhitelist = map[string]bool{
|
var unkeyedLiteralWhitelist = map[string]bool{
|
||||||
/*
|
/*
|
||||||
These types are actually slices. Syntactically, we cannot tell
|
These types are actually slices. Syntactically, we cannot tell
|
||||||
whether the Typ in pkg.Typ{1, 2, 3} is a slice or a struct, so we
|
whether the Typ in pkg.Typ{1, 2, 3} is a slice or a struct, so we
|
||||||
|
|
@ -49,9 +49,9 @@ Non-standard signatures for methods with familiar names, including:
|
||||||
|
|
||||||
Struct tags that do not follow the format understood by reflect.StructTag.Get.
|
Struct tags that do not follow the format understood by reflect.StructTag.Get.
|
||||||
|
|
||||||
4. Untagged composite literals, flag -composites
|
4. Unkeyed composite literals, flag -composites
|
||||||
|
|
||||||
Composite struct literals that do not use the type-tagged syntax.
|
Composite struct literals that do not use the field-keyed syntax.
|
||||||
|
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ var report = map[string]*bool{
|
||||||
"assign": flag.Bool("assign", false, "check for useless assignments"),
|
"assign": flag.Bool("assign", false, "check for useless assignments"),
|
||||||
"atomic": flag.Bool("atomic", false, "check for common mistaken usages of the sync/atomic package"),
|
"atomic": flag.Bool("atomic", false, "check for common mistaken usages of the sync/atomic package"),
|
||||||
"buildtags": flag.Bool("buildtags", false, "check that +build tags are valid"),
|
"buildtags": flag.Bool("buildtags", false, "check that +build tags are valid"),
|
||||||
"composites": flag.Bool("composites", false, "check that composite literals used type-tagged elements"),
|
"composites": flag.Bool("composites", false, "check that composite literals used field-keyed elements"),
|
||||||
"methods": flag.Bool("methods", false, "check that canonically named methods are canonically defined"),
|
"methods": flag.Bool("methods", false, "check that canonically named methods are canonically defined"),
|
||||||
"printf": flag.Bool("printf", false, "check printf-like invocations"),
|
"printf": flag.Bool("printf", false, "check printf-like invocations"),
|
||||||
"rangeloops": flag.Bool("rangeloops", false, "check that range loop variables are used correctly"),
|
"rangeloops": flag.Bool("rangeloops", false, "check that range loop variables are used correctly"),
|
||||||
|
|
@ -400,7 +400,7 @@ func (f *File) walkCallExpr(call *ast.CallExpr) {
|
||||||
|
|
||||||
// walkCompositeLit walks a composite literal.
|
// walkCompositeLit walks a composite literal.
|
||||||
func (f *File) walkCompositeLit(c *ast.CompositeLit) {
|
func (f *File) walkCompositeLit(c *ast.CompositeLit) {
|
||||||
f.checkUntaggedLiteral(c)
|
f.checkUnkeyedLiteral(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
// walkFieldTag walks a struct field tag.
|
// walkFieldTag walks a struct field tag.
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ var Okay4 = MyStruct{
|
||||||
// Testing is awkward because we need to reference things from a separate package
|
// Testing is awkward because we need to reference things from a separate package
|
||||||
// to trigger the warnings.
|
// to trigger the warnings.
|
||||||
|
|
||||||
var BadStructLiteralUsedInTests = flag.Flag{ // ERROR "untagged fields"
|
var BadStructLiteralUsedInTests = flag.Flag{ // ERROR "unkeyed fields"
|
||||||
"Name",
|
"Name",
|
||||||
"Usage",
|
"Usage",
|
||||||
nil, // Value
|
nil, // Value
|
||||||
|
|
@ -40,7 +40,7 @@ func (pkg *Package) check(fs *token.FileSet, astFiles []*ast.File) error {
|
||||||
// isStruct reports whether the composite literal c is a struct.
|
// isStruct reports whether the composite literal c is a struct.
|
||||||
// If it is not (probably a struct), it returns a printable form of the type.
|
// If it is not (probably a struct), it returns a printable form of the type.
|
||||||
func (pkg *Package) isStruct(c *ast.CompositeLit) (bool, string) {
|
func (pkg *Package) isStruct(c *ast.CompositeLit) (bool, string) {
|
||||||
// Check that the CompositeLit's type is a slice or array (which needs no tag), if possible.
|
// Check that the CompositeLit's type is a slice or array (which needs no field keys), if possible.
|
||||||
typ := pkg.types[c]
|
typ := pkg.types[c]
|
||||||
// If it's a named type, pull out the underlying type. If it's not, the Underlying
|
// If it's a named type, pull out the underlying type. If it's not, the Underlying
|
||||||
// method returns the type itself.
|
// method returns the type itself.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue