mirror of
https://github.com/golang/go
synced 2024-11-24 09:10:24 -07:00
gofix: fix for strconv API change
R=golang-dev, gri, adg, r CC=golang-dev https://golang.org/cl/5434098
This commit is contained in:
parent
2666b815a3
commit
4feafeeea0
@ -31,6 +31,7 @@ GOFILES=\
|
||||
signal.go\
|
||||
sorthelpers.go\
|
||||
sortslice.go\
|
||||
strconv.go\
|
||||
stringssplit.go\
|
||||
template.go\
|
||||
timefileinfo.go\
|
||||
|
@ -15,6 +15,7 @@ slice of named type (go/scanner)
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"os"
|
||||
"path"
|
||||
@ -743,3 +744,11 @@ func usesImport(f *ast.File, path string) (used bool) {
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func expr(s string) ast.Expr {
|
||||
x, err := parser.ParseExpr(fset, "", s)
|
||||
if err != nil {
|
||||
panic("parsing " + s + ": " + err.Error())
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
127
src/cmd/gofix/strconv.go
Normal file
127
src/cmd/gofix/strconv.go
Normal file
@ -0,0 +1,127 @@
|
||||
// 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"
|
||||
|
||||
func init() {
|
||||
register(strconvFix)
|
||||
}
|
||||
|
||||
var strconvFix = fix{
|
||||
"strconv",
|
||||
"2011-12-01",
|
||||
strconvFn,
|
||||
`Convert to new strconv API.
|
||||
|
||||
http://codereview.appspot.com/5434095
|
||||
http://codereview.appspot.com/5434069
|
||||
`,
|
||||
}
|
||||
|
||||
func strconvFn(f *ast.File) bool {
|
||||
if !imports(f, "strconv") {
|
||||
return false
|
||||
}
|
||||
|
||||
fixed := false
|
||||
|
||||
walk(f, func(n interface{}) {
|
||||
// Rename functions.
|
||||
call, ok := n.(*ast.CallExpr)
|
||||
if !ok || len(call.Args) < 1 {
|
||||
return
|
||||
}
|
||||
sel, ok := call.Fun.(*ast.SelectorExpr)
|
||||
if !ok || !isTopName(sel.X, "strconv") {
|
||||
return
|
||||
}
|
||||
change := func(name string) {
|
||||
fixed = true
|
||||
sel.Sel.Name = name
|
||||
}
|
||||
add := func(s string) {
|
||||
call.Args = append(call.Args, expr(s))
|
||||
}
|
||||
switch sel.Sel.Name {
|
||||
case "Atob":
|
||||
change("ParseBool")
|
||||
case "Atof32":
|
||||
change("ParseFloat")
|
||||
add("32") // bitSize
|
||||
warn(call.Pos(), "rewrote strconv.Atof32(_) to strconv.ParseFloat(_, 32) but return value must be converted to float32")
|
||||
case "Atof64":
|
||||
change("ParseFloat")
|
||||
add("64") // bitSize
|
||||
case "AtofN":
|
||||
change("ParseFloat")
|
||||
case "Atoi":
|
||||
// Atoi stayed as a convenience wrapper.
|
||||
case "Atoi64":
|
||||
change("ParseInt")
|
||||
add("10") // base
|
||||
add("64") // bitSize
|
||||
case "Atoui":
|
||||
change("ParseUint")
|
||||
add("10") // base
|
||||
add("0") // bitSize
|
||||
warn(call.Pos(), "rewrote strconv.Atoui(_) to strconv.ParseUint(_, 10, 0) but return value must be converted to uint")
|
||||
case "Atoui64":
|
||||
change("ParseUint")
|
||||
add("10") // base
|
||||
add("64") // bitSize
|
||||
case "Btoa":
|
||||
change("FormatBool")
|
||||
case "Btoi64":
|
||||
change("ParseInt")
|
||||
add("64") // bitSize
|
||||
case "Btoui64":
|
||||
change("ParseUint")
|
||||
add("64") // bitSize
|
||||
case "Ftoa32":
|
||||
change("FormatFloat")
|
||||
call.Args[0] = strconvRewrite("float32", "float64", call.Args[0])
|
||||
add("32") // bitSize
|
||||
case "Ftoa64":
|
||||
change("FormatFloat")
|
||||
add("64") // bitSize
|
||||
case "FtoaN":
|
||||
change("FormatFloat")
|
||||
case "Itoa":
|
||||
// Itoa stayed as a convenience wrapper.
|
||||
case "Itoa64":
|
||||
change("FormatInt")
|
||||
add("10") // base
|
||||
case "Itob":
|
||||
change("FormatInt")
|
||||
call.Args[0] = strconvRewrite("int", "int64", call.Args[0])
|
||||
case "Itob64":
|
||||
change("FormatInt")
|
||||
case "Uitoa":
|
||||
change("FormatUint")
|
||||
call.Args[0] = strconvRewrite("uint", "uint64", call.Args[0])
|
||||
add("10") // base
|
||||
case "Uitoa64":
|
||||
change("FormatUint")
|
||||
add("10") // base
|
||||
case "Uitob":
|
||||
change("FormatUint")
|
||||
call.Args[0] = strconvRewrite("uint", "uint64", call.Args[0])
|
||||
case "Uitob64":
|
||||
change("FormatUint")
|
||||
}
|
||||
})
|
||||
return fixed
|
||||
}
|
||||
|
||||
// rewrite from type t1 to type t2
|
||||
// If the expression x is of the form t1(_), use t2(_). Otherwise use t2(x).
|
||||
func strconvRewrite(t1, t2 string, x ast.Expr) ast.Expr {
|
||||
if call, ok := x.(*ast.CallExpr); ok && isTopName(call.Fun, t1) {
|
||||
call.Fun.(*ast.Ident).Name = t2
|
||||
return x
|
||||
}
|
||||
return &ast.CallExpr{Fun: ast.NewIdent(t2), Args: []ast.Expr{x}}
|
||||
}
|
93
src/cmd/gofix/strconv_test.go
Normal file
93
src/cmd/gofix/strconv_test.go
Normal file
@ -0,0 +1,93 @@
|
||||
// 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(strconvTests, strconvFn)
|
||||
}
|
||||
|
||||
var strconvTests = []testCase{
|
||||
{
|
||||
Name: "strconv.0",
|
||||
In: `package main
|
||||
|
||||
import "strconv"
|
||||
|
||||
func f() {
|
||||
foo.Atob("abc")
|
||||
|
||||
strconv.Atob("true")
|
||||
strconv.Btoa(false)
|
||||
|
||||
strconv.Atof32("1.2")
|
||||
strconv.Atof64("1.2")
|
||||
strconv.AtofN("1.2", 64)
|
||||
strconv.Ftoa32(1.2, 'g', 17)
|
||||
strconv.Ftoa64(1.2, 'g', 17)
|
||||
strconv.FtoaN(1.2, 'g', 17, 64)
|
||||
|
||||
strconv.Atoi("3")
|
||||
strconv.Atoi64("3")
|
||||
strconv.Btoi64("1234", 5)
|
||||
|
||||
strconv.Atoui("3")
|
||||
strconv.Atoui64("3")
|
||||
strconv.Btoui64("1234", 5)
|
||||
|
||||
strconv.Itoa(123)
|
||||
strconv.Itoa64(1234)
|
||||
strconv.Itob(123, 5)
|
||||
strconv.Itob64(1234, 5)
|
||||
|
||||
strconv.Uitoa(123)
|
||||
strconv.Uitoa64(1234)
|
||||
strconv.Uitob(123, 5)
|
||||
strconv.Uitob64(1234, 5)
|
||||
|
||||
strconv.Uitoa(uint(x))
|
||||
strconv.Uitoa(f(x))
|
||||
}
|
||||
`,
|
||||
Out: `package main
|
||||
|
||||
import "strconv"
|
||||
|
||||
func f() {
|
||||
foo.Atob("abc")
|
||||
|
||||
strconv.ParseBool("true")
|
||||
strconv.FormatBool(false)
|
||||
|
||||
strconv.ParseFloat("1.2", 32)
|
||||
strconv.ParseFloat("1.2", 64)
|
||||
strconv.ParseFloat("1.2", 64)
|
||||
strconv.FormatFloat(float64(1.2), 'g', 17, 32)
|
||||
strconv.FormatFloat(1.2, 'g', 17, 64)
|
||||
strconv.FormatFloat(1.2, 'g', 17, 64)
|
||||
|
||||
strconv.Atoi("3")
|
||||
strconv.ParseInt("3", 10, 64)
|
||||
strconv.ParseInt("1234", 5, 64)
|
||||
|
||||
strconv.ParseUint("3", 10, 0)
|
||||
strconv.ParseUint("3", 10, 64)
|
||||
strconv.ParseUint("1234", 5, 64)
|
||||
|
||||
strconv.Itoa(123)
|
||||
strconv.FormatInt(1234, 10)
|
||||
strconv.FormatInt(int64(123), 5)
|
||||
strconv.FormatInt(1234, 5)
|
||||
|
||||
strconv.FormatUint(uint64(123), 10)
|
||||
strconv.FormatUint(1234, 10)
|
||||
strconv.FormatUint(uint64(123), 5)
|
||||
strconv.FormatUint(1234, 5)
|
||||
|
||||
strconv.FormatUint(uint64(x), 10)
|
||||
strconv.FormatUint(uint64(f(x)), 10)
|
||||
}
|
||||
`,
|
||||
},
|
||||
}
|
Loading…
Reference in New Issue
Block a user