blob: f701f62f0aeb467134941e523743479b85beb452 [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"
"strings"
)
func init() {
register(go1pkgrenameFix)
}
var go1pkgrenameFix = fix{
"go1rename",
"2011-11-08",
go1pkgrename,
`Rewrite imports for packages moved during transition to Go 1.
http://codereview.appspot.com/5316078
`,
}
var go1PackageRenames = []struct{ old, new string }{
{"asn1", "encoding/asn1"},
{"big", "math/big"},
{"cmath", "math/cmplx"},
{"csv", "encoding/csv"},
{"exec", "os/exec"},
{"exp/template/html", "html/template"},
{"gob", "encoding/gob"},
{"http", "net/http"},
{"http/cgi", "net/http/cgi"},
{"http/fcgi", "net/http/fcgi"},
{"http/httptest", "net/http/httptest"},
{"http/pprof", "net/http/pprof"},
{"json", "encoding/json"},
{"mail", "net/mail"},
{"rpc", "net/rpc"},
{"rpc/jsonrpc", "net/rpc/jsonrpc"},
{"scanner", "text/scanner"},
{"smtp", "net/smtp"},
{"syslog", "log/syslog"},
{"tabwriter", "text/tabwriter"},
{"template", "text/template"},
{"template/parse", "text/template/parse"},
{"rand", "math/rand"},
{"url", "net/url"},
{"utf16", "unicode/utf16"},
{"utf8", "unicode/utf8"},
{"xml", "encoding/xml"},
// go.crypto sub-repository
{"crypto/bcrypt", "code.google.com/p/go.crypto/bcrypt"},
{"crypto/blowfish", "code.google.com/p/go.crypto/blowfish"},
{"crypto/cast5", "code.google.com/p/go.crypto/cast5"},
{"crypto/md4", "code.google.com/p/go.crypto/md4"},
{"crypto/ocsp", "code.google.com/p/go.crypto/ocsp"},
{"crypto/openpgp", "code.google.com/p/go.crypto/openpgp"},
{"crypto/openpgp/armor", "code.google.com/p/go.crypto/openpgp/armor"},
{"crypto/openpgp/elgamal", "code.google.com/p/go.crypto/openpgp/elgamal"},
{"crypto/openpgp/errors", "code.google.com/p/go.crypto/openpgp/errors"},
{"crypto/openpgp/packet", "code.google.com/p/go.crypto/openpgp/packet"},
{"crypto/openpgp/s2k", "code.google.com/p/go.crypto/openpgp/s2k"},
{"crypto/ripemd160", "code.google.com/p/go.crypto/ripemd160"},
{"crypto/twofish", "code.google.com/p/go.crypto/twofish"},
{"crypto/xtea", "code.google.com/p/go.crypto/xtea"},
{"exp/ssh", "code.google.com/p/go.crypto/ssh"},
// go.image sub-repository
{"image/bmp", "code.google.com/p/go.image/bmp"},
{"image/tiff", "code.google.com/p/go.image/tiff"},
// go.net sub-repository
{"net/dict", "code.google.com/p/go.net/dict"},
{"net/websocket", "code.google.com/p/go.net/websocket"},
{"exp/spdy", "code.google.com/p/go.net/spdy"},
{"http/spdy", "code.google.com/p/go.net/spdy"},
// go.codereview sub-repository
{"encoding/git85", "code.google.com/p/go.codereview/git85"},
{"patch", "code.google.com/p/go.codereview/patch"},
// exp
{"ebnf", "exp/ebnf"},
{"go/types", "exp/types"},
// deleted
{"container/vector", ""},
{"exp/datafmt", ""},
{"go/typechecker", ""},
{"old/netchan", ""},
{"old/regexp", ""},
{"old/template", ""},
{"try", ""},
}
var go1PackageNameRenames = []struct{ newPath, old, new string }{
{"html/template", "html", "template"},
{"math/cmplx", "cmath", "cmplx"},
}
func go1pkgrename(f *ast.File) bool {
fixed := false
// First update the imports.
for _, rename := range go1PackageRenames {
spec := importSpec(f, rename.old)
if spec == nil {
continue
}
if rename.new == "" {
warn(spec.Pos(), "package %q has been deleted in Go 1", rename.old)
continue
}
if rewriteImport(f, rename.old, rename.new) {
fixed = true
}
if strings.HasPrefix(rename.new, "exp/") {
warn(spec.Pos(), "package %q is not part of Go 1", rename.new)
}
}
if !fixed {
return false
}
// Now update the package names used by importers.
for _, rename := range go1PackageNameRenames {
// These are rare packages, so do the import test before walking.
if imports(f, rename.newPath) {
walk(f, func(n interface{}) {
if sel, ok := n.(*ast.SelectorExpr); ok {
if isTopName(sel.X, rename.old) {
// We know Sel.X is an Ident.
sel.X.(*ast.Ident).Name = rename.new
return
}
}
})
}
}
return fixed
}