diff options
Diffstat (limited to 'src/cmd/gofix/url.go')
-rw-r--r-- | src/cmd/gofix/url.go | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/cmd/gofix/url.go b/src/cmd/gofix/url.go new file mode 100644 index 000000000..7135d8edf --- /dev/null +++ b/src/cmd/gofix/url.go @@ -0,0 +1,118 @@ +// 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 ( + "fmt" + "os" + "go/ast" +) + +var _ fmt.Stringer +var _ os.Error + +var urlFix = fix{ + "url", + url, + `Move the URL pieces of package http into a new package, url. + +http://codereview.appspot.com/4893043 +`, +} + +func init() { + register(urlFix) +} + +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. + var skip interface{} + urlWalk := func(n interface{}) { + if n == skip { + skip = nil + return + } + // 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 + } + // U{url: ...} is likely a struct field. + if kv, ok := n.(*ast.KeyValueExpr); ok { + if ident, ok := kv.Key.(*ast.Ident); ok && ident.Name == "url" { + skip = ident + } + } + } + + // Fix up URL code and add import, at most once. + fix := func() { + if fixed { + return + } + walkBeforeAfter(f, urlWalk, nop) + addImport(f, "url") + 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 +} |