Commit 72f9b2eb authored by Robert Griesemer's avatar Robert Griesemer

gofmt: fine-tune stripping of parentheses

       (composite literals in control clauses only need
       parentheses if the literals start with a type name)

R=rsc
CC=golang-dev
https://golang.org/cl/962045
parent d971f717
...@@ -950,14 +950,25 @@ func (p *printer) block(s *ast.BlockStmt, indent int) { ...@@ -950,14 +950,25 @@ func (p *printer) block(s *ast.BlockStmt, indent int) {
} }
func isTypeName(x ast.Expr) bool {
switch t := x.(type) {
case *ast.Ident:
return true
case *ast.SelectorExpr:
return isTypeName(t.X)
}
return false
}
// 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, inControlClause bool) ast.Expr { func stripParens(x ast.Expr, inControlClause bool) ast.Expr {
for px, hasParens := x.(*ast.ParenExpr); hasParens; px, hasParens = x.(*ast.ParenExpr) { for px, hasParens := x.(*ast.ParenExpr); hasParens; px, hasParens = x.(*ast.ParenExpr) {
x = px.X x = px.X
if _, isCompositeLit := x.(*ast.CompositeLit); isCompositeLit && inControlClause { if cx, isCompositeLit := x.(*ast.CompositeLit); inControlClause && isCompositeLit && isTypeName(cx.Type) {
// composite literals inside control clauses need parens; // composite literals inside control clauses need parens if they start with a type name;
// don't strip innermost layer // don't strip innermost layer
return px return px
} }
......
...@@ -144,7 +144,7 @@ func _() { ...@@ -144,7 +144,7 @@ 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
} }
...@@ -152,39 +152,63 @@ func _() { ...@@ -152,39 +152,63 @@ func _() {
// Don't remove mandatory parentheses around composite literals in control clauses. // Don't remove mandatory parentheses around composite literals in control clauses.
func _() { func _() {
// strip no parentheses - no composite literals or composite literals don't start with a type name
if x { if x {
} // no ()'s }
if x { if x {
} // no ()'s }
if ([]T{}) { if []T{} {
} // () }
if ([]T{}) { if []T{} {
} // () }
if ([]T{}) { if []T{} {
} // () }
for x { for x {
} // no ()'s }
for x { for x {
} // no ()'s }
for ([]T{}) { for []T{} {
} // () }
for ([]T{}) { for []T{} {
} // () }
for ([]T{}) { for []T{} {
} // () }
switch x { switch x {
} // no ()'s }
switch x { switch x {
} // no ()'s }
switch ([]T{}) { switch []T{} {
} // () }
switch ([]T{}) { switch []T{} {
} // () }
for _ = range ([]T{T{42}}) { for _ = range []T{T{42}} {
} // () }
// leave parentheses - composite literals start with a type name
if (T{}) {
}
if (T{}) {
}
if (T{}) {
}
for (T{}) {
}
for (T{}) {
}
for (T{}) {
}
switch (T{}) {
}
switch (T{}) {
}
for _ = range (T1{T{42}}) {
}
} }
......
...@@ -113,24 +113,39 @@ func _() { ...@@ -113,24 +113,39 @@ func _() {
// Don't remove mandatory parentheses around composite literals in control clauses. // Don't remove mandatory parentheses around composite literals in control clauses.
func _() { func _() {
if (x) {} // no ()'s // strip parentheses - no composite literals or composite literals don't start with a type name
if (((x))) {} // no ()'s if (x) {}
if ([]T{}) {} // () if (((x))) {}
if (([]T{})) {} // () if ([]T{}) {}
if ; (((([]T{})))) {} // () if (([]T{})) {}
if ; (((([]T{})))) {}
for (x) {} // no ()'s
for (((x))) {} // no ()'s for (x) {}
for ([]T{}) {} // () for (((x))) {}
for (([]T{})) {} // () for ([]T{}) {}
for ; (((([]T{})))) ; {} // () for (([]T{})) {}
for ; (((([]T{})))) ; {}
switch (x) {} // no ()'s
switch (((x))) {} // no ()'s switch (x) {}
switch ([]T{}) {} // () switch (((x))) {}
switch (([]T{})) {} // () switch ([]T{}) {}
switch ; (((([]T{})))) {}
for _ = range ((([]T{T{42}}))) {} // ()
for _ = range ((([]T{T{42}}))) {}
// leave parentheses - composite literals start with a type name
if (T{}) {}
if ((T{})) {}
if ; ((((T{})))) {}
for (T{}) {}
for ((T{})) {}
for ; ((((T{})))) ; {}
switch (T{}) {}
switch ; ((((T{})))) {}
for _ = range (((T1{T{42}}))) {}
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment