]> Cypherpunks repositories - gostls13.git/commitdiff
gofmt: don't strip mandatory ()'s around composite literals in control clauses
authorRobert Griesemer <gri@golang.org>
Tue, 27 Apr 2010 17:59:33 +0000 (10:59 -0700)
committerRobert Griesemer <gri@golang.org>
Tue, 27 Apr 2010 17:59:33 +0000 (10:59 -0700)
Fixes #748.

R=rsc
CC=golang-dev
https://golang.org/cl/946043

src/pkg/go/printer/nodes.go
src/pkg/go/printer/testdata/statements.golden
src/pkg/go/printer/testdata/statements.input

index b020060d791d7cf1f20005daff4e6c8a6b3682c0..dbbcf4e83fbdd6321f4f371577c72d1d874e25e8 100644 (file)
@@ -953,9 +953,14 @@ func (p *printer) block(s *ast.BlockStmt, indent int) {
 // TODO(gri): Decide if this should be used more broadly. The printing code
 //            knows when to insert parentheses for precedence reasons, but
 //            need to be careful to keep them around type expressions.
-func stripParens(x ast.Expr) ast.Expr {
-       if px, hasParens := x.(*ast.ParenExpr); hasParens {
-               return stripParens(px.X)
+func stripParens(x ast.Expr, inControlClause bool) ast.Expr {
+       for px, hasParens := x.(*ast.ParenExpr); hasParens; px, hasParens = x.(*ast.ParenExpr) {
+               x = px.X
+               if _, isCompositeLit := x.(*ast.CompositeLit); isCompositeLit && inControlClause {
+                       // composite literals inside control clauses need parens;
+                       // don't strip innermost layer
+                       return px
+               }
        }
        return x
 }
@@ -967,7 +972,7 @@ func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, po
        if init == nil && post == nil {
                // no semicolons required
                if expr != nil {
-                       p.expr(stripParens(expr), ignoreMultiLine)
+                       p.expr(stripParens(expr, true), ignoreMultiLine)
                        needsBlank = true
                }
        } else {
@@ -978,7 +983,7 @@ func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, po
                }
                p.print(token.SEMICOLON, blank)
                if expr != nil {
-                       p.expr(stripParens(expr), ignoreMultiLine)
+                       p.expr(stripParens(expr, true), ignoreMultiLine)
                        needsBlank = true
                }
                if isForStmt {
@@ -1152,7 +1157,7 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) {
                        p.expr(s.Value, multiLine)
                }
                p.print(blank, s.TokPos, s.Tok, blank, token.RANGE, blank)
-               p.expr(stripParens(s.X), multiLine)
+               p.expr(stripParens(s.X, true), multiLine)
                p.print(blank)
                p.block(s.Body, 1)
                *multiLine = true
index 86d8282cd7f321d0d8b9aec8b38a120602ff37aa..455a4d632c40c5b9a1a3156b211bde53b30ab192 100644 (file)
@@ -144,12 +144,50 @@ func _() {
        for x := range []int{} {
                use(x)
        }
-       for x := range []int{} {
+       for x := range ([]int{}) {
                use(x)
        }       // no parens printed
 }
 
 
+// Don't remove mandatory parentheses around composite literals in control clauses.
+func _() {
+       if x {
+       }       // no ()'s
+       if x {
+       }       // no ()'s
+       if ([]T{}) {
+       }       // ()
+       if ([]T{}) {
+       }       // ()
+       if ([]T{}) {
+       }       // ()
+
+       for x {
+       }       // no ()'s
+       for x {
+       }       // no ()'s
+       for ([]T{}) {
+       }       // ()
+       for ([]T{}) {
+       }       // ()
+       for ([]T{}) {
+       }       // ()
+
+       switch x {
+       }       // no ()'s
+       switch x {
+       }       // no ()'s
+       switch ([]T{}) {
+       }       // ()
+       switch ([]T{}) {
+       }       // ()
+
+       for _ = range ([]T{T{42}}) {
+       }       // ()
+}
+
+
 // Extra empty lines inside functions. Do respect source code line
 // breaks between statement boundaries but print at most one empty
 // line at a time.
index 061f7f320506d63562ac8b522063d295ef8d42e1..60133ea48589fa8f8e62572620cb06541dbefcb9 100644 (file)
@@ -111,6 +111,29 @@ func _() {
 }
 
 
+// Don't remove mandatory parentheses around composite literals in control clauses.
+func _() {
+       if (x) {}                // no ()'s
+       if (((x))) {}            // no ()'s
+       if ([]T{}) {}            // ()
+       if (([]T{})) {}          // ()
+       if ; (((([]T{})))) {}    // ()
+
+       for (x) {}                // no ()'s
+       for (((x))) {}            // no ()'s
+       for ([]T{}) {}            // ()
+       for (([]T{})) {}          // ()
+       for ; (((([]T{})))) ; {}  // ()
+
+       switch (x) {}                // no ()'s
+       switch (((x))) {}            // no ()'s
+       switch ([]T{}) {}            // ()
+       switch (([]T{})) {}          // ()
+
+       for _ = range ((([]T{T{42}}))) {}  // ()
+}
+
+
 // Extra empty lines inside functions. Do respect source code line
 // breaks between statement boundaries but print at most one empty
 // line at a time.