mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.regabi] cmd/compile: simplify Op, Node, Nodes printing
nconvFmt calls base.Fatalf if mode is anything but FErr, proving that the only formats that matter for nodes are plain %v, %S, and %L. And the nodes formatter can only get to %v. (%S and %v are the same; we'll clean that up separately.) Node and Nodes can therefore ignore mode, and all the mode code can be removed from those implementations, removing quite a few layers of abstraction. Op similarly only runs in one mode and can be simplified. Passes buildall w/ toolstash -cmp. Change-Id: Ibfd845033e9c68181a20fb81c8f3dd428463920a Reviewed-on: https://go-review.googlesource.com/c/go/+/275775 Trust: Russ Cox <rsc@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
8ce2605c5b
commit
3b25f3c150
3 changed files with 155 additions and 200 deletions
|
|
@ -85,8 +85,6 @@ var knownFormats = map[string]string{
|
||||||
"cmd/compile/internal/gc.itag %v": "",
|
"cmd/compile/internal/gc.itag %v": "",
|
||||||
"cmd/compile/internal/ir.Class %d": "",
|
"cmd/compile/internal/ir.Class %d": "",
|
||||||
"cmd/compile/internal/ir.Class %v": "",
|
"cmd/compile/internal/ir.Class %v": "",
|
||||||
"cmd/compile/internal/ir.FmtMode %d": "",
|
|
||||||
"cmd/compile/internal/ir.Node %+S": "",
|
|
||||||
"cmd/compile/internal/ir.Node %+v": "",
|
"cmd/compile/internal/ir.Node %+v": "",
|
||||||
"cmd/compile/internal/ir.Node %L": "",
|
"cmd/compile/internal/ir.Node %L": "",
|
||||||
"cmd/compile/internal/ir.Node %S": "",
|
"cmd/compile/internal/ir.Node %S": "",
|
||||||
|
|
|
||||||
|
|
@ -481,7 +481,7 @@ opswitch:
|
||||||
switch n.Op() {
|
switch n.Op() {
|
||||||
default:
|
default:
|
||||||
ir.Dump("walk", n)
|
ir.Dump("walk", n)
|
||||||
base.Fatalf("walkexpr: switch 1 unknown op %+S", n)
|
base.Fatalf("walkexpr: switch 1 unknown op %+v", n.Op())
|
||||||
|
|
||||||
case ir.ONONAME, ir.OGETG, ir.ONEWOBJ, ir.OMETHEXPR:
|
case ir.ONONAME, ir.OGETG, ir.ONEWOBJ, ir.OMETHEXPR:
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -170,19 +170,13 @@ func (m FmtMode) Sprint(args ...interface{}) string {
|
||||||
func (m FmtMode) prepareArgs(args []interface{}) {
|
func (m FmtMode) prepareArgs(args []interface{}) {
|
||||||
for i, arg := range args {
|
for i, arg := range args {
|
||||||
switch arg := arg.(type) {
|
switch arg := arg.(type) {
|
||||||
case Op:
|
|
||||||
args[i] = &fmtOp{arg, m}
|
|
||||||
case Node:
|
|
||||||
args[i] = &fmtNode{arg, m}
|
|
||||||
case nil:
|
case nil:
|
||||||
args[i] = &fmtNode{nil, m} // assume this was a node interface
|
args[i] = "<N>" // assume this was a node interface
|
||||||
case *types.Type:
|
case *types.Type:
|
||||||
args[i] = &fmtType{arg, m}
|
args[i] = &fmtType{arg, m}
|
||||||
case *types.Sym:
|
case *types.Sym:
|
||||||
args[i] = &fmtSym{arg, m}
|
args[i] = &fmtSym{arg, m}
|
||||||
case Nodes:
|
case int32, int64, string, Op, Node, Nodes, types.Kind, constant.Value:
|
||||||
args[i] = &fmtNodes{arg, m}
|
|
||||||
case int32, int64, string, types.Kind, constant.Value:
|
|
||||||
// OK: printing these types doesn't depend on mode
|
// OK: printing these types doesn't depend on mode
|
||||||
default:
|
default:
|
||||||
base.Fatalf("mode.prepareArgs type %T", arg)
|
base.Fatalf("mode.prepareArgs type %T", arg)
|
||||||
|
|
@ -265,13 +259,6 @@ func (o Op) GoString() string {
|
||||||
return o.String()
|
return o.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
type fmtOp struct {
|
|
||||||
x Op
|
|
||||||
m FmtMode
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fmtOp) Format(s fmt.State, verb rune) { f.x.Format(s, verb) }
|
|
||||||
|
|
||||||
func (o Op) Format(s fmt.State, verb rune) {
|
func (o Op) Format(s fmt.State, verb rune) {
|
||||||
switch verb {
|
switch verb {
|
||||||
default:
|
default:
|
||||||
|
|
@ -851,7 +838,7 @@ func fldconv(b *bytes.Buffer, f *types.Field, flag FmtFlag, mode FmtMode, visite
|
||||||
|
|
||||||
if s != nil && f.Embedded == 0 {
|
if s != nil && f.Embedded == 0 {
|
||||||
if funarg != types.FunargNone {
|
if funarg != types.FunargNone {
|
||||||
name = modeString(AsNode(f.Nname), mode)
|
name = fmt.Sprint(f.Nname)
|
||||||
} else if flag&FmtLong != 0 {
|
} else if flag&FmtLong != 0 {
|
||||||
name = mode.Sprintf("%0S", s)
|
name = mode.Sprintf("%0S", s)
|
||||||
if !types.IsExported(name) && flag&FmtUnsigned == 0 {
|
if !types.IsExported(name) && flag&FmtUnsigned == 0 {
|
||||||
|
|
@ -887,64 +874,38 @@ func fldconv(b *bytes.Buffer, f *types.Field, flag FmtFlag, mode FmtMode, visite
|
||||||
|
|
||||||
// Node
|
// Node
|
||||||
|
|
||||||
func modeString(n Node, mode FmtMode) string { return mode.Sprint(n) }
|
func FmtNode(n Node, s fmt.State, verb rune) {
|
||||||
|
// TODO(rsc): Remove uses of %#v, which behaves just like %v.
|
||||||
type fmtNode struct {
|
// TODO(rsc): Remove uses of %S, which behaves just like %v.
|
||||||
x Node
|
if verb == 'S' {
|
||||||
m FmtMode
|
verb = 'v'
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *fmtNode) Format(s fmt.State, verb rune) { nodeFormat(f.x, s, verb, f.m) }
|
|
||||||
|
|
||||||
func FmtNode(n Node, s fmt.State, verb rune) {
|
|
||||||
// %+v prints Dump.
|
// %+v prints Dump.
|
||||||
|
// Otherwise we print Go syntax.
|
||||||
if s.Flag('+') && verb == 'v' {
|
if s.Flag('+') && verb == 'v' {
|
||||||
dumpNode(s, n, 1)
|
dumpNode(s, n, 1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise print Go syntax.
|
if verb != 'v' && verb != 'S' && verb != 'L' {
|
||||||
nodeFormat(n, s, verb, FErr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func nodeFormat(n Node, s fmt.State, verb rune, mode FmtMode) {
|
|
||||||
switch verb {
|
|
||||||
case 'v', 'S', 'L':
|
|
||||||
nconvFmt(n, s, fmtFlag(s, verb), mode)
|
|
||||||
|
|
||||||
default:
|
|
||||||
fmt.Fprintf(s, "%%!%c(*Node=%p)", verb, n)
|
fmt.Fprintf(s, "%%!%c(*Node=%p)", verb, n)
|
||||||
}
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// "%L" suffix with "(type %T)" where possible
|
|
||||||
// "%+S" in debug mode, don't recurse, no multiline output
|
|
||||||
func nconvFmt(n Node, s fmt.State, flag FmtFlag, mode FmtMode) {
|
|
||||||
if n == nil {
|
if n == nil {
|
||||||
fmt.Fprint(s, "<N>")
|
fmt.Fprint(s, "<N>")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
flag, mode = flag.update(mode)
|
|
||||||
|
|
||||||
switch mode {
|
|
||||||
case FErr:
|
|
||||||
nodeFmt(n, s, flag, mode)
|
|
||||||
|
|
||||||
default:
|
|
||||||
base.Fatalf("unhandled %%N mode: %d", mode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func nodeFmt(n Node, s fmt.State, flag FmtFlag, mode FmtMode) {
|
|
||||||
t := n.Type()
|
t := n.Type()
|
||||||
if flag&FmtLong != 0 && t != nil {
|
if verb == 'L' && t != nil {
|
||||||
if t.Kind() == types.TNIL {
|
if t.Kind() == types.TNIL {
|
||||||
fmt.Fprint(s, "nil")
|
fmt.Fprint(s, "nil")
|
||||||
} else if n.Op() == ONAME && n.Name().AutoTemp() {
|
} else if n.Op() == ONAME && n.Name().AutoTemp() {
|
||||||
mode.Fprintf(s, "%v value", t)
|
fmt.Fprintf(s, "%v value", t)
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%v (type %v)", n, t)
|
fmt.Fprintf(s, "%v (type %v)", n, t)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -952,11 +913,11 @@ func nodeFmt(n Node, s fmt.State, flag FmtFlag, mode FmtMode) {
|
||||||
// TODO inlining produces expressions with ninits. we can't print these yet.
|
// TODO inlining produces expressions with ninits. we can't print these yet.
|
||||||
|
|
||||||
if OpPrec[n.Op()] < 0 {
|
if OpPrec[n.Op()] < 0 {
|
||||||
stmtFmt(n, s, mode)
|
stmtFmt(n, s)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
exprFmt(n, s, 0, mode)
|
exprFmt(n, s, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
var OpPrec = []int{
|
var OpPrec = []int{
|
||||||
|
|
@ -1089,7 +1050,15 @@ func StmtWithInit(op Op) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func stmtFmt(n Node, s fmt.State, mode FmtMode) {
|
func stmtFmt(n Node, s fmt.State) {
|
||||||
|
// NOTE(rsc): This code used to support the text-based
|
||||||
|
// which was more aggressive about printing full Go syntax
|
||||||
|
// (for example, an actual loop instead of "for loop").
|
||||||
|
// The code is preserved for now in case we want to expand
|
||||||
|
// any of those shortenings later. Or maybe we will delete
|
||||||
|
// the code. But for now, keep it.
|
||||||
|
const exportFormat = false
|
||||||
|
|
||||||
// some statements allow for an init, but at most one,
|
// some statements allow for an init, but at most one,
|
||||||
// but we may have an arbitrary number added, eg by typecheck
|
// but we may have an arbitrary number added, eg by typecheck
|
||||||
// and inlining. If it doesn't fit the syntax, emit an enclosing
|
// and inlining. If it doesn't fit the syntax, emit an enclosing
|
||||||
|
|
@ -1099,7 +1068,7 @@ func stmtFmt(n Node, s fmt.State, mode FmtMode) {
|
||||||
simpleinit := n.Init().Len() == 1 && n.Init().First().Init().Len() == 0 && StmtWithInit(n.Op())
|
simpleinit := n.Init().Len() == 1 && n.Init().First().Init().Len() == 0 && StmtWithInit(n.Op())
|
||||||
|
|
||||||
// otherwise, print the inits as separate statements
|
// otherwise, print the inits as separate statements
|
||||||
complexinit := n.Init().Len() != 0 && !simpleinit && (mode != FErr)
|
complexinit := n.Init().Len() != 0 && !simpleinit && exportFormat
|
||||||
|
|
||||||
// but if it was for if/for/switch, put in an extra surrounding block to limit the scope
|
// but if it was for if/for/switch, put in an extra surrounding block to limit the scope
|
||||||
extrablock := complexinit && StmtWithInit(n.Op())
|
extrablock := complexinit && StmtWithInit(n.Op())
|
||||||
|
|
@ -1109,70 +1078,70 @@ func stmtFmt(n Node, s fmt.State, mode FmtMode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if complexinit {
|
if complexinit {
|
||||||
mode.Fprintf(s, " %v; ", n.Init())
|
fmt.Fprintf(s, " %v; ", n.Init())
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op() {
|
switch n.Op() {
|
||||||
case ODCL:
|
case ODCL:
|
||||||
mode.Fprintf(s, "var %v %v", n.Left().Sym(), n.Left().Type())
|
fmt.Fprintf(s, "var %v %v", n.Left().Sym(), n.Left().Type())
|
||||||
|
|
||||||
// Don't export "v = <N>" initializing statements, hope they're always
|
// Don't export "v = <N>" initializing statements, hope they're always
|
||||||
// preceded by the DCL which will be re-parsed and typechecked to reproduce
|
// preceded by the DCL which will be re-parsed and typechecked to reproduce
|
||||||
// the "v = <N>" again.
|
// the "v = <N>" again.
|
||||||
case OAS:
|
case OAS:
|
||||||
if n.Colas() && !complexinit {
|
if n.Colas() && !complexinit {
|
||||||
mode.Fprintf(s, "%v := %v", n.Left(), n.Right())
|
fmt.Fprintf(s, "%v := %v", n.Left(), n.Right())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%v = %v", n.Left(), n.Right())
|
fmt.Fprintf(s, "%v = %v", n.Left(), n.Right())
|
||||||
}
|
}
|
||||||
|
|
||||||
case OASOP:
|
case OASOP:
|
||||||
if n.Implicit() {
|
if n.Implicit() {
|
||||||
if n.SubOp() == OADD {
|
if n.SubOp() == OADD {
|
||||||
mode.Fprintf(s, "%v++", n.Left())
|
fmt.Fprintf(s, "%v++", n.Left())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%v--", n.Left())
|
fmt.Fprintf(s, "%v--", n.Left())
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
mode.Fprintf(s, "%v %#v= %v", n.Left(), n.SubOp(), n.Right())
|
fmt.Fprintf(s, "%v %#v= %v", n.Left(), n.SubOp(), n.Right())
|
||||||
|
|
||||||
case OAS2, OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
|
case OAS2, OAS2DOTTYPE, OAS2FUNC, OAS2MAPR, OAS2RECV:
|
||||||
if n.Colas() && !complexinit {
|
if n.Colas() && !complexinit {
|
||||||
mode.Fprintf(s, "%.v := %.v", n.List(), n.Rlist())
|
fmt.Fprintf(s, "%.v := %.v", n.List(), n.Rlist())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%.v = %.v", n.List(), n.Rlist())
|
fmt.Fprintf(s, "%.v = %.v", n.List(), n.Rlist())
|
||||||
}
|
}
|
||||||
|
|
||||||
case OBLOCK:
|
case OBLOCK:
|
||||||
if n.List().Len() != 0 {
|
if n.List().Len() != 0 {
|
||||||
mode.Fprintf(s, "%v", n.List())
|
fmt.Fprintf(s, "%v", n.List())
|
||||||
}
|
}
|
||||||
|
|
||||||
case ORETURN:
|
case ORETURN:
|
||||||
mode.Fprintf(s, "return %.v", n.List())
|
fmt.Fprintf(s, "return %.v", n.List())
|
||||||
|
|
||||||
case ORETJMP:
|
case ORETJMP:
|
||||||
mode.Fprintf(s, "retjmp %v", n.Sym())
|
fmt.Fprintf(s, "retjmp %v", n.Sym())
|
||||||
|
|
||||||
case OINLMARK:
|
case OINLMARK:
|
||||||
mode.Fprintf(s, "inlmark %d", n.Offset())
|
fmt.Fprintf(s, "inlmark %d", n.Offset())
|
||||||
|
|
||||||
case OGO:
|
case OGO:
|
||||||
mode.Fprintf(s, "go %v", n.Left())
|
fmt.Fprintf(s, "go %v", n.Left())
|
||||||
|
|
||||||
case ODEFER:
|
case ODEFER:
|
||||||
mode.Fprintf(s, "defer %v", n.Left())
|
fmt.Fprintf(s, "defer %v", n.Left())
|
||||||
|
|
||||||
case OIF:
|
case OIF:
|
||||||
if simpleinit {
|
if simpleinit {
|
||||||
mode.Fprintf(s, "if %v; %v { %v }", n.Init().First(), n.Left(), n.Body())
|
fmt.Fprintf(s, "if %v; %v { %v }", n.Init().First(), n.Left(), n.Body())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "if %v { %v }", n.Left(), n.Body())
|
fmt.Fprintf(s, "if %v { %v }", n.Left(), n.Body())
|
||||||
}
|
}
|
||||||
if n.Rlist().Len() != 0 {
|
if n.Rlist().Len() != 0 {
|
||||||
mode.Fprintf(s, " else { %v }", n.Rlist())
|
fmt.Fprintf(s, " else { %v }", n.Rlist())
|
||||||
}
|
}
|
||||||
|
|
||||||
case OFOR, OFORUNTIL:
|
case OFOR, OFORUNTIL:
|
||||||
|
|
@ -1180,80 +1149,80 @@ func stmtFmt(n Node, s fmt.State, mode FmtMode) {
|
||||||
if n.Op() == OFORUNTIL {
|
if n.Op() == OFORUNTIL {
|
||||||
opname = "foruntil"
|
opname = "foruntil"
|
||||||
}
|
}
|
||||||
if mode == FErr { // TODO maybe only if FmtShort, same below
|
if !exportFormat { // TODO maybe only if FmtShort, same below
|
||||||
fmt.Fprintf(s, "%s loop", opname)
|
fmt.Fprintf(s, "%s loop", opname)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprint(s, opname)
|
fmt.Fprint(s, opname)
|
||||||
if simpleinit {
|
if simpleinit {
|
||||||
mode.Fprintf(s, " %v;", n.Init().First())
|
fmt.Fprintf(s, " %v;", n.Init().First())
|
||||||
} else if n.Right() != nil {
|
} else if n.Right() != nil {
|
||||||
fmt.Fprint(s, " ;")
|
fmt.Fprint(s, " ;")
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Left() != nil {
|
if n.Left() != nil {
|
||||||
mode.Fprintf(s, " %v", n.Left())
|
fmt.Fprintf(s, " %v", n.Left())
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Right() != nil {
|
if n.Right() != nil {
|
||||||
mode.Fprintf(s, "; %v", n.Right())
|
fmt.Fprintf(s, "; %v", n.Right())
|
||||||
} else if simpleinit {
|
} else if simpleinit {
|
||||||
fmt.Fprint(s, ";")
|
fmt.Fprint(s, ";")
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Op() == OFORUNTIL && n.List().Len() != 0 {
|
if n.Op() == OFORUNTIL && n.List().Len() != 0 {
|
||||||
mode.Fprintf(s, "; %v", n.List())
|
fmt.Fprintf(s, "; %v", n.List())
|
||||||
}
|
}
|
||||||
|
|
||||||
mode.Fprintf(s, " { %v }", n.Body())
|
fmt.Fprintf(s, " { %v }", n.Body())
|
||||||
|
|
||||||
case ORANGE:
|
case ORANGE:
|
||||||
if mode == FErr {
|
if !exportFormat {
|
||||||
fmt.Fprint(s, "for loop")
|
fmt.Fprint(s, "for loop")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.List().Len() == 0 {
|
if n.List().Len() == 0 {
|
||||||
mode.Fprintf(s, "for range %v { %v }", n.Right(), n.Body())
|
fmt.Fprintf(s, "for range %v { %v }", n.Right(), n.Body())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
mode.Fprintf(s, "for %.v = range %v { %v }", n.List(), n.Right(), n.Body())
|
fmt.Fprintf(s, "for %.v = range %v { %v }", n.List(), n.Right(), n.Body())
|
||||||
|
|
||||||
case OSELECT, OSWITCH:
|
case OSELECT, OSWITCH:
|
||||||
if mode == FErr {
|
if !exportFormat {
|
||||||
mode.Fprintf(s, "%v statement", n.Op())
|
fmt.Fprintf(s, "%v statement", n.Op())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
mode.Fprintf(s, "%#v", n.Op())
|
fmt.Fprintf(s, "%#v", n.Op())
|
||||||
if simpleinit {
|
if simpleinit {
|
||||||
mode.Fprintf(s, " %v;", n.Init().First())
|
fmt.Fprintf(s, " %v;", n.Init().First())
|
||||||
}
|
}
|
||||||
if n.Left() != nil {
|
if n.Left() != nil {
|
||||||
mode.Fprintf(s, " %v ", n.Left())
|
fmt.Fprintf(s, " %v ", n.Left())
|
||||||
}
|
}
|
||||||
|
|
||||||
mode.Fprintf(s, " { %v }", n.List())
|
fmt.Fprintf(s, " { %v }", n.List())
|
||||||
|
|
||||||
case OCASE:
|
case OCASE:
|
||||||
if n.List().Len() != 0 {
|
if n.List().Len() != 0 {
|
||||||
mode.Fprintf(s, "case %.v", n.List())
|
fmt.Fprintf(s, "case %.v", n.List())
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprint(s, "default")
|
fmt.Fprint(s, "default")
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, ": %v", n.Body())
|
fmt.Fprintf(s, ": %v", n.Body())
|
||||||
|
|
||||||
case OBREAK, OCONTINUE, OGOTO, OFALL:
|
case OBREAK, OCONTINUE, OGOTO, OFALL:
|
||||||
if n.Sym() != nil {
|
if n.Sym() != nil {
|
||||||
mode.Fprintf(s, "%#v %v", n.Op(), n.Sym())
|
fmt.Fprintf(s, "%#v %v", n.Op(), n.Sym())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%#v", n.Op())
|
fmt.Fprintf(s, "%#v", n.Op())
|
||||||
}
|
}
|
||||||
|
|
||||||
case OLABEL:
|
case OLABEL:
|
||||||
mode.Fprintf(s, "%v: ", n.Sym())
|
fmt.Fprintf(s, "%v: ", n.Sym())
|
||||||
}
|
}
|
||||||
|
|
||||||
if extrablock {
|
if extrablock {
|
||||||
|
|
@ -1261,7 +1230,15 @@ func stmtFmt(n Node, s fmt.State, mode FmtMode) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
|
func exprFmt(n Node, s fmt.State, prec int) {
|
||||||
|
// NOTE(rsc): This code used to support the text-based
|
||||||
|
// which was more aggressive about printing full Go syntax
|
||||||
|
// (for example, an actual loop instead of "for loop").
|
||||||
|
// The code is preserved for now in case we want to expand
|
||||||
|
// any of those shortenings later. Or maybe we will delete
|
||||||
|
// the code. But for now, keep it.
|
||||||
|
const exportFormat = false
|
||||||
|
|
||||||
for {
|
for {
|
||||||
if n == nil {
|
if n == nil {
|
||||||
fmt.Fprint(s, "<N>")
|
fmt.Fprint(s, "<N>")
|
||||||
|
|
@ -1292,20 +1269,20 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if prec > nprec {
|
if prec > nprec {
|
||||||
mode.Fprintf(s, "(%v)", n)
|
fmt.Fprintf(s, "(%v)", n)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op() {
|
switch n.Op() {
|
||||||
case OPAREN:
|
case OPAREN:
|
||||||
mode.Fprintf(s, "(%v)", n.Left())
|
fmt.Fprintf(s, "(%v)", n.Left())
|
||||||
|
|
||||||
case ONIL:
|
case ONIL:
|
||||||
fmt.Fprint(s, "nil")
|
fmt.Fprint(s, "nil")
|
||||||
|
|
||||||
case OLITERAL: // this is a bit of a mess
|
case OLITERAL: // this is a bit of a mess
|
||||||
if mode == FErr && n.Sym() != nil {
|
if !exportFormat && n.Sym() != nil {
|
||||||
fmt.Fprint(s, smodeString(n.Sym(), mode))
|
fmt.Fprint(s, smodeString(n.Sym(), FErr))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1314,9 +1291,9 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
// Need parens when type begins with what might
|
// Need parens when type begins with what might
|
||||||
// be misinterpreted as a unary operator: * or <-.
|
// be misinterpreted as a unary operator: * or <-.
|
||||||
if n.Type().IsPtr() || (n.Type().IsChan() && n.Type().ChanDir() == types.Crecv) {
|
if n.Type().IsPtr() || (n.Type().IsChan() && n.Type().ChanDir() == types.Crecv) {
|
||||||
mode.Fprintf(s, "(%v)(", n.Type())
|
fmt.Fprintf(s, "(%v)(", n.Type())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%v(", n.Type())
|
fmt.Fprintf(s, "%v(", n.Type())
|
||||||
}
|
}
|
||||||
needUnparen = true
|
needUnparen = true
|
||||||
}
|
}
|
||||||
|
|
@ -1342,68 +1319,68 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if needUnparen {
|
if needUnparen {
|
||||||
mode.Fprintf(s, ")")
|
fmt.Fprintf(s, ")")
|
||||||
}
|
}
|
||||||
|
|
||||||
case ODCLFUNC:
|
case ODCLFUNC:
|
||||||
if sym := n.Sym(); sym != nil {
|
if sym := n.Sym(); sym != nil {
|
||||||
fmt.Fprint(s, smodeString(sym, mode))
|
fmt.Fprint(s, smodeString(sym, FErr))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "<unnamed Func>")
|
fmt.Fprintf(s, "<unnamed Func>")
|
||||||
|
|
||||||
case ONAME:
|
case ONAME:
|
||||||
// Special case: name used as local variable in export.
|
// Special case: name used as local variable in export.
|
||||||
// _ becomes ~b%d internally; print as _ for export
|
// _ becomes ~b%d internally; print as _ for export
|
||||||
if mode == FErr && n.Sym() != nil && n.Sym().Name[0] == '~' && n.Sym().Name[1] == 'b' {
|
if !exportFormat && n.Sym() != nil && n.Sym().Name[0] == '~' && n.Sym().Name[1] == 'b' {
|
||||||
fmt.Fprint(s, "_")
|
fmt.Fprint(s, "_")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fallthrough
|
fallthrough
|
||||||
case OPACK, ONONAME, OMETHEXPR:
|
case OPACK, ONONAME, OMETHEXPR:
|
||||||
fmt.Fprint(s, smodeString(n.Sym(), mode))
|
fmt.Fprint(s, smodeString(n.Sym(), FErr))
|
||||||
|
|
||||||
case OTYPE:
|
case OTYPE:
|
||||||
if n.Type() == nil && n.Sym() != nil {
|
if n.Type() == nil && n.Sym() != nil {
|
||||||
fmt.Fprint(s, smodeString(n.Sym(), mode))
|
fmt.Fprint(s, smodeString(n.Sym(), FErr))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "%v", n.Type())
|
fmt.Fprintf(s, "%v", n.Type())
|
||||||
|
|
||||||
case OTSLICE:
|
case OTSLICE:
|
||||||
n := n.(*SliceType)
|
n := n.(*SliceType)
|
||||||
if n.DDD {
|
if n.DDD {
|
||||||
mode.Fprintf(s, "...%v", n.Elem)
|
fmt.Fprintf(s, "...%v", n.Elem)
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "[]%v", n.Elem) // happens before typecheck
|
fmt.Fprintf(s, "[]%v", n.Elem) // happens before typecheck
|
||||||
}
|
}
|
||||||
|
|
||||||
case OTARRAY:
|
case OTARRAY:
|
||||||
n := n.(*ArrayType)
|
n := n.(*ArrayType)
|
||||||
if n.Len == nil {
|
if n.Len == nil {
|
||||||
mode.Fprintf(s, "[...]%v", n.Elem)
|
fmt.Fprintf(s, "[...]%v", n.Elem)
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "[%v]%v", n.Len, n.Elem)
|
fmt.Fprintf(s, "[%v]%v", n.Len, n.Elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
case OTMAP:
|
case OTMAP:
|
||||||
n := n.(*MapType)
|
n := n.(*MapType)
|
||||||
mode.Fprintf(s, "map[%v]%v", n.Key, n.Elem)
|
fmt.Fprintf(s, "map[%v]%v", n.Key, n.Elem)
|
||||||
|
|
||||||
case OTCHAN:
|
case OTCHAN:
|
||||||
n := n.(*ChanType)
|
n := n.(*ChanType)
|
||||||
switch n.Dir {
|
switch n.Dir {
|
||||||
case types.Crecv:
|
case types.Crecv:
|
||||||
mode.Fprintf(s, "<-chan %v", n.Elem)
|
fmt.Fprintf(s, "<-chan %v", n.Elem)
|
||||||
|
|
||||||
case types.Csend:
|
case types.Csend:
|
||||||
mode.Fprintf(s, "chan<- %v", n.Elem)
|
fmt.Fprintf(s, "chan<- %v", n.Elem)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if n.Elem != nil && n.Elem.Op() == OTCHAN && n.Elem.(*ChanType).Dir == types.Crecv {
|
if n.Elem != nil && n.Elem.Op() == OTCHAN && n.Elem.(*ChanType).Dir == types.Crecv {
|
||||||
mode.Fprintf(s, "chan (%v)", n.Elem)
|
fmt.Fprintf(s, "chan (%v)", n.Elem)
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "chan %v", n.Elem)
|
fmt.Fprintf(s, "chan %v", n.Elem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1417,104 +1394,104 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
fmt.Fprint(s, "<func>")
|
fmt.Fprint(s, "<func>")
|
||||||
|
|
||||||
case OCLOSURE:
|
case OCLOSURE:
|
||||||
if mode == FErr {
|
if !exportFormat {
|
||||||
fmt.Fprint(s, "func literal")
|
fmt.Fprint(s, "func literal")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Body().Len() != 0 {
|
if n.Body().Len() != 0 {
|
||||||
mode.Fprintf(s, "%v { %v }", n.Type(), n.Body())
|
fmt.Fprintf(s, "%v { %v }", n.Type(), n.Body())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "%v { %v }", n.Type(), n.Func().Body())
|
fmt.Fprintf(s, "%v { %v }", n.Type(), n.Func().Body())
|
||||||
|
|
||||||
case OCOMPLIT:
|
case OCOMPLIT:
|
||||||
if mode == FErr {
|
if !exportFormat {
|
||||||
if n.Implicit() {
|
if n.Implicit() {
|
||||||
mode.Fprintf(s, "... argument")
|
fmt.Fprintf(s, "... argument")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Right() != nil {
|
if n.Right() != nil {
|
||||||
mode.Fprintf(s, "%v{%s}", n.Right(), ellipsisIf(n.List().Len() != 0))
|
fmt.Fprintf(s, "%v{%s}", n.Right(), ellipsisIf(n.List().Len() != 0))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Fprint(s, "composite literal")
|
fmt.Fprint(s, "composite literal")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "(%v{ %.v })", n.Right(), n.List())
|
fmt.Fprintf(s, "(%v{ %.v })", n.Right(), n.List())
|
||||||
|
|
||||||
case OPTRLIT:
|
case OPTRLIT:
|
||||||
mode.Fprintf(s, "&%v", n.Left())
|
fmt.Fprintf(s, "&%v", n.Left())
|
||||||
|
|
||||||
case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
|
case OSTRUCTLIT, OARRAYLIT, OSLICELIT, OMAPLIT:
|
||||||
if mode == FErr {
|
if !exportFormat {
|
||||||
mode.Fprintf(s, "%v{%s}", n.Type(), ellipsisIf(n.List().Len() != 0))
|
fmt.Fprintf(s, "%v{%s}", n.Type(), ellipsisIf(n.List().Len() != 0))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "(%v{ %.v })", n.Type(), n.List())
|
fmt.Fprintf(s, "(%v{ %.v })", n.Type(), n.List())
|
||||||
|
|
||||||
case OKEY:
|
case OKEY:
|
||||||
if n.Left() != nil && n.Right() != nil {
|
if n.Left() != nil && n.Right() != nil {
|
||||||
mode.Fprintf(s, "%v:%v", n.Left(), n.Right())
|
fmt.Fprintf(s, "%v:%v", n.Left(), n.Right())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if n.Left() == nil && n.Right() != nil {
|
if n.Left() == nil && n.Right() != nil {
|
||||||
mode.Fprintf(s, ":%v", n.Right())
|
fmt.Fprintf(s, ":%v", n.Right())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Left() != nil && n.Right() == nil {
|
if n.Left() != nil && n.Right() == nil {
|
||||||
mode.Fprintf(s, "%v:", n.Left())
|
fmt.Fprintf(s, "%v:", n.Left())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
fmt.Fprint(s, ":")
|
fmt.Fprint(s, ":")
|
||||||
|
|
||||||
case OSTRUCTKEY:
|
case OSTRUCTKEY:
|
||||||
mode.Fprintf(s, "%v:%v", n.Sym(), n.Left())
|
fmt.Fprintf(s, "%v:%v", n.Sym(), n.Left())
|
||||||
|
|
||||||
case OCALLPART:
|
case OCALLPART:
|
||||||
exprFmt(n.Left(), s, nprec, mode)
|
exprFmt(n.Left(), s, nprec)
|
||||||
if n.Sym() == nil {
|
if n.Sym() == nil {
|
||||||
fmt.Fprint(s, ".<nil>")
|
fmt.Fprint(s, ".<nil>")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, ".%0S", n.Sym())
|
fmt.Fprintf(s, ".%0S", n.Sym())
|
||||||
|
|
||||||
case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
|
case OXDOT, ODOT, ODOTPTR, ODOTINTER, ODOTMETH:
|
||||||
exprFmt(n.Left(), s, nprec, mode)
|
exprFmt(n.Left(), s, nprec)
|
||||||
if n.Sym() == nil {
|
if n.Sym() == nil {
|
||||||
fmt.Fprint(s, ".<nil>")
|
fmt.Fprint(s, ".<nil>")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, ".%0S", n.Sym())
|
fmt.Fprintf(s, ".%0S", n.Sym())
|
||||||
|
|
||||||
case ODOTTYPE, ODOTTYPE2:
|
case ODOTTYPE, ODOTTYPE2:
|
||||||
exprFmt(n.Left(), s, nprec, mode)
|
exprFmt(n.Left(), s, nprec)
|
||||||
if n.Right() != nil {
|
if n.Right() != nil {
|
||||||
mode.Fprintf(s, ".(%v)", n.Right())
|
fmt.Fprintf(s, ".(%v)", n.Right())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, ".(%v)", n.Type())
|
fmt.Fprintf(s, ".(%v)", n.Type())
|
||||||
|
|
||||||
case OINDEX, OINDEXMAP:
|
case OINDEX, OINDEXMAP:
|
||||||
exprFmt(n.Left(), s, nprec, mode)
|
exprFmt(n.Left(), s, nprec)
|
||||||
mode.Fprintf(s, "[%v]", n.Right())
|
fmt.Fprintf(s, "[%v]", n.Right())
|
||||||
|
|
||||||
case OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
|
case OSLICE, OSLICESTR, OSLICEARR, OSLICE3, OSLICE3ARR:
|
||||||
exprFmt(n.Left(), s, nprec, mode)
|
exprFmt(n.Left(), s, nprec)
|
||||||
fmt.Fprint(s, "[")
|
fmt.Fprint(s, "[")
|
||||||
low, high, max := n.SliceBounds()
|
low, high, max := n.SliceBounds()
|
||||||
if low != nil {
|
if low != nil {
|
||||||
fmt.Fprint(s, modeString(low, mode))
|
fmt.Fprint(s, low)
|
||||||
}
|
}
|
||||||
fmt.Fprint(s, ":")
|
fmt.Fprint(s, ":")
|
||||||
if high != nil {
|
if high != nil {
|
||||||
fmt.Fprint(s, modeString(high, mode))
|
fmt.Fprint(s, high)
|
||||||
}
|
}
|
||||||
if n.Op().IsSlice3() {
|
if n.Op().IsSlice3() {
|
||||||
fmt.Fprint(s, ":")
|
fmt.Fprint(s, ":")
|
||||||
if max != nil {
|
if max != nil {
|
||||||
fmt.Fprint(s, modeString(max, mode))
|
fmt.Fprint(s, max)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmt.Fprint(s, "]")
|
fmt.Fprint(s, "]")
|
||||||
|
|
@ -1523,13 +1500,13 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
if n.List().Len() != 2 {
|
if n.List().Len() != 2 {
|
||||||
base.Fatalf("bad OSLICEHEADER list length %d", n.List().Len())
|
base.Fatalf("bad OSLICEHEADER list length %d", n.List().Len())
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "sliceheader{%v,%v,%v}", n.Left(), n.List().First(), n.List().Second())
|
fmt.Fprintf(s, "sliceheader{%v,%v,%v}", n.Left(), n.List().First(), n.List().Second())
|
||||||
|
|
||||||
case OCOMPLEX, OCOPY:
|
case OCOMPLEX, OCOPY:
|
||||||
if n.Left() != nil {
|
if n.Left() != nil {
|
||||||
mode.Fprintf(s, "%#v(%v, %v)", n.Op(), n.Left(), n.Right())
|
fmt.Fprintf(s, "%#v(%v, %v)", n.Op(), n.Left(), n.Right())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%#v(%.v)", n.Op(), n.List())
|
fmt.Fprintf(s, "%#v(%.v)", n.Op(), n.List())
|
||||||
}
|
}
|
||||||
|
|
||||||
case OCONV,
|
case OCONV,
|
||||||
|
|
@ -1541,14 +1518,14 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
OSTR2RUNES,
|
OSTR2RUNES,
|
||||||
ORUNESTR:
|
ORUNESTR:
|
||||||
if n.Type() == nil || n.Type().Sym() == nil {
|
if n.Type() == nil || n.Type().Sym() == nil {
|
||||||
mode.Fprintf(s, "(%v)", n.Type())
|
fmt.Fprintf(s, "(%v)", n.Type())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "%v", n.Type())
|
fmt.Fprintf(s, "%v", n.Type())
|
||||||
}
|
}
|
||||||
if n.Left() != nil {
|
if n.Left() != nil {
|
||||||
mode.Fprintf(s, "(%v)", n.Left())
|
fmt.Fprintf(s, "(%v)", n.Left())
|
||||||
} else {
|
} else {
|
||||||
mode.Fprintf(s, "(%.v)", n.List())
|
fmt.Fprintf(s, "(%.v)", n.List())
|
||||||
}
|
}
|
||||||
|
|
||||||
case OREAL,
|
case OREAL,
|
||||||
|
|
@ -1568,48 +1545,48 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
OPRINT,
|
OPRINT,
|
||||||
OPRINTN:
|
OPRINTN:
|
||||||
if n.Left() != nil {
|
if n.Left() != nil {
|
||||||
mode.Fprintf(s, "%#v(%v)", n.Op(), n.Left())
|
fmt.Fprintf(s, "%#v(%v)", n.Op(), n.Left())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.IsDDD() {
|
if n.IsDDD() {
|
||||||
mode.Fprintf(s, "%#v(%.v...)", n.Op(), n.List())
|
fmt.Fprintf(s, "%#v(%.v...)", n.Op(), n.List())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "%#v(%.v)", n.Op(), n.List())
|
fmt.Fprintf(s, "%#v(%.v)", n.Op(), n.List())
|
||||||
|
|
||||||
case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG:
|
case OCALL, OCALLFUNC, OCALLINTER, OCALLMETH, OGETG:
|
||||||
exprFmt(n.Left(), s, nprec, mode)
|
exprFmt(n.Left(), s, nprec)
|
||||||
if n.IsDDD() {
|
if n.IsDDD() {
|
||||||
mode.Fprintf(s, "(%.v...)", n.List())
|
fmt.Fprintf(s, "(%.v...)", n.List())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "(%.v)", n.List())
|
fmt.Fprintf(s, "(%.v)", n.List())
|
||||||
|
|
||||||
case OMAKEMAP, OMAKECHAN, OMAKESLICE:
|
case OMAKEMAP, OMAKECHAN, OMAKESLICE:
|
||||||
if n.List().Len() != 0 { // pre-typecheck
|
if n.List().Len() != 0 { // pre-typecheck
|
||||||
mode.Fprintf(s, "make(%v, %.v)", n.Type(), n.List())
|
fmt.Fprintf(s, "make(%v, %.v)", n.Type(), n.List())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Right() != nil {
|
if n.Right() != nil {
|
||||||
mode.Fprintf(s, "make(%v, %v, %v)", n.Type(), n.Left(), n.Right())
|
fmt.Fprintf(s, "make(%v, %v, %v)", n.Type(), n.Left(), n.Right())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.Left() != nil && (n.Op() == OMAKESLICE || !n.Left().Type().IsUntyped()) {
|
if n.Left() != nil && (n.Op() == OMAKESLICE || !n.Left().Type().IsUntyped()) {
|
||||||
mode.Fprintf(s, "make(%v, %v)", n.Type(), n.Left())
|
fmt.Fprintf(s, "make(%v, %v)", n.Type(), n.Left())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mode.Fprintf(s, "make(%v)", n.Type())
|
fmt.Fprintf(s, "make(%v)", n.Type())
|
||||||
|
|
||||||
case OMAKESLICECOPY:
|
case OMAKESLICECOPY:
|
||||||
mode.Fprintf(s, "makeslicecopy(%v, %v, %v)", n.Type(), n.Left(), n.Right())
|
fmt.Fprintf(s, "makeslicecopy(%v, %v, %v)", n.Type(), n.Left(), n.Right())
|
||||||
|
|
||||||
case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
|
case OPLUS, ONEG, OADDR, OBITNOT, ODEREF, ONOT, ORECV:
|
||||||
// Unary
|
// Unary
|
||||||
mode.Fprintf(s, "%#v", n.Op())
|
fmt.Fprintf(s, "%#v", n.Op())
|
||||||
if n.Left() != nil && n.Left().Op() == n.Op() {
|
if n.Left() != nil && n.Left().Op() == n.Op() {
|
||||||
fmt.Fprint(s, " ")
|
fmt.Fprint(s, " ")
|
||||||
}
|
}
|
||||||
exprFmt(n.Left(), s, nprec+1, mode)
|
exprFmt(n.Left(), s, nprec+1)
|
||||||
|
|
||||||
// Binary
|
// Binary
|
||||||
case OADD,
|
case OADD,
|
||||||
|
|
@ -1632,19 +1609,19 @@ func exprFmt(n Node, s fmt.State, prec int, mode FmtMode) {
|
||||||
OSEND,
|
OSEND,
|
||||||
OSUB,
|
OSUB,
|
||||||
OXOR:
|
OXOR:
|
||||||
exprFmt(n.Left(), s, nprec, mode)
|
exprFmt(n.Left(), s, nprec)
|
||||||
mode.Fprintf(s, " %#v ", n.Op())
|
fmt.Fprintf(s, " %#v ", n.Op())
|
||||||
exprFmt(n.Right(), s, nprec+1, mode)
|
exprFmt(n.Right(), s, nprec+1)
|
||||||
|
|
||||||
case OADDSTR:
|
case OADDSTR:
|
||||||
for i, n1 := range n.List().Slice() {
|
for i, n1 := range n.List().Slice() {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
fmt.Fprint(s, " + ")
|
fmt.Fprint(s, " + ")
|
||||||
}
|
}
|
||||||
exprFmt(n1, s, nprec, mode)
|
exprFmt(n1, s, nprec)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
mode.Fprintf(s, "<node %v>", n.Op())
|
fmt.Fprintf(s, "<node %v>", n.Op())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1657,45 +1634,25 @@ func ellipsisIf(b bool) string {
|
||||||
|
|
||||||
// Nodes
|
// Nodes
|
||||||
|
|
||||||
type fmtNodes struct {
|
func (l Nodes) Format(s fmt.State, verb rune) {
|
||||||
x Nodes
|
|
||||||
m FmtMode
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *fmtNodes) Format(s fmt.State, verb rune) { f.x.format(s, verb, FErr) }
|
|
||||||
|
|
||||||
func (l Nodes) Format(s fmt.State, verb rune) { l.format(s, verb, FErr) }
|
|
||||||
|
|
||||||
func (l Nodes) format(s fmt.State, verb rune, mode FmtMode) {
|
|
||||||
if s.Flag('+') && verb == 'v' {
|
if s.Flag('+') && verb == 'v' {
|
||||||
// %+v is DumpList output
|
// %+v is DumpList output
|
||||||
dumpNodes(s, l, 1)
|
dumpNodes(s, l, 1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
switch verb {
|
if verb != 'v' {
|
||||||
case 'v':
|
|
||||||
l.hconv(s, fmtFlag(s, verb), mode)
|
|
||||||
|
|
||||||
default:
|
|
||||||
fmt.Fprintf(s, "%%!%c(Nodes)", verb)
|
fmt.Fprintf(s, "%%!%c(Nodes)", verb)
|
||||||
}
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n Nodes) String() string {
|
|
||||||
return fmt.Sprint(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flags: all those of %N plus '.': separate with comma's instead of semicolons.
|
|
||||||
func (l Nodes) hconv(s fmt.State, flag FmtFlag, mode FmtMode) {
|
|
||||||
flag, mode = flag.update(mode)
|
|
||||||
sep := "; "
|
sep := "; "
|
||||||
if flag&FmtComma != 0 {
|
if _, ok := s.Precision(); ok { // %.v is expr list
|
||||||
sep = ", "
|
sep = ", "
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, n := range l.Slice() {
|
for i, n := range l.Slice() {
|
||||||
fmt.Fprint(s, modeString(n, mode))
|
fmt.Fprint(s, n)
|
||||||
if i+1 < l.Len() {
|
if i+1 < l.Len() {
|
||||||
fmt.Fprint(s, sep)
|
fmt.Fprint(s, sep)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue