Skip to content

Commit 72f9b2e

Browse files
committed
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
1 parent d971f71 commit 72f9b2e

File tree

3 files changed

+96
-46
lines changed

3 files changed

+96
-46
lines changed

src/pkg/go/printer/nodes.go

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -950,14 +950,25 @@ func (p *printer) block(s *ast.BlockStmt, indent int) {
950950
}
951951

952952

953+
func isTypeName(x ast.Expr) bool {
954+
switch t := x.(type) {
955+
case *ast.Ident:
956+
return true
957+
case *ast.SelectorExpr:
958+
return isTypeName(t.X)
959+
}
960+
return false
961+
}
962+
963+
953964
// TODO(gri): Decide if this should be used more broadly. The printing code
954965
// knows when to insert parentheses for precedence reasons, but
955966
// need to be careful to keep them around type expressions.
956967
func stripParens(x ast.Expr, inControlClause bool) ast.Expr {
957968
for px, hasParens := x.(*ast.ParenExpr); hasParens; px, hasParens = x.(*ast.ParenExpr) {
958969
x = px.X
959-
if _, isCompositeLit := x.(*ast.CompositeLit); isCompositeLit && inControlClause {
960-
// composite literals inside control clauses need parens;
970+
if cx, isCompositeLit := x.(*ast.CompositeLit); inControlClause && isCompositeLit && isTypeName(cx.Type) {
971+
// composite literals inside control clauses need parens if they start with a type name;
961972
// don't strip innermost layer
962973
return px
963974
}

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

Lines changed: 50 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -144,47 +144,71 @@ func _() {
144144
for x := range []int{} {
145145
use(x)
146146
}
147-
for x := range ([]int{}) {
147+
for x := range []int{} {
148148
use(x)
149149
} // no parens printed
150150
}
151151

152152

153153
// Don't remove mandatory parentheses around composite literals in control clauses.
154154
func _() {
155+
// strip no parentheses - no composite literals or composite literals don't start with a type name
155156
if x {
156-
} // no ()'s
157+
}
157158
if x {
158-
} // no ()'s
159-
if ([]T{}) {
160-
} // ()
161-
if ([]T{}) {
162-
} // ()
163-
if ([]T{}) {
164-
} // ()
159+
}
160+
if []T{} {
161+
}
162+
if []T{} {
163+
}
164+
if []T{} {
165+
}
165166

166167
for x {
167-
} // no ()'s
168+
}
168169
for x {
169-
} // no ()'s
170-
for ([]T{}) {
171-
} // ()
172-
for ([]T{}) {
173-
} // ()
174-
for ([]T{}) {
175-
} // ()
170+
}
171+
for []T{} {
172+
}
173+
for []T{} {
174+
}
175+
for []T{} {
176+
}
176177

177178
switch x {
178-
} // no ()'s
179+
}
179180
switch x {
180-
} // no ()'s
181-
switch ([]T{}) {
182-
} // ()
183-
switch ([]T{}) {
184-
} // ()
185-
186-
for _ = range ([]T{T{42}}) {
187-
} // ()
181+
}
182+
switch []T{} {
183+
}
184+
switch []T{} {
185+
}
186+
187+
for _ = range []T{T{42}} {
188+
}
189+
190+
// leave parentheses - composite literals start with a type name
191+
if (T{}) {
192+
}
193+
if (T{}) {
194+
}
195+
if (T{}) {
196+
}
197+
198+
for (T{}) {
199+
}
200+
for (T{}) {
201+
}
202+
for (T{}) {
203+
}
204+
205+
switch (T{}) {
206+
}
207+
switch (T{}) {
208+
}
209+
210+
for _ = range (T1{T{42}}) {
211+
}
188212
}
189213

190214

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

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -113,24 +113,39 @@ func _() {
113113

114114
// Don't remove mandatory parentheses around composite literals in control clauses.
115115
func _() {
116-
if (x) {} // no ()'s
117-
if (((x))) {} // no ()'s
118-
if ([]T{}) {} // ()
119-
if (([]T{})) {} // ()
120-
if ; (((([]T{})))) {} // ()
121-
122-
for (x) {} // no ()'s
123-
for (((x))) {} // no ()'s
124-
for ([]T{}) {} // ()
125-
for (([]T{})) {} // ()
126-
for ; (((([]T{})))) ; {} // ()
127-
128-
switch (x) {} // no ()'s
129-
switch (((x))) {} // no ()'s
130-
switch ([]T{}) {} // ()
131-
switch (([]T{})) {} // ()
132-
133-
for _ = range ((([]T{T{42}}))) {} // ()
116+
// strip parentheses - no composite literals or composite literals don't start with a type name
117+
if (x) {}
118+
if (((x))) {}
119+
if ([]T{}) {}
120+
if (([]T{})) {}
121+
if ; (((([]T{})))) {}
122+
123+
for (x) {}
124+
for (((x))) {}
125+
for ([]T{}) {}
126+
for (([]T{})) {}
127+
for ; (((([]T{})))) ; {}
128+
129+
switch (x) {}
130+
switch (((x))) {}
131+
switch ([]T{}) {}
132+
switch ; (((([]T{})))) {}
133+
134+
for _ = range ((([]T{T{42}}))) {}
135+
136+
// leave parentheses - composite literals start with a type name
137+
if (T{}) {}
138+
if ((T{})) {}
139+
if ; ((((T{})))) {}
140+
141+
for (T{}) {}
142+
for ((T{})) {}
143+
for ; ((((T{})))) ; {}
144+
145+
switch (T{}) {}
146+
switch ; ((((T{})))) {}
147+
148+
for _ = range (((T1{T{42}}))) {}
134149
}
135150

136151

0 commit comments

Comments
 (0)