From 8be3105e00a66d0642b69046c043dbdb4a63ea97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Tue, 12 May 2020 23:47:29 +0100 Subject: [PATCH] make "split long lines" idempotent --- format/format.go | 85 ++++++++++++++++++--------------- testdata/scripts/long-lines.txt | 14 ++++-- 2 files changed, 56 insertions(+), 43 deletions(-) diff --git a/format/format.go b/format/format.go index ec7dc2b..a404c25 100644 --- a/format/format.go +++ b/format/format.go @@ -91,6 +91,7 @@ func File(fset *token.FileSet, file *ast.File, goVersion string) { return true } post := func(c *astutil.Cursor) bool { + f.applyPost(c) switch c.Node().(type) { case *ast.FieldList: f.longLineExtra = 0 @@ -257,7 +258,6 @@ func (f *fumpter) lineEnd(line int) token.Pos { // //sys(nb)? | syscall function wrapper prototypes var rxCommentDirective = regexp.MustCompile(`^([a-z]+:|line\b|export\b|extern\b|sys(nb)?\b)`) -// visit takes either an ast.Node or a []ast.Stmt. func (f *fumpter) applyPre(c *astutil.Cursor) { f.splitLongLine(c) @@ -429,6 +429,51 @@ func (f *fumpter) applyPre(c *astutil.Cursor) { f.removeLinesBetween(node.Lbrace, bodyPos) f.removeLinesBetween(bodyEnd, node.Rbrace) + case *ast.CaseClause: + f.stmts(node.Body) + openLine := f.Line(node.Case) + closeLine := f.Line(node.Colon) + if openLine == closeLine { + // nothing to do + break + } + if len(f.commentsBetween(node.Case, node.Colon)) > 0 { + // don't move comments + break + } + if f.printLength(node) > shortLineLimit { + // too long to collapse + break + } + f.removeLines(openLine, closeLine) + + case *ast.CommClause: + f.stmts(node.Body) + + case *ast.FieldList: + switch c.Parent().(type) { + case *ast.FuncDecl, *ast.FuncType, *ast.InterfaceType: + node.List = f.mergeAdjacentFields(node.List) + c.Replace(node) + case *ast.StructType: + // Do not merge adjacent fields in structs. + } + + case *ast.BasicLit: + if semver.Compare(f.goVersion, "v1.13") >= 0 { + if node.Kind == token.INT && rxOctalInteger.MatchString(node.Value) { + node.Value = "0o" + node.Value[1:] + c.Replace(node) + } + } + } +} + +func (f *fumpter) applyPost(c *astutil.Cursor) { + switch node := c.Node().(type) { + // Adding newlines to composite literals happens as a "post" step, so + // that we can take into account whether "pre" steps added any newlines + // that would affect us here. case *ast.CompositeLit: if len(node.Elts) == 0 { // doesn't have elements @@ -493,44 +538,6 @@ func (f *fumpter) applyPre(c *astutil.Cursor) { f.addNewline(elem1.End()) } } - - case *ast.CaseClause: - f.stmts(node.Body) - openLine := f.Line(node.Case) - closeLine := f.Line(node.Colon) - if openLine == closeLine { - // nothing to do - break - } - if len(f.commentsBetween(node.Case, node.Colon)) > 0 { - // don't move comments - break - } - if f.printLength(node) > shortLineLimit { - // too long to collapse - break - } - f.removeLines(openLine, closeLine) - - case *ast.CommClause: - f.stmts(node.Body) - - case *ast.FieldList: - switch c.Parent().(type) { - case *ast.FuncDecl, *ast.FuncType, *ast.InterfaceType: - node.List = f.mergeAdjacentFields(node.List) - c.Replace(node) - case *ast.StructType: - // Do not merge adjacent fields in structs. - } - - case *ast.BasicLit: - if semver.Compare(f.goVersion, "v1.13") >= 0 { - if node.Kind == token.INT && rxOctalInteger.MatchString(node.Value) { - node.Value = "0o" + node.Value[1:] - c.Replace(node) - } - } } } diff --git a/testdata/scripts/long-lines.txt b/testdata/scripts/long-lines.txt index e67978c..ea9f69f 100644 --- a/testdata/scripts/long-lines.txt +++ b/testdata/scripts/long-lines.txt @@ -1,6 +1,9 @@ -gofumpt -w . +gofumpt -w foo.go cmp foo.go foo.go.golden +gofumpt -d foo.go.golden +! stdout . + -- foo.go -- package p @@ -82,15 +85,18 @@ func _() { // Allow splitting at the start of sub-lists too. if err := f(argument1, argument2, argument3, argument4, argument5, argument6, someComplex{ - argument7, argument8, argument9}); err != nil { + argument7, argument8, argument9, + }); err != nil { panic(err) } if err := f(argument1, argument2, argument3, argument4, argument5, argument6, &someComplex{ - argument7, argument8, argument9}); err != nil { + argument7, argument8, argument9, + }); err != nil { panic(err) } if err := f(argument1, argument2, argument3, argument4, argument5, argument6, []someSlice{ - argument7, argument8, argument9}); err != nil { + argument7, argument8, argument9, + }); err != nil { panic(err) } }