| // 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 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 |
| } |