printer: finalize comment printing, yay \o/
This commit is contained in:
parent
c9ef0afb41
commit
66daded6ac
@ -317,10 +317,15 @@ func (p *Parser) scan() token.Token {
|
|||||||
comment, endline = p.consumeCommentGroup(1)
|
comment, endline = p.consumeCommentGroup(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if endline+1 == p.tok.Pos.Line {
|
if endline+1 == p.tok.Pos.Line && p.tok.Type != token.RBRACE {
|
||||||
// The next token is following on the line immediately after the
|
switch p.tok.Type {
|
||||||
// comment group, thus the last comment group is a lead comment.
|
case token.RBRACE, token.RBRACK:
|
||||||
p.leadComment = comment
|
// Do not count for these cases
|
||||||
|
default:
|
||||||
|
// The next token is following on the line immediately after the
|
||||||
|
// comment group, thus the last comment group is a lead comment.
|
||||||
|
p.leadComment = comment
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
118
printer/nodes.go
118
printer/nodes.go
@ -10,14 +10,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
blank = byte(' ')
|
blank = byte(' ')
|
||||||
newline = byte('\n')
|
newline = byte('\n')
|
||||||
tab = byte('\t')
|
tab = byte('\t')
|
||||||
|
infinity = 1 << 30 // offset or line
|
||||||
)
|
)
|
||||||
|
|
||||||
type printer struct {
|
type printer struct {
|
||||||
cfg Config
|
cfg Config
|
||||||
prev ast.Node
|
prev token.Pos
|
||||||
|
|
||||||
comments []*ast.CommentGroup // may be nil, contains all comments
|
comments []*ast.CommentGroup // may be nil, contains all comments
|
||||||
standaloneComments []*ast.CommentGroup // contains all standalone comments (not assigned to any node)
|
standaloneComments []*ast.CommentGroup // contains all standalone comments (not assigned to any node)
|
||||||
@ -78,15 +79,8 @@ func (p *printer) collectComments(node ast.Node) {
|
|||||||
for _, c := range standaloneComments {
|
for _, c := range standaloneComments {
|
||||||
p.standaloneComments = append(p.standaloneComments, c)
|
p.standaloneComments = append(p.standaloneComments, c)
|
||||||
}
|
}
|
||||||
|
|
||||||
sort.Sort(ByPosition(p.standaloneComments))
|
sort.Sort(ByPosition(p.standaloneComments))
|
||||||
|
|
||||||
fmt.Printf("standaloneComments = %+v\n", len(p.standaloneComments))
|
|
||||||
for _, c := range p.standaloneComments {
|
|
||||||
for _, comment := range c.List {
|
|
||||||
fmt.Printf("comment = %+v\n", comment)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var count int
|
var count int
|
||||||
@ -100,31 +94,49 @@ func (p *printer) output(n interface{}) []byte {
|
|||||||
case *ast.File:
|
case *ast.File:
|
||||||
return p.output(t.Node)
|
return p.output(t.Node)
|
||||||
case *ast.ObjectList:
|
case *ast.ObjectList:
|
||||||
for i, item := range t.Items {
|
|
||||||
fmt.Printf("[%d] item: %s\n", i, item.Keys[0].Token.Text)
|
var index int
|
||||||
buf.Write(p.output(item))
|
var nextItem token.Pos
|
||||||
if i != len(t.Items)-1 {
|
var commented bool
|
||||||
|
for {
|
||||||
|
// TODO(arslan): refactor below comment printing, we have the same in objectType
|
||||||
|
|
||||||
|
// print stand alone upper level stand alone comments
|
||||||
|
for _, c := range p.standaloneComments {
|
||||||
|
for _, comment := range c.List {
|
||||||
|
if index != len(t.Items) {
|
||||||
|
nextItem = t.Items[index].Pos()
|
||||||
|
} else {
|
||||||
|
nextItem = token.Pos{Offset: infinity, Line: infinity}
|
||||||
|
}
|
||||||
|
|
||||||
|
if comment.Pos().After(p.prev) && comment.Pos().Before(nextItem) {
|
||||||
|
// if we hit the end add newlines so we can print the comment
|
||||||
|
if index == len(t.Items) {
|
||||||
|
buf.Write([]byte{newline, newline})
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.WriteString(comment.Text)
|
||||||
|
// TODO(arslan): do not print new lines if the comments are one liner
|
||||||
|
buf.Write([]byte{newline, newline})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if index == len(t.Items) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Write(p.output(t.Items[index]))
|
||||||
|
if !commented && index != len(t.Items)-1 {
|
||||||
buf.Write([]byte{newline, newline})
|
buf.Write([]byte{newline, newline})
|
||||||
}
|
}
|
||||||
|
index++
|
||||||
}
|
}
|
||||||
case *ast.ObjectKey:
|
case *ast.ObjectKey:
|
||||||
buf.WriteString(t.Token.Text)
|
buf.WriteString(t.Token.Text)
|
||||||
case *ast.ObjectItem:
|
case *ast.ObjectItem:
|
||||||
for _, c := range p.standaloneComments {
|
p.prev = t.Pos()
|
||||||
for _, comment := range c.List {
|
|
||||||
fmt.Printf("[%d] OBJECTITEM p.prev = %+v\n", count, p.prev.Pos())
|
|
||||||
fmt.Printf("[%d] OBJECTITEM comment.Pos() = %+v\n", count, comment.Pos())
|
|
||||||
fmt.Printf("[%d] OBJECTTYPE t.Pos() = %+v\n", count, t.Pos())
|
|
||||||
if comment.Pos().After(p.prev.Pos()) && comment.Pos().Before(t.Pos()) {
|
|
||||||
buf.WriteString(comment.Text)
|
|
||||||
// TODO(arslan): do not print new lines if the comments are one lines
|
|
||||||
buf.WriteByte(newline)
|
|
||||||
buf.WriteByte(newline)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p.prev = t
|
|
||||||
buf.Write(p.objectItem(t))
|
buf.Write(p.objectItem(t))
|
||||||
case *ast.LiteralType:
|
case *ast.LiteralType:
|
||||||
buf.WriteString(t.Token.Text)
|
buf.WriteString(t.Token.Text)
|
||||||
@ -136,10 +148,6 @@ func (p *printer) output(n interface{}) []byte {
|
|||||||
fmt.Printf(" unknown type: %T\n", n)
|
fmt.Printf(" unknown type: %T\n", n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if item, ok := n.(ast.Node); ok {
|
|
||||||
// p.prev = item
|
|
||||||
// }
|
|
||||||
|
|
||||||
return buf.Bytes()
|
return buf.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,28 +193,36 @@ func (p *printer) objectType(o *ast.ObjectType) []byte {
|
|||||||
|
|
||||||
var index int
|
var index int
|
||||||
var nextItem token.Pos
|
var nextItem token.Pos
|
||||||
|
var commented bool
|
||||||
for {
|
for {
|
||||||
|
// Print stand alone comments
|
||||||
for _, c := range p.standaloneComments {
|
for _, c := range p.standaloneComments {
|
||||||
for _, comment := range c.List {
|
for _, comment := range c.List {
|
||||||
fmt.Printf("[%d] OBJECTTYPE p.prev = %+v\n", count, p.prev.Pos())
|
// if we hit the end, last item should be the brace
|
||||||
fmt.Printf("[%d] OBJECTTYPE comment.Pos() = %+v\n", count, comment.Pos())
|
|
||||||
|
|
||||||
if index != len(o.List.Items) {
|
if index != len(o.List.Items) {
|
||||||
nextItem = o.List.Items[index].Pos()
|
nextItem = o.List.Items[index].Pos()
|
||||||
} else {
|
} else {
|
||||||
nextItem = o.Rbrace
|
nextItem = o.Rbrace
|
||||||
|
|
||||||
}
|
}
|
||||||
fmt.Printf("[%d] OBJECTTYPE nextItem = %+v\n", count, nextItem)
|
|
||||||
if comment.Pos().After(p.prev.Pos()) && comment.Pos().Before(nextItem) {
|
if comment.Pos().After(p.prev) && comment.Pos().Before(nextItem) {
|
||||||
buf.Write(p.indent([]byte(comment.Text))) // TODO(arslan): indent
|
// add newline if it's between other printed nodes
|
||||||
buf.WriteByte(newline)
|
if index > 0 {
|
||||||
|
commented = true
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Write(p.indent([]byte(comment.Text)))
|
||||||
buf.WriteByte(newline)
|
buf.WriteByte(newline)
|
||||||
|
if index != len(o.List.Items) {
|
||||||
|
buf.WriteByte(newline) // do not print on the end
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if index == len(o.List.Items) {
|
if index == len(o.List.Items) {
|
||||||
|
p.prev = o.Rbrace
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -265,30 +281,26 @@ func (p *printer) objectType(o *ast.ObjectType) []byte {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("==================> len(aligned) = %+v\n", len(aligned))
|
// put newlines if the items are between other non aligned items.
|
||||||
for _, b := range aligned {
|
// newlines are also added if there is a standalone comment already, so
|
||||||
fmt.Printf("b = %+v\n", b)
|
// check it too
|
||||||
}
|
if !commented && index != len(aligned) {
|
||||||
|
|
||||||
// put newlines if the items are between other non aligned items
|
|
||||||
if index != len(aligned) {
|
|
||||||
buf.WriteByte(newline)
|
buf.WriteByte(newline)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(aligned) >= 1 {
|
if len(aligned) >= 1 {
|
||||||
p.prev = aligned[len(aligned)-1]
|
p.prev = aligned[len(aligned)-1].Pos()
|
||||||
|
|
||||||
items := p.alignedItems(aligned)
|
items := p.alignedItems(aligned)
|
||||||
buf.Write(p.indent(items))
|
buf.Write(p.indent(items))
|
||||||
} else {
|
} else {
|
||||||
p.prev = o.List.Items[index]
|
p.prev = o.List.Items[index].Pos()
|
||||||
|
|
||||||
buf.Write(p.indent(p.objectItem(o.List.Items[index])))
|
buf.Write(p.indent(p.objectItem(o.List.Items[index])))
|
||||||
index++
|
index++
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.WriteByte(newline)
|
buf.WriteByte(newline)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buf.WriteString("}")
|
buf.WriteString("}")
|
||||||
|
@ -22,7 +22,6 @@ func (c *Config) Fprint(output io.Writer, node ast.Node) error {
|
|||||||
cfg: *c,
|
cfg: *c,
|
||||||
comments: make([]*ast.CommentGroup, 0),
|
comments: make([]*ast.CommentGroup, 0),
|
||||||
standaloneComments: make([]*ast.CommentGroup, 0),
|
standaloneComments: make([]*ast.CommentGroup, 0),
|
||||||
prev: ast.NewNode(),
|
|
||||||
// enableTrace: true,
|
// enableTrace: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,7 @@ var data = []entry{
|
|||||||
{"list.input", "list.golden"},
|
{"list.input", "list.golden"},
|
||||||
{"comment.input", "comment.golden"},
|
{"comment.input", "comment.golden"},
|
||||||
{"comment_aligned.input", "comment_aligned.golden"},
|
{"comment_aligned.input", "comment_aligned.golden"},
|
||||||
|
{"comment_standalone.input", "comment_standalone.golden"},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFiles(t *testing.T) {
|
func TestFiles(t *testing.T) {
|
||||||
|
17
printer/testdata/comment_standalone.golden
vendored
Normal file
17
printer/testdata/comment_standalone.golden
vendored
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// A standalone comment
|
||||||
|
|
||||||
|
aligned = {
|
||||||
|
# Standalone 1
|
||||||
|
|
||||||
|
a = "bar" # yoo1
|
||||||
|
default = "bar" # yoo2
|
||||||
|
|
||||||
|
# Standalone 2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Standalone 3
|
||||||
|
|
||||||
|
numbers = [1, 2] // another line here
|
||||||
|
|
||||||
|
# Standalone 4
|
||||||
|
|
16
printer/testdata/comment_standalone.input
vendored
Normal file
16
printer/testdata/comment_standalone.input
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// A standalone comment
|
||||||
|
|
||||||
|
aligned {
|
||||||
|
# Standalone 1
|
||||||
|
|
||||||
|
a = "bar" # yoo1
|
||||||
|
default = "bar" # yoo2
|
||||||
|
|
||||||
|
# Standalone 2
|
||||||
|
}
|
||||||
|
|
||||||
|
# Standalone 3
|
||||||
|
|
||||||
|
numbers = [1,2] // another line here
|
||||||
|
|
||||||
|
# Standalone 4
|
Loading…
Reference in New Issue
Block a user