From 499851bac88dfa2a85c39a2123f092071098cada Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Tue, 29 Dec 2020 15:36:48 -0800 Subject: [PATCH] [dev.regabi] cmd/compile: generalize ir/mknode.go This CL generalizes ir/mknode.go to get rid of most of almost all of its special cases for node field types. The only remaining speciale case now is Field, which doesn't implement Node any more, but perhaps should. To help with removing special cases, node fields can now be tagged with `mknode:"-"` so that mknode ignores them when generating its helper methods. Further, to simplify skipping all of the orig fields, a new origNode helper type is added which declares an orig field marked as `mknode:"-"` and also provides the Orig and SetOrig methods needed to implement the OrigNode interface. Passes toolstash -cmp. Change-Id: Ic68d4f0a9d2ef6e57e9fe87cdc641e5c4859830b Reviewed-on: https://go-review.googlesource.com/c/go/+/280674 Trust: Matthew Dempsky Run-TryBot: Matthew Dempsky TryBot-Result: Go Bot Reviewed-by: Cuong Manh Le --- src/cmd/compile/internal/ir/copy.go | 8 + src/cmd/compile/internal/ir/expr.go | 57 +- src/cmd/compile/internal/ir/func.go | 4 + src/cmd/compile/internal/ir/mknode.go | 264 ++--- src/cmd/compile/internal/ir/name.go | 4 + src/cmd/compile/internal/ir/node_gen.go | 1345 +++++++++++++++-------- src/cmd/compile/internal/ir/stmt.go | 7 +- src/cmd/compile/internal/ir/type.go | 66 +- src/cmd/compile/internal/ir/visit.go | 22 +- 9 files changed, 1071 insertions(+), 706 deletions(-) diff --git a/src/cmd/compile/internal/ir/copy.go b/src/cmd/compile/internal/ir/copy.go index 0ab355f767..7da9b24940 100644 --- a/src/cmd/compile/internal/ir/copy.go +++ b/src/cmd/compile/internal/ir/copy.go @@ -25,6 +25,14 @@ type OrigNode interface { SetOrig(Node) } +// origNode may be embedded into a Node to make it implement OrigNode. +type origNode struct { + orig Node `mknode:"-"` +} + +func (n *origNode) Orig() Node { return n.orig } +func (n *origNode) SetOrig(o Node) { n.orig = o } + // Orig returns the “original” node for n. // If n implements OrigNode, Orig returns n.Orig(). // Otherwise Orig returns n itself. diff --git a/src/cmd/compile/internal/ir/expr.go b/src/cmd/compile/internal/ir/expr.go index a989ce5e01..55e4b61baf 100644 --- a/src/cmd/compile/internal/ir/expr.go +++ b/src/cmd/compile/internal/ir/expr.go @@ -14,27 +14,6 @@ import ( "go/token" ) -func maybeDo(x Node, err error, do func(Node) error) error { - if x != nil && err == nil { - err = do(x) - } - return err -} - -func maybeDoList(x Nodes, err error, do func(Node) error) error { - if err == nil { - err = DoList(x, do) - } - return err -} - -func maybeEdit(x Node, edit func(Node) Node) Node { - if x == nil { - return x - } - return edit(x) -} - // An Expr is a Node that can appear as an expression. type Expr interface { Node @@ -77,16 +56,6 @@ func (n *miniExpr) Init() Nodes { return n.init } func (n *miniExpr) PtrInit() *Nodes { return &n.init } func (n *miniExpr) SetInit(x Nodes) { n.init = x } -func toNtype(x Node) Ntype { - if x == nil { - return nil - } - if _, ok := x.(Ntype); !ok { - Dump("not Ntype", x) - } - return x.(Ntype) -} - // An AddStringExpr is a string concatenation Expr[0] + Exprs[1] + ... + Expr[len(Expr)-1]. type AddStringExpr struct { miniExpr @@ -189,7 +158,7 @@ const ( // A CallExpr is a function call X(Args). type CallExpr struct { miniExpr - orig Node + origNode X Node Args Nodes Rargs Nodes // TODO(rsc): Delete. @@ -210,9 +179,6 @@ func NewCallExpr(pos src.XPos, op Op, fun Node, args []Node) *CallExpr { func (*CallExpr) isStmt() {} -func (n *CallExpr) Orig() Node { return n.orig } -func (n *CallExpr) SetOrig(x Node) { n.orig = x } - func (n *CallExpr) SetOp(op Op) { switch op { default: @@ -226,7 +192,7 @@ func (n *CallExpr) SetOp(op Op) { // A ClosureExpr is a function literal expression. type ClosureExpr struct { miniExpr - Func *Func + Func *Func `mknode:"-"` Prealloc *Name } @@ -254,7 +220,7 @@ func NewClosureRead(typ *types.Type, offset int64) *ClosureReadExpr { // Before type-checking, the type is Ntype. type CompLitExpr struct { miniExpr - orig Node + origNode Ntype Ntype List Nodes // initialized values Prealloc *Name @@ -270,8 +236,6 @@ func NewCompLitExpr(pos src.XPos, op Op, typ Ntype, list []Node) *CompLitExpr { return n } -func (n *CompLitExpr) Orig() Node { return n.orig } -func (n *CompLitExpr) SetOrig(x Node) { n.orig = x } func (n *CompLitExpr) Implicit() bool { return n.flags&miniExprImplicit != 0 } func (n *CompLitExpr) SetImplicit(b bool) { n.flags.set(miniExprImplicit, b) } @@ -286,14 +250,15 @@ func (n *CompLitExpr) SetOp(op Op) { type ConstExpr struct { miniExpr - val constant.Value - orig Node + origNode + val constant.Value } func NewConstExpr(val constant.Value, orig Node) Node { - n := &ConstExpr{orig: orig, val: val} + n := &ConstExpr{val: val} n.op = OLITERAL n.pos = orig.Pos() + n.orig = orig n.SetType(orig.Type()) n.SetTypecheck(orig.Typecheck()) n.SetDiag(orig.Diag()) @@ -301,8 +266,6 @@ func NewConstExpr(val constant.Value, orig Node) Node { } func (n *ConstExpr) Sym() *types.Sym { return n.orig.Sym() } -func (n *ConstExpr) Orig() Node { return n.orig } -func (n *ConstExpr) SetOrig(orig Node) { panic(n.no("SetOrig")) } func (n *ConstExpr) Val() constant.Value { return n.val } // A ConvExpr is a conversion Type(X). @@ -664,9 +627,9 @@ type TypeAssertExpr struct { // Runtime type information provided by walkDotType. // Caution: These aren't always populated; see walkDotType. - SrcType *AddrExpr // *runtime._type for X's type - DstType *AddrExpr // *runtime._type for Type - Itab *AddrExpr // *runtime.itab for Type implementing X's type + SrcType *AddrExpr `mknode:"-"` // *runtime._type for X's type + DstType *AddrExpr `mknode:"-"` // *runtime._type for Type + Itab *AddrExpr `mknode:"-"` // *runtime.itab for Type implementing X's type } func NewTypeAssertExpr(pos src.XPos, x Node, typ Ntype) *TypeAssertExpr { diff --git a/src/cmd/compile/internal/ir/func.go b/src/cmd/compile/internal/ir/func.go index bffd4dd5ef..32ad37fa80 100644 --- a/src/cmd/compile/internal/ir/func.go +++ b/src/cmd/compile/internal/ir/func.go @@ -115,6 +115,10 @@ func NewFunc(pos src.XPos) *Func { func (f *Func) isStmt() {} +func (n *Func) copy() Node { panic(n.no("copy")) } +func (n *Func) doChildren(do func(Node) error) error { return doNodes(n.Body, do) } +func (n *Func) editChildren(edit func(Node) Node) { editNodes(n.Body, edit) } + func (f *Func) Type() *types.Type { return f.Nname.Type() } func (f *Func) Sym() *types.Sym { return f.Nname.Sym() } func (f *Func) Linksym() *obj.LSym { return f.Nname.Linksym() } diff --git a/src/cmd/compile/internal/ir/mknode.go b/src/cmd/compile/internal/ir/mknode.go index 755ac6ba87..4e26bc5011 100644 --- a/src/cmd/compile/internal/ir/mknode.go +++ b/src/cmd/compile/internal/ir/mknode.go @@ -13,11 +13,16 @@ import ( "go/types" "io/ioutil" "log" + "reflect" + "sort" "strings" "golang.org/x/tools/go/packages" ) +var irPkg *types.Package +var buf bytes.Buffer + func main() { cfg := &packages.Config{ Mode: packages.NeedSyntax | packages.NeedTypes, @@ -26,44 +31,26 @@ func main() { if err != nil { log.Fatal(err) } + irPkg = pkgs[0].Types - pkg := pkgs[0].Types - scope := pkg.Scope() - - lookup := func(name string) *types.Named { - return scope.Lookup(name).(*types.TypeName).Type().(*types.Named) - } - - nodeType := lookup("Node") - ptrNameType := types.NewPointer(lookup("Name")) - ntypeType := lookup("Ntype") - nodesType := lookup("Nodes") - slicePtrCaseClauseType := types.NewSlice(types.NewPointer(lookup("CaseClause"))) - slicePtrCommClauseType := types.NewSlice(types.NewPointer(lookup("CommClause"))) - ptrFieldType := types.NewPointer(lookup("Field")) - slicePtrFieldType := types.NewSlice(ptrFieldType) - ptrIdentType := types.NewPointer(lookup("Ident")) - - var buf bytes.Buffer fmt.Fprintln(&buf, "// Code generated by mknode.go. DO NOT EDIT.") fmt.Fprintln(&buf) fmt.Fprintln(&buf, "package ir") fmt.Fprintln(&buf) fmt.Fprintln(&buf, `import "fmt"`) + scope := irPkg.Scope() for _, name := range scope.Names() { + if strings.HasPrefix(name, "mini") { + continue + } + obj, ok := scope.Lookup(name).(*types.TypeName) if !ok { continue } - - typName := obj.Name() - typ, ok := obj.Type().(*types.Named).Underlying().(*types.Struct) - if !ok { - continue - } - - if strings.HasPrefix(typName, "mini") || !hasMiniNode(typ) { + typ := obj.Type().(*types.Named) + if !implementsNode(types.NewPointer(typ)) { continue } @@ -71,77 +58,31 @@ func main() { fmt.Fprintf(&buf, "func (n *%s) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) }\n", name) switch name { - case "Name": - fmt.Fprintf(&buf, "func (n *%s) copy() Node {panic(\"%s.copy\")}\n", name, name) - default: - fmt.Fprintf(&buf, "func (n *%s) copy() Node { c := *n\n", name) - forNodeFields(typName, typ, func(name string, is func(types.Type) bool) { - switch { - case is(nodesType): - fmt.Fprintf(&buf, "c.%s = c.%s.Copy()\n", name, name) - case is(slicePtrCaseClauseType): - fmt.Fprintf(&buf, "c.%s = copyCases(c.%s)\n", name, name) - case is(slicePtrCommClauseType): - fmt.Fprintf(&buf, "c.%s = copyComms(c.%s)\n", name, name) - case is(ptrFieldType): - fmt.Fprintf(&buf, "if c.%s != nil { c.%s = c.%s.copy() }\n", name, name, name) - case is(slicePtrFieldType): - fmt.Fprintf(&buf, "c.%s = copyFields(c.%s)\n", name, name) - } - }) - fmt.Fprintf(&buf, "return &c }\n") + case "Name", "Func": + // Too specialized to automate. + continue } - fmt.Fprintf(&buf, "func (n *%s) doChildren(do func(Node) error) error { var err error\n", name) - forNodeFields(typName, typ, func(name string, is func(types.Type) bool) { - switch { - case is(ptrIdentType), is(ptrNameType): - fmt.Fprintf(&buf, "if n.%s != nil { err = maybeDo(n.%s, err, do) }\n", name, name) - case is(nodeType), is(ntypeType): - fmt.Fprintf(&buf, "err = maybeDo(n.%s, err, do)\n", name) - case is(nodesType): - fmt.Fprintf(&buf, "err = maybeDoList(n.%s, err, do)\n", name) - case is(slicePtrCaseClauseType): - fmt.Fprintf(&buf, "err = maybeDoCases(n.%s, err, do)\n", name) - case is(slicePtrCommClauseType): - fmt.Fprintf(&buf, "err = maybeDoComms(n.%s, err, do)\n", name) - case is(ptrFieldType): - fmt.Fprintf(&buf, "err = maybeDoField(n.%s, err, do)\n", name) - case is(slicePtrFieldType): - fmt.Fprintf(&buf, "err = maybeDoFields(n.%s, err, do)\n", name) - } - }) - fmt.Fprintf(&buf, "return err }\n") + forNodeFields(typ, + "func (n *%[1]s) copy() Node { c := *n\n", + "", + "c.%[1]s = copy%[2]s(c.%[1]s)", + "return &c }\n") - fmt.Fprintf(&buf, "func (n *%s) editChildren(edit func(Node) Node) {\n", name) - forNodeFields(typName, typ, func(name string, is func(types.Type) bool) { - switch { - case is(ptrIdentType): - fmt.Fprintf(&buf, "if n.%s != nil { n.%s = edit(n.%s).(*Ident) }\n", name, name, name) - case is(ptrNameType): - fmt.Fprintf(&buf, "if n.%s != nil { n.%s = edit(n.%s).(*Name) }\n", name, name, name) - case is(nodeType): - fmt.Fprintf(&buf, "n.%s = maybeEdit(n.%s, edit)\n", name, name) - case is(ntypeType): - fmt.Fprintf(&buf, "n.%s = toNtype(maybeEdit(n.%s, edit))\n", name, name) - case is(nodesType): - fmt.Fprintf(&buf, "editList(n.%s, edit)\n", name) - case is(slicePtrCaseClauseType): - fmt.Fprintf(&buf, "editCases(n.%s, edit)\n", name) - case is(slicePtrCommClauseType): - fmt.Fprintf(&buf, "editComms(n.%s, edit)\n", name) - case is(ptrFieldType): - fmt.Fprintf(&buf, "editField(n.%s, edit)\n", name) - case is(slicePtrFieldType): - fmt.Fprintf(&buf, "editFields(n.%s, edit)\n", name) - } - }) - fmt.Fprintf(&buf, "}\n") + forNodeFields(typ, + "func (n *%[1]s) doChildren(do func(Node) error) error {\n", + "if n.%[1]s != nil { if err := do(n.%[1]s); err != nil { return err } }", + "if err := do%[2]s(n.%[1]s, do); err != nil { return err }", + "return nil }\n") + + forNodeFields(typ, + "func (n *%[1]s) editChildren(edit func(Node) Node) {\n", + "if n.%[1]s != nil { n.%[1]s = edit(n.%[1]s).(%[2]s) }", + "edit%[2]s(n.%[1]s, edit)", + "}\n") } - for _, name := range []string{"CaseClause", "CommClause"} { - sliceHelper(&buf, name) - } + makeHelpers() out, err := format.Source(buf.Bytes()) if err != nil { @@ -155,20 +96,32 @@ func main() { } } -func sliceHelper(buf *bytes.Buffer, name string) { - tmpl := fmt.Sprintf(` -func copy%[1]ss(list []*%[2]s) []*%[2]s { +// needHelper maps needed slice helpers from their base name to their +// respective slice-element type. +var needHelper = map[string]string{} + +func makeHelpers() { + var names []string + for name := range needHelper { + names = append(names, name) + } + sort.Strings(names) + + for _, name := range names { + fmt.Fprintf(&buf, sliceHelperTmpl, name, needHelper[name]) + } +} + +const sliceHelperTmpl = ` +func copy%[1]s(list []%[2]s) []%[2]s { if list == nil { return nil } - c := make([]*%[2]s, len(list)) + c := make([]%[2]s, len(list)) copy(c, list) return c } -func maybeDo%[1]ss(list []*%[2]s, err error, do func(Node) error) error { - if err != nil { - return err - } +func do%[1]s(list []%[2]s, do func(Node) error) error { for _, x := range list { if x != nil { if err := do(x); err != nil { @@ -178,51 +131,98 @@ func maybeDo%[1]ss(list []*%[2]s, err error, do func(Node) error) error { } return nil } -func edit%[1]ss(list []*%[2]s, edit func(Node) Node) { +func edit%[1]s(list []%[2]s, edit func(Node) Node) { for i, x := range list { if x != nil { - list[i] = edit(x).(*%[2]s) + list[i] = edit(x).(%[2]s) } } } -`, strings.TrimSuffix(name, "Clause"), name) - fmt.Fprintln(buf, tmpl) +` + +func forNodeFields(named *types.Named, prologue, singleTmpl, sliceTmpl, epilogue string) { + fmt.Fprintf(&buf, prologue, named.Obj().Name()) + + anyField(named.Underlying().(*types.Struct), func(f *types.Var) bool { + if f.Embedded() { + return false + } + name, typ := f.Name(), f.Type() + + slice, _ := typ.Underlying().(*types.Slice) + if slice != nil { + typ = slice.Elem() + } + + tmpl, what := singleTmpl, types.TypeString(typ, types.RelativeTo(irPkg)) + if implementsNode(typ) { + if slice != nil { + helper := strings.TrimPrefix(what, "*") + "s" + needHelper[helper] = what + tmpl, what = sliceTmpl, helper + } + } else if what == "*Field" { + // Special case for *Field. + tmpl = sliceTmpl + if slice != nil { + what = "Fields" + } else { + what = "Field" + } + } else { + return false + } + + if tmpl == "" { + return false + } + + // Allow template to not use all arguments without + // upsetting fmt.Printf. + s := fmt.Sprintf(tmpl+"\x00 %[1]s %[2]s", name, what) + fmt.Fprintln(&buf, s[:strings.LastIndex(s, "\x00")]) + return false + }) + + fmt.Fprintf(&buf, epilogue) } -func forNodeFields(typName string, typ *types.Struct, f func(name string, is func(types.Type) bool)) { - for i, n := 0, typ.NumFields(); i < n; i++ { - v := typ.Field(i) - if v.Embedded() { - if typ, ok := v.Type().Underlying().(*types.Struct); ok { - forNodeFields(typName, typ, f) - continue - } - } - switch typName { - case "Func": - if strings.ToLower(strings.TrimSuffix(v.Name(), "_")) != "body" { - continue - } - case "Name": - continue - } - switch v.Name() { - case "orig": - continue - } - f(v.Name(), func(t types.Type) bool { return types.Identical(t, v.Type()) }) +func implementsNode(typ types.Type) bool { + if _, ok := typ.Underlying().(*types.Interface); ok { + // TODO(mdempsky): Check the interface implements Node. + // Worst case, node_gen.go will fail to compile if we're wrong. + return true } + + if ptr, ok := typ.(*types.Pointer); ok { + if str, ok := ptr.Elem().Underlying().(*types.Struct); ok { + return anyField(str, func(f *types.Var) bool { + return f.Embedded() && f.Name() == "miniNode" + }) + } + } + + return false } -func hasMiniNode(typ *types.Struct) bool { +func anyField(typ *types.Struct, pred func(f *types.Var) bool) bool { for i, n := 0, typ.NumFields(); i < n; i++ { - v := typ.Field(i) - if v.Name() == "miniNode" { + if value, ok := reflect.StructTag(typ.Tag(i)).Lookup("mknode"); ok { + if value != "-" { + panic(fmt.Sprintf("unexpected tag value: %q", value)) + } + continue + } + + f := typ.Field(i) + if pred(f) { return true } - if v.Embedded() { - if typ, ok := v.Type().Underlying().(*types.Struct); ok && hasMiniNode(typ) { - return true + if f.Embedded() { + if typ, ok := f.Type().Underlying().(*types.Struct); ok { + if anyField(typ, pred) { + return true + } } } } diff --git a/src/cmd/compile/internal/ir/name.go b/src/cmd/compile/internal/ir/name.go index d6135ee29a..b12e833f73 100644 --- a/src/cmd/compile/internal/ir/name.go +++ b/src/cmd/compile/internal/ir/name.go @@ -143,6 +143,10 @@ type Name struct { func (n *Name) isExpr() {} +func (n *Name) copy() Node { panic(n.no("copy")) } +func (n *Name) doChildren(do func(Node) error) error { return nil } +func (n *Name) editChildren(edit func(Node) Node) {} + // CloneName makes a cloned copy of the name. // It's not ir.Copy(n) because in general that operation is a mistake on names, // which uniquely identify variables. diff --git a/src/cmd/compile/internal/ir/node_gen.go b/src/cmd/compile/internal/ir/node_gen.go index 4c48e82d77..21e4eff9fb 100644 --- a/src/cmd/compile/internal/ir/node_gen.go +++ b/src/cmd/compile/internal/ir/node_gen.go @@ -7,22 +7,27 @@ import "fmt" func (n *AddStringExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *AddStringExpr) copy() Node { c := *n - c.init = c.init.Copy() - c.List = c.List.Copy() + c.init = copyNodes(c.init) + c.List = copyNodes(c.List) return &c } func (n *AddStringExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDoList(n.List, err, do) - if n.Prealloc != nil { - err = maybeDo(n.Prealloc, err, do) + if err := doNodes(n.init, do); err != nil { + return err } - return err + if err := doNodes(n.List, do); err != nil { + return err + } + if n.Prealloc != nil { + if err := do(n.Prealloc); err != nil { + return err + } + } + return nil } func (n *AddStringExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - editList(n.List, edit) + editNodes(n.init, edit) + editNodes(n.List, edit) if n.Prealloc != nil { n.Prealloc = edit(n.Prealloc).(*Name) } @@ -31,21 +36,30 @@ func (n *AddStringExpr) editChildren(edit func(Node) Node) { func (n *AddrExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *AddrExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *AddrExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - if n.Prealloc != nil { - err = maybeDo(n.Prealloc, err, do) + if err := doNodes(n.init, do); err != nil { + return err } - return err + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + if n.Prealloc != nil { + if err := do(n.Prealloc); err != nil { + return err + } + } + return nil } func (n *AddrExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } if n.Prealloc != nil { n.Prealloc = edit(n.Prealloc).(*Name) } @@ -57,193 +71,273 @@ func (n *ArrayType) copy() Node { return &c } func (n *ArrayType) doChildren(do func(Node) error) error { - var err error - err = maybeDo(n.Len, err, do) - err = maybeDo(n.Elem, err, do) - return err + if n.Len != nil { + if err := do(n.Len); err != nil { + return err + } + } + if n.Elem != nil { + if err := do(n.Elem); err != nil { + return err + } + } + return nil } func (n *ArrayType) editChildren(edit func(Node) Node) { - n.Len = maybeEdit(n.Len, edit) - n.Elem = toNtype(maybeEdit(n.Elem, edit)) + if n.Len != nil { + n.Len = edit(n.Len).(Node) + } + if n.Elem != nil { + n.Elem = edit(n.Elem).(Ntype) + } } func (n *AssignListStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *AssignListStmt) copy() Node { c := *n - c.init = c.init.Copy() - c.Lhs = c.Lhs.Copy() - c.Rhs = c.Rhs.Copy() + c.init = copyNodes(c.init) + c.Lhs = copyNodes(c.Lhs) + c.Rhs = copyNodes(c.Rhs) return &c } func (n *AssignListStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDoList(n.Lhs, err, do) - err = maybeDoList(n.Rhs, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if err := doNodes(n.Lhs, do); err != nil { + return err + } + if err := doNodes(n.Rhs, do); err != nil { + return err + } + return nil } func (n *AssignListStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) - editList(n.Lhs, edit) - editList(n.Rhs, edit) + editNodes(n.init, edit) + editNodes(n.Lhs, edit) + editNodes(n.Rhs, edit) } func (n *AssignOpStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *AssignOpStmt) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *AssignOpStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - err = maybeDo(n.Y, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + if n.Y != nil { + if err := do(n.Y); err != nil { + return err + } + } + return nil } func (n *AssignOpStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) - n.Y = maybeEdit(n.Y, edit) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } + if n.Y != nil { + n.Y = edit(n.Y).(Node) + } } func (n *AssignStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *AssignStmt) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *AssignStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - err = maybeDo(n.Y, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + if n.Y != nil { + if err := do(n.Y); err != nil { + return err + } + } + return nil } func (n *AssignStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) - n.Y = maybeEdit(n.Y, edit) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } + if n.Y != nil { + n.Y = edit(n.Y).(Node) + } } func (n *BasicLit) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *BasicLit) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *BasicLit) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + return nil } func (n *BasicLit) editChildren(edit func(Node) Node) { - editList(n.init, edit) + editNodes(n.init, edit) } func (n *BinaryExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *BinaryExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *BinaryExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - err = maybeDo(n.Y, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + if n.Y != nil { + if err := do(n.Y); err != nil { + return err + } + } + return nil } func (n *BinaryExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) - n.Y = maybeEdit(n.Y, edit) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } + if n.Y != nil { + n.Y = edit(n.Y).(Node) + } } func (n *BlockStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *BlockStmt) copy() Node { c := *n - c.init = c.init.Copy() - c.List = c.List.Copy() + c.init = copyNodes(c.init) + c.List = copyNodes(c.List) return &c } func (n *BlockStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDoList(n.List, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if err := doNodes(n.List, do); err != nil { + return err + } + return nil } func (n *BlockStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) - editList(n.List, edit) + editNodes(n.init, edit) + editNodes(n.List, edit) } func (n *BranchStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *BranchStmt) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *BranchStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + return nil } func (n *BranchStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) + editNodes(n.init, edit) } func (n *CallExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *CallExpr) copy() Node { c := *n - c.init = c.init.Copy() - c.Args = c.Args.Copy() - c.Rargs = c.Rargs.Copy() - c.Body = c.Body.Copy() + c.init = copyNodes(c.init) + c.Args = copyNodes(c.Args) + c.Rargs = copyNodes(c.Rargs) + c.Body = copyNodes(c.Body) return &c } func (n *CallExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - err = maybeDoList(n.Args, err, do) - err = maybeDoList(n.Rargs, err, do) - err = maybeDoList(n.Body, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + if err := doNodes(n.Args, do); err != nil { + return err + } + if err := doNodes(n.Rargs, do); err != nil { + return err + } + if err := doNodes(n.Body, do); err != nil { + return err + } + return nil } func (n *CallExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) - editList(n.Args, edit) - editList(n.Rargs, edit) - editList(n.Body, edit) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } + editNodes(n.Args, edit) + editNodes(n.Rargs, edit) + editNodes(n.Body, edit) } func (n *CaseClause) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *CaseClause) copy() Node { c := *n - c.init = c.init.Copy() - c.List = c.List.Copy() - c.Body = c.Body.Copy() + c.init = copyNodes(c.init) + c.List = copyNodes(c.List) + c.Body = copyNodes(c.Body) return &c } func (n *CaseClause) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - if n.Var != nil { - err = maybeDo(n.Var, err, do) + if err := doNodes(n.init, do); err != nil { + return err } - err = maybeDoList(n.List, err, do) - err = maybeDoList(n.Body, err, do) - return err + if n.Var != nil { + if err := do(n.Var); err != nil { + return err + } + } + if err := doNodes(n.List, do); err != nil { + return err + } + if err := doNodes(n.Body, do); err != nil { + return err + } + return nil } func (n *CaseClause) editChildren(edit func(Node) Node) { - editList(n.init, edit) + editNodes(n.init, edit) if n.Var != nil { n.Var = edit(n.Var).(*Name) } - editList(n.List, edit) - editList(n.Body, edit) + editNodes(n.List, edit) + editNodes(n.Body, edit) } func (n *ChanType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } @@ -252,30 +346,38 @@ func (n *ChanType) copy() Node { return &c } func (n *ChanType) doChildren(do func(Node) error) error { - var err error - err = maybeDo(n.Elem, err, do) - return err + if n.Elem != nil { + if err := do(n.Elem); err != nil { + return err + } + } + return nil } func (n *ChanType) editChildren(edit func(Node) Node) { - n.Elem = toNtype(maybeEdit(n.Elem, edit)) + if n.Elem != nil { + n.Elem = edit(n.Elem).(Ntype) + } } func (n *ClosureExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *ClosureExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *ClosureExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - if n.Prealloc != nil { - err = maybeDo(n.Prealloc, err, do) + if err := doNodes(n.init, do); err != nil { + return err } - return err + if n.Prealloc != nil { + if err := do(n.Prealloc); err != nil { + return err + } + } + return nil } func (n *ClosureExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) + editNodes(n.init, edit) if n.Prealloc != nil { n.Prealloc = edit(n.Prealloc).(*Name) } @@ -284,59 +386,80 @@ func (n *ClosureExpr) editChildren(edit func(Node) Node) { func (n *ClosureReadExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *ClosureReadExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *ClosureReadExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + return nil } func (n *ClosureReadExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) + editNodes(n.init, edit) } func (n *CommClause) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *CommClause) copy() Node { c := *n - c.init = c.init.Copy() - c.Body = c.Body.Copy() + c.init = copyNodes(c.init) + c.Body = copyNodes(c.Body) return &c } func (n *CommClause) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.Comm, err, do) - err = maybeDoList(n.Body, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.Comm != nil { + if err := do(n.Comm); err != nil { + return err + } + } + if err := doNodes(n.Body, do); err != nil { + return err + } + return nil } func (n *CommClause) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.Comm = maybeEdit(n.Comm, edit) - editList(n.Body, edit) + editNodes(n.init, edit) + if n.Comm != nil { + n.Comm = edit(n.Comm).(Node) + } + editNodes(n.Body, edit) } func (n *CompLitExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *CompLitExpr) copy() Node { c := *n - c.init = c.init.Copy() - c.List = c.List.Copy() + c.init = copyNodes(c.init) + c.List = copyNodes(c.List) return &c } func (n *CompLitExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.Ntype, err, do) - err = maybeDoList(n.List, err, do) - if n.Prealloc != nil { - err = maybeDo(n.Prealloc, err, do) + if err := doNodes(n.init, do); err != nil { + return err } - return err + if n.Ntype != nil { + if err := do(n.Ntype); err != nil { + return err + } + } + if err := doNodes(n.List, do); err != nil { + return err + } + if n.Prealloc != nil { + if err := do(n.Prealloc); err != nil { + return err + } + } + return nil } func (n *CompLitExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.Ntype = toNtype(maybeEdit(n.Ntype, edit)) - editList(n.List, edit) + editNodes(n.init, edit) + if n.Ntype != nil { + n.Ntype = edit(n.Ntype).(Ntype) + } + editNodes(n.List, edit) if n.Prealloc != nil { n.Prealloc = edit(n.Prealloc).(*Name) } @@ -345,33 +468,41 @@ func (n *CompLitExpr) editChildren(edit func(Node) Node) { func (n *ConstExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *ConstExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *ConstExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + return nil } func (n *ConstExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) + editNodes(n.init, edit) } func (n *ConvExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *ConvExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *ConvExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + return nil } func (n *ConvExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } } func (n *Decl) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } @@ -380,11 +511,12 @@ func (n *Decl) copy() Node { return &c } func (n *Decl) doChildren(do func(Node) error) error { - var err error if n.X != nil { - err = maybeDo(n.X, err, do) + if err := do(n.X); err != nil { + return err + } } - return err + return nil } func (n *Decl) editChildren(edit func(Node) Node) { if n.X != nil { @@ -395,59 +527,66 @@ func (n *Decl) editChildren(edit func(Node) Node) { func (n *ForStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *ForStmt) copy() Node { c := *n - c.init = c.init.Copy() - c.Late = c.Late.Copy() - c.Body = c.Body.Copy() + c.init = copyNodes(c.init) + c.Late = copyNodes(c.Late) + c.Body = copyNodes(c.Body) return &c } func (n *ForStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.Cond, err, do) - err = maybeDoList(n.Late, err, do) - err = maybeDo(n.Post, err, do) - err = maybeDoList(n.Body, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.Cond != nil { + if err := do(n.Cond); err != nil { + return err + } + } + if err := doNodes(n.Late, do); err != nil { + return err + } + if n.Post != nil { + if err := do(n.Post); err != nil { + return err + } + } + if err := doNodes(n.Body, do); err != nil { + return err + } + return nil } func (n *ForStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.Cond = maybeEdit(n.Cond, edit) - editList(n.Late, edit) - n.Post = maybeEdit(n.Post, edit) - editList(n.Body, edit) + editNodes(n.init, edit) + if n.Cond != nil { + n.Cond = edit(n.Cond).(Node) + } + editNodes(n.Late, edit) + if n.Post != nil { + n.Post = edit(n.Post).(Node) + } + editNodes(n.Body, edit) } func (n *Func) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } -func (n *Func) copy() Node { - c := *n - c.Body = c.Body.Copy() - return &c -} -func (n *Func) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.Body, err, do) - return err -} -func (n *Func) editChildren(edit func(Node) Node) { - editList(n.Body, edit) -} func (n *FuncType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *FuncType) copy() Node { c := *n - if c.Recv != nil { - c.Recv = c.Recv.copy() - } + c.Recv = copyField(c.Recv) c.Params = copyFields(c.Params) c.Results = copyFields(c.Results) return &c } func (n *FuncType) doChildren(do func(Node) error) error { - var err error - err = maybeDoField(n.Recv, err, do) - err = maybeDoFields(n.Params, err, do) - err = maybeDoFields(n.Results, err, do) - return err + if err := doField(n.Recv, do); err != nil { + return err + } + if err := doFields(n.Params, do); err != nil { + return err + } + if err := doFields(n.Results, do); err != nil { + return err + } + return nil } func (n *FuncType) editChildren(edit func(Node) Node) { editField(n.Recv, edit) @@ -458,111 +597,149 @@ func (n *FuncType) editChildren(edit func(Node) Node) { func (n *GoDeferStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *GoDeferStmt) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *GoDeferStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.Call, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.Call != nil { + if err := do(n.Call); err != nil { + return err + } + } + return nil } func (n *GoDeferStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.Call = maybeEdit(n.Call, edit) + editNodes(n.init, edit) + if n.Call != nil { + n.Call = edit(n.Call).(Node) + } } func (n *Ident) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *Ident) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *Ident) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + return nil } func (n *Ident) editChildren(edit func(Node) Node) { - editList(n.init, edit) + editNodes(n.init, edit) } func (n *IfStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *IfStmt) copy() Node { c := *n - c.init = c.init.Copy() - c.Body = c.Body.Copy() - c.Else = c.Else.Copy() + c.init = copyNodes(c.init) + c.Body = copyNodes(c.Body) + c.Else = copyNodes(c.Else) return &c } func (n *IfStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.Cond, err, do) - err = maybeDoList(n.Body, err, do) - err = maybeDoList(n.Else, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.Cond != nil { + if err := do(n.Cond); err != nil { + return err + } + } + if err := doNodes(n.Body, do); err != nil { + return err + } + if err := doNodes(n.Else, do); err != nil { + return err + } + return nil } func (n *IfStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.Cond = maybeEdit(n.Cond, edit) - editList(n.Body, edit) - editList(n.Else, edit) + editNodes(n.init, edit) + if n.Cond != nil { + n.Cond = edit(n.Cond).(Node) + } + editNodes(n.Body, edit) + editNodes(n.Else, edit) } func (n *IndexExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *IndexExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *IndexExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - err = maybeDo(n.Index, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + if n.Index != nil { + if err := do(n.Index); err != nil { + return err + } + } + return nil } func (n *IndexExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) - n.Index = maybeEdit(n.Index, edit) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } + if n.Index != nil { + n.Index = edit(n.Index).(Node) + } } func (n *InlineMarkStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *InlineMarkStmt) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *InlineMarkStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + return nil } func (n *InlineMarkStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) + editNodes(n.init, edit) } func (n *InlinedCallExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *InlinedCallExpr) copy() Node { c := *n - c.init = c.init.Copy() - c.Body = c.Body.Copy() - c.ReturnVars = c.ReturnVars.Copy() + c.init = copyNodes(c.init) + c.Body = copyNodes(c.Body) + c.ReturnVars = copyNodes(c.ReturnVars) return &c } func (n *InlinedCallExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDoList(n.Body, err, do) - err = maybeDoList(n.ReturnVars, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if err := doNodes(n.Body, do); err != nil { + return err + } + if err := doNodes(n.ReturnVars, do); err != nil { + return err + } + return nil } func (n *InlinedCallExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - editList(n.Body, edit) - editList(n.ReturnVars, edit) + editNodes(n.init, edit) + editNodes(n.Body, edit) + editNodes(n.ReturnVars, edit) } func (n *InterfaceType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } @@ -572,9 +749,10 @@ func (n *InterfaceType) copy() Node { return &c } func (n *InterfaceType) doChildren(do func(Node) error) error { - var err error - err = maybeDoFields(n.Methods, err, do) - return err + if err := doFields(n.Methods, do); err != nil { + return err + } + return nil } func (n *InterfaceType) editChildren(edit func(Node) Node) { editFields(n.Methods, edit) @@ -583,73 +761,113 @@ func (n *InterfaceType) editChildren(edit func(Node) Node) { func (n *KeyExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *KeyExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *KeyExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.Key, err, do) - err = maybeDo(n.Value, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.Key != nil { + if err := do(n.Key); err != nil { + return err + } + } + if n.Value != nil { + if err := do(n.Value); err != nil { + return err + } + } + return nil } func (n *KeyExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.Key = maybeEdit(n.Key, edit) - n.Value = maybeEdit(n.Value, edit) + editNodes(n.init, edit) + if n.Key != nil { + n.Key = edit(n.Key).(Node) + } + if n.Value != nil { + n.Value = edit(n.Value).(Node) + } } func (n *LabelStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *LabelStmt) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *LabelStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + return nil } func (n *LabelStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) + editNodes(n.init, edit) } func (n *LogicalExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *LogicalExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *LogicalExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - err = maybeDo(n.Y, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + if n.Y != nil { + if err := do(n.Y); err != nil { + return err + } + } + return nil } func (n *LogicalExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) - n.Y = maybeEdit(n.Y, edit) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } + if n.Y != nil { + n.Y = edit(n.Y).(Node) + } } func (n *MakeExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *MakeExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *MakeExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.Len, err, do) - err = maybeDo(n.Cap, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.Len != nil { + if err := do(n.Len); err != nil { + return err + } + } + if n.Cap != nil { + if err := do(n.Cap); err != nil { + return err + } + } + return nil } func (n *MakeExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.Len = maybeEdit(n.Len, edit) - n.Cap = maybeEdit(n.Cap, edit) + editNodes(n.init, edit) + if n.Len != nil { + n.Len = edit(n.Len).(Node) + } + if n.Cap != nil { + n.Cap = edit(n.Cap).(Node) + } } func (n *MapType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } @@ -658,41 +876,48 @@ func (n *MapType) copy() Node { return &c } func (n *MapType) doChildren(do func(Node) error) error { - var err error - err = maybeDo(n.Key, err, do) - err = maybeDo(n.Elem, err, do) - return err + if n.Key != nil { + if err := do(n.Key); err != nil { + return err + } + } + if n.Elem != nil { + if err := do(n.Elem); err != nil { + return err + } + } + return nil } func (n *MapType) editChildren(edit func(Node) Node) { - n.Key = toNtype(maybeEdit(n.Key, edit)) - n.Elem = toNtype(maybeEdit(n.Elem, edit)) + if n.Key != nil { + n.Key = edit(n.Key).(Ntype) + } + if n.Elem != nil { + n.Elem = edit(n.Elem).(Ntype) + } } func (n *Name) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } -func (n *Name) copy() Node { panic("Name.copy") } -func (n *Name) doChildren(do func(Node) error) error { - var err error - return err -} -func (n *Name) editChildren(edit func(Node) Node) { -} func (n *NameOffsetExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *NameOffsetExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *NameOffsetExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - if n.Name_ != nil { - err = maybeDo(n.Name_, err, do) + if err := doNodes(n.init, do); err != nil { + return err } - return err + if n.Name_ != nil { + if err := do(n.Name_); err != nil { + return err + } + } + return nil } func (n *NameOffsetExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) + editNodes(n.init, edit) if n.Name_ != nil { n.Name_ = edit(n.Name_).(*Name) } @@ -701,33 +926,41 @@ func (n *NameOffsetExpr) editChildren(edit func(Node) Node) { func (n *NilExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *NilExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *NilExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + return nil } func (n *NilExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) + editNodes(n.init, edit) } func (n *ParenExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *ParenExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *ParenExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + return nil } func (n *ParenExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } } func (n *PkgName) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } @@ -736,8 +969,7 @@ func (n *PkgName) copy() Node { return &c } func (n *PkgName) doChildren(do func(Node) error) error { - var err error - return err + return nil } func (n *PkgName) editChildren(edit func(Node) Node) { } @@ -745,28 +977,51 @@ func (n *PkgName) editChildren(edit func(Node) Node) { func (n *RangeStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *RangeStmt) copy() Node { c := *n - c.init = c.init.Copy() - c.Body = c.Body.Copy() + c.init = copyNodes(c.init) + c.Body = copyNodes(c.Body) return &c } func (n *RangeStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - err = maybeDo(n.Key, err, do) - err = maybeDo(n.Value, err, do) - err = maybeDoList(n.Body, err, do) - if n.Prealloc != nil { - err = maybeDo(n.Prealloc, err, do) + if err := doNodes(n.init, do); err != nil { + return err } - return err + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + if n.Key != nil { + if err := do(n.Key); err != nil { + return err + } + } + if n.Value != nil { + if err := do(n.Value); err != nil { + return err + } + } + if err := doNodes(n.Body, do); err != nil { + return err + } + if n.Prealloc != nil { + if err := do(n.Prealloc); err != nil { + return err + } + } + return nil } func (n *RangeStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) - n.Key = maybeEdit(n.Key, edit) - n.Value = maybeEdit(n.Value, edit) - editList(n.Body, edit) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } + if n.Key != nil { + n.Key = edit(n.Key).(Node) + } + if n.Value != nil { + n.Value = edit(n.Value).(Node) + } + editNodes(n.Body, edit) if n.Prealloc != nil { n.Prealloc = edit(n.Prealloc).(*Name) } @@ -775,75 +1030,93 @@ func (n *RangeStmt) editChildren(edit func(Node) Node) { func (n *ResultExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *ResultExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *ResultExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + return nil } func (n *ResultExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) + editNodes(n.init, edit) } func (n *ReturnStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *ReturnStmt) copy() Node { c := *n - c.init = c.init.Copy() - c.Results = c.Results.Copy() + c.init = copyNodes(c.init) + c.Results = copyNodes(c.Results) return &c } func (n *ReturnStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDoList(n.Results, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if err := doNodes(n.Results, do); err != nil { + return err + } + return nil } func (n *ReturnStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) - editList(n.Results, edit) + editNodes(n.init, edit) + editNodes(n.Results, edit) } func (n *SelectStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *SelectStmt) copy() Node { c := *n - c.init = c.init.Copy() - c.Cases = copyComms(c.Cases) - c.Compiled = c.Compiled.Copy() + c.init = copyNodes(c.init) + c.Cases = copyCommClauses(c.Cases) + c.Compiled = copyNodes(c.Compiled) return &c } func (n *SelectStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDoComms(n.Cases, err, do) - err = maybeDoList(n.Compiled, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if err := doCommClauses(n.Cases, do); err != nil { + return err + } + if err := doNodes(n.Compiled, do); err != nil { + return err + } + return nil } func (n *SelectStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) - editComms(n.Cases, edit) - editList(n.Compiled, edit) + editNodes(n.init, edit) + editCommClauses(n.Cases, edit) + editNodes(n.Compiled, edit) } func (n *SelectorExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *SelectorExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *SelectorExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - if n.Prealloc != nil { - err = maybeDo(n.Prealloc, err, do) + if err := doNodes(n.init, do); err != nil { + return err } - return err + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + if n.Prealloc != nil { + if err := do(n.Prealloc); err != nil { + return err + } + } + return nil } func (n *SelectorExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } if n.Prealloc != nil { n.Prealloc = edit(n.Prealloc).(*Name) } @@ -852,64 +1125,121 @@ func (n *SelectorExpr) editChildren(edit func(Node) Node) { func (n *SendStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *SendStmt) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *SendStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.Chan, err, do) - err = maybeDo(n.Value, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.Chan != nil { + if err := do(n.Chan); err != nil { + return err + } + } + if n.Value != nil { + if err := do(n.Value); err != nil { + return err + } + } + return nil } func (n *SendStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.Chan = maybeEdit(n.Chan, edit) - n.Value = maybeEdit(n.Value, edit) + editNodes(n.init, edit) + if n.Chan != nil { + n.Chan = edit(n.Chan).(Node) + } + if n.Value != nil { + n.Value = edit(n.Value).(Node) + } } func (n *SliceExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *SliceExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *SliceExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - err = maybeDo(n.Low, err, do) - err = maybeDo(n.High, err, do) - err = maybeDo(n.Max, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + if n.Low != nil { + if err := do(n.Low); err != nil { + return err + } + } + if n.High != nil { + if err := do(n.High); err != nil { + return err + } + } + if n.Max != nil { + if err := do(n.Max); err != nil { + return err + } + } + return nil } func (n *SliceExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) - n.Low = maybeEdit(n.Low, edit) - n.High = maybeEdit(n.High, edit) - n.Max = maybeEdit(n.Max, edit) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } + if n.Low != nil { + n.Low = edit(n.Low).(Node) + } + if n.High != nil { + n.High = edit(n.High).(Node) + } + if n.Max != nil { + n.Max = edit(n.Max).(Node) + } } func (n *SliceHeaderExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *SliceHeaderExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *SliceHeaderExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.Ptr, err, do) - err = maybeDo(n.Len, err, do) - err = maybeDo(n.Cap, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.Ptr != nil { + if err := do(n.Ptr); err != nil { + return err + } + } + if n.Len != nil { + if err := do(n.Len); err != nil { + return err + } + } + if n.Cap != nil { + if err := do(n.Cap); err != nil { + return err + } + } + return nil } func (n *SliceHeaderExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.Ptr = maybeEdit(n.Ptr, edit) - n.Len = maybeEdit(n.Len, edit) - n.Cap = maybeEdit(n.Cap, edit) + editNodes(n.init, edit) + if n.Ptr != nil { + n.Ptr = edit(n.Ptr).(Node) + } + if n.Len != nil { + n.Len = edit(n.Len).(Node) + } + if n.Cap != nil { + n.Cap = edit(n.Cap).(Node) + } } func (n *SliceType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } @@ -918,46 +1248,65 @@ func (n *SliceType) copy() Node { return &c } func (n *SliceType) doChildren(do func(Node) error) error { - var err error - err = maybeDo(n.Elem, err, do) - return err + if n.Elem != nil { + if err := do(n.Elem); err != nil { + return err + } + } + return nil } func (n *SliceType) editChildren(edit func(Node) Node) { - n.Elem = toNtype(maybeEdit(n.Elem, edit)) + if n.Elem != nil { + n.Elem = edit(n.Elem).(Ntype) + } } func (n *StarExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *StarExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *StarExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + return nil } func (n *StarExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } } func (n *StructKeyExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *StructKeyExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *StructKeyExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.Value, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.Value != nil { + if err := do(n.Value); err != nil { + return err + } + } + return nil } func (n *StructKeyExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.Value = maybeEdit(n.Value, edit) + editNodes(n.init, edit) + if n.Value != nil { + n.Value = edit(n.Value).(Node) + } } func (n *StructType) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } @@ -967,9 +1316,10 @@ func (n *StructType) copy() Node { return &c } func (n *StructType) doChildren(do func(Node) error) error { - var err error - err = maybeDoFields(n.Fields, err, do) - return err + if err := doFields(n.Fields, do); err != nil { + return err + } + return nil } func (n *StructType) editChildren(edit func(Node) Node) { editFields(n.Fields, edit) @@ -978,43 +1328,67 @@ func (n *StructType) editChildren(edit func(Node) Node) { func (n *SwitchStmt) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *SwitchStmt) copy() Node { c := *n - c.init = c.init.Copy() - c.Cases = copyCases(c.Cases) - c.Compiled = c.Compiled.Copy() + c.init = copyNodes(c.init) + c.Cases = copyCaseClauses(c.Cases) + c.Compiled = copyNodes(c.Compiled) return &c } func (n *SwitchStmt) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.Tag, err, do) - err = maybeDoCases(n.Cases, err, do) - err = maybeDoList(n.Compiled, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.Tag != nil { + if err := do(n.Tag); err != nil { + return err + } + } + if err := doCaseClauses(n.Cases, do); err != nil { + return err + } + if err := doNodes(n.Compiled, do); err != nil { + return err + } + return nil } func (n *SwitchStmt) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.Tag = maybeEdit(n.Tag, edit) - editCases(n.Cases, edit) - editList(n.Compiled, edit) + editNodes(n.init, edit) + if n.Tag != nil { + n.Tag = edit(n.Tag).(Node) + } + editCaseClauses(n.Cases, edit) + editNodes(n.Compiled, edit) } func (n *TypeAssertExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *TypeAssertExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *TypeAssertExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - err = maybeDo(n.Ntype, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + if n.Ntype != nil { + if err := do(n.Ntype); err != nil { + return err + } + } + return nil } func (n *TypeAssertExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) - n.Ntype = toNtype(maybeEdit(n.Ntype, edit)) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } + if n.Ntype != nil { + n.Ntype = edit(n.Ntype).(Ntype) + } } func (n *TypeSwitchGuard) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } @@ -1023,35 +1397,49 @@ func (n *TypeSwitchGuard) copy() Node { return &c } func (n *TypeSwitchGuard) doChildren(do func(Node) error) error { - var err error if n.Tag != nil { - err = maybeDo(n.Tag, err, do) + if err := do(n.Tag); err != nil { + return err + } } - err = maybeDo(n.X, err, do) - return err + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + return nil } func (n *TypeSwitchGuard) editChildren(edit func(Node) Node) { if n.Tag != nil { n.Tag = edit(n.Tag).(*Ident) } - n.X = maybeEdit(n.X, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } } func (n *UnaryExpr) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } func (n *UnaryExpr) copy() Node { c := *n - c.init = c.init.Copy() + c.init = copyNodes(c.init) return &c } func (n *UnaryExpr) doChildren(do func(Node) error) error { - var err error - err = maybeDoList(n.init, err, do) - err = maybeDo(n.X, err, do) - return err + if err := doNodes(n.init, do); err != nil { + return err + } + if n.X != nil { + if err := do(n.X); err != nil { + return err + } + } + return nil } func (n *UnaryExpr) editChildren(edit func(Node) Node) { - editList(n.init, edit) - n.X = maybeEdit(n.X, edit) + editNodes(n.init, edit) + if n.X != nil { + n.X = edit(n.X).(Node) + } } func (n *typeNode) Format(s fmt.State, verb rune) { fmtNode(n, s, verb) } @@ -1060,13 +1448,12 @@ func (n *typeNode) copy() Node { return &c } func (n *typeNode) doChildren(do func(Node) error) error { - var err error - return err + return nil } func (n *typeNode) editChildren(edit func(Node) Node) { } -func copyCases(list []*CaseClause) []*CaseClause { +func copyCaseClauses(list []*CaseClause) []*CaseClause { if list == nil { return nil } @@ -1074,10 +1461,7 @@ func copyCases(list []*CaseClause) []*CaseClause { copy(c, list) return c } -func maybeDoCases(list []*CaseClause, err error, do func(Node) error) error { - if err != nil { - return err - } +func doCaseClauses(list []*CaseClause, do func(Node) error) error { for _, x := range list { if x != nil { if err := do(x); err != nil { @@ -1087,7 +1471,7 @@ func maybeDoCases(list []*CaseClause, err error, do func(Node) error) error { } return nil } -func editCases(list []*CaseClause, edit func(Node) Node) { +func editCaseClauses(list []*CaseClause, edit func(Node) Node) { for i, x := range list { if x != nil { list[i] = edit(x).(*CaseClause) @@ -1095,7 +1479,7 @@ func editCases(list []*CaseClause, edit func(Node) Node) { } } -func copyComms(list []*CommClause) []*CommClause { +func copyCommClauses(list []*CommClause) []*CommClause { if list == nil { return nil } @@ -1103,10 +1487,7 @@ func copyComms(list []*CommClause) []*CommClause { copy(c, list) return c } -func maybeDoComms(list []*CommClause, err error, do func(Node) error) error { - if err != nil { - return err - } +func doCommClauses(list []*CommClause, do func(Node) error) error { for _, x := range list { if x != nil { if err := do(x); err != nil { @@ -1116,10 +1497,36 @@ func maybeDoComms(list []*CommClause, err error, do func(Node) error) error { } return nil } -func editComms(list []*CommClause, edit func(Node) Node) { +func editCommClauses(list []*CommClause, edit func(Node) Node) { for i, x := range list { if x != nil { list[i] = edit(x).(*CommClause) } } } + +func copyNodes(list []Node) []Node { + if list == nil { + return nil + } + c := make([]Node, len(list)) + copy(c, list) + return c +} +func doNodes(list []Node, do func(Node) error) error { + for _, x := range list { + if x != nil { + if err := do(x); err != nil { + return err + } + } + } + return nil +} +func editNodes(list []Node, edit func(Node) Node) { + for i, x := range list { + if x != nil { + list[i] = edit(x).(Node) + } + } +} diff --git a/src/cmd/compile/internal/ir/stmt.go b/src/cmd/compile/internal/ir/stmt.go index 4575dec260..9c2cba9a08 100644 --- a/src/cmd/compile/internal/ir/stmt.go +++ b/src/cmd/compile/internal/ir/stmt.go @@ -322,8 +322,8 @@ func NewRangeStmt(pos src.XPos, key, value, x Node, body []Node) *RangeStmt { // A ReturnStmt is a return statement. type ReturnStmt struct { miniStmt - orig Node // for typecheckargs rewrite - Results Nodes // return list + origNode // for typecheckargs rewrite + Results Nodes // return list } func NewReturnStmt(pos src.XPos, results []Node) *ReturnStmt { @@ -335,9 +335,6 @@ func NewReturnStmt(pos src.XPos, results []Node) *ReturnStmt { return n } -func (n *ReturnStmt) Orig() Node { return n.orig } -func (n *ReturnStmt) SetOrig(x Node) { n.orig = x } - // A SelectStmt is a block: { Cases }. type SelectStmt struct { miniStmt diff --git a/src/cmd/compile/internal/ir/type.go b/src/cmd/compile/internal/ir/type.go index 408f6ed563..7dd394f9ea 100644 --- a/src/cmd/compile/internal/ir/type.go +++ b/src/cmd/compile/internal/ir/type.go @@ -185,45 +185,32 @@ func (f *Field) String() string { return typ } -func (f *Field) copy() *Field { +// TODO(mdempsky): Make Field a Node again so these can be generated? +// Fields are Nodes in go/ast and cmd/compile/internal/syntax. + +func copyField(f *Field) *Field { + if f == nil { + return nil + } c := *f return &c } - -func copyFields(list []*Field) []*Field { - out := make([]*Field, len(list)) - copy(out, list) - for i, f := range out { - out[i] = f.copy() +func doField(f *Field, do func(Node) error) error { + if f == nil { + return nil } - return out -} - -func maybeDoField(f *Field, err error, do func(Node) error) error { - if f != nil { - if err == nil && f.Decl != nil { - err = do(f.Decl) - } - if err == nil && f.Ntype != nil { - err = do(f.Ntype) - } - } - return err -} - -func maybeDoFields(list []*Field, err error, do func(Node) error) error { - if err != nil { - return err - } - for _, f := range list { - err = maybeDoField(f, err, do) - if err != nil { + if f.Decl != nil { + if err := do(f.Decl); err != nil { return err } } - return err + if f.Ntype != nil { + if err := do(f.Ntype); err != nil { + return err + } + } + return nil } - func editField(f *Field, edit func(Node) Node) { if f == nil { return @@ -232,10 +219,25 @@ func editField(f *Field, edit func(Node) Node) { f.Decl = edit(f.Decl).(*Name) } if f.Ntype != nil { - f.Ntype = toNtype(edit(f.Ntype)) + f.Ntype = edit(f.Ntype).(Ntype) } } +func copyFields(list []*Field) []*Field { + out := make([]*Field, len(list)) + for i, f := range list { + out[i] = copyField(f) + } + return out +} +func doFields(list []*Field, do func(Node) error) error { + for _, x := range list { + if err := doField(x, do); err != nil { + return err + } + } + return nil +} func editFields(list []*Field, edit func(Node) Node) { for _, f := range list { editField(f, edit) diff --git a/src/cmd/compile/internal/ir/visit.go b/src/cmd/compile/internal/ir/visit.go index 8839e1664d..4616390b7c 100644 --- a/src/cmd/compile/internal/ir/visit.go +++ b/src/cmd/compile/internal/ir/visit.go @@ -106,14 +106,7 @@ func DoChildren(n Node, do func(Node) error) error { // Note that DoList only calls do on the nodes in the list, not their children. // If x's children should be processed, do(x) must call DoChildren(x, do) itself. func DoList(list Nodes, do func(Node) error) error { - for _, x := range list { - if x != nil { - if err := do(x); err != nil { - return err - } - } - } - return nil + return doNodes(list, do) } // Visit visits each non-nil node x in the IR tree rooted at n @@ -210,16 +203,3 @@ func EditChildren(n Node, edit func(Node) Node) { } n.editChildren(edit) } - -// editList calls edit on each non-nil node x in the list, -// saving the result of edit back into the list. -// -// Note that editList only calls edit on the nodes in the list, not their children. -// If x's children should be processed, edit(x) must call EditChildren(x, edit) itself. -func editList(list Nodes, edit func(Node) Node) { - for i, x := range list { - if x != nil { - list[i] = edit(x) - } - } -}