From 51b71fc2842bf4bddafe314494b61b95b1db163b 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 | 34 +++++++++++++++++++++--- 2 files changed, 64 insertions(+), 9 deletions(-) diff --git a/format/format.go b/format/format.go index 727acce..c0f077c 100644 --- a/format/format.go +++ b/format/format.go @@ -316,23 +316,39 @@ func (f *fumpter) applyPre(c *astutil.Cursor) { switch node := c.Node().(type) { 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. + // Abort if there are empty lines in between, + // 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) || containsAnyDirective(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 } + // Are there things between these two declarations? e.g. empty lines, comments, directives + // If so, break the chain on empty lines and directives, continue below for comments. + if f.Line(lastPos) < f.Line(cont.Pos())-1 { + // break on empty line + if cont.Doc == nil { + break + } + // break on directive + for i, comment := range cont.Doc.List { + if f.Line(comment.Slash) != f.Line(lastPos)+1+i || rxCommentDirective.MatchString(strings.TrimPrefix(comment.Text, "//")) { + break contLoop + } + } + // continue below for comments + } + start.Specs = append(start.Specs, cont.Specs...) if c := f.inlineComment(cont.End()); c != nil { // don't move an inline comment outside @@ -1018,3 +1034,16 @@ func setPos(v reflect.Value, pos token.Pos) { } } } + +func containsAnyDirective(group *ast.CommentGroup) bool { + if group == nil { + return false + } + for _, comment := range group.List { + body := strings.TrimPrefix(comment.Text, "//") + if rxCommentDirective.MatchString(body) { + return true + } + } + return false +} diff --git a/testdata/scripts/decl-group-many.txt b/testdata/scripts/decl-group-many.txt index 0678b6e..eaaefb9 100644 --- a/testdata/scripts/decl-group-many.txt +++ b/testdata/scripts/decl-group-many.txt @@ -18,15 +18,26 @@ 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' +/* comment */ var v3 = 'd' const inline1 = "s1" // c1 @@ -51,14 +62,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 +84,14 @@ var ( v3 = 'd' ) +// comment +var ( + v1 = 's' + v2 = 'd' + /* comment */ + v3 = 'd' +) + const ( inline1 = "s1" // c1 inline2 = "s2" // c2