summaryrefslogtreecommitdiff
path: root/src/cmd/fix/timefileinfo.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/fix/timefileinfo.go')
-rw-r--r--src/cmd/fix/timefileinfo.go298
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
-}