mirror of
https://github.com/golang/go
synced 2024-11-18 14:34:39 -07:00
cmd/gofmt: simplify map key literals
Simplify map key literals in "gofmt -s" Fixes #16461. Change-Id: Ia61739b34a30ac27f6696f94a98809109a8a7b61 Reviewed-on: https://go-review.googlesource.com/25530 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
This commit is contained in:
parent
d07345a633
commit
56b5546b91
@ -17,47 +17,33 @@ func (s simplifier) Visit(node ast.Node) ast.Visitor {
|
|||||||
case *ast.CompositeLit:
|
case *ast.CompositeLit:
|
||||||
// array, slice, and map composite literals may be simplified
|
// array, slice, and map composite literals may be simplified
|
||||||
outer := n
|
outer := n
|
||||||
var eltType ast.Expr
|
var keyType, eltType ast.Expr
|
||||||
switch typ := outer.Type.(type) {
|
switch typ := outer.Type.(type) {
|
||||||
case *ast.ArrayType:
|
case *ast.ArrayType:
|
||||||
eltType = typ.Elt
|
eltType = typ.Elt
|
||||||
case *ast.MapType:
|
case *ast.MapType:
|
||||||
|
keyType = typ.Key
|
||||||
eltType = typ.Value
|
eltType = typ.Value
|
||||||
}
|
}
|
||||||
|
|
||||||
if eltType != nil {
|
if eltType != nil {
|
||||||
|
var ktyp reflect.Value
|
||||||
|
if keyType != nil {
|
||||||
|
ktyp = reflect.ValueOf(keyType)
|
||||||
|
}
|
||||||
typ := reflect.ValueOf(eltType)
|
typ := reflect.ValueOf(eltType)
|
||||||
for i, x := range outer.Elts {
|
for i, x := range outer.Elts {
|
||||||
px := &outer.Elts[i]
|
px := &outer.Elts[i]
|
||||||
// look at value of indexed/named elements
|
// look at value of indexed/named elements
|
||||||
if t, ok := x.(*ast.KeyValueExpr); ok {
|
if t, ok := x.(*ast.KeyValueExpr); ok {
|
||||||
|
if keyType != nil {
|
||||||
|
s.simplifyLiteral(ktyp, keyType, t.Key, &t.Key)
|
||||||
|
}
|
||||||
x = t.Value
|
x = t.Value
|
||||||
px = &t.Value
|
px = &t.Value
|
||||||
}
|
}
|
||||||
ast.Walk(s, x) // simplify x
|
s.simplifyLiteral(typ, eltType, x, px)
|
||||||
// if the element is a composite literal and its literal type
|
|
||||||
// matches the outer literal's element type exactly, the inner
|
|
||||||
// literal type may be omitted
|
|
||||||
if inner, ok := x.(*ast.CompositeLit); ok {
|
|
||||||
if match(nil, typ, reflect.ValueOf(inner.Type)) {
|
|
||||||
inner.Type = nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if the outer literal's element type is a pointer type *T
|
|
||||||
// and the element is & of a composite literal of type T,
|
|
||||||
// the inner &T may be omitted.
|
|
||||||
if ptr, ok := eltType.(*ast.StarExpr); ok {
|
|
||||||
if addr, ok := x.(*ast.UnaryExpr); ok && addr.Op == token.AND {
|
|
||||||
if inner, ok := addr.X.(*ast.CompositeLit); ok {
|
|
||||||
if match(nil, reflect.ValueOf(ptr.X), reflect.ValueOf(inner.Type)) {
|
|
||||||
inner.Type = nil // drop T
|
|
||||||
*px = inner // drop &
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// node was simplified - stop walk (there are no subnodes to simplify)
|
// node was simplified - stop walk (there are no subnodes to simplify)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -113,6 +99,32 @@ func (s simplifier) Visit(node ast.Node) ast.Visitor {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s simplifier) simplifyLiteral(typ reflect.Value, astType, x ast.Expr, px *ast.Expr) {
|
||||||
|
ast.Walk(s, x) // simplify x
|
||||||
|
|
||||||
|
// if the element is a composite literal and its literal type
|
||||||
|
// matches the outer literal's element type exactly, the inner
|
||||||
|
// literal type may be omitted
|
||||||
|
if inner, ok := x.(*ast.CompositeLit); ok {
|
||||||
|
if match(nil, typ, reflect.ValueOf(inner.Type)) {
|
||||||
|
inner.Type = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if the outer literal's element type is a pointer type *T
|
||||||
|
// and the element is & of a composite literal of type T,
|
||||||
|
// the inner &T may be omitted.
|
||||||
|
if ptr, ok := astType.(*ast.StarExpr); ok {
|
||||||
|
if addr, ok := x.(*ast.UnaryExpr); ok && addr.Op == token.AND {
|
||||||
|
if inner, ok := addr.X.(*ast.CompositeLit); ok {
|
||||||
|
if match(nil, reflect.ValueOf(ptr.X), reflect.ValueOf(inner.Type)) {
|
||||||
|
inner.Type = nil // drop T
|
||||||
|
*px = inner // drop &
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func isBlank(x ast.Expr) bool {
|
func isBlank(x ast.Expr) bool {
|
||||||
ident, ok := x.(*ast.Ident)
|
ident, ok := x.(*ast.Ident)
|
||||||
return ok && ident.Name == "_"
|
return ok && ident.Name == "_"
|
||||||
|
14
src/cmd/gofmt/testdata/composites.golden
vendored
14
src/cmd/gofmt/testdata/composites.golden
vendored
@ -6,6 +6,10 @@ type T struct {
|
|||||||
x, y int
|
x, y int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type T2 struct {
|
||||||
|
w, z int
|
||||||
|
}
|
||||||
|
|
||||||
var _ = [42]T{
|
var _ = [42]T{
|
||||||
{},
|
{},
|
||||||
{1, 2},
|
{1, 2},
|
||||||
@ -202,3 +206,13 @@ var pieces4 = []*Piece{
|
|||||||
{2, 0, Point{4, 1}, []Point{{0, 0}, {1, 0}, {1, 0}, {1, 0}}, nil, nil},
|
{2, 0, Point{4, 1}, []Point{{0, 0}, {1, 0}, {1, 0}, {1, 0}}, nil, nil},
|
||||||
{3, 0, Point{1, 4}, []Point{{0, 0}, {0, 1}, {0, 1}, {0, 1}}, nil, nil},
|
{3, 0, Point{1, 4}, []Point{{0, 0}, {0, 1}, {0, 1}, {0, 1}}, nil, nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ = map[T]T2{
|
||||||
|
{1, 2}: {3, 4},
|
||||||
|
{5, 6}: {7, 8},
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = map[*T]*T2{
|
||||||
|
{1, 2}: {3, 4},
|
||||||
|
{5, 6}: {7, 8},
|
||||||
|
}
|
||||||
|
14
src/cmd/gofmt/testdata/composites.input
vendored
14
src/cmd/gofmt/testdata/composites.input
vendored
@ -6,6 +6,10 @@ type T struct {
|
|||||||
x, y int
|
x, y int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type T2 struct {
|
||||||
|
w, z int
|
||||||
|
}
|
||||||
|
|
||||||
var _ = [42]T{
|
var _ = [42]T{
|
||||||
T{},
|
T{},
|
||||||
T{1, 2},
|
T{1, 2},
|
||||||
@ -202,3 +206,13 @@ var pieces4 = []*Piece{
|
|||||||
&Piece{2, 0, Point{4, 1}, []Point{Point{0, 0}, Point{1, 0}, Point{1, 0}, Point{1, 0}}, nil, nil},
|
&Piece{2, 0, Point{4, 1}, []Point{Point{0, 0}, Point{1, 0}, Point{1, 0}, Point{1, 0}}, nil, nil},
|
||||||
&Piece{3, 0, Point{1, 4}, []Point{Point{0, 0}, Point{0, 1}, Point{0, 1}, Point{0, 1}}, nil, nil},
|
&Piece{3, 0, Point{1, 4}, []Point{Point{0, 0}, Point{0, 1}, Point{0, 1}, Point{0, 1}}, nil, nil},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var _ = map[T]T2{
|
||||||
|
T{1, 2}: T2{3, 4},
|
||||||
|
T{5, 6}: T2{7, 8},
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ = map[*T]*T2{
|
||||||
|
&T{1, 2}: &T2{3, 4},
|
||||||
|
&T{5, 6}: &T2{7, 8},
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user