cmd/gofmt: handle ... in rewrite of calls

Fixes #5059.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/8284043
This commit is contained in:
Robert Griesemer 2013-04-02 13:18:32 -07:00
parent c5d4196834
commit 9115e411f5
6 changed files with 73 additions and 1 deletions

View File

@ -82,6 +82,8 @@ var tests = []struct {
{"testdata/rewrite3.input", "-r=x->x"},
{"testdata/rewrite4.input", "-r=(x)->x"},
{"testdata/rewrite5.input", "-r=x+x->2*x"},
{"testdata/rewrite6.input", "-r=fun(x)->Fun(x)"},
{"testdata/rewrite7.input", "-r=fun(x...)->Fun(x)"},
{"testdata/stdin*.input", "-stdin"},
{"testdata/comments.input", ""},
{"testdata/import.input", ""},

View File

@ -107,6 +107,7 @@ var (
identType = reflect.TypeOf((*ast.Ident)(nil))
objectPtrType = reflect.TypeOf((*ast.Object)(nil))
positionType = reflect.TypeOf(token.NoPos)
callExprType = reflect.TypeOf((*ast.CallExpr)(nil))
scopePtrType = reflect.TypeOf((*ast.Scope)(nil))
)
@ -192,8 +193,17 @@ func match(m map[string]reflect.Value, pattern, val reflect.Value) bool {
v := val.Interface().(*ast.Ident)
return p == nil && v == nil || p != nil && v != nil && p.Name == v.Name
case objectPtrType, positionType:
// object pointers and token positions don't need to match
// object pointers and token positions always match
return true
case callExprType:
// For calls, the Ellipsis fields (token.Position) must
// match since that is how f(x) and f(x...) are different.
// Check them here but fall through for the remaining fields.
p := pattern.Interface().(*ast.CallExpr)
v := val.Interface().(*ast.CallExpr)
if p.Ellipsis.IsValid() != v.Ellipsis.IsValid() {
return false
}
}
p := reflect.Indirect(pattern)

15
src/cmd/gofmt/testdata/rewrite6.golden vendored Normal file
View File

@ -0,0 +1,15 @@
// Copyright 2013 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.
// Rewriting of calls must take the ... (ellipsis)
// attribute for the last argument into account.
package p
func fun(x []int) {}
func g(x []int) {
Fun(x) // -r='fun(x)->Fun(x)' should rewrite this to Fun(x)
fun(x...) // -r='fun(x)->Fun(x)' should not rewrite this
}

15
src/cmd/gofmt/testdata/rewrite6.input vendored Normal file
View File

@ -0,0 +1,15 @@
// Copyright 2013 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.
// Rewriting of calls must take the ... (ellipsis)
// attribute for the last argument into account.
package p
func fun(x []int) {}
func g(x []int) {
fun(x) // -r='fun(x)->Fun(x)' should rewrite this to Fun(x)
fun(x...) // -r='fun(x)->Fun(x)' should not rewrite this
}

15
src/cmd/gofmt/testdata/rewrite7.golden vendored Normal file
View File

@ -0,0 +1,15 @@
// Copyright 2013 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.
// Rewriting of calls must take the ... (ellipsis)
// attribute for the last argument into account.
package p
func fun(x []int) {}
func g(x []int) {
fun(x) // -r='fun(x...)->Fun(x)' should not rewrite this
Fun(x) // -r='fun(x...)->Fun(x)' should rewrite this to Fun(x)
}

15
src/cmd/gofmt/testdata/rewrite7.input vendored Normal file
View File

@ -0,0 +1,15 @@
// Copyright 2013 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.
// Rewriting of calls must take the ... (ellipsis)
// attribute for the last argument into account.
package p
func fun(x []int) {}
func g(x []int) {
fun(x) // -r='fun(x...)->Fun(x)' should not rewrite this
fun(x...) // -r='fun(x...)->Fun(x)' should rewrite this to Fun(x)
}