mirror of
https://github.com/golang/go
synced 2024-11-25 08:47:56 -07:00
gofmt: don't strip mandatory ()'s around composite literals in control clauses
Fixes #748. R=rsc CC=golang-dev https://golang.org/cl/946043
This commit is contained in:
parent
0e8384af65
commit
2bfc2d7772
@ -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
|
// TODO(gri): Decide if this should be used more broadly. The printing code
|
||||||
// knows when to insert parentheses for precedence reasons, but
|
// knows when to insert parentheses for precedence reasons, but
|
||||||
// need to be careful to keep them around type expressions.
|
// need to be careful to keep them around type expressions.
|
||||||
func stripParens(x ast.Expr) ast.Expr {
|
func stripParens(x ast.Expr, inControlClause bool) ast.Expr {
|
||||||
if px, hasParens := x.(*ast.ParenExpr); hasParens {
|
for px, hasParens := x.(*ast.ParenExpr); hasParens; px, hasParens = x.(*ast.ParenExpr) {
|
||||||
return stripParens(px.X)
|
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
|
return x
|
||||||
}
|
}
|
||||||
@ -967,7 +972,7 @@ func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, po
|
|||||||
if init == nil && post == nil {
|
if init == nil && post == nil {
|
||||||
// no semicolons required
|
// no semicolons required
|
||||||
if expr != nil {
|
if expr != nil {
|
||||||
p.expr(stripParens(expr), ignoreMultiLine)
|
p.expr(stripParens(expr, true), ignoreMultiLine)
|
||||||
needsBlank = true
|
needsBlank = true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -978,7 +983,7 @@ func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, po
|
|||||||
}
|
}
|
||||||
p.print(token.SEMICOLON, blank)
|
p.print(token.SEMICOLON, blank)
|
||||||
if expr != nil {
|
if expr != nil {
|
||||||
p.expr(stripParens(expr), ignoreMultiLine)
|
p.expr(stripParens(expr, true), ignoreMultiLine)
|
||||||
needsBlank = true
|
needsBlank = true
|
||||||
}
|
}
|
||||||
if isForStmt {
|
if isForStmt {
|
||||||
@ -1152,7 +1157,7 @@ func (p *printer) stmt(stmt ast.Stmt, multiLine *bool) {
|
|||||||
p.expr(s.Value, multiLine)
|
p.expr(s.Value, multiLine)
|
||||||
}
|
}
|
||||||
p.print(blank, s.TokPos, s.Tok, blank, token.RANGE, blank)
|
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.print(blank)
|
||||||
p.block(s.Body, 1)
|
p.block(s.Body, 1)
|
||||||
*multiLine = true
|
*multiLine = true
|
||||||
|
40
src/pkg/go/printer/testdata/statements.golden
vendored
40
src/pkg/go/printer/testdata/statements.golden
vendored
@ -144,12 +144,50 @@ func _() {
|
|||||||
for x := range []int{} {
|
for x := range []int{} {
|
||||||
use(x)
|
use(x)
|
||||||
}
|
}
|
||||||
for x := range []int{} {
|
for x := range ([]int{}) {
|
||||||
use(x)
|
use(x)
|
||||||
} // no parens printed
|
} // 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
|
// Extra empty lines inside functions. Do respect source code line
|
||||||
// breaks between statement boundaries but print at most one empty
|
// breaks between statement boundaries but print at most one empty
|
||||||
// line at a time.
|
// line at a time.
|
||||||
|
23
src/pkg/go/printer/testdata/statements.input
vendored
23
src/pkg/go/printer/testdata/statements.input
vendored
@ -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
|
// Extra empty lines inside functions. Do respect source code line
|
||||||
// breaks between statement boundaries but print at most one empty
|
// breaks between statement boundaries but print at most one empty
|
||||||
// line at a time.
|
// line at a time.
|
||||||
|
Loading…
Reference in New Issue
Block a user