From 6e1ed83c8fa11738d630492075bfc30a5013e2db Mon Sep 17 00:00:00 2001 From: Takbir Newaz Date: Mon, 21 Mar 2022 18:20:52 +0600 Subject: [PATCH] format: decl group allow first comment fixes #212 --- format/format.go | 39 +++++++++++++++++++++++++--- testdata/scripts/decl-group-many.txt | 32 ++++++++++++++++++++--- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/format/format.go b/format/format.go index 727acce..67e0029 100644 --- a/format/format.go +++ b/format/format.go @@ -317,22 +317,33 @@ func (f *fumpter) applyPre(c *astutil.Cursor) { case *ast.File: // Join contiguous lone var/const/import lines. // Abort if there are empty lines or comments in between, - // including a leading comment, which could be a directive. + // including a leading comment if it's a directive. newDecls := make([]ast.Decl, 0, len(node.Decls)) for i := 0; i < len(node.Decls); { newDecls = append(newDecls, node.Decls[i]) start, ok := node.Decls[i].(*ast.GenDecl) - if !ok || isCgoImport(start) || start.Doc != nil { + if !ok || isCgoImport(start) || isCommentGrpDirective(start.Doc) { i++ continue } lastPos := start.Pos() + contLoop: for i++; i < len(node.Decls); { cont, ok := node.Decls[i].(*ast.GenDecl) - if !ok || cont.Tok != start.Tok || cont.Lparen != token.NoPos || - f.Line(lastPos) < f.Line(cont.Pos())-1 || isCgoImport(cont) { + if !ok || cont.Tok != start.Tok || cont.Lparen != token.NoPos || isCgoImport(cont) { break } + if f.Line(lastPos) < f.Line(cont.Pos())-1 { + if cont.Doc == nil { + break + } + for i, comment := range cont.Doc.List { + if f.Line(comment.Slash) != f.Line(lastPos)+1+i || isCommentDirective(comment) { + break contLoop + } + } + } + start.Specs = append(start.Specs, cont.Specs...) if c := f.inlineComment(cont.End()); c != nil { // don't move an inline comment outside @@ -1018,3 +1029,23 @@ func setPos(v reflect.Value, pos token.Pos) { } } } + +func isCommentGrpDirective(cg *ast.CommentGroup) bool { + if cg == nil { + return false + } + for _, comment := range cg.List { + if isCommentDirective(comment) { + return true + } + } + return false +} + +func isCommentDirective(comment *ast.Comment) bool { + if comment == nil { + return false + } + body := strings.TrimPrefix(comment.Text, "//") + return rxCommentDirective.MatchString(body) +} diff --git a/testdata/scripts/decl-group-many.txt b/testdata/scripts/decl-group-many.txt index 0678b6e..fe13cc1 100644 --- a/testdata/scripts/decl-group-many.txt +++ b/testdata/scripts/decl-group-many.txt @@ -18,13 +18,23 @@ const four = 'r' var not = 'a' var v1 = 's' -// comment, e.g. directive +//go:embed hello.txt +var v2 = 'd' + +var v1 = 's' +// comment line 1 +// comment line 2 var v2 = 'd' var v1 = "mixed" const c1 = "mixed" -// comment, e.g. directive +//go:embed hello.txt +var v1 = 's' +var v2 = 'd' +var v3 = 'd' + +// comment var v1 = 's' var v2 = 'd' var v3 = 'd' @@ -51,14 +61,21 @@ var not = 'a' var v1 = 's' -// comment, e.g. directive +//go:embed hello.txt var v2 = 'd' +var ( + v1 = 's' + // comment line 1 + // comment line 2 + v2 = 'd' +) + var v1 = "mixed" const c1 = "mixed" -// comment, e.g. directive +//go:embed hello.txt var v1 = 's' var ( @@ -66,6 +83,13 @@ var ( v3 = 'd' ) +// comment +var ( + v1 = 's' + v2 = 'd' + v3 = 'd' +) + const ( inline1 = "s1" // c1 inline2 = "s2" // c2