mirror of
https://github.com/golang/go
synced 2024-11-20 08:54:40 -07:00
gofix: add mapdelete
R=golang-dev, r CC=golang-dev https://golang.org/cl/5286043
This commit is contained in:
parent
1d687c742d
commit
7242052bc7
@ -16,6 +16,7 @@ GOFILES=\
|
||||
imagenew.go\
|
||||
iocopyn.go\
|
||||
main.go\
|
||||
mapdelete.go\
|
||||
math.go\
|
||||
netdial.go\
|
||||
netudpgroup.go\
|
||||
|
@ -53,6 +53,7 @@ var fixes = fixlist{
|
||||
mathFix,
|
||||
ioCopyNFix,
|
||||
imagecolorFix,
|
||||
mapdeleteFix,
|
||||
}
|
||||
|
||||
// walk traverses the AST x, calling visit(y) for each node y in the tree but
|
||||
|
84
src/cmd/gofix/mapdelete.go
Normal file
84
src/cmd/gofix/mapdelete.go
Normal file
@ -0,0 +1,84 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import "go/ast"
|
||||
|
||||
var mapdeleteFix = fix{
|
||||
"mapdelete",
|
||||
mapdelete,
|
||||
`Use delete(m, k) instead of m[k] = 0, false.
|
||||
|
||||
http://codereview.appspot.com/5272045
|
||||
`,
|
||||
}
|
||||
|
||||
func mapdelete(f *ast.File) bool {
|
||||
fixed := false
|
||||
walk(f, func(n interface{}) {
|
||||
stmt, ok := n.(*ast.Stmt)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
as, ok := (*stmt).(*ast.AssignStmt)
|
||||
if !ok || len(as.Lhs) != 1 || len(as.Rhs) != 2 {
|
||||
return
|
||||
}
|
||||
ix, ok := as.Lhs[0].(*ast.IndexExpr)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if !isTopName(as.Rhs[1], "false") {
|
||||
warn(as.Pos(), "two-element map assignment with non-false second value")
|
||||
return
|
||||
}
|
||||
if !canDrop(as.Rhs[0]) {
|
||||
warn(as.Pos(), "two-element map assignment with non-trivial first value")
|
||||
return
|
||||
}
|
||||
*stmt = &ast.ExprStmt{
|
||||
X: &ast.CallExpr{
|
||||
Fun: &ast.Ident{
|
||||
NamePos: as.Pos(),
|
||||
Name: "delete",
|
||||
},
|
||||
Args: []ast.Expr{ix.X, ix.Index},
|
||||
},
|
||||
}
|
||||
fixed = true
|
||||
})
|
||||
return fixed
|
||||
}
|
||||
|
||||
// canDrop reports whether it is safe to drop the
|
||||
// evaluation of n from the program.
|
||||
// It is very conservative.
|
||||
func canDrop(n ast.Expr) bool {
|
||||
switch n := n.(type) {
|
||||
case *ast.Ident, *ast.BasicLit:
|
||||
return true
|
||||
case *ast.ParenExpr:
|
||||
return canDrop(n.X)
|
||||
case *ast.SelectorExpr:
|
||||
return canDrop(n.X)
|
||||
case *ast.CompositeLit:
|
||||
if !canDrop(n.Type) {
|
||||
return false
|
||||
}
|
||||
for _, e := range n.Elts {
|
||||
if !canDrop(e) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
case *ast.StarExpr:
|
||||
// Dropping *x is questionable,
|
||||
// but we have to be able to drop (*T)(nil).
|
||||
return canDrop(n.X)
|
||||
case *ast.ArrayType, *ast.ChanType, *ast.FuncType, *ast.InterfaceType, *ast.MapType, *ast.StructType:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
43
src/cmd/gofix/mapdelete_test.go
Normal file
43
src/cmd/gofix/mapdelete_test.go
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
func init() {
|
||||
addTestCases(mapdeleteTests, mapdelete)
|
||||
}
|
||||
|
||||
var mapdeleteTests = []testCase{
|
||||
{
|
||||
Name: "mapdelete.0",
|
||||
In: `package main
|
||||
|
||||
func f() {
|
||||
m[x] = 0, false
|
||||
m[x] = g(), false
|
||||
m[x] = 1
|
||||
delete(m, x)
|
||||
m[x] = 0, b
|
||||
}
|
||||
|
||||
func g(false bool) {
|
||||
m[x] = 0, false
|
||||
}
|
||||
`,
|
||||
Out: `package main
|
||||
|
||||
func f() {
|
||||
delete(m, x)
|
||||
m[x] = g(), false
|
||||
m[x] = 1
|
||||
delete(m, x)
|
||||
m[x] = 0, b
|
||||
}
|
||||
|
||||
func g(false bool) {
|
||||
m[x] = 0, false
|
||||
}
|
||||
`,
|
||||
},
|
||||
}
|
Loading…
Reference in New Issue
Block a user