printer: initial implementation. I'm still experimenting though

This commit is contained in:
Fatih Arslan 2015-10-25 01:23:50 +03:00
parent 71105156e2
commit 5918e3592b
3 changed files with 95 additions and 12 deletions

View File

@ -1 +1,84 @@
package printer package printer
import (
"bytes"
"fmt"
"github.com/fatih/hcl/ast"
)
func (p *printer) printNode(n ast.Node) []byte {
var buf bytes.Buffer
switch t := n.(type) {
case *ast.ObjectList:
fmt.Println("printing objectList", t)
for _, item := range t.Items {
buf.Write(p.printObjectItem(item))
}
case *ast.ObjectKey:
fmt.Println("printing objectKey", t)
case *ast.ObjectItem:
fmt.Println("printing objectItem", t)
buf.Write(p.printObjectItem(t))
case *ast.LiteralType:
buf.Write(p.printLiteral(t))
case *ast.ListType:
buf.Write(p.printList(t))
case *ast.ObjectType:
fmt.Println("printing ObjectType", t)
default:
fmt.Printf(" unknown type: %T\n", n)
}
return buf.Bytes()
}
func (p *printer) printObjectItem(o *ast.ObjectItem) []byte {
var buf bytes.Buffer
for i, k := range o.Keys {
buf.WriteString(k.Token.Text)
if i != len(o.Keys)-1 || len(o.Keys) == 1 {
buf.WriteString(" ")
}
// reach end of key
if i == len(o.Keys)-1 {
buf.WriteString("=")
buf.WriteString(" ")
}
}
buf.Write(p.printNode(o.Val))
return buf.Bytes()
}
func (p *printer) printLiteral(l *ast.LiteralType) []byte {
return []byte(l.Token.Text)
}
func (p *printer) printList(l *ast.ListType) []byte {
var buf bytes.Buffer
buf.WriteString("[")
for i, item := range l.List {
if item.Pos().Line != l.Lbrack.Line {
// not same line
buf.WriteString("\n")
}
buf.Write(p.printNode(item))
if i != len(l.List)-1 {
buf.WriteString(",")
buf.WriteString(" ")
} else if item.Pos().Line != l.Lbrack.Line {
buf.WriteString(",")
buf.WriteString("\n")
}
}
buf.WriteString("]")
return buf.Bytes()
}

View File

@ -1,7 +1,6 @@
package printer package printer
import ( import (
"bytes"
"fmt" "fmt"
"io" "io"
"text/tabwriter" "text/tabwriter"
@ -10,20 +9,14 @@ import (
) )
type printer struct { type printer struct {
out []byte // raw printer result
cfg Config cfg Config
node ast.Node node ast.Node
} }
func (p *printer) output() []byte { func (p *printer) output() []byte {
var buf bytes.Buffer
fmt.Println("STARTING OUTPUT") fmt.Println("STARTING OUTPUT")
return p.printNode(p.node)
ast.Walk(p.node, func(n ast.Node) bool {
fmt.Printf("n = %+v\n", n)
return true
})
return buf.Bytes()
} }
// A Mode value is a set of flags (or 0). They control printing. // A Mode value is a set of flags (or 0). They control printing.
@ -38,7 +31,7 @@ const (
// A Config node controls the output of Fprint. // A Config node controls the output of Fprint.
type Config struct { type Config struct {
Mode Mode // default: 0 Mode Mode // default: 0
Tabwidth int // default: 8 Tabwidth int // default: 4
Indent int // default: 0 (all code is indented at least by this much) Indent int // default: 0 (all code is indented at least by this much)
} }
@ -94,5 +87,5 @@ func (c *Config) Fprint(output io.Writer, node ast.Node) error {
// Fprint "pretty-prints" an HCL node to output // Fprint "pretty-prints" an HCL node to output
// It calls Config.Fprint with default settings. // It calls Config.Fprint with default settings.
func Fprint(output io.Writer, node ast.Node) error { func Fprint(output io.Writer, node ast.Node) error {
return (&Config{Tabwidth: 8}).Fprint(output, node) return (&Config{Tabwidth: 4}).Fprint(output, node)
} }

View File

@ -7,6 +7,12 @@ import (
"github.com/fatih/hcl/parser" "github.com/fatih/hcl/parser"
) )
var listHCL = `foo = ["fatih", "arslan"]`
var listHCL2 = `foo = [
"fatih",
"arslan",
]`
var complexHcl = `// This comes from Terraform, as a test var complexHcl = `// This comes from Terraform, as a test
variable "foo" { variable "foo" {
default = "bar" default = "bar"
@ -52,7 +58,8 @@ output "web_ip" {
` `
func TestPrint(t *testing.T) { func TestPrint(t *testing.T) {
node, err := parser.Parse([]byte(complexHcl)) // node, err := parser.Parse([]byte(complexHcl))
node, err := parser.Parse([]byte(listHCL2))
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }