diff options
Diffstat (limited to 'src/cmd/gofix/oserrorstring.go')
-rw-r--r-- | src/cmd/gofix/oserrorstring.go | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/cmd/gofix/oserrorstring.go b/src/cmd/gofix/oserrorstring.go new file mode 100644 index 000000000..5e61ab952 --- /dev/null +++ b/src/cmd/gofix/oserrorstring.go @@ -0,0 +1,75 @@ +// 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 oserrorstringFix = fix{ + "oserrorstring", + oserrorstring, + `Replace os.ErrorString() conversions with calls to os.NewError(). + +http://codereview.appspot.com/4607052 +`, +} + +func init() { + register(oserrorstringFix) +} + +func oserrorstring(f *ast.File) bool { + if !imports(f, "os") { + return false + } + + fixed := false + walk(f, func(n interface{}) { + // The conversion os.ErrorString(x) looks like a call + // of os.ErrorString with one argument. + if call := callExpr(n, "os", "ErrorString"); call != nil { + // os.ErrorString(args) -> os.NewError(args) + call.Fun.(*ast.SelectorExpr).Sel.Name = "NewError" + // os.ErrorString(args) -> os.NewError(args) + call.Fun.(*ast.SelectorExpr).Sel.Name = "NewError" + fixed = true + return + } + + // Remove os.Error type from variable declarations initialized + // with an os.NewError. + // (An *ast.ValueSpec may also be used in a const declaration + // but those won't be initialized with a call to os.NewError.) + if spec, ok := n.(*ast.ValueSpec); ok && + len(spec.Names) == 1 && + isPkgDot(spec.Type, "os", "Error") && + len(spec.Values) == 1 && + callExpr(spec.Values[0], "os", "NewError") != nil { + // var name os.Error = os.NewError(x) -> + // var name = os.NewError(x) + spec.Type = nil + fixed = true + return + } + + // Other occurrences of os.ErrorString are not fixed + // but they are rare. + + }) + return fixed +} + + +// callExpr returns the call expression if x is a call to pkg.name with one argument; +// otherwise it returns nil. +func callExpr(x interface{}, pkg, name string) *ast.CallExpr { + if call, ok := x.(*ast.CallExpr); ok && + len(call.Args) == 1 && + isPkgDot(call.Fun, pkg, name) { + return call + } + return nil +} |