|
|
|
@ -164,18 +164,6 @@ func gen(buf *bytes.Buffer, imports map[string]struct{}, name string, typ *types
|
|
|
|
|
|
|
|
|
|
switch t := typ.Underlying().(type) {
|
|
|
|
|
case *types.Struct:
|
|
|
|
|
// We generate two bits of code simultaneously while we walk the struct.
|
|
|
|
|
// One is the Clone method itself, which we write directly to buf.
|
|
|
|
|
// The other is a variable assignment that will fail if the struct
|
|
|
|
|
// changes without the Clone method getting regenerated.
|
|
|
|
|
// We write that to regenBuf, and then append it to buf at the end.
|
|
|
|
|
regenBuf := new(bytes.Buffer)
|
|
|
|
|
writeRegen := func(format string, args ...interface{}) {
|
|
|
|
|
fmt.Fprintf(regenBuf, format+"\n", args...)
|
|
|
|
|
}
|
|
|
|
|
writeRegen("// A compilation failure here means this code must be regenerated, with the command at the top of this file.")
|
|
|
|
|
writeRegen("var _%sNeedsRegeneration = %s(struct {", name, name)
|
|
|
|
|
|
|
|
|
|
name := typ.Obj().Name()
|
|
|
|
|
fmt.Fprintf(buf, "// Clone makes a deep copy of %s.\n", name)
|
|
|
|
|
fmt.Fprintf(buf, "// The result aliases no memory with the original.\n")
|
|
|
|
@ -191,9 +179,6 @@ func gen(buf *bytes.Buffer, imports map[string]struct{}, name string, typ *types
|
|
|
|
|
for i := 0; i < t.NumFields(); i++ {
|
|
|
|
|
fname := t.Field(i).Name()
|
|
|
|
|
ft := t.Field(i).Type()
|
|
|
|
|
|
|
|
|
|
writeRegen("\t%s %s", fname, importedName(ft))
|
|
|
|
|
|
|
|
|
|
if !containsPointers(ft) {
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
@ -258,9 +243,7 @@ func gen(buf *bytes.Buffer, imports map[string]struct{}, name string, typ *types
|
|
|
|
|
writef("return dst")
|
|
|
|
|
fmt.Fprintf(buf, "}\n\n")
|
|
|
|
|
|
|
|
|
|
writeRegen("}{})\n")
|
|
|
|
|
|
|
|
|
|
buf.Write(regenBuf.Bytes())
|
|
|
|
|
buf.Write(codegen.AssertStructUnchanged(t, name, "", thisPkg, imports))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|