1
0
mirror of https://github.com/golang/go synced 2024-11-25 10:57:58 -07:00

fix: add fix for crypto type change

Fixes #2905.

R=golang-dev, bradfitz, r
CC=golang-dev
https://golang.org/cl/5645088
This commit is contained in:
Russ Cox 2012-02-13 16:01:34 -05:00
parent 1f2445d27b
commit d3f9f21fdf
3 changed files with 180 additions and 8 deletions

36
src/cmd/fix/cryptotype.go Normal file
View File

@ -0,0 +1,36 @@
// Copyright 2012 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
var cryptotypeFix = fix{
"cryptotype",
"2012-02-12",
renameFix(cryptotypeReplace),
`Rewrite uses of concrete cipher types to refer to the generic cipher.Block.
http://codereview.appspot.com/5625045/
`,
}
var cryptotypeReplace = []rename{
{
OldImport: "crypto/aes",
NewImport: "crypto/cipher",
Old: "*aes.Cipher",
New: "cipher.Block",
},
{
OldImport: "crypto/des",
NewImport: "crypto/cipher",
Old: "*des.Cipher",
New: "cipher.Block",
},
{
OldImport: "crypto/des",
NewImport: "crypto/cipher",
Old: "*des.TripleDESCipher",
New: "cipher.Block",
},
}

View File

@ -0,0 +1,43 @@
// Copyright 2012 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
func init() {
addTestCases(cryptotypeTests, cryptotypeFix.f)
}
var cryptotypeTests = []testCase{
{
Name: "cryptotype.0",
In: `package main
import (
"crypto/aes"
"crypto/des"
)
var (
_ *aes.Cipher
_ *des.Cipher
_ *des.TripleDESCipher
_ = aes.New()
)
`,
Out: `package main
import (
"crypto/aes"
"crypto/cipher"
)
var (
_ cipher.Block
_ cipher.Block
_ cipher.Block
_ = aes.New()
)
`,
},
}

View File

@ -4,14 +4,6 @@
package main
/*
receiver named error
function named error
method on error
exiterror
slice of named type (go/scanner)
*/
import (
"fmt"
"go/ast"
@ -19,6 +11,7 @@ import (
"go/token"
"os"
"path"
"reflect"
"strconv"
"strings"
)
@ -750,5 +743,105 @@ func expr(s string) ast.Expr {
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
}