diff options
Diffstat (limited to 'src/cmd/gofix/template.go')
-rw-r--r-- | src/cmd/gofix/template.go | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/cmd/gofix/template.go b/src/cmd/gofix/template.go new file mode 100644 index 000000000..a3dd1440b --- /dev/null +++ b/src/cmd/gofix/template.go @@ -0,0 +1,111 @@ +// 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 +} |