| // 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 | |
| } |