printer: collect standalone comments for printing

This commit is contained in:
Fatih Arslan 2015-10-31 01:15:36 +03:00
parent 407cd650d1
commit 629539558b
4 changed files with 66 additions and 6 deletions

View File

@ -11,6 +11,8 @@ func Walk(node Node, fn func(Node) bool) {
}
switch n := node.(type) {
case *File:
Walk(n.Node, fn)
case *ObjectList:
for _, item := range n.Items {
Walk(item, fn)

View File

@ -17,7 +17,6 @@ type Parser struct {
// Last read token
tok token.Token
// comments
comments []*ast.CommentGroup
leadComment *ast.CommentGroup // last lead comment
lineComment *ast.CommentGroup // last line comment

View File

@ -5,6 +5,7 @@ import (
"fmt"
"github.com/fatih/hcl/ast"
"github.com/fatih/hcl/token"
)
const (
@ -13,6 +14,64 @@ const (
tab = byte('\t')
)
type printer struct {
cfg Config
comments []*ast.CommentGroup // may be nil, contains all comments
standaloneComments []*ast.CommentGroup // contains all standalone comments (not assigned to any node)
}
func (p *printer) collectComments(node ast.Node) {
leadComments := make([]*ast.CommentGroup, 0)
lineComments := make([]*ast.CommentGroup, 0)
ast.Walk(node, func(nn ast.Node) bool {
switch t := nn.(type) {
case *ast.File:
// will happen only once
p.comments = t.Comments
case *ast.ObjectItem:
if t.LeadComment != nil {
leadComments = append(leadComments, t.LeadComment)
}
if t.LineComment != nil {
lineComments = append(lineComments, t.LineComment)
}
}
return true
})
standaloneComments := make(map[token.Pos]*ast.CommentGroup, 0)
for _, c := range p.comments {
standaloneComments[c.Pos()] = c
}
for _, lead := range leadComments {
for _, comment := range lead.List {
if _, ok := standaloneComments[comment.Pos()]; ok {
delete(standaloneComments, comment.Pos())
}
}
}
for _, line := range lineComments {
for _, comment := range line.List {
if _, ok := standaloneComments[comment.Pos()]; ok {
delete(standaloneComments, comment.Pos())
}
}
}
for _, c := range standaloneComments {
p.standaloneComments = append(p.standaloneComments, c)
}
fmt.Printf("All comments len = %+v\n", len(p.comments))
fmt.Printf("Lead commetns = %+v\n", len(leadComments))
fmt.Printf("len(lineComments) = %+v\n", len(lineComments))
fmt.Printf("StandAlone Comments = %+v\n", len(p.standaloneComments))
}
// output prints creates a printable HCL output and returns it.
func (p *printer) output(n interface{}) []byte {
var buf bytes.Buffer

View File

@ -12,10 +12,6 @@ import (
var DefaultConfig = Config{}
type printer struct {
cfg Config
}
// A Config node controls the output of Fprint.
type Config struct {
SpacesWidth int // if set, it will use spaces instead of tabs for alignment
@ -23,9 +19,13 @@ type Config struct {
func (c *Config) Fprint(output io.Writer, node ast.Node) error {
p := &printer{
cfg: *c,
cfg: *c,
comments: make([]*ast.CommentGroup, 0),
standaloneComments: make([]*ast.CommentGroup, 0),
}
p.collectComments(node)
if _, err := output.Write(p.output(node)); err != nil {
return err
}