diff options
Diffstat (limited to 'src/cmd/fix/timefileinfo.go')
-rw-r--r-- | src/cmd/fix/timefileinfo.go | 298 |
1 files changed, 0 insertions, 298 deletions
diff --git a/src/cmd/fix/timefileinfo.go b/src/cmd/fix/timefileinfo.go deleted file mode 100644 index b2ea23d8f..000000000 --- a/src/cmd/fix/timefileinfo.go +++ /dev/null @@ -1,298 +0,0 @@ -// 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" - "go/token" - "strings" -) - -func init() { - register(timefileinfoFix) -} - -var timefileinfoFix = fix{ - "time+fileinfo", - "2011-11-29", - timefileinfo, - `Rewrite for new time and os.FileInfo APIs. - -This fix applies some of the more mechanical changes, -but most code will still need manual cleanup. - -http://codereview.appspot.com/5392041 -http://codereview.appspot.com/5416060 -`, -} - -var timefileinfoTypeConfig = &TypeConfig{ - Type: map[string]*Type{ - "os.File": { - Method: map[string]string{ - "Readdir": "func() []*os.FileInfo", - "Stat": "func() (*os.FileInfo, error)", - }, - }, - "time.Time": { - Method: map[string]string{ - "Seconds": "time.raw", - "Nanoseconds": "time.raw", - }, - }, - }, - Func: map[string]string{ - "ioutil.ReadDir": "([]*os.FileInfo, error)", - "os.Stat": "(*os.FileInfo, error)", - "os.Lstat": "(*os.FileInfo, error)", - "time.LocalTime": "*time.Time", - "time.UTC": "*time.Time", - "time.SecondsToLocalTime": "*time.Time", - "time.SecondsToUTC": "*time.Time", - "time.NanosecondsToLocalTime": "*time.Time", - "time.NanosecondsToUTC": "*time.Time", - "time.Parse": "(*time.Time, error)", - "time.Nanoseconds": "time.raw", - "time.Seconds": "time.raw", - }, -} - -// timefileinfoIsOld reports whether f has evidence of being -// "old code", from before the API changes. Evidence means: -// -// a mention of *os.FileInfo (the pointer) -// a mention of *time.Time (the pointer) -// a mention of old functions from package time -// an attempt to call time.UTC -// -func timefileinfoIsOld(f *ast.File, typeof map[interface{}]string) bool { - old := false - - // called records the expressions that appear as - // the function part of a function call, so that - // we can distinguish a ref to the possibly new time.UTC - // from the definitely old time.UTC() function call. - called := make(map[interface{}]bool) - - before := func(n interface{}) { - if old { - return - } - if star, ok := n.(*ast.StarExpr); ok { - if isPkgDot(star.X, "os", "FileInfo") || isPkgDot(star.X, "time", "Time") { - old = true - return - } - } - if sel, ok := n.(*ast.SelectorExpr); ok { - if isTopName(sel.X, "time") { - if timefileinfoOldTimeFunc[sel.Sel.Name] { - old = true - return - } - } - if typeof[sel.X] == "os.FileInfo" || typeof[sel.X] == "*os.FileInfo" { - switch sel.Sel.Name { - case "Mtime_ns", "IsDirectory", "IsRegular": - old = true - return - case "Name", "Mode", "Size": - if !called[sel] { - old = true - return - } - } - } - } - call, ok := n.(*ast.CallExpr) - if ok && isPkgDot(call.Fun, "time", "UTC") { - old = true - return - } - if ok { - called[call.Fun] = true - } - } - walkBeforeAfter(f, before, nop) - return old -} - -var timefileinfoOldTimeFunc = map[string]bool{ - "LocalTime": true, - "SecondsToLocalTime": true, - "SecondsToUTC": true, - "NanosecondsToLocalTime": true, - "NanosecondsToUTC": true, - "Seconds": true, - "Nanoseconds": true, -} - -var isTimeNow = map[string]bool{ - "LocalTime": true, - "UTC": true, - "Seconds": true, - "Nanoseconds": true, -} - -func timefileinfo(f *ast.File) bool { - if !imports(f, "os") && !imports(f, "time") && !imports(f, "io/ioutil") { - return false - } - - typeof, _ := typecheck(timefileinfoTypeConfig, f) - - if !timefileinfoIsOld(f, typeof) { - return false - } - - fixed := false - walk(f, func(n interface{}) { - p, ok := n.(*ast.Expr) - if !ok { - return - } - nn := *p - - // Rewrite *os.FileInfo and *time.Time to drop the pointer. - if star, ok := nn.(*ast.StarExpr); ok { - if isPkgDot(star.X, "os", "FileInfo") || isPkgDot(star.X, "time", "Time") { - fixed = true - *p = star.X - return - } - } - - // Rewrite old time API calls to new calls. - // The code will still not compile after this edit, - // but the compiler will catch that, and the replacement - // code will be the correct functions to use in the new API. - if sel, ok := nn.(*ast.SelectorExpr); ok && isTopName(sel.X, "time") { - fn := sel.Sel.Name - if fn == "LocalTime" || fn == "Seconds" || fn == "Nanoseconds" { - fixed = true - sel.Sel.Name = "Now" - return - } - } - - if call, ok := nn.(*ast.CallExpr); ok { - if sel, ok := call.Fun.(*ast.SelectorExpr); ok { - // Rewrite time.UTC but only when called (there's a new time.UTC var now). - if isPkgDot(sel, "time", "UTC") { - fixed = true - sel.Sel.Name = "Now" - // rewrite time.Now() into time.Now().UTC() - *p = &ast.CallExpr{ - Fun: &ast.SelectorExpr{ - X: call, - Sel: ast.NewIdent("UTC"), - }, - } - return - } - - // Rewrite conversions. - if ok && isTopName(sel.X, "time") && len(call.Args) == 1 { - fn := sel.Sel.Name - switch fn { - case "SecondsToLocalTime", "SecondsToUTC", - "NanosecondsToLocalTime", "NanosecondsToUTC": - fixed = true - sel.Sel.Name = "Unix" - call.Args = append(call.Args, nil) - if strings.HasPrefix(fn, "Seconds") { - // Unix(sec, 0) - call.Args[1] = ast.NewIdent("0") - } else { - // Unix(0, nsec) - call.Args[1] = call.Args[0] - call.Args[0] = ast.NewIdent("0") - } - if strings.HasSuffix(fn, "ToUTC") { - // rewrite call into call.UTC() - *p = &ast.CallExpr{ - Fun: &ast.SelectorExpr{ - X: call, - Sel: ast.NewIdent("UTC"), - }, - } - } - return - } - } - - // Rewrite method calls. - switch typeof[sel.X] { - case "*time.Time", "time.Time": - switch sel.Sel.Name { - case "Seconds": - fixed = true - sel.Sel.Name = "Unix" - return - case "Nanoseconds": - fixed = true - sel.Sel.Name = "UnixNano" - return - } - - case "*os.FileInfo", "os.FileInfo": - switch sel.Sel.Name { - case "IsDirectory": - fixed = true - sel.Sel.Name = "IsDir" - return - case "IsRegular": - fixed = true - sel.Sel.Name = "IsDir" - *p = &ast.UnaryExpr{ - Op: token.NOT, - X: call, - } - return - } - } - } - } - - // Rewrite subtraction of two times. - // Cannot handle +=/-=. - if bin, ok := nn.(*ast.BinaryExpr); ok && - bin.Op == token.SUB && - (typeof[bin.X] == "time.raw" || typeof[bin.Y] == "time.raw") { - fixed = true - *p = &ast.CallExpr{ - Fun: &ast.SelectorExpr{ - X: bin.X, - Sel: ast.NewIdent("Sub"), - }, - Args: []ast.Expr{bin.Y}, - } - } - - // Rewrite field references for os.FileInfo. - if sel, ok := nn.(*ast.SelectorExpr); ok { - if typ := typeof[sel.X]; typ == "*os.FileInfo" || typ == "os.FileInfo" { - addCall := false - switch sel.Sel.Name { - case "Name", "Size", "Mode": - fixed = true - addCall = true - case "Mtime_ns": - fixed = true - sel.Sel.Name = "ModTime" - addCall = true - } - if addCall { - *p = &ast.CallExpr{ - Fun: sel, - } - return - } - } - } - }) - - return true -} |