mirror of
https://github.com/golang/go.git
synced 2026-06-28 03:40:37 +00:00
go/printer: do not indent composite literals in return statements
When indentList counts multi-line elements to decide whether to indent
an expression list, composite literals and address-of-composite-literal
expressions (&T{...}) were counted. This inflated the count and caused
extra indentation in return statements with multiple composite literals.
Introduce isCompositeLitLike to identify such expressions and exclude
them from the multi-line element count in indentList.
Fixes #7195
Change-Id: I363a62592dad9c551a54fb47bf958f403fba3ab1
Reviewed-on: https://go-review.googlesource.com/c/go/+/752220
Reviewed-by: Robert Griesemer <gri@google.com>
Reviewed-by: Junyang Shao <shaojunyang@google.com>
TryBot-Bypass: Robert Griesemer <gri@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
This commit is contained in:
parent
4e51025e3e
commit
f142be8f2f
3 changed files with 64 additions and 6 deletions
|
|
@ -1309,6 +1309,20 @@ func (p *printer) controlClause(isForStmt bool, init ast.Stmt, expr ast.Expr, po
|
|||
}
|
||||
}
|
||||
|
||||
// isCompositeLitLike reports whether x is a composite literal or an expression
|
||||
// whose core is a composite literal (e.g. &T{...}), ignoring parentheses.
|
||||
func isCompositeLitLike(x ast.Expr) bool {
|
||||
x = stripParensAlways(x)
|
||||
switch x := x.(type) {
|
||||
case *ast.CompositeLit:
|
||||
return true
|
||||
case *ast.UnaryExpr:
|
||||
_, ok := stripParensAlways(x.X).(*ast.CompositeLit)
|
||||
return x.Op == token.AND && ok
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// indentList reports whether an expression list would look better if it
|
||||
// were indented wholesale (starting with the very first element, rather
|
||||
// than starting at the first line break).
|
||||
|
|
@ -1332,8 +1346,10 @@ func (p *printer) indentList(list []ast.Expr) bool {
|
|||
return true
|
||||
}
|
||||
if xb < xe {
|
||||
// x is a multi-line element
|
||||
n++
|
||||
// x is a multi-line element.
|
||||
if !isCompositeLitLike(x) {
|
||||
n++
|
||||
}
|
||||
}
|
||||
line = xe
|
||||
}
|
||||
|
|
|
|||
|
|
@ -902,3 +902,45 @@ func TestEmptyDecl(t *testing.T) { // issue 63566
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestIssue7195 checks that go/printer does not add an extra level of indentation
|
||||
// when printing a return statement with multiple multi-line composite literals.
|
||||
func TestIssue7195(t *testing.T) {
|
||||
const src = `package p
|
||||
|
||||
type T struct{ x int }
|
||||
|
||||
func f() (*T, *T) {
|
||||
return &T{
|
||||
x: 1,
|
||||
}, &T{
|
||||
x: 2,
|
||||
}
|
||||
}
|
||||
`
|
||||
fset := token.NewFileSet()
|
||||
file, err := parser.ParseFile(fset, "", src, 0)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := Fprint(&buf, fset, file); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
const want = `package p
|
||||
|
||||
type T struct{ x int }
|
||||
|
||||
func f() (*T, *T) {
|
||||
return &T{
|
||||
x: 1,
|
||||
}, &T{
|
||||
x: 2,
|
||||
}
|
||||
}
|
||||
`
|
||||
if got := buf.String(); got != want {
|
||||
t.Fatalf("got:\n%s\nwant:\n%s\n", got, want)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
8
src/go/printer/testdata/statements.golden
vendored
8
src/go/printer/testdata/statements.golden
vendored
|
|
@ -82,10 +82,10 @@ func _f() {
|
|||
z
|
||||
return func() {}
|
||||
return func() {
|
||||
_ = 0
|
||||
}, T{
|
||||
1, 2,
|
||||
}
|
||||
_ = 0
|
||||
}, T{
|
||||
1, 2,
|
||||
}
|
||||
return func() {
|
||||
_ = 0
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue