diff --git a/src/cmd/godoc/godoc.go b/src/cmd/godoc/godoc.go index 71be62fb47..41bd37ad66 100644 --- a/src/cmd/godoc/godoc.go +++ b/src/cmd/godoc/godoc.go @@ -374,7 +374,7 @@ func writeNode(w io.Writer, fset *token.FileSet, x interface{}) { // with an another printer mode (which is more efficiently // implemented in the printer than here with another layer) mode := printer.TabIndent | printer.UseSpaces - (&printer.Config{Mode: mode, Tabwidth: *tabwidth}).Fprint(&tconv{output: w}, fset, x) + (&printer.Config{mode, *tabwidth}).Fprint(&tconv{output: w}, fset, x) } diff --git a/src/cmd/gofix/main.go b/src/cmd/gofix/main.go index ca4becfa75..9ca2ddb461 100644 --- a/src/cmd/gofix/main.go +++ b/src/cmd/gofix/main.go @@ -127,7 +127,7 @@ func processFile(filename string, useStdin bool) os.Error { fmt.Fprintf(os.Stderr, "%s: %s\n", filename, buf.String()[1:]) buf.Reset() - _, err = (&printer.Config{Mode: printerMode, Tabwidth: tabWidth}).Fprint(&buf, fset, file) + _, err = (&printer.Config{printerMode, tabWidth}).Fprint(&buf, fset, file) if err != nil { return err } diff --git a/src/cmd/gofix/main_test.go b/src/cmd/gofix/main_test.go index ffcbe7cb09..e4d0f60cce 100644 --- a/src/cmd/gofix/main_test.go +++ b/src/cmd/gofix/main_test.go @@ -37,7 +37,7 @@ func parseFixPrint(t *testing.T, fn func(*ast.File) bool, desc, in string) (out var buf bytes.Buffer buf.Reset() - _, err = (&printer.Config{Mode: printerMode, Tabwidth: tabWidth}).Fprint(&buf, fset, file) + _, err = (&printer.Config{printerMode, tabWidth}).Fprint(&buf, fset, file) if err != nil { t.Errorf("%s: printing: %v", desc, err) return @@ -60,7 +60,7 @@ func parseFixPrint(t *testing.T, fn func(*ast.File) bool, desc, in string) (out } buf.Reset() - _, err = (&printer.Config{Mode: printerMode, Tabwidth: tabWidth}).Fprint(&buf, fset, file) + _, err = (&printer.Config{printerMode, tabWidth}).Fprint(&buf, fset, file) if err != nil { t.Errorf("%s: printing: %v", desc, err) return diff --git a/src/cmd/gofmt/gofmt.go b/src/cmd/gofmt/gofmt.go index 943877aa27..a688c8184c 100644 --- a/src/cmd/gofmt/gofmt.go +++ b/src/cmd/gofmt/gofmt.go @@ -103,7 +103,7 @@ func processFile(f *os.File) os.Error { } var buf bytes.Buffer - _, err = (&printer.Config{Mode: printerMode, Tabwidth: *tabWidth}).Fprint(&buf, fset, file) + _, err = (&printer.Config{printerMode, *tabWidth}).Fprint(&buf, fset, file) if err != nil { return err } diff --git a/src/pkg/go/printer/nodes.go b/src/pkg/go/printer/nodes.go index f55a641975..2238b6bedc 100644 --- a/src/pkg/go/printer/nodes.go +++ b/src/pkg/go/printer/nodes.go @@ -1318,9 +1318,9 @@ func (p *printer) nodeSize(n ast.Node, maxSize int) (size int) { // nodeSize computation must be indendent of particular // style so that we always get the same decision; print // in RawFormat - cfg := Config{Mode: RawFormat, nodeSizes: p.nodeSizes} + cfg := Config{Mode: RawFormat} var buf bytes.Buffer - if _, err := cfg.Fprint(&buf, p.fset, n); err != nil { + if _, err := cfg.fprint(&buf, p.fset, n, p.nodeSizes); err != nil { return } if buf.Len() <= maxSize { diff --git a/src/pkg/go/printer/printer.go b/src/pkg/go/printer/printer.go index 6c925ad4fd..a43e4a12c7 100644 --- a/src/pkg/go/printer/printer.go +++ b/src/pkg/go/printer/printer.go @@ -98,15 +98,19 @@ type printer struct { comments []*ast.CommentGroup // may be nil cindex int // current comment index useNodeComments bool // if not set, ignore lead and line comments of nodes + + // Cache of already computed node sizes. + nodeSizes map[ast.Node]int } -func (p *printer) init(output io.Writer, cfg *Config, fset *token.FileSet) { +func (p *printer) init(output io.Writer, cfg *Config, fset *token.FileSet, nodeSizes map[ast.Node]int) { p.output = output p.Config = *cfg p.fset = fset p.errors = make(chan os.Error) p.buffer = make([]whiteSpace, 0, 16) // whitespace sequences are short + p.nodeSizes = nodeSizes } @@ -986,25 +990,13 @@ const ( // A Config node controls the output of Fprint. type Config struct { - Mode uint // default: 0 - Tabwidth int // default: 8 - nodeSizes map[ast.Node]int // memoized node sizes as computed by nodeSize + Mode uint // default: 0 + Tabwidth int // default: 8 } -// Fprint "pretty-prints" an AST node to output and returns the number -// of bytes written and an error (if any) for a given configuration cfg. -// Position information is interpreted relative to the file set fset. -// The node type must be *ast.File, or assignment-compatible to ast.Expr, -// ast.Decl, ast.Spec, or ast.Stmt. -// -func (cfg *Config) Fprint(output io.Writer, fset *token.FileSet, node interface{}) (int, os.Error) { - // only if Fprint is called recursively (via nodeSize) - // does cfg.nodeSizes exist - set it up otherwise - if cfg.nodeSizes == nil { - cfg.nodeSizes = make(map[ast.Node]int) - } - +// fprint implements Fprint and takes a nodesSizes map for setting up the printer state. +func (cfg *Config) fprint(output io.Writer, fset *token.FileSet, node interface{}, nodeSizes map[ast.Node]int) (int, os.Error) { // redirect output through a trimmer to eliminate trailing whitespace // (Input to a tabwriter must be untrimmed since trailing tabs provide // formatting information. The tabwriter could provide trimming @@ -1033,7 +1025,7 @@ func (cfg *Config) Fprint(output io.Writer, fset *token.FileSet, node interface{ // setup printer and print node var p printer - p.init(output, cfg, fset) + p.init(output, cfg, fset, nodeSizes) go func() { switch n := node.(type) { case ast.Expr: @@ -1080,6 +1072,17 @@ func (cfg *Config) Fprint(output io.Writer, fset *token.FileSet, node interface{ } +// Fprint "pretty-prints" an AST node to output and returns the number +// of bytes written and an error (if any) for a given configuration cfg. +// Position information is interpreted relative to the file set fset. +// The node type must be *ast.File, or assignment-compatible to ast.Expr, +// ast.Decl, ast.Spec, or ast.Stmt. +// +func (cfg *Config) Fprint(output io.Writer, fset *token.FileSet, node interface{}) (int, os.Error) { + return cfg.fprint(output, fset, node, make(map[ast.Node]int)) +} + + // Fprint "pretty-prints" an AST node to output. // It calls Config.Fprint with default settings. //