mirror of
https://github.com/golang/go
synced 2024-11-25 04:47:57 -07:00
go/printer: line comments must always end in a newline
Fixes #1503. R=rsc CC=golang-dev https://golang.org/cl/4170045
This commit is contained in:
parent
ea46bda72b
commit
6b526eb300
@ -145,11 +145,13 @@ func (p *printer) nlines(n, min int) int {
|
|||||||
// write0 does not indent after newlines, and does not HTML-escape or update p.pos.
|
// write0 does not indent after newlines, and does not HTML-escape or update p.pos.
|
||||||
//
|
//
|
||||||
func (p *printer) write0(data []byte) {
|
func (p *printer) write0(data []byte) {
|
||||||
n, err := p.output.Write(data)
|
if len(data) > 0 {
|
||||||
p.written += n
|
n, err := p.output.Write(data)
|
||||||
if err != nil {
|
p.written += n
|
||||||
p.errors <- err
|
if err != nil {
|
||||||
runtime.Goexit()
|
p.errors <- err
|
||||||
|
runtime.Goexit()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,14 +256,13 @@ func (p *printer) writeItem(pos token.Position, data []byte) {
|
|||||||
// If there is any pending whitespace, it consumes as much of
|
// If there is any pending whitespace, it consumes as much of
|
||||||
// it as is likely to help position the comment nicely.
|
// it as is likely to help position the comment nicely.
|
||||||
// pos is the comment position, next the position of the item
|
// pos is the comment position, next the position of the item
|
||||||
// after all pending comments, isFirst indicates if this is the
|
// after all pending comments, prev is the previous comment in
|
||||||
// first comment in a group of comments, and isKeyword indicates
|
// a group of comments (or nil), and isKeyword indicates if the
|
||||||
// if the next item is a keyword.
|
// next item is a keyword.
|
||||||
//
|
//
|
||||||
func (p *printer) writeCommentPrefix(pos, next token.Position, isFirst, isKeyword bool) {
|
func (p *printer) writeCommentPrefix(pos, next token.Position, prev *ast.Comment, isKeyword bool) {
|
||||||
if !p.last.IsValid() {
|
if p.written == 0 {
|
||||||
// there was no preceeding item and the comment is the
|
// the comment is the first item to be printed - don't write any whitespace
|
||||||
// first item to be printed - don't write any whitespace
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,11 +272,12 @@ func (p *printer) writeCommentPrefix(pos, next token.Position, isFirst, isKeywor
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if pos.IsValid() && pos.Line == p.last.Line {
|
if pos.Line == p.last.Line && (prev == nil || prev.Text[1] != '/') {
|
||||||
// comment on the same line as last item:
|
// comment on the same line as last item:
|
||||||
// separate with at least one separator
|
// separate with at least one separator
|
||||||
hasSep := false
|
hasSep := false
|
||||||
if isFirst {
|
if prev == nil {
|
||||||
|
// first comment of a comment group
|
||||||
j := 0
|
j := 0
|
||||||
for i, ch := range p.buffer {
|
for i, ch := range p.buffer {
|
||||||
switch ch {
|
switch ch {
|
||||||
@ -312,7 +314,8 @@ func (p *printer) writeCommentPrefix(pos, next token.Position, isFirst, isKeywor
|
|||||||
} else {
|
} else {
|
||||||
// comment on a different line:
|
// comment on a different line:
|
||||||
// separate with at least one line break
|
// separate with at least one line break
|
||||||
if isFirst {
|
if prev == nil {
|
||||||
|
// first comment of a comment group
|
||||||
j := 0
|
j := 0
|
||||||
for i, ch := range p.buffer {
|
for i, ch := range p.buffer {
|
||||||
switch ch {
|
switch ch {
|
||||||
@ -344,10 +347,14 @@ func (p *printer) writeCommentPrefix(pos, next token.Position, isFirst, isKeywor
|
|||||||
}
|
}
|
||||||
// use formfeeds to break columns before a comment;
|
// use formfeeds to break columns before a comment;
|
||||||
// this is analogous to using formfeeds to separate
|
// this is analogous to using formfeeds to separate
|
||||||
// individual lines of /*-style comments
|
// individual lines of /*-style comments - but make
|
||||||
// (if !pos.IsValid(), pos.Line == 0, and this will
|
// sure there is at least one line break if the previous
|
||||||
// print no newlines)
|
// comment was a line comment
|
||||||
p.writeNewlines(pos.Line-p.last.Line, true)
|
n := pos.Line - p.last.Line // if !pos.IsValid(), pos.Line == 0, and n will be 0
|
||||||
|
if n <= 0 && prev != nil && prev.Text[1] == '/' {
|
||||||
|
n = 1
|
||||||
|
}
|
||||||
|
p.writeNewlines(n, true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -611,7 +618,7 @@ func (p *printer) intersperseComments(next token.Position, tok token.Token) (dro
|
|||||||
var last *ast.Comment
|
var last *ast.Comment
|
||||||
for ; p.commentBefore(next); p.cindex++ {
|
for ; p.commentBefore(next); p.cindex++ {
|
||||||
for _, c := range p.comments[p.cindex].List {
|
for _, c := range p.comments[p.cindex].List {
|
||||||
p.writeCommentPrefix(p.fset.Position(c.Pos()), next, last == nil, tok.IsKeyword())
|
p.writeCommentPrefix(p.fset.Position(c.Pos()), next, last, tok.IsKeyword())
|
||||||
p.writeComment(c)
|
p.writeComment(c)
|
||||||
last = c
|
last = c
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ var data = []entry{
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func Test(t *testing.T) {
|
func TestFiles(t *testing.T) {
|
||||||
for _, e := range data {
|
for _, e := range data {
|
||||||
source := path.Join(dataDir, e.source)
|
source := path.Join(dataDir, e.source)
|
||||||
golden := path.Join(dataDir, e.golden)
|
golden := path.Join(dataDir, e.golden)
|
||||||
@ -136,3 +136,38 @@ func Test(t *testing.T) {
|
|||||||
//check(t, golden, golden, e.mode);
|
//check(t, golden, golden, e.mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TestLineComments, using a simple test case, checks that consequtive line
|
||||||
|
// comments are properly terminated with a newline even if the AST position
|
||||||
|
// information is incorrect.
|
||||||
|
//
|
||||||
|
func TestLineComments(t *testing.T) {
|
||||||
|
const src = `// comment 1
|
||||||
|
// comment 2
|
||||||
|
// comment 3
|
||||||
|
package main
|
||||||
|
`
|
||||||
|
|
||||||
|
fset := token.NewFileSet()
|
||||||
|
ast1, err1 := parser.ParseFile(fset, "", src, parser.ParseComments)
|
||||||
|
if err1 != nil {
|
||||||
|
panic(err1)
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
fset = token.NewFileSet() // use the wrong file set
|
||||||
|
Fprint(&buf, fset, ast1)
|
||||||
|
|
||||||
|
nlines := 0
|
||||||
|
for _, ch := range buf.Bytes() {
|
||||||
|
if ch == '\n' {
|
||||||
|
nlines++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const expected = 3
|
||||||
|
if nlines < expected {
|
||||||
|
t.Errorf("got %d, expected %d\n", nlines, expected)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user