aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/fix/fix.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/fix/fix.go')
-rw-r--r--src/cmd/fix/fix.go292
1 files changed, 0 insertions, 292 deletions
diff --git a/src/cmd/fix/fix.go b/src/cmd/fix/fix.go
index 2c64e9b414..b49db37571 100644
--- a/src/cmd/fix/fix.go
+++ b/src/cmd/fix/fix.go
@@ -7,13 +7,9 @@ package main
import (
"fmt"
"go/ast"
- "go/parser"
"go/token"
- "os"
"path"
- "reflect"
"strconv"
- "strings"
)
type fix struct {
@@ -323,160 +319,12 @@ func declImports(gen *ast.GenDecl, path string) bool {
return false
}
-// isPkgDot reports whether t is the expression "pkg.name"
-// where pkg is an imported identifier.
-func isPkgDot(t ast.Expr, pkg, name string) bool {
- sel, ok := t.(*ast.SelectorExpr)
- return ok && isTopName(sel.X, pkg) && sel.Sel.String() == name
-}
-
-// isPtrPkgDot reports whether f is the expression "*pkg.name"
-// where pkg is an imported identifier.
-func isPtrPkgDot(t ast.Expr, pkg, name string) bool {
- ptr, ok := t.(*ast.StarExpr)
- return ok && isPkgDot(ptr.X, pkg, name)
-}
-
// isTopName reports whether n is a top-level unresolved identifier with the given name.
func isTopName(n ast.Expr, name string) bool {
id, ok := n.(*ast.Ident)
return ok && id.Name == name && id.Obj == nil
}
-// isName reports whether n is an identifier with the given name.
-func isName(n ast.Expr, name string) bool {
- id, ok := n.(*ast.Ident)
- return ok && id.String() == name
-}
-
-// isCall reports whether t is a call to pkg.name.
-func isCall(t ast.Expr, pkg, name string) bool {
- call, ok := t.(*ast.CallExpr)
- return ok && isPkgDot(call.Fun, pkg, name)
-}
-
-// If n is an *ast.Ident, isIdent returns it; otherwise isIdent returns nil.
-func isIdent(n interface{}) *ast.Ident {
- id, _ := n.(*ast.Ident)
- return id
-}
-
-// refersTo reports whether n is a reference to the same object as x.
-func refersTo(n ast.Node, x *ast.Ident) bool {
- id, ok := n.(*ast.Ident)
- // The test of id.Name == x.Name handles top-level unresolved
- // identifiers, which all have Obj == nil.
- return ok && id.Obj == x.Obj && id.Name == x.Name
-}
-
-// isBlank reports whether n is the blank identifier.
-func isBlank(n ast.Expr) bool {
- return isName(n, "_")
-}
-
-// isEmptyString reports whether n is an empty string literal.
-func isEmptyString(n ast.Expr) bool {
- lit, ok := n.(*ast.BasicLit)
- return ok && lit.Kind == token.STRING && len(lit.Value) == 2
-}
-
-func warn(pos token.Pos, msg string, args ...interface{}) {
- if pos.IsValid() {
- msg = "%s: " + msg
- arg1 := []interface{}{fset.Position(pos).String()}
- args = append(arg1, args...)
- }
- fmt.Fprintf(os.Stderr, msg+"\n", args...)
-}
-
-// countUses returns the number of uses of the identifier x in scope.
-func countUses(x *ast.Ident, scope []ast.Stmt) int {
- count := 0
- ff := func(n interface{}) {
- if n, ok := n.(ast.Node); ok && refersTo(n, x) {
- count++
- }
- }
- for _, n := range scope {
- walk(n, ff)
- }
- return count
-}
-
-// rewriteUses replaces all uses of the identifier x and !x in scope
-// with f(x.Pos()) and fnot(x.Pos()).
-func rewriteUses(x *ast.Ident, f, fnot func(token.Pos) ast.Expr, scope []ast.Stmt) {
- var lastF ast.Expr
- ff := func(n interface{}) {
- ptr, ok := n.(*ast.Expr)
- if !ok {
- return
- }
- nn := *ptr
-
- // The child node was just walked and possibly replaced.
- // If it was replaced and this is a negation, replace with fnot(p).
- not, ok := nn.(*ast.UnaryExpr)
- if ok && not.Op == token.NOT && not.X == lastF {
- *ptr = fnot(nn.Pos())
- return
- }
- if refersTo(nn, x) {
- lastF = f(nn.Pos())
- *ptr = lastF
- }
- }
- for _, n := range scope {
- walk(n, ff)
- }
-}
-
-// assignsTo reports whether any of the code in scope assigns to or takes the address of x.
-func assignsTo(x *ast.Ident, scope []ast.Stmt) bool {
- assigned := false
- ff := func(n interface{}) {
- if assigned {
- return
- }
- switch n := n.(type) {
- case *ast.UnaryExpr:
- // use of &x
- if n.Op == token.AND && refersTo(n.X, x) {
- assigned = true
- return
- }
- case *ast.AssignStmt:
- for _, l := range n.Lhs {
- if refersTo(l, x) {
- assigned = true
- return
- }
- }
- }
- }
- for _, n := range scope {
- if assigned {
- break
- }
- walk(n, ff)
- }
- return assigned
-}
-
-// newPkgDot returns an ast.Expr referring to "pkg.name" at position pos.
-func newPkgDot(pos token.Pos, pkg, name string) ast.Expr {
- return &ast.SelectorExpr{
- X: &ast.Ident{
- NamePos: pos,
- Name: pkg,
- },
- Sel: &ast.Ident{
- NamePos: pos,
- Name: name,
- },
- }
-}
-
// renameTop renames all references to the top-level name old.
// It reports whether it makes any changes.
func renameTop(f *ast.File, old, new string) bool {
@@ -707,143 +555,3 @@ func rewriteImport(f *ast.File, oldPath, newPath string) (rewrote bool) {
}
return
}
-
-func usesImport(f *ast.File, path string) (used bool) {
- spec := importSpec(f, path)
- if spec == nil {
- return
- }
-
- name := spec.Name.String()
- switch name {
- case "<nil>":
- // If the package name is not explicitly specified,
- // make an educated guess. This is not guaranteed to be correct.
- lastSlash := strings.LastIndex(path, "/")
- if lastSlash == -1 {
- name = path
- } else {
- name = path[lastSlash+1:]
- }
- case "_", ".":
- // Not sure if this import is used - err on the side of caution.
- return true
- }
-
- walk(f, func(n interface{}) {
- sel, ok := n.(*ast.SelectorExpr)
- if ok && isTopName(sel.X, name) {
- used = true
- }
- })
-
- return
-}
-
-func expr(s string) ast.Expr {
- x, err := parser.ParseExpr(s)
- if err != nil {
- panic("parsing " + s + ": " + err.Error())
- }
- // Remove position information to avoid spurious newlines.
- killPos(reflect.ValueOf(x))
- return x
-}
-
-var posType = reflect.TypeOf(token.Pos(0))
-
-func killPos(v reflect.Value) {
- switch v.Kind() {
- case reflect.Ptr, reflect.Interface:
- if !v.IsNil() {
- killPos(v.Elem())
- }
- case reflect.Slice:
- n := v.Len()
- for i := 0; i < n; i++ {
- killPos(v.Index(i))
- }
- case reflect.Struct:
- n := v.NumField()
- for i := 0; i < n; i++ {
- f := v.Field(i)
- if f.Type() == posType {
- f.SetInt(0)
- continue
- }
- killPos(f)
- }
- }
-}
-
-// A Rename describes a single renaming.
-type rename struct {
- OldImport string // only apply rename if this import is present
- NewImport string // add this import during rewrite
- Old string // old name: p.T or *p.T
- New string // new name: p.T or *p.T
-}
-
-func renameFix(tab []rename) func(*ast.File) bool {
- return func(f *ast.File) bool {
- return renameFixTab(f, tab)
- }
-}
-
-func parseName(s string) (ptr bool, pkg, nam string) {
- i := strings.Index(s, ".")
- if i < 0 {
- panic("parseName: invalid name " + s)
- }
- if strings.HasPrefix(s, "*") {
- ptr = true
- s = s[1:]
- i--
- }
- pkg = s[:i]
- nam = s[i+1:]
- return
-}
-
-func renameFixTab(f *ast.File, tab []rename) bool {
- fixed := false
- added := map[string]bool{}
- check := map[string]bool{}
- for _, t := range tab {
- if !imports(f, t.OldImport) {
- continue
- }
- optr, opkg, onam := parseName(t.Old)
- walk(f, func(n interface{}) {
- np, ok := n.(*ast.Expr)
- if !ok {
- return
- }
- x := *np
- if optr {
- p, ok := x.(*ast.StarExpr)
- if !ok {
- return
- }
- x = p.X
- }
- if !isPkgDot(x, opkg, onam) {
- return
- }
- if t.NewImport != "" && !added[t.NewImport] {
- addImport(f, t.NewImport)
- added[t.NewImport] = true
- }
- *np = expr(t.New)
- check[t.OldImport] = true
- fixed = true
- })
- }
-
- for ipath := range check {
- if !usesImport(f, ipath) {
- deleteImport(f, ipath)
- }
- }
- return fixed
-}