| // 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(templateFix) |
| } |
| |
| var templateFix = fix{ |
| "template", |
| "2011-11-22", |
| template, |
| `Rewrite calls to template.ParseFile to template.ParseFiles |
| |
| http://codereview.appspot.com/5433048 |
| `, |
| } |
| |
| var templateSetGlobals = []string{ |
| "ParseSetFiles", |
| "ParseSetGlob", |
| "ParseTemplateFiles", |
| "ParseTemplateGlob", |
| "Set", |
| "SetMust", |
| } |
| |
| var templateSetMethods = []string{ |
| "ParseSetFiles", |
| "ParseSetGlob", |
| "ParseTemplateFiles", |
| "ParseTemplateGlob", |
| } |
| |
| var templateTypeConfig = &TypeConfig{ |
| Type: map[string]*Type{ |
| "template.Template": { |
| Method: map[string]string{ |
| "Funcs": "func() *template.Template", |
| "Delims": "func() *template.Template", |
| "Parse": "func() (*template.Template, error)", |
| "ParseFile": "func() (*template.Template, error)", |
| "ParseInSet": "func() (*template.Template, error)", |
| }, |
| }, |
| "template.Set": { |
| Method: map[string]string{ |
| "ParseSetFiles": "func() (*template.Set, error)", |
| "ParseSetGlob": "func() (*template.Set, error)", |
| "ParseTemplateFiles": "func() (*template.Set, error)", |
| "ParseTemplateGlob": "func() (*template.Set, error)", |
| }, |
| }, |
| }, |
| |
| Func: map[string]string{ |
| "template.New": "*template.Template", |
| "template.Must": "(*template.Template, error)", |
| "template.SetMust": "(*template.Set, error)", |
| }, |
| } |
| |
| func template(f *ast.File) bool { |
| if !imports(f, "text/template") && !imports(f, "html/template") { |
| return false |
| } |
| |
| fixed := false |
| |
| typeof, _ := typecheck(templateTypeConfig, f) |
| |
| // Now update the names used by importers. |
| walk(f, func(n interface{}) { |
| if sel, ok := n.(*ast.SelectorExpr); ok { |
| // Reference to top-level function ParseFile. |
| if isPkgDot(sel, "template", "ParseFile") { |
| sel.Sel.Name = "ParseFiles" |
| fixed = true |
| return |
| } |
| // Reference to ParseFiles method. |
| if typeof[sel.X] == "*template.Template" && sel.Sel.Name == "ParseFile" { |
| sel.Sel.Name = "ParseFiles" |
| fixed = true |
| return |
| } |
| // The Set type and its functions are now gone. |
| for _, name := range templateSetGlobals { |
| if isPkgDot(sel, "template", name) { |
| warn(sel.Pos(), "reference to template.%s must be fixed manually", name) |
| return |
| } |
| } |
| // The methods of Set are now gone. |
| for _, name := range templateSetMethods { |
| if typeof[sel.X] == "*template.Set" && sel.Sel.Name == name { |
| warn(sel.Pos(), "reference to template.*Set.%s must be fixed manually", name) |
| return |
| } |
| } |
| } |
| }) |
| |
| return fixed |
| } |