Skip to content

Commit

Permalink
relax the composite rule under some scenarios
Browse files Browse the repository at this point in the history
If a composite literal has many elements but they all immediately follow
each other, and neither brace has a newline, that's fine.
  • Loading branch information
mvdan committed Mar 31, 2019
1 parent 7ac76eb commit e02a0e1
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 15 deletions.
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@ if err != nil {
}
```

Multi-line composite literals should keep elements in their own lines:
Composite literals with newlines between elements must also separate the opening
and closing braces with newlines:


```
var _ = []int{1, 2,
3, 4}
var bad = []int{1, 2,
3, 4}
var good = []int{
1, 2,
3, 4,
}
```

### License
Expand Down
38 changes: 26 additions & 12 deletions gofumpt.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
func gofumpt(fset *token.FileSet, file *ast.File) {
tfile := fset.File(file.Pos())

posLine := func(pos token.Pos) int { return tfile.Position(pos).Line }

commentsBetween := func(p1, p2 token.Pos) []*ast.CommentGroup {
comments := file.Comments
i1 := sort.Search(len(comments), func(i int) bool {
Expand Down Expand Up @@ -53,8 +55,8 @@ func gofumpt(fset *token.FileSet, file *ast.File) {
// removeLines joins all lines between two positions, for example to
// remove empty lines.
removeLines := func(from, to token.Pos) {
fromLine := tfile.Position(from).Line
toLine := tfile.Position(to).Line
fromLine := posLine(from)
toLine := posLine(to)
for fromLine+1 < toLine {
tfile.MergeLine(fromLine)
toLine--
Expand Down Expand Up @@ -83,26 +85,38 @@ func gofumpt(fset *token.FileSet, file *ast.File) {
// doesn't have elements
break
}
openLine := tfile.Position(node.Lbrace).Line
closeLine := tfile.Position(node.Rbrace).Line
openLine := posLine(node.Lbrace)
closeLine := posLine(node.Rbrace)
if openLine == closeLine {
// not multi-line
// all in a single line
break
}
first := node.Elts[0]
if len(node.Elts) == 1 &&
tfile.Position(first.Pos()).Line == openLine &&
tfile.Position(first.End()).Line == closeLine {
// wrapping a single expression

newlineBetweenElems := false
lastLine := openLine
for _, elem := range node.Elts {
if posLine(elem.Pos()) > lastLine {
newlineBetweenElems = true
}
lastLine = posLine(elem.End())
}
if closeLine > lastLine {
newlineBetweenElems = true
}

if !newlineBetweenElems {
// no newlines between elements (and braces)
break
}

if openLine == tfile.Position(first.Pos()).Line {
first := node.Elts[0]
if openLine == posLine(first.Pos()) {
// We want the newline right after the brace.
addNewline(node.Lbrace, 1)
closeLine = posLine(node.Rbrace)
}
last := node.Elts[len(node.Elts)-1]
if closeLine == tfile.Position(last.End()).Line {
if closeLine == posLine(last.End()) {
addNewline(last.End(), 0)
}
}
Expand Down
12 changes: 12 additions & 0 deletions testdata/scripts/composite-multiline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ var _ = [][]string{{
"if wrapping a single expression",
}}

var _ = []string{`
no need for newlines
`, `
if no elements are surrounded by newlines
`}

-- foo.go.golden --
package p

Expand All @@ -33,3 +39,9 @@ var _ = [][]string{{
"no need for more newlines",
"if wrapping a single expression",
}}

var _ = []string{`
no need for newlines
`, `
if no elements are surrounded by newlines
`}

0 comments on commit e02a0e1

Please sign in to comment.