mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-10 20:42:26 +00:00
Switch to typeless generated deepcopy functions for less reflection
This commit is contained in:
parent
6049623a13
commit
61cde63622
@ -204,6 +204,7 @@ func Packages(context *generator.Context, arguments *args.GeneratorArgs) generat
|
||||
const (
|
||||
apiPackagePath = "k8s.io/kubernetes/pkg/api"
|
||||
conversionPackagePath = "k8s.io/kubernetes/pkg/conversion"
|
||||
runtimePackagePath = "k8s.io/kubernetes/pkg/runtime"
|
||||
)
|
||||
|
||||
// genDeepCopy produces a file with autogenerated deep-copy functions.
|
||||
@ -384,8 +385,10 @@ func (g *genDeepCopy) Init(c *generator.Context, w io.Writer) error {
|
||||
sw.Do("if err := $.scheme|raw$.AddGeneratedDeepCopyFuncs(\n", map[string]interface{}{
|
||||
"scheme": scheme,
|
||||
})
|
||||
reflect := c.Universe.Type(types.Name{Package: "reflect", Name: "TypeOf"})
|
||||
for _, t := range g.typesForInit {
|
||||
sw.Do(fmt.Sprintf("%s,\n", g.funcNameTmpl(t)), argsFromType(t))
|
||||
g.imports.AddType(reflect)
|
||||
sw.Do(fmt.Sprintf("conversion.GeneratedDeepCopyFunc{Fn: %s, InType: reflect.TypeOf(func() *$.type|raw$ {var x *$.type|raw$; return x}())},\n", g.funcNameTmpl(t)), argsFromType(t))
|
||||
}
|
||||
sw.Do("); err != nil {\n", nil)
|
||||
sw.Do("// if one of the deep copy functions is malformed, detect it immediately.\n", nil)
|
||||
@ -425,10 +428,11 @@ func (g *genDeepCopy) GenerateType(c *generator.Context, t *types.Type, w io.Wri
|
||||
|
||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||
funcName := g.funcNameTmpl(t)
|
||||
sw.Do(fmt.Sprintf("func %s(in *$.type|raw$, out *$.type|raw$, c *$.Cloner|raw$) error {\n", funcName), g.withGlobals(argsFromType(t)))
|
||||
sw.Do(fmt.Sprintf("func %s(in interface{}, out interface{}, c *$.Cloner|raw$) error {{\n", funcName), g.withGlobals(argsFromType(t)))
|
||||
sw.Do("in := in.(*$.type|raw$)\nout := out.(*$.type|raw$)\n", g.withGlobals(argsFromType(t)))
|
||||
g.generateFor(t, sw)
|
||||
sw.Do("return nil\n", nil)
|
||||
sw.Do("}\n\n", nil)
|
||||
sw.Do("}}\n\n", nil)
|
||||
return sw.Error()
|
||||
}
|
||||
|
||||
@ -531,6 +535,10 @@ func (g *genDeepCopy) doSlice(t *types.Type, sw *generator.SnippetWriter) {
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) doStruct(t *types.Type, sw *generator.SnippetWriter) {
|
||||
if len(t.Members) == 0 {
|
||||
// at least do something with in/out to avoid "declared and not used" errors
|
||||
sw.Do("_ = in\n_ = out\n", nil)
|
||||
}
|
||||
for _, m := range t.Members {
|
||||
t := m.Type
|
||||
if t.Kind == types.Alias {
|
||||
|
@ -25,14 +25,14 @@ import (
|
||||
type Cloner struct {
|
||||
// Map from the type to a function which can do the deep copy.
|
||||
deepCopyFuncs map[reflect.Type]reflect.Value
|
||||
generatedDeepCopyFuncs map[reflect.Type]reflect.Value
|
||||
generatedDeepCopyFuncs map[reflect.Type]func(in interface{}, out interface{}, c *Cloner) error
|
||||
}
|
||||
|
||||
// NewCloner creates a new Cloner object.
|
||||
func NewCloner() *Cloner {
|
||||
c := &Cloner{
|
||||
deepCopyFuncs: map[reflect.Type]reflect.Value{},
|
||||
generatedDeepCopyFuncs: map[reflect.Type]reflect.Value{},
|
||||
generatedDeepCopyFuncs: map[reflect.Type]func(in interface{}, out interface{}, c *Cloner) error{},
|
||||
}
|
||||
if err := c.RegisterDeepCopyFunc(byteSliceDeepCopy); err != nil {
|
||||
// If one of the deep-copy functions is malformed, detect it immediately.
|
||||
@ -103,15 +103,17 @@ func (c *Cloner) RegisterDeepCopyFunc(deepCopyFunc interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GeneratedDeepCopyFunc bundles an untyped generated deep-copy function of a type
|
||||
// with a reflection type object used as a key to lookup the deep-copy function.
|
||||
type GeneratedDeepCopyFunc struct {
|
||||
Fn func(in interface{}, out interface{}, c *Cloner) error
|
||||
InType reflect.Type
|
||||
}
|
||||
|
||||
// Similar to RegisterDeepCopyFunc, but registers deep copy function that were
|
||||
// automatically generated.
|
||||
func (c *Cloner) RegisterGeneratedDeepCopyFunc(deepCopyFunc interface{}) error {
|
||||
fv := reflect.ValueOf(deepCopyFunc)
|
||||
ft := fv.Type()
|
||||
if err := verifyDeepCopyFunctionSignature(ft); err != nil {
|
||||
return err
|
||||
}
|
||||
c.generatedDeepCopyFuncs[ft.In(0)] = fv
|
||||
func (c *Cloner) RegisterGeneratedDeepCopyFunc(fn GeneratedDeepCopyFunc) error {
|
||||
c.generatedDeepCopyFuncs[fn.InType] = fn.Fn
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -146,7 +148,10 @@ func (c *Cloner) deepCopy(src reflect.Value) (reflect.Value, error) {
|
||||
return c.customDeepCopy(src, fv)
|
||||
}
|
||||
if fv, ok := c.generatedDeepCopyFuncs[inType]; ok {
|
||||
return c.customDeepCopy(src, fv)
|
||||
var outValue reflect.Value
|
||||
outValue = reflect.New(inType.Elem())
|
||||
err := fv(src.Interface(), outValue.Interface(), c)
|
||||
return outValue, err
|
||||
}
|
||||
return c.defaultDeepCopy(src)
|
||||
}
|
||||
|
@ -357,9 +357,9 @@ func (s *Scheme) AddDeepCopyFuncs(deepCopyFuncs ...interface{}) error {
|
||||
|
||||
// Similar to AddDeepCopyFuncs, but registers deep-copy functions that were
|
||||
// automatically generated.
|
||||
func (s *Scheme) AddGeneratedDeepCopyFuncs(deepCopyFuncs ...interface{}) error {
|
||||
for _, f := range deepCopyFuncs {
|
||||
if err := s.cloner.RegisterGeneratedDeepCopyFunc(f); err != nil {
|
||||
func (s *Scheme) AddGeneratedDeepCopyFuncs(deepCopyFuncs ...conversion.GeneratedDeepCopyFunc) error {
|
||||
for _, fn := range deepCopyFuncs {
|
||||
if err := s.cloner.RegisterGeneratedDeepCopyFunc(fn); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user