]> Cypherpunks repositories - gostls13.git/commitdiff
gofmt: handle &T in composite literal simplify
authorRuss Cox <rsc@golang.org>
Fri, 2 Dec 2011 19:14:04 +0000 (14:14 -0500)
committerRuss Cox <rsc@golang.org>
Fri, 2 Dec 2011 19:14:04 +0000 (14:14 -0500)
R=gri
CC=golang-dev
https://golang.org/cl/5448086

src/cmd/gofmt/simplify.go
src/cmd/gofmt/testdata/composites.golden
src/cmd/gofmt/testdata/composites.input

index d9afc0e7b4c02b771968a94d23682b224f3582b1..9d3cb91439edebb778251daacc41a3f29fdaf9b6 100644 (file)
@@ -6,6 +6,7 @@ package main
 
 import (
        "go/ast"
+       "go/token"
        "reflect"
 )
 
@@ -26,10 +27,12 @@ func (s *simplifier) Visit(node ast.Node) ast.Visitor {
 
                if eltType != nil {
                        typ := reflect.ValueOf(eltType)
-                       for _, x := range outer.Elts {
+                       for i, x := range outer.Elts {
+                               px := &outer.Elts[i]
                                // look at value of indexed/named elements
                                if t, ok := x.(*ast.KeyValueExpr); ok {
                                        x = t.Value
+                                       px = &t.Value
                                }
                                simplify(x)
                                // if the element is a composite literal and its literal type
@@ -40,6 +43,19 @@ func (s *simplifier) Visit(node ast.Node) ast.Visitor {
                                                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)
index 1fd5847c11e726f53473aab48ed426b771858875..b2825e732aa516d1612e6d95270206c79c40f8bd 100644 (file)
@@ -102,3 +102,101 @@ var pieces4 = []Piece{
        {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},
 }
+
+var _ = [42]*T{
+       {},
+       {1, 2},
+       {3, 4},
+}
+
+var _ = [...]*T{
+       {},
+       {1, 2},
+       {3, 4},
+}
+
+var _ = []*T{
+       {},
+       {1, 2},
+       {3, 4},
+}
+
+var _ = []*T{
+       {},
+       10: {1, 2},
+       20: {3, 4},
+}
+
+var _ = []*struct {
+       x, y int
+}{
+       {},
+       10: {1, 2},
+       20: {3, 4},
+}
+
+var _ = []interface{}{
+       &T{},
+       10: &T{1, 2},
+       20: &T{3, 4},
+}
+
+var _ = []*[]int{
+       {},
+       {1, 2},
+       {3, 4},
+}
+
+var _ = []*[]int{
+       (&[]int{}),
+       (&[]int{1, 2}),
+       {3, 4},
+}
+
+var _ = []*[]*[]int{
+       {},
+       {
+               {},
+               {0, 1, 2, 3},
+               {4, 5},
+       },
+}
+
+var _ = map[string]*T{
+       "foo": {},
+       "bar": {1, 2},
+       "bal": {3, 4},
+}
+
+var _ = map[string]*struct {
+       x, y int
+}{
+       "foo": {},
+       "bar": {1, 2},
+       "bal": {3, 4},
+}
+
+var _ = map[string]interface{}{
+       "foo": &T{},
+       "bar": &T{1, 2},
+       "bal": &T{3, 4},
+}
+
+var _ = map[string]*[]int{
+       "foo": {},
+       "bar": {1, 2},
+       "bal": {3, 4},
+}
+
+var _ = map[string]*[]int{
+       "foo": (&[]int{}),
+       "bar": (&[]int{1, 2}),
+       "bal": {3, 4},
+}
+
+var pieces4 = []*Piece{
+       {0, 0, Point{4, 1}, []Point{{0, 0}, {1, 0}, {1, 0}, {1, 0}}, nil, nil},
+       {1, 0, Point{1, 4}, []Point{{0, 0}, {0, 1}, {0, 1}, {0, 1}}, 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},
+}
index 15afd9e5c4f32cc8d56607369efa52e1344f7160..7210dafc96c1820371efffa9c2e3e5d6e3d6330b 100644 (file)
@@ -102,3 +102,101 @@ 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{3, 0, Point{1, 4}, []Point{Point{0, 0}, Point{0, 1}, Point{0, 1}, Point{0, 1}}, nil, nil},
 }
+
+var _ = [42]*T{
+       &T{},
+       &T{1, 2},
+       &T{3, 4},
+}
+
+var _ = [...]*T{
+       &T{},
+       &T{1, 2},
+       &T{3, 4},
+}
+
+var _ = []*T{
+       &T{},
+       &T{1, 2},
+       &T{3, 4},
+}
+
+var _ = []*T{
+       &T{},
+       10: &T{1, 2},
+       20: &T{3, 4},
+}
+
+var _ = []*struct {
+       x, y int
+}{
+       &struct{ x, y int }{},
+       10: &struct{ x, y int }{1, 2},
+       20: &struct{ x, y int }{3, 4},
+}
+
+var _ = []interface{}{
+       &T{},
+       10: &T{1, 2},
+       20: &T{3, 4},
+}
+
+var _ = []*[]int{
+       &[]int{},
+       &[]int{1, 2},
+       &[]int{3, 4},
+}
+
+var _ = []*[]int{
+       (&[]int{}),
+       (&[]int{1, 2}),
+       &[]int{3, 4},
+}
+
+var _ = []*[]*[]int{
+       &[]*[]int{},
+       &[]*[]int{
+               &[]int{},
+               &[]int{0, 1, 2, 3},
+               &[]int{4, 5},
+       },
+}
+
+var _ = map[string]*T{
+       "foo": &T{},
+       "bar": &T{1, 2},
+       "bal": &T{3, 4},
+}
+
+var _ = map[string]*struct {
+       x, y int
+}{
+       "foo": &struct{ x, y int }{},
+       "bar": &struct{ x, y int }{1, 2},
+       "bal": &struct{ x, y int }{3, 4},
+}
+
+var _ = map[string]interface{}{
+       "foo": &T{},
+       "bar": &T{1, 2},
+       "bal": &T{3, 4},
+}
+
+var _ = map[string]*[]int{
+       "foo": &[]int{},
+       "bar": &[]int{1, 2},
+       "bal": &[]int{3, 4},
+}
+
+var _ = map[string]*[]int{
+       "foo": (&[]int{}),
+       "bar": (&[]int{1, 2}),
+       "bal": &[]int{3, 4},
+}
+
+var pieces4 = []*Piece{
+       &Piece{0, 0, Point{4, 1}, []Point{Point{0, 0}, Point{1, 0}, Point{1, 0}, Point{1, 0}}, nil, nil},
+       &Piece{1, 0, Point{1, 4}, []Point{Point{0, 0}, Point{0, 1}, Point{0, 1}, Point{0, 1}}, 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},
+}