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) - } - } -}