]> Cypherpunks repositories - gostls13.git/commitdiff
go/printer: don't drop required semi/linebreak after /*-comment
authorRobert Griesemer <gri@golang.org>
Wed, 9 Nov 2016 22:15:59 +0000 (14:15 -0800)
committerRobert Griesemer <gri@golang.org>
Thu, 10 Nov 2016 18:41:38 +0000 (18:41 +0000)
For details, see the issues.

Fixes #11274.
Fixes #15137.

Change-Id: Ia11e71a054b3195e3007f490418a9c53a7e9cdf1
Reviewed-on: https://go-review.googlesource.com/33016
Reviewed-by: Alan Donovan <adonovan@google.com>
src/go/printer/printer.go
src/go/printer/testdata/comments.golden
src/go/printer/testdata/comments.input

index 2390544b6f5d2565d449140a5f92d02ba6d475d4..eabf23e8b28691ec975c0fdcb5aee2584081f893 100644 (file)
@@ -712,6 +712,16 @@ func (p *printer) writeCommentSuffix(needsLinebreak bool) (wroteNewline, dropped
        return
 }
 
+// containsLinebreak reports whether the whitespace buffer contains any line breaks.
+func (p *printer) containsLinebreak() bool {
+       for _, ch := range p.wsbuf {
+               if ch == newline || ch == formfeed {
+                       return true
+               }
+       }
+       return false
+}
+
 // intersperseComments consumes all comments that appear before the next token
 // tok and prints it together with the buffered whitespace (i.e., the whitespace
 // that needs to be written before the next token). A heuristic is used to mix
@@ -730,23 +740,31 @@ func (p *printer) intersperseComments(next token.Position, tok token.Token) (wro
        }
 
        if last != nil {
-               // if the last comment is a /*-style comment and the next item
+               // If the last comment is a /*-style comment and the next item
                // follows on the same line but is not a comma, and not a "closing"
                // token immediately following its corresponding "opening" token,
-               // add an extra blank for separation unless explicitly disabled
+               // add an extra separator unless explicitly disabled. Use a blank
+               // as separator unless we have pending linebreaks and they are not
+               // disabled, in which case we want a linebreak (issue 15137).
+               needsLinebreak := false
                if p.mode&noExtraBlank == 0 &&
                        last.Text[1] == '*' && p.lineFor(last.Pos()) == next.Line &&
                        tok != token.COMMA &&
                        (tok != token.RPAREN || p.prevOpen == token.LPAREN) &&
                        (tok != token.RBRACK || p.prevOpen == token.LBRACK) {
-                       p.writeByte(' ', 1)
+                       if p.containsLinebreak() && p.mode&noExtraLinebreak == 0 {
+                               needsLinebreak = true
+                       } else {
+                               p.writeByte(' ', 1)
+                       }
+               }
+               // Ensure that there is a line break after a //-style comment,
+               // before EOF, and before a closing '}' unless explicitly disabled.
+               if last.Text[1] == '/' ||
+                       tok == token.EOF ||
+                       tok == token.RBRACE && p.mode&noExtraLinebreak == 0 {
+                       needsLinebreak = true
                }
-               // ensure that there is a line break after a //-style comment,
-               // before a closing '}' unless explicitly disabled, or at eof
-               needsLinebreak :=
-                       last.Text[1] == '/' ||
-                               tok == token.RBRACE && p.mode&noExtraLinebreak == 0 ||
-                               tok == token.EOF
                return p.writeCommentSuffix(needsLinebreak)
        }
 
index 849fa624489a61eeeea84bd66b6bce63fea9670f..4d92e65327990ac314c5429376ac3dcf4497b88f 100644 (file)
@@ -601,6 +601,32 @@ func _() {
        _ = a
 }
 
+// Test cases from issues 11274, 15137:
+// Semicolon must not be lost when multiple statements are on the same line with a comment.
+func _() {
+       x := 0 /**/
+       y := 1
+}
+
+func _() {
+       f()
+       f()
+       f() /* comment */
+       f()
+       f() /* comment */
+       f()
+       f() /* a */ /* b */
+       f()
+       f() /* a */ /* b */
+       f()
+       f() /* a */ /* b */
+       f()
+}
+
+func _() {
+       f() /* a */ /* b */
+}
+
 // Comments immediately adjacent to punctuation followed by a newline
 // remain after the punctuation (looks better and permits alignment of
 // comments).
index 30cd23c6dd4cd006ca348d172aea0181e951e7be..40351eeef69943f09e5390fe3232b76c75efe382 100644 (file)
@@ -607,6 +607,24 @@ func _() {
        _ = a
 }
 
+// Test cases from issues 11274, 15137:
+// Semicolon must not be lost when multiple statements are on the same line with a comment.
+func _() {
+    x := 0 /**/; y := 1
+}
+
+func _() {
+       f(); f()
+       f(); /* comment */ f()
+       f() /* comment */; f()  
+       f(); /* a */ /* b */ f()
+       f() /* a */ /* b */; f()
+       f() /* a */; /* b */ f()
+}
+
+func _() {
+       f() /* a */ /* b */ }
+
 // Comments immediately adjacent to punctuation followed by a newline
 // remain after the punctuation (looks better and permits alignment of
 // comments).