diff --git a/format/format.go b/format/format.go index 25666db..4eec251 100644 --- a/format/format.go +++ b/format/format.go @@ -511,29 +511,40 @@ func (f *fumpter) applyPre(c *astutil.Cursor) { if sign != nil { endLine := f.Line(sign.End()) - paramClosingIsFirstCharOnEndLine := sign.Params != nil && - f.Position(sign.Params.Closing).Column == 1 && - f.Line(sign.Params.Closing) == endLine - - resultClosingIsFirstCharOnEndLine := sign.Results != nil && - f.Position(sign.Results.Closing).Column == 1 && - f.Line(sign.Results.Closing) == endLine - - endLineIsIndented := !(paramClosingIsFirstCharOnEndLine || resultClosingIsFirstCharOnEndLine) - - if f.Line(sign.Pos()) != endLine && endLineIsIndented { - // The body is preceded by a multi-line function - // signature, we move the `) {` to avoid the empty line. - switch { - case sign.Results != nil && - !resultClosingIsFirstCharOnEndLine && - sign.Results.Closing.IsValid(): // there may be no ")" - sign.Results.Closing += 1 - f.addNewline(sign.Results.Closing) - - case sign.Params != nil && !paramClosingIsFirstCharOnEndLine: - sign.Params.Closing += 1 - f.addNewline(sign.Params.Closing) + if f.Line(sign.Pos()) != endLine { + handleMultiLine := func(fl *ast.FieldList) { + if fl == nil || len(fl.List) == 0 { + return + } + lastFieldEnd := fl.List[len(fl.List)-1].End() + lastFieldLine := f.Line(lastFieldEnd) + fieldClosingLine := f.Line(fl.Closing) + isLastFieldOnFieldClosingLine := lastFieldLine == fieldClosingLine + isLastFieldOnSigClosingLine := lastFieldLine == endLine + + var isLastCommentGrpOnFieldClosingLine, isLastCommentGrpOnSigClosingLine bool + if comments := f.commentsBetween(lastFieldEnd, fl.Closing); len(comments) > 0 { + lastCommentGrp := comments[len(comments)-1] + lastCommentGrpLine := f.Line(lastCommentGrp.End()) + + isLastCommentGrpOnFieldClosingLine = lastCommentGrpLine == fieldClosingLine + isLastCommentGrpOnSigClosingLine = lastCommentGrpLine == endLine + } + + // is there a comment grp/last field, field closing and sig closing on the same line? + if (isLastFieldOnFieldClosingLine && isLastFieldOnSigClosingLine) || + (isLastCommentGrpOnFieldClosingLine && isLastCommentGrpOnSigClosingLine) { + fl.Closing += 1 + f.addNewline(fl.Closing) + } + } + handleMultiLine(sign.Params) + if sign.Results != nil { + lastResultLine := f.Line(sign.Results.List[len(sign.Results.List)-1].End()) + isLastResultOnParamClosingLine := sign.Params != nil && lastResultLine == f.Line(sign.Params.Closing) + if !isLastResultOnParamClosingLine { + handleMultiLine(sign.Results) + } } } } diff --git a/testdata/scripts/func-newlines.txt b/testdata/scripts/func-newlines.txt index daa6e8f..2bc0c50 100644 --- a/testdata/scripts/func-newlines.txt +++ b/testdata/scripts/func-newlines.txt @@ -258,6 +258,22 @@ func f(p1 string, println("body") return 0 } + +func a() { + f := func(s string, + b bool, + ) { + // foo + } +} + +func f(p1 string, + p2 string) (int, string, + /* baz */) { + + println("body") + return 0, "" +} -- foo.go.golden -- package p @@ -469,3 +485,19 @@ func f(p1 string, println("body") return 0 } + +func a() { + f := func(s string, + b bool, + ) { + // foo + } +} + +func f(p1 string, + p2 string) (int, string, + +/* baz */) { + println("body") + return 0, "" +}