blob: 49aac739b3586ca7e77d92ee6098ad9a55a39f8a [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"
func init() {
register(urlFix)
}
var urlFix = fix{
"url",
"2011-08-17",
url,
`Move the URL pieces of package http into a new package, url.
http://codereview.appspot.com/4893043
`,
}
var urlRenames = []struct{ in, out string }{
{"URL", "URL"},
{"ParseURL", "Parse"},
{"ParseURLReference", "ParseWithReference"},
{"ParseQuery", "ParseQuery"},
{"Values", "Values"},
{"URLEscape", "QueryEscape"},
{"URLUnescape", "QueryUnescape"},
{"URLError", "Error"},
{"URLEscapeError", "EscapeError"},
}
func url(f *ast.File) bool {
if imports(f, "url") || !imports(f, "http") {
return false
}
fixed := false
// Update URL code.
urlWalk := func(n interface{}) {
// Is it an identifier?
if ident, ok := n.(*ast.Ident); ok && ident.Name == "url" {
ident.Name = "url_"
return
}
// Parameter and result names.
if fn, ok := n.(*ast.FuncType); ok {
fixed = urlDoFields(fn.Params) || fixed
fixed = urlDoFields(fn.Results) || fixed
}
}
// Fix up URL code and add import, at most once.
fix := func() {
if fixed {
return
}
addImport(f, "url")
walkBeforeAfter(f, urlWalk, nop)
fixed = true
}
walk(f, func(n interface{}) {
// Rename functions and methods.
if expr, ok := n.(ast.Expr); ok {
for _, s := range urlRenames {
if isPkgDot(expr, "http", s.in) {
fix()
expr.(*ast.SelectorExpr).X.(*ast.Ident).Name = "url"
expr.(*ast.SelectorExpr).Sel.Name = s.out
return
}
}
}
})
// Remove the http import if no longer needed.
if fixed && !usesImport(f, "http") {
deleteImport(f, "http")
}
return fixed
}
func urlDoFields(list *ast.FieldList) (fixed bool) {
if list == nil {
return
}
for _, field := range list.List {
for _, ident := range field.Names {
if ident.Name == "url" {
fixed = true
ident.Name = "url_"
}
}
}
return
}