Merge pull request #157 from hashicorp/b-comment-array
hcl/{parser,printer}: track and print lead comments for list items
This commit is contained in:
commit
06a327dabb
@ -156,7 +156,8 @@ func (o *ObjectKey) Pos() token.Pos {
|
|||||||
type LiteralType struct {
|
type LiteralType struct {
|
||||||
Token token.Token
|
Token token.Token
|
||||||
|
|
||||||
// associated line comment, only when used in a list
|
// comment types, only used when in a list
|
||||||
|
LeadComment *CommentGroup
|
||||||
LineComment *CommentGroup
|
LineComment *CommentGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,6 +337,12 @@ func (p *Parser) listType() (*ast.ListType, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there is a lead comment, apply it
|
||||||
|
if p.leadComment != nil {
|
||||||
|
node.LeadComment = p.leadComment
|
||||||
|
p.leadComment = nil
|
||||||
|
}
|
||||||
|
|
||||||
l.Add(node)
|
l.Add(node)
|
||||||
needComma = true
|
needComma = true
|
||||||
case token.COMMA:
|
case token.COMMA:
|
||||||
|
@ -152,6 +152,109 @@ func TestListOfMaps_requiresComma(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestListType_leadComment(t *testing.T) {
|
||||||
|
var literals = []struct {
|
||||||
|
src string
|
||||||
|
comment []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
`foo = [
|
||||||
|
1,
|
||||||
|
# bar
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
]`,
|
||||||
|
[]string{"", "# bar", ""},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, l := range literals {
|
||||||
|
p := newParser([]byte(l.src))
|
||||||
|
item, err := p.objectItem()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
list, ok := item.Val.(*ast.ListType)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("node should be of type LiteralType, got: %T", item.Val)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(list.List) != len(l.comment) {
|
||||||
|
t.Fatalf("bad: %d", len(list.List))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, li := range list.List {
|
||||||
|
lt := li.(*ast.LiteralType)
|
||||||
|
comment := l.comment[i]
|
||||||
|
|
||||||
|
if (lt.LeadComment == nil) != (comment == "") {
|
||||||
|
t.Fatalf("bad: %#v", lt)
|
||||||
|
}
|
||||||
|
|
||||||
|
if comment == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := lt.LeadComment.List[0].Text
|
||||||
|
if actual != comment {
|
||||||
|
t.Fatalf("bad: %q %q", actual, comment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListType_lineComment(t *testing.T) {
|
||||||
|
var literals = []struct {
|
||||||
|
src string
|
||||||
|
comment []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
`foo = [
|
||||||
|
1,
|
||||||
|
2, # bar
|
||||||
|
3,
|
||||||
|
]`,
|
||||||
|
[]string{"", "# bar", ""},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, l := range literals {
|
||||||
|
p := newParser([]byte(l.src))
|
||||||
|
item, err := p.objectItem()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
list, ok := item.Val.(*ast.ListType)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("node should be of type LiteralType, got: %T", item.Val)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(list.List) != len(l.comment) {
|
||||||
|
t.Fatalf("bad: %d", len(list.List))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, li := range list.List {
|
||||||
|
lt := li.(*ast.LiteralType)
|
||||||
|
comment := l.comment[i]
|
||||||
|
|
||||||
|
if (lt.LineComment == nil) != (comment == "") {
|
||||||
|
t.Fatalf("bad: %s", lt)
|
||||||
|
}
|
||||||
|
|
||||||
|
if comment == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := lt.LineComment.List[0].Text
|
||||||
|
if actual != comment {
|
||||||
|
t.Fatalf("bad: %q %q", actual, comment)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestObjectType(t *testing.T) {
|
func TestObjectType(t *testing.T) {
|
||||||
var literals = []struct {
|
var literals = []struct {
|
||||||
src string
|
src string
|
||||||
|
@ -62,6 +62,14 @@ func (p *printer) collectComments(node ast.Node) {
|
|||||||
ast.Walk(node, func(nn ast.Node) (ast.Node, bool) {
|
ast.Walk(node, func(nn ast.Node) (ast.Node, bool) {
|
||||||
switch t := nn.(type) {
|
switch t := nn.(type) {
|
||||||
case *ast.LiteralType:
|
case *ast.LiteralType:
|
||||||
|
if t.LeadComment != nil {
|
||||||
|
for _, comment := range t.LeadComment.List {
|
||||||
|
if _, ok := standaloneComments[comment.Pos()]; ok {
|
||||||
|
delete(standaloneComments, comment.Pos())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if t.LineComment != nil {
|
if t.LineComment != nil {
|
||||||
for _, comment := range t.LineComment.List {
|
for _, comment := range t.LineComment.List {
|
||||||
if _, ok := standaloneComments[comment.Pos()]; ok {
|
if _, ok := standaloneComments[comment.Pos()]; ok {
|
||||||
@ -440,11 +448,33 @@ func (p *printer) list(l *ast.ListType) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
insertSpaceBeforeItem := false
|
insertSpaceBeforeItem := false
|
||||||
|
lastHadLeadComment := false
|
||||||
for i, item := range l.List {
|
for i, item := range l.List {
|
||||||
if item.Pos().Line != l.Lbrack.Line {
|
if item.Pos().Line != l.Lbrack.Line {
|
||||||
// multiline list, add newline before we add each item
|
// multiline list, add newline before we add each item
|
||||||
buf.WriteByte(newline)
|
buf.WriteByte(newline)
|
||||||
insertSpaceBeforeItem = false
|
insertSpaceBeforeItem = false
|
||||||
|
|
||||||
|
// If we have a lead comment, then we want to write that first
|
||||||
|
leadComment := false
|
||||||
|
if lit, ok := item.(*ast.LiteralType); ok && lit.LeadComment != nil {
|
||||||
|
leadComment = true
|
||||||
|
|
||||||
|
// If this isn't the first item and the previous element
|
||||||
|
// didn't have a lead comment, then we need to add an extra
|
||||||
|
// newline to properly space things out. If it did have a
|
||||||
|
// lead comment previously then this would be done
|
||||||
|
// automatically.
|
||||||
|
if i > 0 && !lastHadLeadComment {
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, comment := range lit.LeadComment.List {
|
||||||
|
buf.Write(p.indent([]byte(comment.Text)))
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// also indent each line
|
// also indent each line
|
||||||
val := p.output(item)
|
val := p.output(item)
|
||||||
curLen := len(val)
|
curLen := len(val)
|
||||||
@ -463,9 +493,16 @@ func (p *printer) list(l *ast.ListType) []byte {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if i == len(l.List)-1 {
|
lastItem := i == len(l.List)-1
|
||||||
|
if lastItem {
|
||||||
buf.WriteByte(newline)
|
buf.WriteByte(newline)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if leadComment && !lastItem {
|
||||||
|
buf.WriteByte(newline)
|
||||||
|
}
|
||||||
|
|
||||||
|
lastHadLeadComment = leadComment
|
||||||
} else {
|
} else {
|
||||||
if insertSpaceBeforeItem {
|
if insertSpaceBeforeItem {
|
||||||
buf.WriteByte(blank)
|
buf.WriteByte(blank)
|
||||||
|
@ -33,6 +33,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_array.input", "comment_array.golden"},
|
||||||
{"comment_newline.input", "comment_newline.golden"},
|
{"comment_newline.input", "comment_newline.golden"},
|
||||||
{"comment_standalone.input", "comment_standalone.golden"},
|
{"comment_standalone.input", "comment_standalone.golden"},
|
||||||
{"empty_block.input", "empty_block.golden"},
|
{"empty_block.input", "empty_block.golden"},
|
||||||
|
13
hcl/printer/testdata/comment_array.golden
vendored
Normal file
13
hcl/printer/testdata/comment_array.golden
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
banana = [
|
||||||
|
# I really want to comment this item in the array.
|
||||||
|
"a",
|
||||||
|
|
||||||
|
# This as well
|
||||||
|
"b",
|
||||||
|
|
||||||
|
"c", # And C
|
||||||
|
"d",
|
||||||
|
|
||||||
|
# And another
|
||||||
|
"e",
|
||||||
|
]
|
13
hcl/printer/testdata/comment_array.input
vendored
Normal file
13
hcl/printer/testdata/comment_array.input
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
banana = [
|
||||||
|
# I really want to comment this item in the array.
|
||||||
|
"a",
|
||||||
|
|
||||||
|
# This as well
|
||||||
|
"b",
|
||||||
|
|
||||||
|
"c", # And C
|
||||||
|
"d",
|
||||||
|
|
||||||
|
# And another
|
||||||
|
"e",
|
||||||
|
]
|
Loading…
x
Reference in New Issue
Block a user