diff options
author | Robert Griesemer <gri@golang.org> | 2021-01-07 12:57:15 -0800 |
---|---|---|
committer | Robert Griesemer <gri@golang.org> | 2021-01-08 17:32:14 +0000 |
commit | 934f9dc0efbae667c445684915676323b98b34d0 (patch) | |
tree | 1c4af8dff3303dc337466dedad8a45f41a647191 /src/cmd/compile/internal/syntax/printer.go | |
parent | 5b9152de579a75962a48d5380abcc2d4deedbf28 (diff) | |
download | go-934f9dc0efbae667c445684915676323b98b34d0.tar.gz go-934f9dc0efbae667c445684915676323b98b34d0.zip |
[dev.typeparams] cmd/compile/internal/syntax: clean up node printing API
Preparation for using the syntax printer as expression printer in types2.
- Introduced Form to control printing format
- Cleaned up/added String and ShortString convenience functions
- Implemented ShortForm format which prints … for non-empty
function and composite literal bodies
- Added test to check write error handling
Change-Id: Ie86e46d766fb60fcf07ef643c7788b2ef440ffa8
Reviewed-on: https://go-review.googlesource.com/c/go/+/282552
Trust: Robert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/syntax/printer.go')
-rw-r--r-- | src/cmd/compile/internal/syntax/printer.go | 80 |
1 files changed, 60 insertions, 20 deletions
diff --git a/src/cmd/compile/internal/syntax/printer.go b/src/cmd/compile/internal/syntax/printer.go index c8bf59675a..0a60e1753d 100644 --- a/src/cmd/compile/internal/syntax/printer.go +++ b/src/cmd/compile/internal/syntax/printer.go @@ -13,19 +13,28 @@ import ( "strings" ) -// TODO(gri) Consider removing the linebreaks flag from this signature. -// Its likely rarely used in common cases. +// Form controls print formatting. +type Form uint -func Fprint(w io.Writer, x Node, linebreaks bool) (n int, err error) { +const ( + _ Form = iota // default + LineForm // use spaces instead of linebreaks where possible + ShortForm // like LineForm but print "…" for non-empty function or composite literal bodies +) + +// Fprint prints node x to w in the specified form. +// It returns the number of bytes written, and whether there was an error. +func Fprint(w io.Writer, x Node, form Form) (n int, err error) { p := printer{ output: w, - linebreaks: linebreaks, + form: form, + linebreaks: form == 0, } defer func() { n = p.written if e := recover(); e != nil { - err = e.(localError).err // re-panics if it's not a localError + err = e.(writeError).err // re-panics if it's not a writeError } }() @@ -35,15 +44,20 @@ func Fprint(w io.Writer, x Node, linebreaks bool) (n int, err error) { return } -func String(n Node) string { +func asString(n Node, form Form) string { var buf bytes.Buffer - _, err := Fprint(&buf, n, false) + _, err := Fprint(&buf, n, form) if err != nil { - panic(err) // TODO(gri) print something sensible into buf instead + fmt.Fprintf(&buf, "<<< ERROR: %s", err) } return buf.String() } +// String and ShortString are convenience functions that print n in +// LineForm or ShortForm respectively, and return the printed string. +func String(n Node) string { return asString(n, LineForm) } +func ShortString(n Node) string { return asString(n, ShortForm) } + type ctrlSymbol int const ( @@ -65,7 +79,8 @@ type whitespace struct { type printer struct { output io.Writer - written int // number of bytes written + written int // number of bytes written + form Form linebreaks bool // print linebreaks instead of semis indent int // current indentation level @@ -81,7 +96,7 @@ func (p *printer) write(data []byte) { n, err := p.output.Write(data) p.written += n if err != nil { - panic(localError{err}) + panic(writeError{err}) } } @@ -355,17 +370,34 @@ func (p *printer) printRawNode(n Node) { p.print(_Name, n.Value) // _Name requires actual value following immediately case *FuncLit: - p.print(n.Type, blank, n.Body) + p.print(n.Type, blank) + if n.Body != nil { + if p.form == ShortForm { + p.print(_Lbrace) + if len(n.Body.List) > 0 { + p.print(_Name, "…") + } + p.print(_Rbrace) + } else { + p.print(n.Body) + } + } case *CompositeLit: if n.Type != nil { p.print(n.Type) } p.print(_Lbrace) - if n.NKeys > 0 && n.NKeys == len(n.ElemList) { - p.printExprLines(n.ElemList) + if p.form == ShortForm { + if len(n.ElemList) > 0 { + p.print(_Name, "…") + } } else { - p.printExprList(n.ElemList) + if n.NKeys > 0 && n.NKeys == len(n.ElemList) { + p.printExprLines(n.ElemList) + } else { + p.printExprList(n.ElemList) + } } p.print(_Rbrace) @@ -450,9 +482,13 @@ func (p *printer) printRawNode(n Node) { } p.print(_Lbrace) if len(n.FieldList) > 0 { - p.print(newline, indent) - p.printFieldList(n.FieldList, n.TagList) - p.print(outdent, newline) + if p.linebreaks { + p.print(newline, indent) + p.printFieldList(n.FieldList, n.TagList) + p.print(outdent, newline) + } else { + p.printFieldList(n.FieldList, n.TagList) + } } p.print(_Rbrace) @@ -467,9 +503,13 @@ func (p *printer) printRawNode(n Node) { } p.print(_Lbrace) if len(n.MethodList) > 0 { - p.print(newline, indent) - p.printMethodList(n.MethodList) - p.print(outdent, newline) + if p.linebreaks { + p.print(newline, indent) + p.printMethodList(n.MethodList) + p.print(outdent, newline) + } else { + p.printMethodList(n.MethodList) + } } p.print(_Rbrace) |