| // 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": &Type{ | 
 | 			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": &Type{ | 
 | 			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 | 
 | } |