@@ -316,23 +316,39 @@ func (f *fumpter) applyPre(c *astutil.Cursor) {
316316 switch node := c .Node ().(type ) {
317317 case * ast.File :
318318 // Join contiguous lone var/const/import lines.
319- // Abort if there are empty lines or comments in between,
320- // including a leading comment, which could be a directive.
319+ // Abort if there are empty lines in between,
320+ // including a leading comment if it's a directive.
321321 newDecls := make ([]ast.Decl , 0 , len (node .Decls ))
322322 for i := 0 ; i < len (node .Decls ); {
323323 newDecls = append (newDecls , node .Decls [i ])
324324 start , ok := node .Decls [i ].(* ast.GenDecl )
325- if ! ok || isCgoImport (start ) || start .Doc != nil {
325+ if ! ok || isCgoImport (start ) || containsAnyDirective ( start .Doc ) {
326326 i ++
327327 continue
328328 }
329329 lastPos := start .Pos ()
330+ contLoop:
330331 for i ++ ; i < len (node .Decls ); {
331332 cont , ok := node .Decls [i ].(* ast.GenDecl )
332- if ! ok || cont .Tok != start .Tok || cont .Lparen != token .NoPos ||
333- f .Line (lastPos ) < f .Line (cont .Pos ())- 1 || isCgoImport (cont ) {
333+ if ! ok || cont .Tok != start .Tok || cont .Lparen != token .NoPos || isCgoImport (cont ) {
334334 break
335335 }
336+ // Are there things between these two declarations? e.g. empty lines, comments, directives
337+ // If so, break the chain on empty lines and directives, continue below for comments.
338+ if f .Line (lastPos ) < f .Line (cont .Pos ())- 1 {
339+ // break on empty line
340+ if cont .Doc == nil {
341+ break
342+ }
343+ // break on directive
344+ for i , comment := range cont .Doc .List {
345+ if f .Line (comment .Slash ) != f .Line (lastPos )+ 1 + i || rxCommentDirective .MatchString (strings .TrimPrefix (comment .Text , "//" )) {
346+ break contLoop
347+ }
348+ }
349+ // continue below for comments
350+ }
351+
336352 start .Specs = append (start .Specs , cont .Specs ... )
337353 if c := f .inlineComment (cont .End ()); c != nil {
338354 // don't move an inline comment outside
@@ -1018,3 +1034,16 @@ func setPos(v reflect.Value, pos token.Pos) {
10181034 }
10191035 }
10201036}
1037+
1038+ func containsAnyDirective (group * ast.CommentGroup ) bool {
1039+ if group == nil {
1040+ return false
1041+ }
1042+ for _ , comment := range group .List {
1043+ body := strings .TrimPrefix (comment .Text , "//" )
1044+ if rxCommentDirective .MatchString (body ) {
1045+ return true
1046+ }
1047+ }
1048+ return false
1049+ }
0 commit comments