| // 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" | |
| ) | |
| func init() { | |
| register(stringssplitFix) | |
| } | |
| var stringssplitFix = fix{ | |
| "stringssplit", | |
| "2011-06-28", | |
| stringssplit, | |
| `Restore strings.Split to its original meaning and add strings.SplitN. Bytes too. | |
| http://codereview.appspot.com/4661051 | |
| `, | |
| } | |
| func stringssplit(f *ast.File) bool { | |
| if !imports(f, "bytes") && !imports(f, "strings") { | |
| return false | |
| } | |
| fixed := false | |
| walk(f, func(n interface{}) { | |
| call, ok := n.(*ast.CallExpr) | |
| // func Split(s, sep string, n int) []string | |
| // func SplitAfter(s, sep string, n int) []string | |
| if !ok || len(call.Args) != 3 { | |
| return | |
| } | |
| // Is this our function? | |
| switch { | |
| case isPkgDot(call.Fun, "bytes", "Split"): | |
| case isPkgDot(call.Fun, "bytes", "SplitAfter"): | |
| case isPkgDot(call.Fun, "strings", "Split"): | |
| case isPkgDot(call.Fun, "strings", "SplitAfter"): | |
| default: | |
| return | |
| } | |
| sel := call.Fun.(*ast.SelectorExpr) | |
| args := call.Args | |
| fixed = true // We're committed. | |
| // Is the last argument -1? If so, drop the arg. | |
| // (Actually we just look for a negative integer literal.) | |
| // Otherwise, Split->SplitN and keep the arg. | |
| final := args[2] | |
| if unary, ok := final.(*ast.UnaryExpr); ok && unary.Op == token.SUB { | |
| if lit, ok := unary.X.(*ast.BasicLit); ok { | |
| // Is it an integer? If so, it's a negative integer and that's what we're after. | |
| if lit.Kind == token.INT { | |
| // drop the last arg. | |
| call.Args = args[0:2] | |
| return | |
| } | |
| } | |
| } | |
| // If not, rename and keep the argument list. | |
| sel.Sel.Name += "N" | |
| }) | |
| return fixed | |
| } |