blob: 0e2190b1f4c95e3dfb5456f141b3897d8a5ae377 [file] [log] [blame]
// 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"
"go/token"
)
var procattrFix = fix{
"procattr",
procattr,
`Adapt calls to os.StartProcess to use new ProcAttr type.
http://codereview.appspot.com/4253052
`,
}
func init() {
register(procattrFix)
}
func procattr(f *ast.File) bool {
if !imports(f, "os") && !imports(f, "syscall") {
return false
}
fixed := false
walk(f, func(n interface{}) {
call, ok := n.(*ast.CallExpr)
if !ok || len(call.Args) != 5 {
return
}
var pkg string
if isPkgDot(call.Fun, "os", "StartProcess") {
pkg = "os"
} else if isPkgDot(call.Fun, "syscall", "StartProcess") {
pkg = "syscall"
} else {
return
}
// os.StartProcess(a, b, c, d, e) -> os.StartProcess(a, b, &os.ProcAttr{Env: c, Dir: d, Files: e})
lit := &ast.CompositeLit{Type: ast.NewIdent(pkg + ".ProcAttr")}
env, dir, files := call.Args[2], call.Args[3], call.Args[4]
if !isName(env, "nil") && !isCall(env, "os", "Environ") {
lit.Elts = append(lit.Elts, &ast.KeyValueExpr{Key: ast.NewIdent("Env"), Value: env})
}
if !isEmptyString(dir) {
lit.Elts = append(lit.Elts, &ast.KeyValueExpr{Key: ast.NewIdent("Dir"), Value: dir})
}
if !isName(files, "nil") {
lit.Elts = append(lit.Elts, &ast.KeyValueExpr{Key: ast.NewIdent("Files"), Value: files})
}
call.Args[2] = &ast.UnaryExpr{Op: token.AND, X: lit}
call.Args = call.Args[:3]
fixed = true
})
return fixed
}