mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-22 03:11:40 +00:00
bump(k8s.io/gengo): 712a17394a0980fabbcf3d968972e185d80c0fa4
This commit is contained in:
parent
0d88afa131
commit
774560085e
21
Godeps/Godeps.json
generated
21
Godeps/Godeps.json
generated
@ -2231,7 +2231,6 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/pelletier/go-buffruneio",
|
||||
"Comment": "v0.1.0",
|
||||
"Rev": "df1e16fde7fc330a0ca68167c23bf7ed6ac31d6d"
|
||||
},
|
||||
{
|
||||
@ -2985,43 +2984,43 @@
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/gengo/args",
|
||||
"Rev": "c79c13d131b0a8f42d05faa6491c12e94ccc6f30"
|
||||
"Rev": "712a17394a0980fabbcf3d968972e185d80c0fa4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/gengo/examples/deepcopy-gen/generators",
|
||||
"Rev": "c79c13d131b0a8f42d05faa6491c12e94ccc6f30"
|
||||
"Rev": "712a17394a0980fabbcf3d968972e185d80c0fa4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/gengo/examples/defaulter-gen/generators",
|
||||
"Rev": "c79c13d131b0a8f42d05faa6491c12e94ccc6f30"
|
||||
"Rev": "712a17394a0980fabbcf3d968972e185d80c0fa4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/gengo/examples/import-boss/generators",
|
||||
"Rev": "c79c13d131b0a8f42d05faa6491c12e94ccc6f30"
|
||||
"Rev": "712a17394a0980fabbcf3d968972e185d80c0fa4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/gengo/examples/set-gen/generators",
|
||||
"Rev": "c79c13d131b0a8f42d05faa6491c12e94ccc6f30"
|
||||
"Rev": "712a17394a0980fabbcf3d968972e185d80c0fa4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/gengo/examples/set-gen/sets",
|
||||
"Rev": "c79c13d131b0a8f42d05faa6491c12e94ccc6f30"
|
||||
"Rev": "712a17394a0980fabbcf3d968972e185d80c0fa4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/gengo/generator",
|
||||
"Rev": "c79c13d131b0a8f42d05faa6491c12e94ccc6f30"
|
||||
"Rev": "712a17394a0980fabbcf3d968972e185d80c0fa4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/gengo/namer",
|
||||
"Rev": "c79c13d131b0a8f42d05faa6491c12e94ccc6f30"
|
||||
"Rev": "712a17394a0980fabbcf3d968972e185d80c0fa4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/gengo/parser",
|
||||
"Rev": "c79c13d131b0a8f42d05faa6491c12e94ccc6f30"
|
||||
"Rev": "712a17394a0980fabbcf3d968972e185d80c0fa4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/gengo/types",
|
||||
"Rev": "c79c13d131b0a8f42d05faa6491c12e94ccc6f30"
|
||||
"Rev": "712a17394a0980fabbcf3d968972e185d80c0fa4"
|
||||
},
|
||||
{
|
||||
"ImportPath": "k8s.io/heapster/metrics/api/v1/types",
|
||||
|
329
vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy.go
generated
vendored
329
vendor/k8s.io/gengo/examples/deepcopy-gen/generators/deepcopy.go
generated
vendored
@ -20,6 +20,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/gengo/args"
|
||||
@ -38,7 +39,11 @@ type CustomArgs struct {
|
||||
}
|
||||
|
||||
// This is the comment tag that carries parameters for deep-copy generation.
|
||||
const tagName = "k8s:deepcopy-gen"
|
||||
const (
|
||||
tagName = "k8s:deepcopy-gen"
|
||||
interfacesTagName = tagName + ":interfaces"
|
||||
interfacesNonPointerTagName = tagName + ":nonpointer-interfaces" // attach the DeepCopy<Interface> methods to the
|
||||
)
|
||||
|
||||
// Known values for the comment tag.
|
||||
const tagValuePackage = "package"
|
||||
@ -217,11 +222,6 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
|
||||
return packages
|
||||
}
|
||||
|
||||
const (
|
||||
conversionPackagePath = "k8s.io/apimachinery/pkg/conversion"
|
||||
runtimePackagePath = "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// genDeepCopy produces a file with autogenerated deep-copy functions.
|
||||
type genDeepCopy struct {
|
||||
generator.DefaultGen
|
||||
@ -251,11 +251,6 @@ func (g *genDeepCopy) Namers(c *generator.Context) namer.NameSystems {
|
||||
// Have the raw namer for this file track what it imports.
|
||||
return namer.NameSystems{
|
||||
"raw": namer.NewRawNamer(g.targetPackage, g.imports),
|
||||
"dcFnName": &dcFnNamer{
|
||||
public: deepCopyNamer(),
|
||||
tracker: g.imports,
|
||||
myPackage: g.targetPackage,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,7 +292,7 @@ func (g *genDeepCopy) copyableAndInBounds(t *types.Type) bool {
|
||||
// for a type T is:
|
||||
// func (t T) DeepCopy() T
|
||||
// or:
|
||||
// func (t *T) DeepCopyt() T
|
||||
// func (t *T) DeepCopy() T
|
||||
func hasDeepCopyMethod(t *types.Type) bool {
|
||||
for mn, mt := range t.Methods {
|
||||
if mn != "DeepCopy" {
|
||||
@ -363,47 +358,47 @@ func (g *genDeepCopy) Imports(c *generator.Context) (imports []string) {
|
||||
return importLines
|
||||
}
|
||||
|
||||
func argsFromType(t *types.Type) generator.Args {
|
||||
return generator.Args{
|
||||
"type": t,
|
||||
func argsFromType(ts ...*types.Type) generator.Args {
|
||||
a := generator.Args{
|
||||
"type": ts[0],
|
||||
}
|
||||
}
|
||||
|
||||
type dcFnNamer struct {
|
||||
public namer.Namer
|
||||
tracker namer.ImportTracker
|
||||
myPackage string
|
||||
}
|
||||
|
||||
func (n *dcFnNamer) Name(t *types.Type) string {
|
||||
pubName := n.public.Name(t)
|
||||
n.tracker.AddType(t)
|
||||
if t.Name.Package == n.myPackage {
|
||||
return "DeepCopy_" + pubName
|
||||
for i, t := range ts {
|
||||
a[fmt.Sprintf("type%d", i+1)] = t
|
||||
}
|
||||
return fmt.Sprintf("%s.DeepCopy_%s", n.tracker.LocalNameOf(t.Name.Package), pubName)
|
||||
return a
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) Init(c *generator.Context, w io.Writer) error {
|
||||
glog.V(5).Infof("Registering types in pkg %q", g.targetPackage)
|
||||
|
||||
// the legacy restration will go away when the cloner is removed from Kubernetes, replaced
|
||||
// with static function calls to the DeepCopy methods.
|
||||
return g.legacyRegistration(c, w)
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) legacyRegistration(c *generator.Context, w io.Writer) error {
|
||||
conversionPackagePath := "k8s.io/apimachinery/pkg/conversion"
|
||||
runtimePackagePath := "k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
cloner := c.Universe.Type(types.Name{Package: conversionPackagePath, Name: "Cloner"})
|
||||
g.imports.AddType(cloner)
|
||||
if !g.registerTypes {
|
||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||
sw.Do("// GetGeneratedDeepCopyFuncs returns the generated funcs, since we aren't registering them.\n", nil)
|
||||
sw.Do("// Deprecated: GetGeneratedDeepCopyFuncs returns the generated funcs, since we aren't registering them.\n", nil)
|
||||
sw.Do("func GetGeneratedDeepCopyFuncs() []conversion.GeneratedDeepCopyFunc{\n", nil)
|
||||
sw.Do("return []conversion.GeneratedDeepCopyFunc{\n", nil)
|
||||
for _, t := range g.typesForInit {
|
||||
args := argsFromType(t).
|
||||
With("typeof", c.Universe.Package("reflect").Function("TypeOf"))
|
||||
sw.Do("{Fn: $.type|dcFnName$, InType: $.typeof|raw$(&$.type|raw${})},\n", args)
|
||||
sw.Do("{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {in.(*$.type|raw$).DeepCopyInto(out.(*$.type|raw$)); return nil}, InType: $.typeof|raw$(&$.type|raw${})},\n", args)
|
||||
}
|
||||
sw.Do("}\n", nil)
|
||||
sw.Do("}\n\n", nil)
|
||||
return sw.Error()
|
||||
}
|
||||
glog.V(5).Infof("Registering types in pkg %q", g.targetPackage)
|
||||
|
||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||
sw.Do("// Deprecated: register deep-copy functions.\n", nil)
|
||||
sw.Do("func init() {\n", nil)
|
||||
sw.Do("SchemeBuilder.Register(RegisterDeepCopies)\n", nil)
|
||||
sw.Do("}\n\n", nil)
|
||||
@ -413,14 +408,14 @@ func (g *genDeepCopy) Init(c *generator.Context, w io.Writer) error {
|
||||
Kind: types.Pointer,
|
||||
Elem: scheme,
|
||||
}
|
||||
sw.Do("// RegisterDeepCopies adds deep-copy functions to the given scheme. Public\n", nil)
|
||||
sw.Do("// Deprecated: RegisterDeepCopies adds deep-copy functions to the given scheme. Public\n", nil)
|
||||
sw.Do("// to allow building arbitrary schemes.\n", nil)
|
||||
sw.Do("func RegisterDeepCopies(scheme $.|raw$) error {\n", schemePtr)
|
||||
sw.Do("return scheme.AddGeneratedDeepCopyFuncs(\n", nil)
|
||||
for _, t := range g.typesForInit {
|
||||
args := argsFromType(t).
|
||||
With("typeof", c.Universe.Package("reflect").Function("TypeOf"))
|
||||
sw.Do("conversion.GeneratedDeepCopyFunc{Fn: $.type|dcFnName$, InType: $.typeof|raw$(&$.type|raw${})},\n", args)
|
||||
sw.Do("conversion.GeneratedDeepCopyFunc{Fn: func(in interface{}, out interface{}, c *conversion.Cloner) error {in.(*$.type|raw$).DeepCopyInto(out.(*$.type|raw$)); return nil}, InType: $.typeof|raw$(&$.type|raw${})},\n", args)
|
||||
}
|
||||
sw.Do(")\n", nil)
|
||||
sw.Do("}\n\n", nil)
|
||||
@ -449,6 +444,97 @@ func (g *genDeepCopy) needsGeneration(t *types.Type) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func extractInterfacesTag(comments []string) []string {
|
||||
var result []string
|
||||
values := types.ExtractCommentTags("+", comments)[interfacesTagName]
|
||||
for _, v := range values {
|
||||
if len(v) == 0 {
|
||||
continue
|
||||
}
|
||||
intfs := strings.Split(v, ",")
|
||||
for _, intf := range intfs {
|
||||
if intf == "" {
|
||||
continue
|
||||
}
|
||||
result = append(result, intf)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func extractNonPointerInterfaces(comments []string) (bool, error) {
|
||||
values := types.ExtractCommentTags("+", comments)[interfacesNonPointerTagName]
|
||||
if len(values) == 0 {
|
||||
return false, nil
|
||||
}
|
||||
result := values[0] == "true"
|
||||
for _, v := range values {
|
||||
if v == "true" != result {
|
||||
return false, fmt.Errorf("contradicting %v value %q found to previous value %v", interfacesNonPointerTagName, v, result)
|
||||
}
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) deepCopyableInterfaces(c *generator.Context, t *types.Type) ([]*types.Type, error) {
|
||||
if t.Kind != types.Struct {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
intfs := extractInterfacesTag(append(t.SecondClosestCommentLines, t.CommentLines...))
|
||||
|
||||
var ts []*types.Type
|
||||
for _, intf := range intfs {
|
||||
t := types.ParseFullyQualifiedName(intf)
|
||||
c.AddDir(t.Package)
|
||||
intfT := c.Universe.Type(t)
|
||||
if intfT == nil {
|
||||
return nil, fmt.Errorf("unknown type %q in %s tag of type %s", intf, interfacesTagName, intfT)
|
||||
}
|
||||
if intfT.Kind != types.Interface {
|
||||
return nil, fmt.Errorf("type %q in %s tag of type %s is not an interface, but: %q", intf, interfacesTagName, t, intfT.Kind)
|
||||
}
|
||||
g.imports.AddType(intfT)
|
||||
ts = append(ts, intfT)
|
||||
}
|
||||
|
||||
return ts, nil
|
||||
}
|
||||
|
||||
// DeepCopyableInterfaces returns the interface types to implement and whether they apply to a non-pointer receiver.
|
||||
func (g *genDeepCopy) DeepCopyableInterfaces(c *generator.Context, t *types.Type) ([]*types.Type, bool, error) {
|
||||
ts, err := g.deepCopyableInterfaces(c, t)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
set := map[string]*types.Type{}
|
||||
for _, t := range ts {
|
||||
set[t.String()] = t
|
||||
}
|
||||
|
||||
result := []*types.Type{}
|
||||
for _, t := range set {
|
||||
result = append(result, t)
|
||||
}
|
||||
|
||||
TypeSlice(result).Sort() // we need a stable sorting because it determines the order in generation
|
||||
|
||||
nonPointerReceiver, err := extractNonPointerInterfaces(append(t.SecondClosestCommentLines, t.CommentLines...))
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
return result, nonPointerReceiver, nil
|
||||
}
|
||||
|
||||
type TypeSlice []*types.Type
|
||||
|
||||
func (s TypeSlice) Len() int { return len(s) }
|
||||
func (s TypeSlice) Less(i, j int) bool { return s[i].String() < s[j].String() }
|
||||
func (s TypeSlice) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
|
||||
func (s TypeSlice) Sort() { sort.Sort(s) }
|
||||
|
||||
func (g *genDeepCopy) GenerateType(c *generator.Context, t *types.Type, w io.Writer) error {
|
||||
if !g.needsGeneration(t) {
|
||||
return nil
|
||||
@ -456,14 +542,58 @@ func (g *genDeepCopy) GenerateType(c *generator.Context, t *types.Type, w io.Wri
|
||||
glog.V(5).Infof("Generating deepcopy function for type %v", t)
|
||||
|
||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||
args := argsFromType(t).
|
||||
With("clonerType", types.Ref(conversionPackagePath, "Cloner"))
|
||||
sw.Do("// $.type|dcFnName$ is an autogenerated deepcopy function.\n", args)
|
||||
sw.Do("func $.type|dcFnName$(in interface{}, out interface{}, c *$.clonerType|raw$) error {{\n", args)
|
||||
sw.Do("in := in.(*$.type|raw$)\nout := out.(*$.type|raw$)\n", argsFromType(t))
|
||||
g.generateFor(t, sw)
|
||||
sw.Do("return nil\n", nil)
|
||||
sw.Do("}}\n\n", nil)
|
||||
args := argsFromType(t)
|
||||
|
||||
_, foundDeepCopyInto := t.Methods["DeepCopyInto"]
|
||||
_, foundDeepCopy := t.Methods["DeepCopy"]
|
||||
if !foundDeepCopyInto {
|
||||
sw.Do("// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\n", args)
|
||||
sw.Do("func (in *$.type|raw$) DeepCopyInto(out *$.type|raw$) {\n", args)
|
||||
if foundDeepCopy {
|
||||
if t.Methods["DeepCopy"].Signature.Receiver.Kind == types.Pointer {
|
||||
sw.Do("clone := in.DeepCopy()\n", nil)
|
||||
sw.Do("*out = *clone\n", nil)
|
||||
} else {
|
||||
sw.Do("*out = in.DeepCopy()\n", nil)
|
||||
}
|
||||
sw.Do("return\n", nil)
|
||||
} else {
|
||||
g.generateFor(t, sw)
|
||||
sw.Do("return\n", nil)
|
||||
}
|
||||
sw.Do("}\n\n", nil)
|
||||
}
|
||||
|
||||
if !foundDeepCopy {
|
||||
sw.Do("// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, creating a new $.type|raw$.\n", args)
|
||||
sw.Do("func (x *$.type|raw$) DeepCopy() *$.type|raw$ {\n", args)
|
||||
sw.Do("if x == nil { return nil }\n", nil)
|
||||
sw.Do("out := new($.type|raw$)\n", args)
|
||||
sw.Do("x.DeepCopyInto(out)\n", nil)
|
||||
sw.Do("return out\n", nil)
|
||||
sw.Do("}\n\n", nil)
|
||||
}
|
||||
|
||||
intfs, nonPointerReceiver, err := g.DeepCopyableInterfaces(c, t)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, intf := range intfs {
|
||||
sw.Do(fmt.Sprintf("// DeepCopy%s is an autogenerated deepcopy function, copying the receiver, creating a new $.type2|raw$.\n", intf.Name.Name), argsFromType(t, intf))
|
||||
if nonPointerReceiver {
|
||||
sw.Do(fmt.Sprintf("func (x $.type|raw$) DeepCopy%s() $.type2|raw$ {\n", intf.Name.Name), argsFromType(t, intf))
|
||||
sw.Do("return *x.DeepCopy()", nil)
|
||||
sw.Do("}\n\n", nil)
|
||||
} else {
|
||||
sw.Do(fmt.Sprintf("func (x *$.type|raw$) DeepCopy%s() $.type2|raw$ {\n", intf.Name.Name), argsFromType(t, intf))
|
||||
sw.Do("if c := x.DeepCopy(); c != nil {\n", nil)
|
||||
sw.Do("return c\n", nil)
|
||||
sw.Do("} else {\n", nil)
|
||||
sw.Do("return nil\n", nil)
|
||||
sw.Do("}}\n\n", nil)
|
||||
}
|
||||
}
|
||||
|
||||
return sw.Error()
|
||||
}
|
||||
|
||||
@ -498,7 +628,7 @@ func (g *genDeepCopy) doBuiltin(t *types.Type, sw *generator.SnippetWriter) {
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) doMap(t *types.Type, sw *generator.SnippetWriter) {
|
||||
sw.Do("*out = make($.|raw$)\n", t)
|
||||
sw.Do("*out = make($.|raw$, len(*in))\n", t)
|
||||
if t.Key.IsAssignable() {
|
||||
switch {
|
||||
case hasDeepCopyMethod(t.Elem):
|
||||
@ -513,20 +643,32 @@ func (g *genDeepCopy) doMap(t *types.Type, sw *generator.SnippetWriter) {
|
||||
sw.Do("for key, val := range *in {\n", nil)
|
||||
sw.Do("(*out)[key] = val\n", nil)
|
||||
sw.Do("}\n", nil)
|
||||
case t.Elem.Kind == types.Interface:
|
||||
sw.Do("for key, val := range *in {\n", nil)
|
||||
sw.Do("if val == nil {(*out)[key]=nil} else {\n", nil)
|
||||
sw.Do(fmt.Sprintf("(*out)[key] = val.DeepCopy%s()\n", t.Elem.Name.Name), t)
|
||||
sw.Do("}}\n", nil)
|
||||
default:
|
||||
sw.Do("for key, val := range *in {\n", nil)
|
||||
if g.copyableAndInBounds(t.Elem) {
|
||||
sw.Do("newVal := new($.|raw$)\n", t.Elem)
|
||||
sw.Do("if err := $.type|dcFnName$(&val, newVal, c); err != nil {\n", argsFromType(t.Elem))
|
||||
sw.Do("return err\n", nil)
|
||||
sw.Do("}\n", nil)
|
||||
sw.Do("val.DeepCopyInto(newVal)\n", nil)
|
||||
sw.Do("(*out)[key] = *newVal\n", nil)
|
||||
} else {
|
||||
sw.Do("if newVal, err := c.DeepCopy(&val); err != nil {\n", nil)
|
||||
sw.Do("return err\n", nil)
|
||||
sw.Do("} else {\n", nil)
|
||||
sw.Do("(*out)[key] = *newVal.(*$.|raw$)\n", t.Elem)
|
||||
} else if t.Elem.Kind == types.Slice && t.Elem.Elem.Kind == types.Builtin {
|
||||
sw.Do("if val==nil { (*out)[key]=nil } else {\n", nil)
|
||||
sw.Do("(*out)[key] = make($.|raw$, len(val))\n", t.Elem)
|
||||
sw.Do("copy((*out)[key], val)\n", nil)
|
||||
sw.Do("}\n", nil)
|
||||
} else if t.Elem.Kind == types.Alias && t.Elem.Underlying.Kind == types.Slice && t.Elem.Underlying.Elem.Kind == types.Builtin {
|
||||
sw.Do("(*out)[key] = make($.|raw$, len(val))\n", t.Elem)
|
||||
sw.Do("copy((*out)[key], val)\n", nil)
|
||||
} else if t.Elem.Kind == types.Pointer {
|
||||
sw.Do("if val==nil { (*out)[key]=nil } else {\n", nil)
|
||||
sw.Do("(*out)[key] = new($.Elem|raw$)\n", t.Elem)
|
||||
sw.Do("val.DeepCopyInto((*out)[key])\n", nil)
|
||||
sw.Do("}\n", nil)
|
||||
} else {
|
||||
sw.Do("(*out)[key] = *val.DeepCopy()\n", t.Elem)
|
||||
}
|
||||
sw.Do("}\n", nil)
|
||||
}
|
||||
@ -558,16 +700,24 @@ func (g *genDeepCopy) doSlice(t *types.Type, sw *generator.SnippetWriter) {
|
||||
sw.Do("in, out := &(*in)[i], &(*out)[i]\n", nil)
|
||||
g.generateFor(t.Elem, sw)
|
||||
sw.Do("}\n", nil)
|
||||
} else if g.copyableAndInBounds(t.Elem) {
|
||||
sw.Do("if err := $.type|dcFnName$(&(*in)[i], &(*out)[i], c); err != nil {\n", argsFromType(t.Elem))
|
||||
sw.Do("return err\n", nil)
|
||||
} else if hasDeepCopyMethod(t.Elem) {
|
||||
sw.Do("(*out)[i] = (*in)[i].DeepCopy()\n", nil)
|
||||
// REVISIT(sttts): the following is removed in master
|
||||
//} else if t.Elem.IsAssignable() {
|
||||
// sw.Do("(*out)[i] = (*in)[i]\n", nil)
|
||||
} else if t.Elem.Kind == types.Interface {
|
||||
sw.Do("if (*in)[i] == nil {(*out)[i]=nil} else {\n", nil)
|
||||
sw.Do(fmt.Sprintf("(*out)[i] = (*in)[i].DeepCopy%s()\n", t.Elem.Name.Name), t)
|
||||
sw.Do("}\n", nil)
|
||||
} else if t.Elem.Kind == types.Pointer {
|
||||
sw.Do("if (*in)[i]==nil { (*out)[i]=nil } else {\n", nil)
|
||||
sw.Do("(*out)[i] = new($.Elem|raw$)\n", t.Elem)
|
||||
sw.Do("(*in)[i].DeepCopyInto((*out)[i])\n", nil)
|
||||
sw.Do("}\n", nil)
|
||||
} else if t.Elem.Kind == types.Struct {
|
||||
sw.Do("(*in)[i].DeepCopyInto(&(*out)[i])\n", nil)
|
||||
} else {
|
||||
sw.Do("if newVal, err := c.DeepCopy(&(*in)[i]); err != nil {\n", nil)
|
||||
sw.Do("return err\n", nil)
|
||||
sw.Do("} else {\n", nil)
|
||||
sw.Do("(*out)[i] = *newVal.(*$.|raw$)\n", t.Elem)
|
||||
sw.Do("}\n", nil)
|
||||
sw.Do("(*out)[i] = (*in)[i].DeepCopy()\n", nil)
|
||||
}
|
||||
sw.Do("}\n", nil)
|
||||
}
|
||||
@ -601,6 +751,7 @@ func (g *genDeepCopy) doStruct(t *types.Type, sw *generator.SnippetWriter) {
|
||||
if hasMethod {
|
||||
sw.Do("out.$.name$ = in.$.name$.DeepCopy()\n", args)
|
||||
}
|
||||
// the initial *out = *in was enough
|
||||
case types.Map, types.Slice, types.Pointer:
|
||||
if hasMethod {
|
||||
sw.Do("if in.$.name$ != nil {\n", args)
|
||||
@ -617,39 +768,16 @@ func (g *genDeepCopy) doStruct(t *types.Type, sw *generator.SnippetWriter) {
|
||||
if hasMethod {
|
||||
sw.Do("out.$.name$ = in.$.name$.DeepCopy()\n", args)
|
||||
} else if t.IsAssignable() {
|
||||
// Nothing else needed.
|
||||
} else if g.copyableAndInBounds(t) {
|
||||
// Not assignable but should have a deepcopy function.
|
||||
// TODO: do a topological sort of packages and ensure that this works, else inline it.
|
||||
sw.Do("if err := $.type|dcFnName$(&in.$.name$, &out.$.name$, c); err != nil {\n", args)
|
||||
sw.Do("return err\n", nil)
|
||||
sw.Do("}\n", nil)
|
||||
sw.Do("out.$.name$ = in.$.name$\n", args)
|
||||
} else {
|
||||
// Fall back on the slow-path and hope it works.
|
||||
// TODO: don't depend on kubernetes code for this
|
||||
sw.Do("if newVal, err := c.DeepCopy(&in.$.name$); err != nil {\n", args)
|
||||
sw.Do("return err\n", nil)
|
||||
sw.Do("} else {\n", nil)
|
||||
sw.Do("out.$.name$ = *newVal.(*$.type|raw$)\n", args)
|
||||
sw.Do("}\n", nil)
|
||||
sw.Do("in.$.name$.DeepCopyInto(&out.$.name$)\n", args)
|
||||
}
|
||||
case types.Interface:
|
||||
sw.Do("if in.$.name$ == nil {out.$.name$=nil} else {\n", args)
|
||||
sw.Do(fmt.Sprintf("out.$.name$ = in.$.name$.DeepCopy%s()\n", t.Name.Name), args)
|
||||
sw.Do("}\n", nil)
|
||||
default:
|
||||
// Interfaces, Arrays, and other Kinds we don't understand.
|
||||
sw.Do("// in.$.name$ is kind '$.kind$'\n", args)
|
||||
if hasMethod {
|
||||
sw.Do("if in.$.name$ != nil {\n", args)
|
||||
sw.Do("out.$.name$ = in.$.name$.DeepCopy()\n", args)
|
||||
sw.Do("}\n", args)
|
||||
} else {
|
||||
// TODO: don't depend on kubernetes code for this
|
||||
sw.Do("if in.$.name$ != nil {\n", args)
|
||||
sw.Do("if newVal, err := c.DeepCopy(&in.$.name$); err != nil {\n", args)
|
||||
sw.Do("return err\n", nil)
|
||||
sw.Do("} else {\n", nil)
|
||||
sw.Do("out.$.name$ = *newVal.(*$.type|raw$)\n", args)
|
||||
sw.Do("}\n", nil)
|
||||
sw.Do("}\n", nil)
|
||||
}
|
||||
sw.Do("out.$.name$ = in.$.name$.DeepCopy()\n", args)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -660,24 +788,27 @@ func (g *genDeepCopy) doInterface(t *types.Type, sw *generator.SnippetWriter) {
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) doPointer(t *types.Type, sw *generator.SnippetWriter) {
|
||||
sw.Do("if *in == nil { *out = nil } else {\n", t)
|
||||
if hasDeepCopyMethod(t.Elem) {
|
||||
sw.Do("*out = new($.Elem|raw$)\n", t)
|
||||
sw.Do("**out = (*in).DeepCopy()\n", nil)
|
||||
} else if t.Elem.IsAssignable() {
|
||||
sw.Do("*out = new($.Elem|raw$)\n", t)
|
||||
sw.Do("**out = **in", nil)
|
||||
} else if g.copyableAndInBounds(t.Elem) {
|
||||
sw.Do("*out = new($.Elem|raw$)\n", t)
|
||||
sw.Do("if err := $.type|dcFnName$(*in, *out, c); err != nil {\n", argsFromType(t.Elem))
|
||||
sw.Do("return err\n", nil)
|
||||
sw.Do("}\n", nil)
|
||||
} else {
|
||||
sw.Do("if newVal, err := c.DeepCopy(*in); err != nil {\n", nil)
|
||||
sw.Do("return err\n", nil)
|
||||
sw.Do("} else {\n", nil)
|
||||
sw.Do("*out = newVal.(*$.|raw$)\n", t.Elem)
|
||||
sw.Do("}\n", nil)
|
||||
switch t.Elem.Kind {
|
||||
case types.Map, types.Slice:
|
||||
sw.Do("*out = new($.Elem|raw$)\n", t)
|
||||
sw.Do("if **in != nil {\n", t)
|
||||
sw.Do("in, out := *in, *out\n", nil)
|
||||
g.generateFor(t.Elem, sw)
|
||||
sw.Do("}\n", nil)
|
||||
default:
|
||||
sw.Do("*out = new($.Elem|raw$)\n", t)
|
||||
sw.Do("(*in).DeepCopyInto(*out)\n", nil)
|
||||
}
|
||||
}
|
||||
sw.Do("}", t)
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) doAlias(t *types.Type, sw *generator.SnippetWriter) {
|
||||
|
51
vendor/k8s.io/gengo/examples/defaulter-gen/generators/defaulter.go
generated
vendored
51
vendor/k8s.io/gengo/examples/defaulter-gen/generators/defaulter.go
generated
vendored
@ -320,7 +320,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
|
||||
if d.object != nil {
|
||||
continue
|
||||
}
|
||||
if buildCallTreeForType(t, true, existingDefaulters, newDefaulters) != nil {
|
||||
if newCallTreeForType(existingDefaulters, newDefaulters).build(t, true) != nil {
|
||||
args := defaultingArgsFromType(t)
|
||||
sw.Do("$.inType|objectdefaultfn$", args)
|
||||
newDefaulters[t] = defaults{
|
||||
@ -387,7 +387,22 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
|
||||
return packages
|
||||
}
|
||||
|
||||
// buildCallTreeForType creates a tree of paths to fields (based on how they would be accessed in Go - pointer, elem,
|
||||
// callTreeForType contains fields necessary to build a tree for types.
|
||||
type callTreeForType struct {
|
||||
existingDefaulters defaulterFuncMap
|
||||
newDefaulters defaulterFuncMap
|
||||
currentlyBuildingTypes map[*types.Type]bool
|
||||
}
|
||||
|
||||
func newCallTreeForType(existingDefaulters, newDefaulters defaulterFuncMap) *callTreeForType {
|
||||
return &callTreeForType{
|
||||
existingDefaulters: existingDefaulters,
|
||||
newDefaulters: newDefaulters,
|
||||
currentlyBuildingTypes: make(map[*types.Type]bool),
|
||||
}
|
||||
}
|
||||
|
||||
// build creates a tree of paths to fields (based on how they would be accessed in Go - pointer, elem,
|
||||
// slice, or key) and the functions that should be invoked on each field. An in-order traversal of the resulting tree
|
||||
// can be used to generate a Go function that invokes each nested function on the appropriate type. The return
|
||||
// value may be nil if there are no functions to call on type or the type is a primitive (Defaulters can only be
|
||||
@ -396,7 +411,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
|
||||
// that could be or will be generated. If newDefaulters has an entry for a type, but the 'object' field is nil,
|
||||
// this function skips adding that defaulter - this allows us to avoid generating object defaulter functions for
|
||||
// list types that call empty defaulters.
|
||||
func buildCallTreeForType(t *types.Type, root bool, existingDefaulters, newDefaulters defaulterFuncMap) *callNode {
|
||||
func (c *callTreeForType) build(t *types.Type, root bool) *callNode {
|
||||
parent := &callNode{}
|
||||
|
||||
if root {
|
||||
@ -404,8 +419,8 @@ func buildCallTreeForType(t *types.Type, root bool, existingDefaulters, newDefau
|
||||
parent.elem = true
|
||||
}
|
||||
|
||||
defaults, _ := existingDefaulters[t]
|
||||
newDefaults, generated := newDefaulters[t]
|
||||
defaults, _ := c.existingDefaulters[t]
|
||||
newDefaults, generated := c.newDefaulters[t]
|
||||
switch {
|
||||
case !root && generated && newDefaults.object != nil:
|
||||
parent.call = append(parent.call, newDefaults.object)
|
||||
@ -432,19 +447,33 @@ func buildCallTreeForType(t *types.Type, root bool, existingDefaulters, newDefau
|
||||
// base has been added already, now add any additional defaulters defined for this object
|
||||
parent.call = append(parent.call, defaults.additional...)
|
||||
|
||||
// if the type already exists, don't build the tree for it and don't generate anything.
|
||||
// This is used to avoid recursion for nested recursive types.
|
||||
if c.currentlyBuildingTypes[t] {
|
||||
return nil
|
||||
}
|
||||
// if type doesn't exist, mark it as existing
|
||||
c.currentlyBuildingTypes[t] = true
|
||||
|
||||
defer func() {
|
||||
// The type will now acts as a parent, not a nested recursive type.
|
||||
// We can now build the tree for it safely.
|
||||
c.currentlyBuildingTypes[t] = false
|
||||
}()
|
||||
|
||||
switch t.Kind {
|
||||
case types.Pointer:
|
||||
if child := buildCallTreeForType(t.Elem, false, existingDefaulters, newDefaulters); child != nil {
|
||||
if child := c.build(t.Elem, false); child != nil {
|
||||
child.elem = true
|
||||
parent.children = append(parent.children, *child)
|
||||
}
|
||||
case types.Slice, types.Array:
|
||||
if child := buildCallTreeForType(t.Elem, false, existingDefaulters, newDefaulters); child != nil {
|
||||
if child := c.build(t.Elem, false); child != nil {
|
||||
child.index = true
|
||||
parent.children = append(parent.children, *child)
|
||||
}
|
||||
case types.Map:
|
||||
if child := buildCallTreeForType(t.Elem, false, existingDefaulters, newDefaulters); child != nil {
|
||||
if child := c.build(t.Elem, false); child != nil {
|
||||
child.key = true
|
||||
parent.children = append(parent.children, *child)
|
||||
}
|
||||
@ -458,13 +487,13 @@ func buildCallTreeForType(t *types.Type, root bool, existingDefaulters, newDefau
|
||||
name = field.Type.Name.Name
|
||||
}
|
||||
}
|
||||
if child := buildCallTreeForType(field.Type, false, existingDefaulters, newDefaulters); child != nil {
|
||||
if child := c.build(field.Type, false); child != nil {
|
||||
child.field = name
|
||||
parent.children = append(parent.children, *child)
|
||||
}
|
||||
}
|
||||
case types.Alias:
|
||||
if child := buildCallTreeForType(t.Underlying, false, existingDefaulters, newDefaulters); child != nil {
|
||||
if child := c.build(t.Underlying, false); child != nil {
|
||||
parent.children = append(parent.children, *child)
|
||||
}
|
||||
}
|
||||
@ -571,7 +600,7 @@ func (g *genDefaulter) GenerateType(c *generator.Context, t *types.Type, w io.Wr
|
||||
|
||||
glog.V(5).Infof("generating for type %v", t)
|
||||
|
||||
callTree := buildCallTreeForType(t, true, g.existingDefaulters, g.newDefaulters)
|
||||
callTree := newCallTreeForType(g.existingDefaulters, g.newDefaulters).build(t, true)
|
||||
if callTree == nil {
|
||||
glog.V(5).Infof(" no defaulters defined")
|
||||
return nil
|
||||
|
15
vendor/k8s.io/gengo/types/types.go
generated
vendored
15
vendor/k8s.io/gengo/types/types.go
generated
vendored
@ -16,6 +16,8 @@ limitations under the License.
|
||||
|
||||
package types
|
||||
|
||||
import "strings"
|
||||
|
||||
// Ref makes a reference to the given type. It can only be used for e.g.
|
||||
// passing to namers.
|
||||
func Ref(packageName, typeName string) *Type {
|
||||
@ -44,6 +46,19 @@ func (n Name) String() string {
|
||||
return n.Package + "." + n.Name
|
||||
}
|
||||
|
||||
// ParseFullyQualifiedName parses a name like k8s.io/kubernetes/pkg/api.Pod into a Name.
|
||||
func ParseFullyQualifiedName(fqn string) Name {
|
||||
cs := strings.Split(fqn, ".")
|
||||
pkg := ""
|
||||
if len(cs) > 1 {
|
||||
pkg = strings.Join(cs[0:len(cs) - 1], ".")
|
||||
}
|
||||
return Name{
|
||||
Name: cs[len(cs) - 1],
|
||||
Package: pkg,
|
||||
}
|
||||
}
|
||||
|
||||
// The possible classes of types.
|
||||
type Kind string
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user