// 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" ) func init() { register(procattrFix) } var procattrFix = fix{ "procattr", "2011-03-15", procattr, `Adapt calls to os.StartProcess to use new ProcAttr type. http://codereview.appspot.com/4253052 `, } 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 }