mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-10 12:32:03 +00:00
Move gengo/examples/deepcopy -> code_generator
Merge comments in main.go and fix a bunch of pre-existing lint errors.
This commit is contained in:
parent
01a1865934
commit
cb7f0593ae
@ -23,10 +23,10 @@ package tools
|
||||
import (
|
||||
// build script dependencies
|
||||
_ "github.com/onsi/ginkgo/v2/ginkgo"
|
||||
_ "k8s.io/code-generator/cmd/deepcopy-gen"
|
||||
_ "k8s.io/code-generator/cmd/go-to-protobuf"
|
||||
_ "k8s.io/code-generator/cmd/go-to-protobuf/protoc-gen-gogo"
|
||||
_ "k8s.io/code-generator/cmd/import-boss"
|
||||
_ "k8s.io/gengo/v2/examples/deepcopy-gen/generators"
|
||||
_ "k8s.io/gengo/v2/examples/defaulter-gen/generators"
|
||||
_ "k8s.io/kube-openapi/cmd/openapi-gen"
|
||||
|
||||
|
@ -21,17 +21,20 @@ import (
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
"k8s.io/gengo/v2/args"
|
||||
"k8s.io/gengo/v2/examples/deepcopy-gen/generators"
|
||||
)
|
||||
|
||||
// CustomArgs is used by the gengo framework to pass args specific to this generator.
|
||||
type CustomArgs generators.CustomArgs
|
||||
type CustomArgs struct {
|
||||
OutputFile string
|
||||
BoundingDirs []string // Only deal with types rooted under these dirs.
|
||||
GoHeaderFile string
|
||||
}
|
||||
|
||||
// NewDefaults returns default arguments for the generator.
|
||||
func NewDefaults() (*args.GeneratorArgs, *CustomArgs) {
|
||||
genericArgs := args.Default()
|
||||
customArgs := &CustomArgs{}
|
||||
genericArgs.CustomArgs = (*generators.CustomArgs)(customArgs) // convert to upstream type to make type-casts work there
|
||||
genericArgs.CustomArgs = (*CustomArgs)(customArgs) // convert to upstream type to make type-casts work there
|
||||
return genericArgs, customArgs
|
||||
}
|
||||
|
||||
@ -47,7 +50,7 @@ func (ca *CustomArgs) AddFlags(fs *pflag.FlagSet) {
|
||||
|
||||
// Validate checks the given arguments.
|
||||
func Validate(genericArgs *args.GeneratorArgs) error {
|
||||
custom := genericArgs.CustomArgs.(*generators.CustomArgs)
|
||||
custom := genericArgs.CustomArgs.(*CustomArgs)
|
||||
|
||||
if len(custom.OutputFile) == 0 {
|
||||
return fmt.Errorf("--output-file must be specified")
|
||||
|
@ -0,0 +1,897 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package generators
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
deepcopyargs "k8s.io/code-generator/cmd/deepcopy-gen/args"
|
||||
"k8s.io/gengo/v2/args"
|
||||
"k8s.io/gengo/v2/generator"
|
||||
"k8s.io/gengo/v2/namer"
|
||||
"k8s.io/gengo/v2/types"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
// This is the comment tag that carries parameters for deep-copy generation.
|
||||
const (
|
||||
tagEnabledName = "k8s:deepcopy-gen"
|
||||
interfacesTagName = tagEnabledName + ":interfaces"
|
||||
interfacesNonPointerTagName = tagEnabledName + ":nonpointer-interfaces" // attach the DeepCopy<Interface> methods to the
|
||||
)
|
||||
|
||||
// Known values for the comment tag.
|
||||
const tagValuePackage = "package"
|
||||
|
||||
// enabledTagValue holds parameters from a tagName tag.
|
||||
type enabledTagValue struct {
|
||||
value string
|
||||
register bool
|
||||
}
|
||||
|
||||
func extractEnabledTypeTag(t *types.Type) *enabledTagValue {
|
||||
comments := append(append([]string{}, t.SecondClosestCommentLines...), t.CommentLines...)
|
||||
return extractEnabledTag(comments)
|
||||
}
|
||||
|
||||
func extractEnabledTag(comments []string) *enabledTagValue {
|
||||
tagVals := types.ExtractCommentTags("+", comments)[tagEnabledName]
|
||||
if tagVals == nil {
|
||||
// No match for the tag.
|
||||
return nil
|
||||
}
|
||||
// If there are multiple values, abort.
|
||||
if len(tagVals) > 1 {
|
||||
klog.Fatalf("Found %d %s tags: %q", len(tagVals), tagEnabledName, tagVals)
|
||||
}
|
||||
|
||||
// If we got here we are returning something.
|
||||
tag := &enabledTagValue{}
|
||||
|
||||
// Get the primary value.
|
||||
parts := strings.Split(tagVals[0], ",")
|
||||
if len(parts) >= 1 {
|
||||
tag.value = parts[0]
|
||||
}
|
||||
|
||||
// Parse extra arguments.
|
||||
parts = parts[1:]
|
||||
for i := range parts {
|
||||
kv := strings.SplitN(parts[i], "=", 2)
|
||||
k := kv[0]
|
||||
v := ""
|
||||
if len(kv) == 2 {
|
||||
v = kv[1]
|
||||
}
|
||||
switch k {
|
||||
case "register":
|
||||
if v != "false" {
|
||||
tag.register = true
|
||||
}
|
||||
default:
|
||||
klog.Fatalf("Unsupported %s param: %q", tagEnabledName, parts[i])
|
||||
}
|
||||
}
|
||||
return tag
|
||||
}
|
||||
|
||||
// TODO: This is created only to reduce number of changes in a single PR.
|
||||
// Remove it and use PublicNamer instead.
|
||||
func deepCopyNamer() *namer.NameStrategy {
|
||||
return &namer.NameStrategy{
|
||||
Join: func(pre string, in []string, post string) string {
|
||||
return strings.Join(in, "_")
|
||||
},
|
||||
PrependPackageNames: 1,
|
||||
}
|
||||
}
|
||||
|
||||
// NameSystems returns the name system used by the generators in this package.
|
||||
func NameSystems() namer.NameSystems {
|
||||
return namer.NameSystems{
|
||||
"public": deepCopyNamer(),
|
||||
"raw": namer.NewRawNamer("", nil),
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultNameSystem returns the default name system for ordering the types to be
|
||||
// processed by the generators in this package.
|
||||
func DefaultNameSystem() string {
|
||||
return "public"
|
||||
}
|
||||
|
||||
func GetTargets(context *generator.Context, arguments *args.GeneratorArgs) []generator.Target {
|
||||
customArgs := arguments.CustomArgs.(*deepcopyargs.CustomArgs)
|
||||
|
||||
boilerplate, err := args.GoBoilerplate(customArgs.GoHeaderFile, args.StdBuildTag, args.StdGeneratedBy)
|
||||
if err != nil {
|
||||
klog.Fatalf("Failed loading boilerplate: %v", err)
|
||||
}
|
||||
|
||||
boundingDirs := []string{}
|
||||
if customArgs.BoundingDirs == nil {
|
||||
customArgs.BoundingDirs = context.Inputs
|
||||
}
|
||||
for i := range customArgs.BoundingDirs {
|
||||
// Strip any trailing slashes - they are not exactly "correct" but
|
||||
// this is friendlier.
|
||||
boundingDirs = append(boundingDirs, strings.TrimRight(customArgs.BoundingDirs[i], "/"))
|
||||
}
|
||||
|
||||
targets := []generator.Target{}
|
||||
|
||||
for _, i := range context.Inputs {
|
||||
klog.V(3).Infof("Considering pkg %q", i)
|
||||
pkg := context.Universe[i]
|
||||
if pkg == nil {
|
||||
// If the input had no Go files, for example.
|
||||
continue
|
||||
}
|
||||
|
||||
ptag := extractEnabledTag(pkg.Comments)
|
||||
ptagValue := ""
|
||||
ptagRegister := false
|
||||
if ptag != nil {
|
||||
ptagValue = ptag.value
|
||||
if ptagValue != tagValuePackage {
|
||||
klog.Fatalf("Package %v: unsupported %s value: %q", i, tagEnabledName, ptagValue)
|
||||
}
|
||||
ptagRegister = ptag.register
|
||||
klog.V(3).Infof(" tag.value: %q, tag.register: %t", ptagValue, ptagRegister)
|
||||
} else {
|
||||
klog.V(3).Infof(" no tag")
|
||||
}
|
||||
|
||||
// If the pkg-scoped tag says to generate, we can skip scanning types.
|
||||
pkgNeedsGeneration := (ptagValue == tagValuePackage)
|
||||
if !pkgNeedsGeneration {
|
||||
// If the pkg-scoped tag did not exist, scan all types for one that
|
||||
// explicitly wants generation. Ensure all types that want generation
|
||||
// can be copied.
|
||||
var uncopyable []string
|
||||
for _, t := range pkg.Types {
|
||||
klog.V(3).Infof(" considering type %q", t.Name.String())
|
||||
ttag := extractEnabledTypeTag(t)
|
||||
if ttag != nil && ttag.value == "true" {
|
||||
klog.V(3).Infof(" tag=true")
|
||||
if !copyableType(t) {
|
||||
uncopyable = append(uncopyable, fmt.Sprintf("%v", t))
|
||||
} else {
|
||||
pkgNeedsGeneration = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(uncopyable) > 0 {
|
||||
klog.Fatalf("Types requested deepcopy generation but are not copyable: %s",
|
||||
strings.Join(uncopyable, ", "))
|
||||
}
|
||||
}
|
||||
|
||||
if pkgNeedsGeneration {
|
||||
klog.V(3).Infof("Package %q needs generation", i)
|
||||
targets = append(targets,
|
||||
&generator.SimpleTarget{
|
||||
PkgName: strings.Split(filepath.Base(pkg.Path), ".")[0],
|
||||
PkgPath: pkg.Path,
|
||||
PkgDir: pkg.SourcePath, // output pkg is the same as the input
|
||||
HeaderComment: boilerplate,
|
||||
FilterFunc: func(c *generator.Context, t *types.Type) bool {
|
||||
return t.Name.Package == pkg.Path
|
||||
},
|
||||
GeneratorsFunc: func(c *generator.Context) (generators []generator.Generator) {
|
||||
return []generator.Generator{
|
||||
NewGenDeepCopy(customArgs.OutputFile, pkg.Path, boundingDirs, (ptagValue == tagValuePackage), ptagRegister),
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
return targets
|
||||
}
|
||||
|
||||
// genDeepCopy produces a file with autogenerated deep-copy functions.
|
||||
type genDeepCopy struct {
|
||||
generator.GoGenerator
|
||||
targetPackage string
|
||||
boundingDirs []string
|
||||
allTypes bool
|
||||
registerTypes bool
|
||||
imports namer.ImportTracker
|
||||
typesForInit []*types.Type
|
||||
}
|
||||
|
||||
func NewGenDeepCopy(outputFilename, targetPackage string, boundingDirs []string, allTypes, registerTypes bool) generator.Generator {
|
||||
return &genDeepCopy{
|
||||
GoGenerator: generator.GoGenerator{
|
||||
OutputFilename: outputFilename,
|
||||
},
|
||||
targetPackage: targetPackage,
|
||||
boundingDirs: boundingDirs,
|
||||
allTypes: allTypes,
|
||||
registerTypes: registerTypes,
|
||||
imports: generator.NewImportTracker(),
|
||||
typesForInit: make([]*types.Type, 0),
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) Filter(c *generator.Context, t *types.Type) bool {
|
||||
// Filter out types not being processed or not copyable within the package.
|
||||
enabled := g.allTypes
|
||||
if !enabled {
|
||||
ttag := extractEnabledTypeTag(t)
|
||||
if ttag != nil && ttag.value == "true" {
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
if !enabled {
|
||||
return false
|
||||
}
|
||||
if !copyableType(t) {
|
||||
klog.V(3).Infof("Type %v is not copyable", t)
|
||||
return false
|
||||
}
|
||||
klog.V(3).Infof("Type %v is copyable", t)
|
||||
g.typesForInit = append(g.typesForInit, t)
|
||||
return true
|
||||
}
|
||||
|
||||
// deepCopyMethod returns the signature of a DeepCopy() method, nil or an error
|
||||
// if the type does not match. This allows more efficient deep copy
|
||||
// implementations to be defined by the type's author. The correct signature
|
||||
// for a type T is:
|
||||
//
|
||||
// func (t T) DeepCopy() T
|
||||
//
|
||||
// or:
|
||||
//
|
||||
// func (t *T) DeepCopy() *T
|
||||
func deepCopyMethod(t *types.Type) (*types.Signature, error) {
|
||||
f, found := t.Methods["DeepCopy"]
|
||||
if !found {
|
||||
return nil, nil
|
||||
}
|
||||
if len(f.Signature.Parameters) != 0 {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected no parameters", t)
|
||||
}
|
||||
if len(f.Signature.Results) != 1 {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected exactly one result", t)
|
||||
}
|
||||
|
||||
ptrResult := f.Signature.Results[0].Kind == types.Pointer && f.Signature.Results[0].Elem.Name == t.Name
|
||||
nonPtrResult := f.Signature.Results[0].Name == t.Name
|
||||
|
||||
if !ptrResult && !nonPtrResult {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected to return %s or *%s", t, t.Name.Name, t.Name.Name)
|
||||
}
|
||||
|
||||
ptrRcvr := f.Signature.Receiver != nil && f.Signature.Receiver.Kind == types.Pointer && f.Signature.Receiver.Elem.Name == t.Name
|
||||
nonPtrRcvr := f.Signature.Receiver != nil && f.Signature.Receiver.Name == t.Name
|
||||
|
||||
if ptrRcvr && !ptrResult {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected a *%s result for a *%s receiver", t, t.Name.Name, t.Name.Name)
|
||||
}
|
||||
if nonPtrRcvr && !nonPtrResult {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected a %s result for a %s receiver", t, t.Name.Name, t.Name.Name)
|
||||
}
|
||||
|
||||
return f.Signature, nil
|
||||
}
|
||||
|
||||
// deepCopyMethodOrDie returns the signatrue of a DeepCopy method, nil or calls klog.Fatalf
|
||||
// if the type does not match.
|
||||
func deepCopyMethodOrDie(t *types.Type) *types.Signature {
|
||||
ret, err := deepCopyMethod(t)
|
||||
if err != nil {
|
||||
klog.Fatal(err)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// deepCopyIntoMethod returns the signature of a DeepCopyInto() method, nil or an error
|
||||
// if the type is wrong. DeepCopyInto allows more efficient deep copy
|
||||
// implementations to be defined by the type's author. The correct signature
|
||||
// for a type T is:
|
||||
//
|
||||
// func (t T) DeepCopyInto(t *T)
|
||||
//
|
||||
// or:
|
||||
//
|
||||
// func (t *T) DeepCopyInto(t *T)
|
||||
func deepCopyIntoMethod(t *types.Type) (*types.Signature, error) {
|
||||
f, found := t.Methods["DeepCopyInto"]
|
||||
if !found {
|
||||
return nil, nil
|
||||
}
|
||||
if len(f.Signature.Parameters) != 1 {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected exactly one parameter", t)
|
||||
}
|
||||
if len(f.Signature.Results) != 0 {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected no result type", t)
|
||||
}
|
||||
|
||||
ptrParam := f.Signature.Parameters[0].Kind == types.Pointer && f.Signature.Parameters[0].Elem.Name == t.Name
|
||||
|
||||
if !ptrParam {
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected parameter of type *%s", t, t.Name.Name)
|
||||
}
|
||||
|
||||
ptrRcvr := f.Signature.Receiver != nil && f.Signature.Receiver.Kind == types.Pointer && f.Signature.Receiver.Elem.Name == t.Name
|
||||
nonPtrRcvr := f.Signature.Receiver != nil && f.Signature.Receiver.Name == t.Name
|
||||
|
||||
if !ptrRcvr && !nonPtrRcvr {
|
||||
// this should never happen
|
||||
return nil, fmt.Errorf("type %v: invalid DeepCopy signature, expected a receiver of type %s or *%s", t, t.Name.Name, t.Name.Name)
|
||||
}
|
||||
|
||||
return f.Signature, nil
|
||||
}
|
||||
|
||||
// deepCopyIntoMethodOrDie returns the signature of a DeepCopyInto() method, nil or calls klog.Fatalf
|
||||
// if the type is wrong.
|
||||
func deepCopyIntoMethodOrDie(t *types.Type) *types.Signature {
|
||||
ret, err := deepCopyIntoMethod(t)
|
||||
if err != nil {
|
||||
klog.Fatal(err)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func copyableType(t *types.Type) bool {
|
||||
// If the type opts out of copy-generation, stop.
|
||||
ttag := extractEnabledTypeTag(t)
|
||||
if ttag != nil && ttag.value == "false" {
|
||||
return false
|
||||
}
|
||||
|
||||
// Filter out private types.
|
||||
if namer.IsPrivateGoName(t.Name.Name) {
|
||||
return false
|
||||
}
|
||||
|
||||
if t.Kind == types.Alias {
|
||||
// if the underlying built-in is not deepcopy-able, deepcopy is opt-in through definition of custom methods.
|
||||
// Note that aliases of builtins, maps, slices can have deepcopy methods.
|
||||
if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil {
|
||||
return true
|
||||
} else {
|
||||
return t.Underlying.Kind != types.Builtin || copyableType(t.Underlying)
|
||||
}
|
||||
}
|
||||
|
||||
if t.Kind != types.Struct {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func underlyingType(t *types.Type) *types.Type {
|
||||
for t.Kind == types.Alias {
|
||||
t = t.Underlying
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) isOtherPackage(pkg string) bool {
|
||||
if pkg == g.targetPackage {
|
||||
return false
|
||||
}
|
||||
if strings.HasSuffix(pkg, "\""+g.targetPackage+"\"") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) Imports(c *generator.Context) (imports []string) {
|
||||
importLines := []string{}
|
||||
for _, singleImport := range g.imports.ImportLines() {
|
||||
if g.isOtherPackage(singleImport) {
|
||||
importLines = append(importLines, singleImport)
|
||||
}
|
||||
}
|
||||
return importLines
|
||||
}
|
||||
|
||||
func argsFromType(ts ...*types.Type) generator.Args {
|
||||
a := generator.Args{
|
||||
"type": ts[0],
|
||||
}
|
||||
for i, t := range ts {
|
||||
a[fmt.Sprintf("type%d", i+1)] = t
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) Init(c *generator.Context, w io.Writer) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *genDeepCopy) needsGeneration(t *types.Type) bool {
|
||||
tag := extractEnabledTypeTag(t)
|
||||
tv := ""
|
||||
if tag != nil {
|
||||
tv = tag.value
|
||||
if tv != "true" && tv != "false" {
|
||||
klog.Fatalf("Type %v: unsupported %s value: %q", t, tagEnabledName, tag.value)
|
||||
}
|
||||
}
|
||||
if g.allTypes && tv == "false" {
|
||||
// The whole package is being generated, but this type has opted out.
|
||||
klog.V(2).Infof("Not generating for type %v because type opted out", t)
|
||||
return false
|
||||
}
|
||||
if !g.allTypes && tv != "true" {
|
||||
// The whole package is NOT being generated, and this type has NOT opted in.
|
||||
klog.V(2).Infof("Not generating for type %v because type did not opt in", t)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func extractInterfacesTag(t *types.Type) []string {
|
||||
var result []string
|
||||
comments := append(append([]string{}, t.SecondClosestCommentLines...), t.CommentLines...)
|
||||
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(t *types.Type) (bool, error) {
|
||||
comments := append(append([]string{}, t.SecondClosestCommentLines...), t.CommentLines...)
|
||||
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) deepCopyableInterfacesInner(c *generator.Context, t *types.Type) ([]*types.Type, error) {
|
||||
if t.Kind != types.Struct {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
intfs := extractInterfacesTag(t)
|
||||
|
||||
var ts []*types.Type
|
||||
for _, intf := range intfs {
|
||||
t := types.ParseFullyQualifiedName(intf)
|
||||
klog.V(3).Infof("Loading package for interface %v", intf)
|
||||
_, err := c.LoadPackages(t.Package)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
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.deepCopyableInterfacesInner(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(t)
|
||||
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
|
||||
}
|
||||
klog.V(2).Infof("Generating deepcopy functions for type %v", t)
|
||||
|
||||
sw := generator.NewSnippetWriter(w, c, "$", "$")
|
||||
args := argsFromType(t)
|
||||
|
||||
if deepCopyIntoMethodOrDie(t) == nil {
|
||||
sw.Do("// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.\n", args)
|
||||
if isReference(t) {
|
||||
sw.Do("func (in $.type|raw$) DeepCopyInto(out *$.type|raw$) {\n", args)
|
||||
sw.Do("{in:=&in\n", nil)
|
||||
} else {
|
||||
sw.Do("func (in *$.type|raw$) DeepCopyInto(out *$.type|raw$) {\n", args)
|
||||
}
|
||||
if deepCopyMethodOrDie(t) != nil {
|
||||
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)
|
||||
}
|
||||
if isReference(t) {
|
||||
sw.Do("}\n", nil)
|
||||
}
|
||||
sw.Do("}\n\n", nil)
|
||||
}
|
||||
|
||||
if deepCopyMethodOrDie(t) == nil {
|
||||
sw.Do("// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new $.type|raw$.\n", args)
|
||||
if isReference(t) {
|
||||
sw.Do("func (in $.type|raw$) DeepCopy() $.type|raw$ {\n", args)
|
||||
} else {
|
||||
sw.Do("func (in *$.type|raw$) DeepCopy() *$.type|raw$ {\n", args)
|
||||
}
|
||||
sw.Do("if in == nil { return nil }\n", nil)
|
||||
sw.Do("out := new($.type|raw$)\n", args)
|
||||
sw.Do("in.DeepCopyInto(out)\n", nil)
|
||||
if isReference(t) {
|
||||
sw.Do("return *out\n", nil)
|
||||
} else {
|
||||
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 (in $.type|raw$) DeepCopy%s() $.type2|raw$ {\n", intf.Name.Name), argsFromType(t, intf))
|
||||
sw.Do("return *in.DeepCopy()", nil)
|
||||
sw.Do("}\n\n", nil)
|
||||
} else {
|
||||
sw.Do(fmt.Sprintf("func (in *$.type|raw$) DeepCopy%s() $.type2|raw$ {\n", intf.Name.Name), argsFromType(t, intf))
|
||||
sw.Do("if c := in.DeepCopy(); c != nil {\n", nil)
|
||||
sw.Do("return c\n", nil)
|
||||
sw.Do("}\n", nil)
|
||||
sw.Do("return nil\n", nil)
|
||||
sw.Do("}\n\n", nil)
|
||||
}
|
||||
}
|
||||
|
||||
return sw.Error()
|
||||
}
|
||||
|
||||
// isReference return true for pointer, maps, slices and aliases of those.
|
||||
func isReference(t *types.Type) bool {
|
||||
if t.Kind == types.Pointer || t.Kind == types.Map || t.Kind == types.Slice {
|
||||
return true
|
||||
}
|
||||
return t.Kind == types.Alias && isReference(underlyingType(t))
|
||||
}
|
||||
|
||||
// we use the system of shadowing 'in' and 'out' so that the same code is valid
|
||||
// at any nesting level. This makes the autogenerator easy to understand, and
|
||||
// the compiler shouldn't care.
|
||||
func (g *genDeepCopy) generateFor(t *types.Type, sw *generator.SnippetWriter) {
|
||||
// derive inner types if t is an alias. We call the do* methods below with the alias type.
|
||||
// basic rule: generate according to inner type, but construct objects with the alias type.
|
||||
ut := underlyingType(t)
|
||||
|
||||
var f func(*types.Type, *generator.SnippetWriter)
|
||||
switch ut.Kind {
|
||||
case types.Builtin:
|
||||
f = g.doBuiltin
|
||||
case types.Map:
|
||||
f = g.doMap
|
||||
case types.Slice:
|
||||
f = g.doSlice
|
||||
case types.Struct:
|
||||
f = g.doStruct
|
||||
case types.Pointer:
|
||||
f = g.doPointer
|
||||
case types.Interface:
|
||||
// interfaces are handled in-line in the other cases
|
||||
klog.Fatalf("Hit an interface type %v. This should never happen.", t)
|
||||
case types.Alias:
|
||||
// can never happen because we branch on the underlying type which is never an alias
|
||||
klog.Fatalf("Hit an alias type %v. This should never happen.", t)
|
||||
default:
|
||||
klog.Fatalf("Hit an unsupported type %v.", t)
|
||||
}
|
||||
f(t, sw)
|
||||
}
|
||||
|
||||
// doBuiltin generates code for a builtin or an alias to a builtin. The generated code is
|
||||
// is the same for both cases, i.e. it's the code for the underlying type.
|
||||
func (g *genDeepCopy) doBuiltin(t *types.Type, sw *generator.SnippetWriter) {
|
||||
if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil {
|
||||
sw.Do("*out = in.DeepCopy()\n", nil)
|
||||
return
|
||||
}
|
||||
|
||||
sw.Do("*out = *in\n", nil)
|
||||
}
|
||||
|
||||
// doMap generates code for a map or an alias to a map. The generated code is
|
||||
// is the same for both cases, i.e. it's the code for the underlying type.
|
||||
func (g *genDeepCopy) doMap(t *types.Type, sw *generator.SnippetWriter) {
|
||||
ut := underlyingType(t)
|
||||
uet := underlyingType(ut.Elem)
|
||||
|
||||
if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil {
|
||||
sw.Do("*out = in.DeepCopy()\n", nil)
|
||||
return
|
||||
}
|
||||
|
||||
if !ut.Key.IsAssignable() {
|
||||
klog.Fatalf("Hit an unsupported type %v for: %v", uet, t)
|
||||
}
|
||||
|
||||
sw.Do("*out = make($.|raw$, len(*in))\n", t)
|
||||
sw.Do("for key, val := range *in {\n", nil)
|
||||
dc, dci := deepCopyMethodOrDie(ut.Elem), deepCopyIntoMethodOrDie(ut.Elem)
|
||||
switch {
|
||||
case dc != nil || dci != nil:
|
||||
// Note: a DeepCopy exists because it is added if DeepCopyInto is manually defined
|
||||
leftPointer := ut.Elem.Kind == types.Pointer
|
||||
rightPointer := !isReference(ut.Elem)
|
||||
if dc != nil {
|
||||
rightPointer = dc.Results[0].Kind == types.Pointer
|
||||
}
|
||||
if leftPointer == rightPointer {
|
||||
sw.Do("(*out)[key] = val.DeepCopy()\n", nil)
|
||||
} else if leftPointer {
|
||||
sw.Do("x := val.DeepCopy()\n", nil)
|
||||
sw.Do("(*out)[key] = &x\n", nil)
|
||||
} else {
|
||||
sw.Do("(*out)[key] = *val.DeepCopy()\n", nil)
|
||||
}
|
||||
case ut.Elem.IsAnonymousStruct(): // not uet here because it needs type cast
|
||||
sw.Do("(*out)[key] = val\n", nil)
|
||||
case uet.IsAssignable():
|
||||
sw.Do("(*out)[key] = val\n", nil)
|
||||
case uet.Kind == types.Interface:
|
||||
// Note: do not generate code that won't compile as `DeepCopyinterface{}()` is not a valid function
|
||||
if uet.Name.Name == "interface{}" {
|
||||
klog.Fatalf("DeepCopy of %q is unsupported. Instead, use named interfaces with DeepCopy<named-interface> as one of the methods.", uet.Name.Name)
|
||||
}
|
||||
sw.Do("if val == nil {(*out)[key]=nil} else {\n", nil)
|
||||
// Note: if t.Elem has been an alias "J" of an interface "I" in Go, we will see it
|
||||
// as kind Interface of name "J" here, i.e. generate val.DeepCopyJ(). The golang
|
||||
// parser does not give us the underlying interface name. So we cannot do any better.
|
||||
sw.Do(fmt.Sprintf("(*out)[key] = val.DeepCopy%s()\n", uet.Name.Name), nil)
|
||||
sw.Do("}\n", nil)
|
||||
case uet.Kind == types.Slice || uet.Kind == types.Map || uet.Kind == types.Pointer:
|
||||
sw.Do("var outVal $.|raw$\n", uet)
|
||||
sw.Do("if val == nil { (*out)[key] = nil } else {\n", nil)
|
||||
sw.Do("in, out := &val, &outVal\n", uet)
|
||||
g.generateFor(ut.Elem, sw)
|
||||
sw.Do("}\n", nil)
|
||||
sw.Do("(*out)[key] = outVal\n", nil)
|
||||
case uet.Kind == types.Struct:
|
||||
sw.Do("(*out)[key] = *val.DeepCopy()\n", uet)
|
||||
default:
|
||||
klog.Fatalf("Hit an unsupported type %v for %v", uet, t)
|
||||
}
|
||||
sw.Do("}\n", nil)
|
||||
}
|
||||
|
||||
// doSlice generates code for a slice or an alias to a slice. The generated code is
|
||||
// is the same for both cases, i.e. it's the code for the underlying type.
|
||||
func (g *genDeepCopy) doSlice(t *types.Type, sw *generator.SnippetWriter) {
|
||||
ut := underlyingType(t)
|
||||
uet := underlyingType(ut.Elem)
|
||||
|
||||
if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil {
|
||||
sw.Do("*out = in.DeepCopy()\n", nil)
|
||||
return
|
||||
}
|
||||
|
||||
sw.Do("*out = make($.|raw$, len(*in))\n", t)
|
||||
if deepCopyMethodOrDie(ut.Elem) != nil || deepCopyIntoMethodOrDie(ut.Elem) != nil {
|
||||
sw.Do("for i := range *in {\n", nil)
|
||||
// Note: a DeepCopyInto exists because it is added if DeepCopy is manually defined
|
||||
sw.Do("(*in)[i].DeepCopyInto(&(*out)[i])\n", nil)
|
||||
sw.Do("}\n", nil)
|
||||
} else if uet.Kind == types.Builtin || uet.IsAssignable() {
|
||||
sw.Do("copy(*out, *in)\n", nil)
|
||||
} else {
|
||||
sw.Do("for i := range *in {\n", nil)
|
||||
if uet.Kind == types.Slice || uet.Kind == types.Map || uet.Kind == types.Pointer || deepCopyMethodOrDie(ut.Elem) != nil || deepCopyIntoMethodOrDie(ut.Elem) != nil {
|
||||
sw.Do("if (*in)[i] != nil {\n", nil)
|
||||
sw.Do("in, out := &(*in)[i], &(*out)[i]\n", nil)
|
||||
g.generateFor(ut.Elem, sw)
|
||||
sw.Do("}\n", nil)
|
||||
} else if uet.Kind == types.Interface {
|
||||
// Note: do not generate code that won't compile as `DeepCopyinterface{}()` is not a valid function
|
||||
if uet.Name.Name == "interface{}" {
|
||||
klog.Fatalf("DeepCopy of %q is unsupported. Instead, use named interfaces with DeepCopy<named-interface> as one of the methods.", uet.Name.Name)
|
||||
}
|
||||
sw.Do("if (*in)[i] != nil {\n", nil)
|
||||
// Note: if t.Elem has been an alias "J" of an interface "I" in Go, we will see it
|
||||
// as kind Interface of name "J" here, i.e. generate val.DeepCopyJ(). The golang
|
||||
// parser does not give us the underlying interface name. So we cannot do any better.
|
||||
sw.Do(fmt.Sprintf("(*out)[i] = (*in)[i].DeepCopy%s()\n", uet.Name.Name), nil)
|
||||
sw.Do("}\n", nil)
|
||||
} else if uet.Kind == types.Struct {
|
||||
sw.Do("(*in)[i].DeepCopyInto(&(*out)[i])\n", nil)
|
||||
} else {
|
||||
klog.Fatalf("Hit an unsupported type %v for %v", uet, t)
|
||||
}
|
||||
sw.Do("}\n", nil)
|
||||
}
|
||||
}
|
||||
|
||||
// doStruct generates code for a struct or an alias to a struct. The generated code is
|
||||
// is the same for both cases, i.e. it's the code for the underlying type.
|
||||
func (g *genDeepCopy) doStruct(t *types.Type, sw *generator.SnippetWriter) {
|
||||
ut := underlyingType(t)
|
||||
|
||||
if deepCopyMethodOrDie(t) != nil || deepCopyIntoMethodOrDie(t) != nil {
|
||||
sw.Do("*out = in.DeepCopy()\n", nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Simple copy covers a lot of cases.
|
||||
sw.Do("*out = *in\n", nil)
|
||||
|
||||
// Now fix-up fields as needed.
|
||||
for _, m := range ut.Members {
|
||||
ft := m.Type
|
||||
uft := underlyingType(ft)
|
||||
|
||||
args := generator.Args{
|
||||
"type": ft,
|
||||
"kind": ft.Kind,
|
||||
"name": m.Name,
|
||||
}
|
||||
dc, dci := deepCopyMethodOrDie(ft), deepCopyIntoMethodOrDie(ft)
|
||||
switch {
|
||||
case dc != nil || dci != nil:
|
||||
// Note: a DeepCopyInto exists because it is added if DeepCopy is manually defined
|
||||
leftPointer := ft.Kind == types.Pointer
|
||||
rightPointer := !isReference(ft)
|
||||
if dc != nil {
|
||||
rightPointer = dc.Results[0].Kind == types.Pointer
|
||||
}
|
||||
if leftPointer == rightPointer {
|
||||
sw.Do("out.$.name$ = in.$.name$.DeepCopy()\n", args)
|
||||
} else if leftPointer {
|
||||
sw.Do("x := in.$.name$.DeepCopy()\n", args)
|
||||
sw.Do("out.$.name$ = = &x\n", args)
|
||||
} else {
|
||||
sw.Do("in.$.name$.DeepCopyInto(&out.$.name$)\n", args)
|
||||
}
|
||||
case uft.Kind == types.Builtin:
|
||||
// the initial *out = *in was enough
|
||||
case uft.Kind == types.Map, uft.Kind == types.Slice, uft.Kind == types.Pointer:
|
||||
// Fixup non-nil reference-semantic types.
|
||||
sw.Do("if in.$.name$ != nil {\n", args)
|
||||
sw.Do("in, out := &in.$.name$, &out.$.name$\n", args)
|
||||
g.generateFor(ft, sw)
|
||||
sw.Do("}\n", nil)
|
||||
case uft.Kind == types.Array:
|
||||
sw.Do("out.$.name$ = in.$.name$\n", args)
|
||||
case uft.Kind == types.Struct:
|
||||
if ft.IsAssignable() {
|
||||
sw.Do("out.$.name$ = in.$.name$\n", args)
|
||||
} else {
|
||||
sw.Do("in.$.name$.DeepCopyInto(&out.$.name$)\n", args)
|
||||
}
|
||||
case uft.Kind == types.Interface:
|
||||
// Note: do not generate code that won't compile as `DeepCopyinterface{}()` is not a valid function
|
||||
if uft.Name.Name == "interface{}" {
|
||||
klog.Fatalf("DeepCopy of %q is unsupported. Instead, use named interfaces with DeepCopy<named-interface> as one of the methods.", uft.Name.Name)
|
||||
}
|
||||
sw.Do("if in.$.name$ != nil {\n", args)
|
||||
// Note: if t.Elem has been an alias "J" of an interface "I" in Go, we will see it
|
||||
// as kind Interface of name "J" here, i.e. generate val.DeepCopyJ(). The golang
|
||||
// parser does not give us the underlying interface name. So we cannot do any better.
|
||||
sw.Do(fmt.Sprintf("out.$.name$ = in.$.name$.DeepCopy%s()\n", uft.Name.Name), args)
|
||||
sw.Do("}\n", nil)
|
||||
default:
|
||||
klog.Fatalf("Hit an unsupported type '%v' for '%v', from %v.%v", uft, ft, t, m.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// doPointer generates code for a pointer or an alias to a pointer. The generated code is
|
||||
// is the same for both cases, i.e. it's the code for the underlying type.
|
||||
func (g *genDeepCopy) doPointer(t *types.Type, sw *generator.SnippetWriter) {
|
||||
ut := underlyingType(t)
|
||||
uet := underlyingType(ut.Elem)
|
||||
|
||||
dc, dci := deepCopyMethodOrDie(ut.Elem), deepCopyIntoMethodOrDie(ut.Elem)
|
||||
switch {
|
||||
case dc != nil || dci != nil:
|
||||
rightPointer := !isReference(ut.Elem)
|
||||
if dc != nil {
|
||||
rightPointer = dc.Results[0].Kind == types.Pointer
|
||||
}
|
||||
if rightPointer {
|
||||
sw.Do("*out = (*in).DeepCopy()\n", nil)
|
||||
} else {
|
||||
sw.Do("x := (*in).DeepCopy()\n", nil)
|
||||
sw.Do("*out = &x\n", nil)
|
||||
}
|
||||
case uet.IsAssignable():
|
||||
sw.Do("*out = new($.Elem|raw$)\n", ut)
|
||||
sw.Do("**out = **in", nil)
|
||||
case uet.Kind == types.Map, uet.Kind == types.Slice, uet.Kind == types.Pointer:
|
||||
sw.Do("*out = new($.Elem|raw$)\n", ut)
|
||||
sw.Do("if **in != nil {\n", nil)
|
||||
sw.Do("in, out := *in, *out\n", nil)
|
||||
g.generateFor(uet, sw)
|
||||
sw.Do("}\n", nil)
|
||||
case uet.Kind == types.Struct:
|
||||
sw.Do("*out = new($.Elem|raw$)\n", ut)
|
||||
sw.Do("(*in).DeepCopyInto(*out)\n", nil)
|
||||
default:
|
||||
klog.Fatalf("Hit an unsupported type %v for %v", uet, t)
|
||||
}
|
||||
}
|
@ -0,0 +1,666 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package generators
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/gengo/v2/types"
|
||||
)
|
||||
|
||||
func Test_deepCopyMethod(t *testing.T) {
|
||||
testCases := []struct {
|
||||
typ types.Type
|
||||
expect bool
|
||||
error bool
|
||||
}{
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
// No DeepCopy method.
|
||||
Methods: map[string]*types.Type{},
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// No DeepCopy method.
|
||||
"method": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func()"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (no result).
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func()"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (wrong result).
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func() int"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Name: types.Name{Name: "int"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature with pointer receiver, but non-pointer result.
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func() pkgname.typename"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature with non-pointer receiver, but pointer result.
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func() pkgname.typename"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Correct signature with non-pointer receiver.
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func() pkgname.typename"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Correct signature with pointer receiver.
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func() pkgname.typename"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (has params).
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func(int) pkgname.typename"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{
|
||||
{
|
||||
Name: types.Name{Name: "int"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (extra results).
|
||||
"DeepCopy": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func() (pkgname.typename, int)"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
{
|
||||
Name: types.Name{Name: "int"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
r, err := deepCopyMethod(&tc.typ)
|
||||
if tc.error && err == nil {
|
||||
t.Errorf("case[%d]: expected an error, got none", i)
|
||||
} else if !tc.error && err != nil {
|
||||
t.Errorf("case[%d]: expected no error, got: %v", i, err)
|
||||
} else if !tc.error && (r != nil) != tc.expect {
|
||||
t.Errorf("case[%d]: expected result %v, got: %v", i, tc.expect, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_deepCopyIntoMethod(t *testing.T) {
|
||||
testCases := []struct {
|
||||
typ types.Type
|
||||
expect bool
|
||||
error bool
|
||||
}{
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
// No DeepCopyInto method.
|
||||
Methods: map[string]*types.Type{},
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// No DeepCopyInto method.
|
||||
"method": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func()"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (no parameter).
|
||||
"DeepCopyInto": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func()"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (unexpected result).
|
||||
"DeepCopyInto": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func(*pkgname.typename) int"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{
|
||||
{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
},
|
||||
Results: []*types.Type{
|
||||
{
|
||||
Name: types.Name{Name: "int"},
|
||||
Kind: types.Builtin,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (non-pointer parameter, pointer receiver).
|
||||
"DeepCopyInto": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func(pkgname.typename)"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{
|
||||
{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Wrong signature (non-pointer parameter, non-pointer receiver).
|
||||
"DeepCopyInto": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func(pkgname.typename)"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
Parameters: []*types.Type{
|
||||
{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: false,
|
||||
error: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Correct signature with non-pointer receiver.
|
||||
"DeepCopyInto": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func(*pkgname.typename)"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
Parameters: []*types.Type{
|
||||
{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
{
|
||||
typ: types.Type{
|
||||
Name: types.Name{Package: "pkgname", Name: "typename"},
|
||||
Kind: types.Builtin,
|
||||
Methods: map[string]*types.Type{
|
||||
// Correct signature with pointer receiver.
|
||||
"DeepCopyInto": {
|
||||
Name: types.Name{Package: "pkgname", Name: "func(*pkgname.typename)"},
|
||||
Kind: types.Func,
|
||||
Signature: &types.Signature{
|
||||
Receiver: &types.Type{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
Parameters: []*types.Type{
|
||||
{
|
||||
Kind: types.Pointer,
|
||||
Elem: &types.Type{Kind: types.Struct, Name: types.Name{Package: "pkgname", Name: "typename"}},
|
||||
},
|
||||
},
|
||||
Results: []*types.Type{},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expect: true,
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
r, err := deepCopyIntoMethod(&tc.typ)
|
||||
if tc.error && err == nil {
|
||||
t.Errorf("case[%d]: expected an error, got none", i)
|
||||
} else if !tc.error && err != nil {
|
||||
t.Errorf("case[%d]: expected no error, got: %v", i, err)
|
||||
} else if !tc.error && (r != nil) != tc.expect {
|
||||
t.Errorf("case[%d]: expected result %v, got: %v", i, tc.expect, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_extractTagParams(t *testing.T) {
|
||||
testCases := []struct {
|
||||
comments []string
|
||||
expect *enabledTagValue
|
||||
}{
|
||||
{
|
||||
comments: []string{
|
||||
"Human comment",
|
||||
},
|
||||
expect: nil,
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"Human comment",
|
||||
"+k8s:deepcopy-gen",
|
||||
},
|
||||
expect: &enabledTagValue{
|
||||
value: "",
|
||||
register: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"Human comment",
|
||||
"+k8s:deepcopy-gen=package",
|
||||
},
|
||||
expect: &enabledTagValue{
|
||||
value: "package",
|
||||
register: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"Human comment",
|
||||
"+k8s:deepcopy-gen=package,register",
|
||||
},
|
||||
expect: &enabledTagValue{
|
||||
value: "package",
|
||||
register: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"Human comment",
|
||||
"+k8s:deepcopy-gen=package,register=true",
|
||||
},
|
||||
expect: &enabledTagValue{
|
||||
value: "package",
|
||||
register: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"Human comment",
|
||||
"+k8s:deepcopy-gen=package,register=false",
|
||||
},
|
||||
expect: &enabledTagValue{
|
||||
value: "package",
|
||||
register: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
r := extractEnabledTag(tc.comments)
|
||||
if r == nil && tc.expect != nil {
|
||||
t.Errorf("case[%d]: expected non-nil", i)
|
||||
}
|
||||
if r != nil && tc.expect == nil {
|
||||
t.Errorf("case[%d]: expected nil, got %v", i, *r)
|
||||
}
|
||||
if r != nil && *r != *tc.expect {
|
||||
t.Errorf("case[%d]: expected %v, got %v", i, *tc.expect, *r)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func Test_extractInterfacesTag(t *testing.T) {
|
||||
testCases := []struct {
|
||||
comments, secondComments []string
|
||||
expect []string
|
||||
}{
|
||||
{
|
||||
comments: []string{},
|
||||
expect: nil,
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
expect: []string{
|
||||
"k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.Object",
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.List",
|
||||
},
|
||||
expect: []string{
|
||||
"k8s.io/kubernetes/runtime.Object",
|
||||
"k8s.io/kubernetes/runtime.List",
|
||||
},
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.Object",
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
expect: []string{
|
||||
"k8s.io/kubernetes/runtime.Object",
|
||||
"k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
},
|
||||
{
|
||||
secondComments: []string{
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
expect: []string{
|
||||
"k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
secondComments: []string{
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.List",
|
||||
},
|
||||
expect: []string{
|
||||
"k8s.io/kubernetes/runtime.List",
|
||||
"k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
},
|
||||
{
|
||||
comments: []string{
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
secondComments: []string{
|
||||
"+k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
expect: []string{
|
||||
"k8s.io/kubernetes/runtime.Object",
|
||||
"k8s.io/kubernetes/runtime.Object",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range testCases {
|
||||
typ := &types.Type{
|
||||
CommentLines: tc.comments,
|
||||
SecondClosestCommentLines: tc.secondComments,
|
||||
}
|
||||
r := extractInterfacesTag(typ)
|
||||
if r == nil && tc.expect != nil {
|
||||
t.Errorf("case[%d]: expected non-nil", i)
|
||||
}
|
||||
if r != nil && tc.expect == nil {
|
||||
t.Errorf("case[%d]: expected nil, got %v", i, r)
|
||||
}
|
||||
if r != nil && !reflect.DeepEqual(r, tc.expect) {
|
||||
t.Errorf("case[%d]: expected %v, got %v", i, tc.expect, r)
|
||||
}
|
||||
}
|
||||
}
|
@ -16,14 +16,24 @@ limitations under the License.
|
||||
|
||||
// deepcopy-gen is a tool for auto-generating DeepCopy functions.
|
||||
//
|
||||
// Given a list of input directories, it will generate functions that
|
||||
// efficiently perform a full deep-copy of each type. For any type that
|
||||
// offers a `.DeepCopy()` method, it will simply call that. Otherwise it will
|
||||
// use standard value assignment whenever possible. If that is not possible it
|
||||
// will try to call its own generated copy function for the type, if the type is
|
||||
// within the allowed root packages. Failing that, it will fall back on
|
||||
// `conversion.Cloner.DeepCopy(val)` to make the copy. The resulting file will
|
||||
// be stored in the same directory as the processed source package.
|
||||
// Given a list of input directories, it will generate DeepCopy and
|
||||
// DeepCopyInto methods that efficiently perform a full deep-copy of each type.
|
||||
// If these methods already exist (are predefined by the developer), they are
|
||||
// used instead of generating new ones. Generated code will use standard value
|
||||
// assignment whenever possible. If that is not possible it will try to call
|
||||
// its own generated copy function for the type. Failing that, it will fall
|
||||
// back on `conversion.Cloner.DeepCopy(val)` to make the copy. The resulting
|
||||
// file will be stored in the same directory as the processed source package.
|
||||
//
|
||||
// If interfaces are referenced in types, it is expected that corresponding
|
||||
// DeepCopyInterfaceName methods exist, e.g. DeepCopyObject for runtime.Object.
|
||||
// These can be predefined by the developer or generated through tags, see
|
||||
// below. They must be added to the interfaces themselves manually, e.g.
|
||||
//
|
||||
// type Object interface {
|
||||
// ...
|
||||
// DeepCopyObject() Object
|
||||
// }
|
||||
//
|
||||
// Generation is governed by comment tags in the source. Any package may
|
||||
// request DeepCopy generation by including a comment in the file-comments of
|
||||
@ -32,17 +42,30 @@ limitations under the License.
|
||||
// // +k8s:deepcopy-gen=package
|
||||
//
|
||||
// DeepCopy functions can be generated for individual types, rather than the
|
||||
// entire package by specifying a comment on the type definion of the form:
|
||||
// entire package by specifying a comment on the type definition of the form:
|
||||
//
|
||||
// // +k8s:deepcopy-gen=true
|
||||
//
|
||||
// When generating for a whole package, individual types may opt out of
|
||||
// DeepCopy generation by specifying a comment on the of the form:
|
||||
// DeepCopy generation by specifying a comment on the type definition of the
|
||||
// form:
|
||||
//
|
||||
// // +k8s:deepcopy-gen=false
|
||||
//
|
||||
// Note that registration is a whole-package option, and is not available for
|
||||
// individual types.
|
||||
// Additional DeepCopyInterfaceName methods can be generated by specifying a
|
||||
// comment on the type definition of the form:
|
||||
//
|
||||
// // +k8s:deepcopy-gen:interfaces=k8s.io/kubernetes/runtime.Object,k8s.io/kubernetes/runtime.List
|
||||
//
|
||||
// This leads to the generation of DeepCopyObject and DeepCopyList with the given
|
||||
// interfaces as return types. We say that the tagged type implements deepcopy for the
|
||||
// interfaces.
|
||||
//
|
||||
// The deepcopy funcs for interfaces using "+k8s:deepcopy-gen:interfaces" use the pointer
|
||||
// of the type as receiver. For those special cases where the non-pointer object should
|
||||
// implement the interface, this can be done with:
|
||||
//
|
||||
// // +k8s:deepcopy-gen:nonpointer-interfaces=true
|
||||
package main
|
||||
|
||||
import (
|
||||
@ -50,8 +73,8 @@ import (
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
generatorargs "k8s.io/code-generator/cmd/deepcopy-gen/args"
|
||||
"k8s.io/code-generator/cmd/deepcopy-gen/generators"
|
||||
"k8s.io/gengo/v2/args"
|
||||
"k8s.io/gengo/v2/examples/deepcopy-gen/generators"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
|
@ -0,0 +1,89 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package aliases
|
||||
|
||||
// Note: the following AliasInterface and AliasAliasInterface +k8s:deepcopy-gen:interfaces tags
|
||||
// are necessary because Golang flattens interface alias in the type system. I.e. an alias J of
|
||||
// an interface I is actually equivalent to I. So support deepcopies of those aliases, we have
|
||||
// to implement all aliases of that interface.
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/code-generator/cmd/deepcopy-gen/output_tests/aliases.Interface
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/code-generator/cmd/deepcopy-gen/output_tests/aliases.AliasInterface
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/code-generator/cmd/deepcopy-gen/output_tests/aliases.AliasAliasInterface
|
||||
type Foo struct {
|
||||
X int
|
||||
}
|
||||
|
||||
type Interface interface {
|
||||
DeepCopyInterface() Interface
|
||||
DeepCopyAliasInterface() AliasInterface
|
||||
DeepCopyAliasAliasInterface() AliasAliasInterface
|
||||
}
|
||||
|
||||
type Builtin int
|
||||
type Slice []int
|
||||
type Pointer *int
|
||||
type PointerAlias *Builtin
|
||||
type Struct Foo
|
||||
type Map map[string]int
|
||||
|
||||
type FooAlias Foo
|
||||
type FooSlice []Foo
|
||||
type FooPointer *Foo
|
||||
type FooMap map[string]Foo
|
||||
|
||||
type AliasBuiltin Builtin
|
||||
type AliasSlice Slice
|
||||
type AliasPointer Pointer
|
||||
type AliasStruct Struct
|
||||
type AliasMap Map
|
||||
|
||||
type AliasInterface Interface
|
||||
type AliasAliasInterface AliasInterface
|
||||
type AliasInterfaceMap map[string]AliasInterface
|
||||
type AliasInterfaceSlice []AliasInterface
|
||||
|
||||
// Aliases
|
||||
type Ttest struct {
|
||||
Builtin Builtin
|
||||
Slice Slice
|
||||
Pointer Pointer
|
||||
PointerAlias PointerAlias
|
||||
Struct Struct
|
||||
Map Map
|
||||
SliceSlice []Slice
|
||||
MapSlice map[string]Slice
|
||||
|
||||
FooAlias FooAlias
|
||||
FooSlice FooSlice
|
||||
FooPointer FooPointer
|
||||
FooMap FooMap
|
||||
|
||||
AliasBuiltin AliasBuiltin
|
||||
AliasSlice AliasSlice
|
||||
AliasPointer AliasPointer
|
||||
AliasStruct AliasStruct
|
||||
AliasMap AliasMap
|
||||
|
||||
AliasInterface AliasInterface
|
||||
AliasAliasInterface AliasAliasInterface
|
||||
AliasInterfaceMap AliasInterfaceMap
|
||||
AliasInterfaceSlice AliasInterfaceSlice
|
||||
}
|
413
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/aliases/zz_generated.deepcopy.go
generated
Normal file
413
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/aliases/zz_generated.deepcopy.go
generated
Normal file
@ -0,0 +1,413 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package aliases
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in AliasInterfaceMap) DeepCopyInto(out *AliasInterfaceMap) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(AliasInterfaceMap, len(*in))
|
||||
for key, val := range *in {
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
(*out)[key] = val.DeepCopyAliasInterface()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasInterfaceMap.
|
||||
func (in AliasInterfaceMap) DeepCopy() AliasInterfaceMap {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AliasInterfaceMap)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in AliasInterfaceSlice) DeepCopyInto(out *AliasInterfaceSlice) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(AliasInterfaceSlice, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
(*out)[i] = (*in)[i].DeepCopyAliasInterface()
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasInterfaceSlice.
|
||||
func (in AliasInterfaceSlice) DeepCopy() AliasInterfaceSlice {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AliasInterfaceSlice)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in AliasMap) DeepCopyInto(out *AliasMap) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(AliasMap, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasMap.
|
||||
func (in AliasMap) DeepCopy() AliasMap {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AliasMap)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in AliasSlice) DeepCopyInto(out *AliasSlice) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(AliasSlice, len(*in))
|
||||
copy(*out, *in)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasSlice.
|
||||
func (in AliasSlice) DeepCopy() AliasSlice {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AliasSlice)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AliasStruct) DeepCopyInto(out *AliasStruct) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasStruct.
|
||||
func (in *AliasStruct) DeepCopy() *AliasStruct {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AliasStruct)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Foo) DeepCopyInto(out *Foo) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Foo.
|
||||
func (in *Foo) DeepCopy() *Foo {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Foo)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyAliasAliasInterface is an autogenerated deepcopy function, copying the receiver, creating a new AliasAliasInterface.
|
||||
func (in *Foo) DeepCopyAliasAliasInterface() AliasAliasInterface {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyAliasInterface is an autogenerated deepcopy function, copying the receiver, creating a new AliasInterface.
|
||||
func (in *Foo) DeepCopyAliasInterface() AliasInterface {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new Interface.
|
||||
func (in *Foo) DeepCopyInterface() Interface {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FooAlias) DeepCopyInto(out *FooAlias) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FooAlias.
|
||||
func (in *FooAlias) DeepCopy() *FooAlias {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FooAlias)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in FooMap) DeepCopyInto(out *FooMap) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(FooMap, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FooMap.
|
||||
func (in FooMap) DeepCopy() FooMap {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FooMap)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in FooSlice) DeepCopyInto(out *FooSlice) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(FooSlice, len(*in))
|
||||
copy(*out, *in)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FooSlice.
|
||||
func (in FooSlice) DeepCopy() FooSlice {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FooSlice)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in Map) DeepCopyInto(out *Map) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(Map, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Map.
|
||||
func (in Map) DeepCopy() Map {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Map)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in Slice) DeepCopyInto(out *Slice) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(Slice, len(*in))
|
||||
copy(*out, *in)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Slice.
|
||||
func (in Slice) DeepCopy() Slice {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Slice)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Struct) DeepCopyInto(out *Struct) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Struct.
|
||||
func (in *Struct) DeepCopy() *Struct {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Struct)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Ttest) DeepCopyInto(out *Ttest) {
|
||||
*out = *in
|
||||
if in.Slice != nil {
|
||||
in, out := &in.Slice, &out.Slice
|
||||
*out = make(Slice, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Pointer != nil {
|
||||
in, out := &in.Pointer, &out.Pointer
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.PointerAlias != nil {
|
||||
in, out := &in.PointerAlias, &out.PointerAlias
|
||||
*out = new(Builtin)
|
||||
**out = **in
|
||||
}
|
||||
out.Struct = in.Struct
|
||||
if in.Map != nil {
|
||||
in, out := &in.Map, &out.Map
|
||||
*out = make(Map, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.SliceSlice != nil {
|
||||
in, out := &in.SliceSlice, &out.SliceSlice
|
||||
*out = make([]Slice, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = make(Slice, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.MapSlice != nil {
|
||||
in, out := &in.MapSlice, &out.MapSlice
|
||||
*out = make(map[string]Slice, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []int
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make(Slice, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
out.FooAlias = in.FooAlias
|
||||
if in.FooSlice != nil {
|
||||
in, out := &in.FooSlice, &out.FooSlice
|
||||
*out = make(FooSlice, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.FooPointer != nil {
|
||||
in, out := &in.FooPointer, &out.FooPointer
|
||||
*out = new(Foo)
|
||||
**out = **in
|
||||
}
|
||||
if in.FooMap != nil {
|
||||
in, out := &in.FooMap, &out.FooMap
|
||||
*out = make(FooMap, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.AliasSlice != nil {
|
||||
in, out := &in.AliasSlice, &out.AliasSlice
|
||||
*out = make(AliasSlice, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.AliasPointer != nil {
|
||||
in, out := &in.AliasPointer, &out.AliasPointer
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
out.AliasStruct = in.AliasStruct
|
||||
if in.AliasMap != nil {
|
||||
in, out := &in.AliasMap, &out.AliasMap
|
||||
*out = make(AliasMap, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.AliasInterface != nil {
|
||||
out.AliasInterface = in.AliasInterface.DeepCopyAliasInterface()
|
||||
}
|
||||
if in.AliasAliasInterface != nil {
|
||||
out.AliasAliasInterface = in.AliasAliasInterface.DeepCopyAliasAliasInterface()
|
||||
}
|
||||
if in.AliasInterfaceMap != nil {
|
||||
in, out := &in.AliasInterfaceMap, &out.AliasInterfaceMap
|
||||
*out = make(AliasInterfaceMap, len(*in))
|
||||
for key, val := range *in {
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
(*out)[key] = val.DeepCopyAliasInterface()
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.AliasInterfaceSlice != nil {
|
||||
in, out := &in.AliasInterfaceSlice, &out.AliasInterfaceSlice
|
||||
*out = make(AliasInterfaceSlice, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
(*out)[i] = (*in)[i].DeepCopyAliasInterface()
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
|
||||
func (in *Ttest) DeepCopy() *Ttest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Ttest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package builtins
|
||||
|
||||
type Ttest struct {
|
||||
Byte byte
|
||||
// Int8 int8 // TODO: int8 becomes byte in SnippetWriter
|
||||
Int16 int16
|
||||
Int32 int32
|
||||
Int64 int64
|
||||
Uint8 uint8
|
||||
Uint16 uint16
|
||||
Uint32 uint32
|
||||
Uint64 uint64
|
||||
Float32 float32
|
||||
Float64 float64
|
||||
String string
|
||||
}
|
38
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/builtins/zz_generated.deepcopy.go
generated
Normal file
38
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/builtins/zz_generated.deepcopy.go
generated
Normal file
@ -0,0 +1,38 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package builtins
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Ttest) DeepCopyInto(out *Ttest) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
|
||||
func (in *Ttest) DeepCopy() *Ttest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Ttest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
/*
|
||||
Copyright 2024 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
//go:generate go run k8s.io/code-generator/cmd/deepcopy-gen --output-file zz_generated.deepcopy.go --go-header-file=../../../examples/hack/boilerplate.go.txt k8s.io/code-generator/cmd/deepcopy-gen/output_tests/...
|
||||
package outputtests
|
@ -0,0 +1,131 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package outputtests
|
||||
|
||||
import (
|
||||
"github.com/google/gofuzz"
|
||||
|
||||
"k8s.io/code-generator/cmd/deepcopy-gen/output_tests/aliases"
|
||||
"k8s.io/code-generator/cmd/deepcopy-gen/output_tests/interfaces"
|
||||
)
|
||||
|
||||
// interfaceFuzzers contains fuzzer that set all interface to nil because our
|
||||
// JSON deepcopy does not work with it.
|
||||
// TODO: test also interface deepcopy
|
||||
var interfaceFuzzers = []interface{}{
|
||||
func(s *aliases.AliasAliasInterface, c fuzz.Continue) {
|
||||
if c.RandBool() {
|
||||
*s = nil
|
||||
} else {
|
||||
*s = &aliasAliasInterfaceInstance{X: c.Int()}
|
||||
}
|
||||
},
|
||||
func(s *aliases.AliasInterface, c fuzz.Continue) {
|
||||
if c.RandBool() {
|
||||
*s = nil
|
||||
} else {
|
||||
*s = &aliasAliasInterfaceInstance{X: c.Int()}
|
||||
}
|
||||
},
|
||||
func(s *aliases.Interface, c fuzz.Continue) {
|
||||
if c.RandBool() {
|
||||
*s = nil
|
||||
} else {
|
||||
*s = &aliasAliasInterfaceInstance{X: c.Int()}
|
||||
}
|
||||
},
|
||||
func(s *aliases.AliasInterfaceMap, c fuzz.Continue) {
|
||||
if c.RandBool() {
|
||||
*s = nil
|
||||
} else {
|
||||
*s = make(aliases.AliasInterfaceMap)
|
||||
for i := 0; i < c.Intn(3); i++ {
|
||||
if c.RandBool() {
|
||||
(*s)[c.RandString()] = nil
|
||||
} else {
|
||||
(*s)[c.RandString()] = &aliasAliasInterfaceInstance{X: c.Int()}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
func(s *aliases.AliasInterfaceSlice, c fuzz.Continue) {
|
||||
if c.RandBool() {
|
||||
*s = nil
|
||||
} else {
|
||||
*s = make(aliases.AliasInterfaceSlice, 0)
|
||||
for i := 0; i < c.Intn(3); i++ {
|
||||
if c.RandBool() {
|
||||
*s = append(*s, nil)
|
||||
} else {
|
||||
*s = append(*s, &aliasAliasInterfaceInstance{X: c.Int()})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
func(s *interfaces.Inner, c fuzz.Continue) {
|
||||
if c.RandBool() {
|
||||
*s = nil
|
||||
} else {
|
||||
*s = &interfacesInnerInstance{X: c.Float64()}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
type aliasAliasInterfaceInstance struct {
|
||||
X int
|
||||
}
|
||||
|
||||
func (i *aliasAliasInterfaceInstance) DeepCopyInterface() aliases.Interface {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &aliasAliasInterfaceInstance{X: i.X}
|
||||
}
|
||||
|
||||
func (i *aliasAliasInterfaceInstance) DeepCopyAliasInterface() aliases.AliasInterface {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &aliasAliasInterfaceInstance{X: i.X}
|
||||
}
|
||||
|
||||
func (i *aliasAliasInterfaceInstance) DeepCopyAliasAliasInterface() aliases.AliasAliasInterface {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &aliasAliasInterfaceInstance{X: i.X}
|
||||
}
|
||||
|
||||
type interfacesInnerInstance struct {
|
||||
X float64
|
||||
}
|
||||
|
||||
func (i *interfacesInnerInstance) DeepCopyInner() interfaces.Inner {
|
||||
if i == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &interfacesInnerInstance{X: i.X}
|
||||
}
|
||||
|
||||
func (i *interfacesInnerInstance) Function() float64 {
|
||||
return i.X
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package interfaces
|
||||
|
||||
type Inner interface {
|
||||
Function() float64
|
||||
DeepCopyInner() Inner
|
||||
}
|
||||
|
||||
type Ttest struct {
|
||||
I []Inner
|
||||
}
|
47
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/interfaces/zz_generated.deepcopy.go
generated
Normal file
47
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/interfaces/zz_generated.deepcopy.go
generated
Normal file
@ -0,0 +1,47 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package interfaces
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Ttest) DeepCopyInto(out *Ttest) {
|
||||
*out = *in
|
||||
if in.I != nil {
|
||||
in, out := &in.I, &out.I
|
||||
*out = make([]Inner, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
(*out)[i] = (*in)[i].DeepCopyInner()
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
|
||||
func (in *Ttest) DeepCopy() *Ttest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Ttest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package maps
|
||||
|
||||
type Ttest struct {
|
||||
Byte map[string]byte
|
||||
// Int8 map[string]int8 //TODO: int8 becomes byte in SnippetWriter
|
||||
Int16 map[string]int16
|
||||
Int32 map[string]int32
|
||||
Int64 map[string]int64
|
||||
Uint8 map[string]uint8
|
||||
Uint16 map[string]uint16
|
||||
Uint32 map[string]uint32
|
||||
Uint64 map[string]uint64
|
||||
Float32 map[string]float32
|
||||
Float64 map[string]float64
|
||||
String map[string]string
|
||||
StringPtr map[string]*string
|
||||
StringPtrPtr map[string]**string
|
||||
Map map[string]map[string]string
|
||||
MapPtr map[string]*map[string]string
|
||||
Slice map[string][]string
|
||||
SlicePtr map[string]*[]string
|
||||
Struct map[string]Ttest
|
||||
StructPtr map[string]*Ttest
|
||||
}
|
243
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/maps/zz_generated.deepcopy.go
generated
Normal file
243
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/maps/zz_generated.deepcopy.go
generated
Normal file
@ -0,0 +1,243 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package maps
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Ttest) DeepCopyInto(out *Ttest) {
|
||||
*out = *in
|
||||
if in.Byte != nil {
|
||||
in, out := &in.Byte, &out.Byte
|
||||
*out = make(map[string]byte, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Int16 != nil {
|
||||
in, out := &in.Int16, &out.Int16
|
||||
*out = make(map[string]int16, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Int32 != nil {
|
||||
in, out := &in.Int32, &out.Int32
|
||||
*out = make(map[string]int32, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Int64 != nil {
|
||||
in, out := &in.Int64, &out.Int64
|
||||
*out = make(map[string]int64, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Uint8 != nil {
|
||||
in, out := &in.Uint8, &out.Uint8
|
||||
*out = make(map[string]byte, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Uint16 != nil {
|
||||
in, out := &in.Uint16, &out.Uint16
|
||||
*out = make(map[string]uint16, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Uint32 != nil {
|
||||
in, out := &in.Uint32, &out.Uint32
|
||||
*out = make(map[string]uint32, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Uint64 != nil {
|
||||
in, out := &in.Uint64, &out.Uint64
|
||||
*out = make(map[string]uint64, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Float32 != nil {
|
||||
in, out := &in.Float32, &out.Float32
|
||||
*out = make(map[string]float32, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Float64 != nil {
|
||||
in, out := &in.Float64, &out.Float64
|
||||
*out = make(map[string]float64, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.String != nil {
|
||||
in, out := &in.String, &out.String
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.StringPtr != nil {
|
||||
in, out := &in.StringPtr, &out.StringPtr
|
||||
*out = make(map[string]*string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal *string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.StringPtrPtr != nil {
|
||||
in, out := &in.StringPtrPtr, &out.StringPtrPtr
|
||||
*out = make(map[string]**string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal **string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = new(*string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.Map != nil {
|
||||
in, out := &in.Map, &out.Map
|
||||
*out = make(map[string]map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal map[string]string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.MapPtr != nil {
|
||||
in, out := &in.MapPtr, &out.MapPtr
|
||||
*out = make(map[string]*map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal *map[string]string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = new(map[string]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.Slice != nil {
|
||||
in, out := &in.Slice, &out.Slice
|
||||
*out = make(map[string][]string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.SlicePtr != nil {
|
||||
in, out := &in.SlicePtr, &out.SlicePtr
|
||||
*out = make(map[string]*[]string, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal *[]string
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = new([]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
if in.Struct != nil {
|
||||
in, out := &in.Struct, &out.Struct
|
||||
*out = make(map[string]Ttest, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = *val.DeepCopy()
|
||||
}
|
||||
}
|
||||
if in.StructPtr != nil {
|
||||
in, out := &in.StructPtr, &out.StructPtr
|
||||
*out = make(map[string]*Ttest, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal *Ttest
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
in, out := &val, &outVal
|
||||
*out = new(Ttest)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
|
||||
func (in *Ttest) DeepCopy() *Ttest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Ttest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package otherpkg
|
||||
|
||||
type Object interface {
|
||||
DeepCopyObject() Object
|
||||
}
|
||||
|
||||
type List interface {
|
||||
DeepCopyList() List
|
||||
}
|
@ -0,0 +1,173 @@
|
||||
/*
|
||||
Copyright 2024 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package outputtests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/google/gofuzz"
|
||||
|
||||
"k8s.io/code-generator/cmd/deepcopy-gen/output_tests/aliases"
|
||||
"k8s.io/code-generator/cmd/deepcopy-gen/output_tests/builtins"
|
||||
"k8s.io/code-generator/cmd/deepcopy-gen/output_tests/interfaces"
|
||||
"k8s.io/code-generator/cmd/deepcopy-gen/output_tests/maps"
|
||||
"k8s.io/code-generator/cmd/deepcopy-gen/output_tests/pointer"
|
||||
"k8s.io/code-generator/cmd/deepcopy-gen/output_tests/slices"
|
||||
"k8s.io/code-generator/cmd/deepcopy-gen/output_tests/structs"
|
||||
)
|
||||
|
||||
func TestWithValueFuzzer(t *testing.T) {
|
||||
tests := []interface{}{
|
||||
aliases.Ttest{},
|
||||
builtins.Ttest{},
|
||||
interfaces.Ttest{},
|
||||
maps.Ttest{},
|
||||
pointer.Ttest{},
|
||||
slices.Ttest{},
|
||||
structs.Ttest{},
|
||||
}
|
||||
|
||||
fuzzer := fuzz.New()
|
||||
fuzzer.NilChance(0.5)
|
||||
fuzzer.NumElements(0, 2)
|
||||
fuzzer.Funcs(interfaceFuzzers...)
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(fmt.Sprintf("%T", test), func(t *testing.T) {
|
||||
N := 1000
|
||||
for i := 0; i < N; i++ {
|
||||
original := reflect.New(reflect.TypeOf(test)).Interface()
|
||||
|
||||
fuzzer.Fuzz(original)
|
||||
|
||||
reflectCopy := ReflectDeepCopy(original)
|
||||
|
||||
if !reflect.DeepEqual(original, reflectCopy) {
|
||||
t.Errorf("original and reflectCopy are different:\n\n original = %s\n\n jsonCopy = %s", spew.Sdump(original), spew.Sdump(reflectCopy))
|
||||
}
|
||||
|
||||
deepCopy := reflect.ValueOf(original).MethodByName("DeepCopy").Call(nil)[0].Interface()
|
||||
|
||||
if !reflect.DeepEqual(original, deepCopy) {
|
||||
t.Fatalf("original and deepCopy are different:\n\n original = %s\n\n deepCopy() = %s", spew.Sdump(original), spew.Sdump(deepCopy))
|
||||
}
|
||||
|
||||
ValueFuzz(original)
|
||||
|
||||
if !reflect.DeepEqual(reflectCopy, deepCopy) {
|
||||
t.Fatalf("reflectCopy and deepCopy are different:\n\n origin = %s\n\n jsonCopy() = %s", spew.Sdump(original), spew.Sdump(deepCopy))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkReflectDeepCopy(b *testing.B) {
|
||||
fourtytwo := "fourtytwo"
|
||||
fourtytwoPtr := &fourtytwo
|
||||
var nilMap map[string]string
|
||||
var nilSlice []string
|
||||
mapPtr := &map[string]string{"0": "fourtytwo", "1": "fourtytwo"}
|
||||
slicePtr := &[]string{"fourtytwo", "fourtytwo", "fourtytwo"}
|
||||
structPtr := &pointer.Ttest{
|
||||
Builtin: &fourtytwo,
|
||||
Ptr: &fourtytwoPtr,
|
||||
}
|
||||
|
||||
tests := []interface{}{
|
||||
maps.Ttest{
|
||||
Byte: map[string]byte{"0": 42, "1": 42, "3": 42},
|
||||
Int16: map[string]int16{"0": 42, "1": 42, "3": 42},
|
||||
Int32: map[string]int32{"0": 42, "1": 42, "3": 42},
|
||||
Int64: map[string]int64{"0": 42, "1": 42, "3": 42},
|
||||
Uint8: map[string]uint8{"0": 42, "1": 42, "3": 42},
|
||||
Uint16: map[string]uint16{"0": 42, "1": 42, "3": 42},
|
||||
Uint32: map[string]uint32{"0": 42, "1": 42, "3": 42},
|
||||
Uint64: map[string]uint64{"0": 42, "1": 42, "3": 42},
|
||||
Float32: map[string]float32{"0": 42.0, "1": 42.0, "3": 42.0},
|
||||
Float64: map[string]float64{"0": 42, "1": 42, "3": 42},
|
||||
String: map[string]string{"0": "fourtytwo", "1": "fourtytwo", "3": "fourtytwo"},
|
||||
StringPtr: map[string]*string{"0": &fourtytwo, "1": &fourtytwo, "3": &fourtytwo},
|
||||
StringPtrPtr: map[string]**string{"0": &fourtytwoPtr, "1": &fourtytwoPtr, "3": &fourtytwoPtr},
|
||||
Map: map[string]map[string]string{"0": nil, "1": {"a": fourtytwo, "b": fourtytwo}, "3": {}},
|
||||
MapPtr: map[string]*map[string]string{"0": nil, "1": {"a": fourtytwo, "b": fourtytwo}, "3": &nilMap},
|
||||
Slice: map[string][]string{"0": nil, "1": {"a", "b"}, "2": {}},
|
||||
SlicePtr: map[string]*[]string{"0": nil, "1": {"a", "b"}, "2": &nilSlice},
|
||||
Struct: map[string]maps.Ttest{"0": {}, "1": {Byte: map[string]byte{"0": 42, "1": 42, "3": 42}}},
|
||||
StructPtr: map[string]*maps.Ttest{"0": nil, "1": {}, "2": {Byte: map[string]byte{"0": 42, "1": 42, "3": 42}}},
|
||||
},
|
||||
slices.Ttest{
|
||||
Byte: []byte{42, 42, 42},
|
||||
Int16: []int16{42, 42, 42},
|
||||
Int32: []int32{42, 42, 42},
|
||||
Int64: []int64{42, 42, 42},
|
||||
Uint8: []uint8{42, 42, 42},
|
||||
Uint16: []uint16{42, 42, 42},
|
||||
Uint32: []uint32{42, 42, 42},
|
||||
Uint64: []uint64{42, 42, 42},
|
||||
Float32: []float32{42.0, 42.0, 42.0},
|
||||
Float64: []float64{42, 42, 42},
|
||||
String: []string{"fourtytwo", "fourtytwo", "fourtytwo"},
|
||||
StringPtr: []*string{&fourtytwo, &fourtytwo, &fourtytwo},
|
||||
StringPtrPtr: []**string{&fourtytwoPtr, &fourtytwoPtr, &fourtytwoPtr},
|
||||
Map: []map[string]string{nil, {"a": fourtytwo, "b": fourtytwo}, {}},
|
||||
MapPtr: []*map[string]string{nil, {"a": fourtytwo, "b": fourtytwo}, &nilMap},
|
||||
Slice: [][]string{nil, {"a", "b"}, {}},
|
||||
SlicePtr: []*[]string{nil, {"a", "b"}, &nilSlice},
|
||||
Struct: []slices.Ttest{{}, {Byte: []byte{42, 42, 42}}},
|
||||
StructPtr: []*slices.Ttest{nil, {}, {Byte: []byte{42, 42, 42}}},
|
||||
},
|
||||
pointer.Ttest{
|
||||
Builtin: &fourtytwo,
|
||||
Ptr: &fourtytwoPtr,
|
||||
Map: &map[string]string{"0": "fourtytwo", "1": "fourtytwo"},
|
||||
Slice: &[]string{"fourtytwo", "fourtytwo", "fourtytwo"},
|
||||
MapPtr: &mapPtr,
|
||||
SlicePtr: &slicePtr,
|
||||
Struct: &pointer.Ttest{
|
||||
Builtin: &fourtytwo,
|
||||
Ptr: &fourtytwoPtr,
|
||||
},
|
||||
StructPtr: &structPtr,
|
||||
},
|
||||
}
|
||||
|
||||
fuzzer := fuzz.New()
|
||||
fuzzer.NilChance(0.5)
|
||||
fuzzer.NumElements(0, 2)
|
||||
fuzzer.Funcs(interfaceFuzzers...)
|
||||
|
||||
for _, test := range tests {
|
||||
b.Run(fmt.Sprintf("%T", test), func(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
switch t := test.(type) {
|
||||
case maps.Ttest:
|
||||
t.DeepCopy()
|
||||
case slices.Ttest:
|
||||
t.DeepCopy()
|
||||
case pointer.Ttest:
|
||||
t.DeepCopy()
|
||||
default:
|
||||
b.Fatalf("missing type case in switch for %T", t)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package pointer
|
||||
|
||||
type Ttest struct {
|
||||
Builtin *string
|
||||
Ptr **string
|
||||
Map *map[string]string
|
||||
Slice *[]string
|
||||
MapPtr **map[string]string
|
||||
SlicePtr **[]string
|
||||
Struct *Ttest
|
||||
StructPtr **Ttest
|
||||
}
|
114
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/pointer/zz_generated.deepcopy.go
generated
Normal file
114
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/pointer/zz_generated.deepcopy.go
generated
Normal file
@ -0,0 +1,114 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package pointer
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Ttest) DeepCopyInto(out *Ttest) {
|
||||
*out = *in
|
||||
if in.Builtin != nil {
|
||||
in, out := &in.Builtin, &out.Builtin
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Ptr != nil {
|
||||
in, out := &in.Ptr, &out.Ptr
|
||||
*out = new(*string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
if in.Map != nil {
|
||||
in, out := &in.Map, &out.Map
|
||||
*out = new(map[string]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.Slice != nil {
|
||||
in, out := &in.Slice, &out.Slice
|
||||
*out = new([]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
if in.MapPtr != nil {
|
||||
in, out := &in.MapPtr, &out.MapPtr
|
||||
*out = new(*map[string]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = new(map[string]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.SlicePtr != nil {
|
||||
in, out := &in.SlicePtr, &out.SlicePtr
|
||||
*out = new(*[]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = new([]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.Struct != nil {
|
||||
in, out := &in.Struct, &out.Struct
|
||||
*out = new(Ttest)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.StructPtr != nil {
|
||||
in, out := &in.StructPtr, &out.StructPtr
|
||||
*out = new(*Ttest)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = new(Ttest)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
|
||||
func (in *Ttest) DeepCopy() *Ttest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Ttest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package outputtests
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// ReflectDeepCopy deep copies the object using reflection.
|
||||
func ReflectDeepCopy(in interface{}) interface{} {
|
||||
return reflectDeepCopy(reflect.ValueOf(in)).Interface()
|
||||
}
|
||||
|
||||
func reflectDeepCopy(src reflect.Value) reflect.Value {
|
||||
switch src.Kind() {
|
||||
case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
|
||||
if src.IsNil() {
|
||||
return src
|
||||
}
|
||||
}
|
||||
|
||||
switch src.Kind() {
|
||||
case reflect.Chan, reflect.Func, reflect.UnsafePointer, reflect.Uintptr:
|
||||
panic(fmt.Sprintf("cannot deep copy kind: %s", src.Kind()))
|
||||
case reflect.Array:
|
||||
dst := reflect.New(src.Type())
|
||||
for i := 0; i < src.Len(); i++ {
|
||||
dst.Elem().Index(i).Set(reflectDeepCopy(src.Index(i)))
|
||||
}
|
||||
return dst.Elem()
|
||||
case reflect.Interface:
|
||||
return reflectDeepCopy(src.Elem())
|
||||
case reflect.Map:
|
||||
dst := reflect.MakeMap(src.Type())
|
||||
for _, k := range src.MapKeys() {
|
||||
dst.SetMapIndex(k, reflectDeepCopy(src.MapIndex(k)))
|
||||
}
|
||||
return dst
|
||||
case reflect.Ptr:
|
||||
dst := reflect.New(src.Type().Elem())
|
||||
dst.Elem().Set(reflectDeepCopy(src.Elem()))
|
||||
return dst
|
||||
case reflect.Slice:
|
||||
dst := reflect.MakeSlice(src.Type(), 0, src.Len())
|
||||
for i := 0; i < src.Len(); i++ {
|
||||
dst = reflect.Append(dst, reflectDeepCopy(src.Index(i)))
|
||||
}
|
||||
return dst
|
||||
case reflect.Struct:
|
||||
dst := reflect.New(src.Type())
|
||||
for i := 0; i < src.NumField(); i++ {
|
||||
if !dst.Elem().Field(i).CanSet() {
|
||||
// Can't set private fields. At this point, the
|
||||
// best we can do is a shallow copy. For
|
||||
// example, time.Time is a value type with
|
||||
// private members that can be shallow copied.
|
||||
return src
|
||||
}
|
||||
dst.Elem().Field(i).Set(reflectDeepCopy(src.Field(i)))
|
||||
}
|
||||
return dst.Elem()
|
||||
default:
|
||||
// Value types like numbers, booleans, and strings.
|
||||
return src
|
||||
}
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package slices
|
||||
|
||||
type Ttest struct {
|
||||
Byte []byte
|
||||
// Int8 []int8 //TODO: int8 becomes byte in SnippetWriter
|
||||
Int16 []int16
|
||||
Int32 []int32
|
||||
Int64 []int64
|
||||
Uint8 []uint8
|
||||
Uint16 []uint16
|
||||
Uint32 []uint32
|
||||
Uint64 []uint64
|
||||
Float32 []float32
|
||||
Float64 []float64
|
||||
String []string
|
||||
StringPtr []*string
|
||||
StringPtrPtr []**string
|
||||
Map []map[string]string
|
||||
MapPtr []*map[string]string
|
||||
Slice [][]string
|
||||
SlicePtr []*[]string
|
||||
Struct []Ttest
|
||||
StructPtr []*Ttest
|
||||
}
|
193
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/slices/zz_generated.deepcopy.go
generated
Normal file
193
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/slices/zz_generated.deepcopy.go
generated
Normal file
@ -0,0 +1,193 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package slices
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Ttest) DeepCopyInto(out *Ttest) {
|
||||
*out = *in
|
||||
if in.Byte != nil {
|
||||
in, out := &in.Byte, &out.Byte
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Int16 != nil {
|
||||
in, out := &in.Int16, &out.Int16
|
||||
*out = make([]int16, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Int32 != nil {
|
||||
in, out := &in.Int32, &out.Int32
|
||||
*out = make([]int32, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Int64 != nil {
|
||||
in, out := &in.Int64, &out.Int64
|
||||
*out = make([]int64, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Uint8 != nil {
|
||||
in, out := &in.Uint8, &out.Uint8
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Uint16 != nil {
|
||||
in, out := &in.Uint16, &out.Uint16
|
||||
*out = make([]uint16, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Uint32 != nil {
|
||||
in, out := &in.Uint32, &out.Uint32
|
||||
*out = make([]uint32, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Uint64 != nil {
|
||||
in, out := &in.Uint64, &out.Uint64
|
||||
*out = make([]uint64, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Float32 != nil {
|
||||
in, out := &in.Float32, &out.Float32
|
||||
*out = make([]float32, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Float64 != nil {
|
||||
in, out := &in.Float64, &out.Float64
|
||||
*out = make([]float64, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.String != nil {
|
||||
in, out := &in.String, &out.String
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.StringPtr != nil {
|
||||
in, out := &in.StringPtr, &out.StringPtr
|
||||
*out = make([]*string, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.StringPtrPtr != nil {
|
||||
in, out := &in.StringPtrPtr, &out.StringPtrPtr
|
||||
*out = make([]**string, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(*string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.Map != nil {
|
||||
in, out := &in.Map, &out.Map
|
||||
*out = make([]map[string]string, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.MapPtr != nil {
|
||||
in, out := &in.MapPtr, &out.MapPtr
|
||||
*out = make([]*map[string]string, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(map[string]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.Slice != nil {
|
||||
in, out := &in.Slice, &out.Slice
|
||||
*out = make([][]string, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.SlicePtr != nil {
|
||||
in, out := &in.SlicePtr, &out.SlicePtr
|
||||
*out = make([]*[]string, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new([]string)
|
||||
if **in != nil {
|
||||
in, out := *in, *out
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.Struct != nil {
|
||||
in, out := &in.Struct, &out.Struct
|
||||
*out = make([]Ttest, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.StructPtr != nil {
|
||||
in, out := &in.StructPtr, &out.StructPtr
|
||||
*out = make([]*Ttest, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = new(Ttest)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
|
||||
func (in *Ttest) DeepCopy() *Ttest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Ttest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package structs
|
||||
|
||||
type Inner struct {
|
||||
Byte byte
|
||||
// Int8 int8 //TODO: int8 becomes byte in SnippetWriter
|
||||
Int16 int16
|
||||
Int32 int32
|
||||
Int64 int64
|
||||
Uint8 uint8
|
||||
Uint16 uint16
|
||||
Uint32 uint32
|
||||
Uint64 uint64
|
||||
Float32 float32
|
||||
Float64 float64
|
||||
String string
|
||||
}
|
||||
|
||||
type Ttest struct {
|
||||
Inner1 Inner
|
||||
Inner2 Inner
|
||||
}
|
56
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/structs/zz_generated.deepcopy.go
generated
Normal file
56
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/structs/zz_generated.deepcopy.go
generated
Normal file
@ -0,0 +1,56 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package structs
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Inner) DeepCopyInto(out *Inner) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Inner.
|
||||
func (in *Inner) DeepCopy() *Inner {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Inner)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Ttest) DeepCopyInto(out *Ttest) {
|
||||
*out = *in
|
||||
out.Inner1 = in.Inner1
|
||||
out.Inner2 = in.Inner2
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ttest.
|
||||
func (in *Ttest) DeepCopy() *Ttest {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Ttest)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
@ -0,0 +1,86 @@
|
||||
/*
|
||||
Copyright 2018 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package outputtests
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// ValueFuzz recursively changes all basic type values in an object. Any kind of references will not
|
||||
// be touched, i.e. the addresses of slices, maps, pointers will stay unchanged.
|
||||
func ValueFuzz(obj interface{}) {
|
||||
valueFuzz(reflect.ValueOf(obj))
|
||||
}
|
||||
|
||||
func valueFuzz(obj reflect.Value) {
|
||||
switch obj.Kind() {
|
||||
case reflect.Array:
|
||||
for i := 0; i < obj.Len(); i++ {
|
||||
valueFuzz(obj.Index(i))
|
||||
}
|
||||
case reflect.Slice:
|
||||
if obj.IsNil() {
|
||||
// TODO: set non-nil value
|
||||
} else {
|
||||
for i := 0; i < obj.Len(); i++ {
|
||||
valueFuzz(obj.Index(i))
|
||||
}
|
||||
}
|
||||
case reflect.Interface, reflect.Ptr:
|
||||
if obj.IsNil() {
|
||||
// TODO: set non-nil value
|
||||
} else {
|
||||
valueFuzz(obj.Elem())
|
||||
}
|
||||
case reflect.Struct:
|
||||
for i, n := 0, obj.NumField(); i < n; i++ {
|
||||
valueFuzz(obj.Field(i))
|
||||
}
|
||||
case reflect.Map:
|
||||
if obj.IsNil() {
|
||||
// TODO: set non-nil value
|
||||
} else {
|
||||
for _, k := range obj.MapKeys() {
|
||||
// map values are not addressable. We need a copy.
|
||||
v := obj.MapIndex(k)
|
||||
copy := reflect.New(v.Type())
|
||||
copy.Elem().Set(v)
|
||||
valueFuzz(copy.Elem())
|
||||
obj.SetMapIndex(k, copy.Elem())
|
||||
}
|
||||
// TODO: set some new value
|
||||
}
|
||||
case reflect.Func: // ignore, we don't have function types in our API
|
||||
default:
|
||||
if !obj.CanSet() {
|
||||
return
|
||||
}
|
||||
switch obj.Kind() {
|
||||
case reflect.String:
|
||||
obj.SetString(obj.String() + "x")
|
||||
case reflect.Bool:
|
||||
obj.SetBool(!obj.Bool())
|
||||
case reflect.Float32, reflect.Float64:
|
||||
obj.SetFloat(obj.Float()*2.0 + 1.0)
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||
obj.SetInt(obj.Int() + 1)
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||
obj.SetUint(obj.Uint() + 1)
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package wholepkg
|
||||
|
||||
import "k8s.io/code-generator/cmd/deepcopy-gen/output_tests/otherpkg"
|
||||
|
||||
// Trivial
|
||||
type StructEmpty struct{}
|
||||
|
||||
// Only primitives
|
||||
type StructPrimitives struct {
|
||||
BoolField bool
|
||||
IntField int
|
||||
StringField string
|
||||
FloatField float64
|
||||
}
|
||||
type StructPrimitivesAlias StructPrimitives
|
||||
type StructEmbedStructPrimitives struct {
|
||||
StructPrimitives
|
||||
}
|
||||
type StructEmbedInt struct {
|
||||
int //nolint:unused
|
||||
}
|
||||
type StructStructPrimitives struct {
|
||||
StructField StructPrimitives
|
||||
}
|
||||
|
||||
// Manual DeepCopy method
|
||||
type ManualStruct struct {
|
||||
StringField string
|
||||
}
|
||||
|
||||
func (m ManualStruct) DeepCopy() ManualStruct {
|
||||
return m
|
||||
}
|
||||
|
||||
type ManualStructAlias ManualStruct
|
||||
|
||||
type StructEmbedManualStruct struct {
|
||||
ManualStruct
|
||||
}
|
||||
|
||||
// Only pointers to primitives
|
||||
type StructPrimitivePointers struct {
|
||||
BoolPtrField *bool
|
||||
IntPtrField *int
|
||||
StringPtrField *string
|
||||
FloatPtrField *float64
|
||||
}
|
||||
type StructPrimitivePointersAlias StructPrimitivePointers
|
||||
type StructEmbedStructPrimitivePointers struct {
|
||||
StructPrimitivePointers
|
||||
}
|
||||
type StructEmbedPointer struct {
|
||||
*int
|
||||
}
|
||||
type StructStructPrimitivePointers struct {
|
||||
StructField StructPrimitivePointers
|
||||
}
|
||||
|
||||
// Manual DeepCopy method
|
||||
type ManualSlice []string
|
||||
|
||||
func (m ManualSlice) DeepCopy() ManualSlice {
|
||||
r := make(ManualSlice, len(m))
|
||||
copy(r, m)
|
||||
return r
|
||||
}
|
||||
|
||||
// Slices
|
||||
type StructSlices struct {
|
||||
SliceBoolField []bool
|
||||
SliceByteField []byte
|
||||
SliceIntField []int
|
||||
SliceStringField []string
|
||||
SliceFloatField []float64
|
||||
SliceStructPrimitivesField []StructPrimitives
|
||||
SliceStructPrimitivesAliasField []StructPrimitivesAlias
|
||||
SliceStructPrimitivePointersField []StructPrimitivePointers
|
||||
SliceStructPrimitivePointersAliasField []StructPrimitivePointersAlias
|
||||
SliceSliceIntField [][]int
|
||||
SliceManualStructField []ManualStruct
|
||||
ManualSliceField ManualSlice
|
||||
}
|
||||
type StructSlicesAlias StructSlices
|
||||
type StructEmbedStructSlices struct {
|
||||
StructSlices
|
||||
}
|
||||
type StructStructSlices struct {
|
||||
StructField StructSlices
|
||||
}
|
||||
|
||||
// Everything
|
||||
type StructEverything struct {
|
||||
BoolField bool
|
||||
IntField int
|
||||
StringField string
|
||||
FloatField float64
|
||||
StructField StructPrimitives
|
||||
EmptyStructField StructEmpty
|
||||
ManualStructField ManualStruct
|
||||
ManualStructAliasField ManualStructAlias
|
||||
BoolPtrField *bool
|
||||
IntPtrField *int
|
||||
StringPtrField *string
|
||||
FloatPtrField *float64
|
||||
PrimitivePointersField StructPrimitivePointers
|
||||
ManualStructPtrField *ManualStruct
|
||||
ManualStructAliasPtrField *ManualStructAlias
|
||||
SliceBoolField []bool
|
||||
SliceByteField []byte
|
||||
SliceIntField []int
|
||||
SliceStringField []string
|
||||
SliceFloatField []float64
|
||||
SlicesField StructSlices
|
||||
SliceManualStructField []ManualStruct
|
||||
ManualSliceField ManualSlice
|
||||
}
|
||||
|
||||
// An Object
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/code-generator/cmd/deepcopy-gen/output_tests/otherpkg.Object
|
||||
type StructExplicitObject struct {
|
||||
x int //nolint:unused
|
||||
}
|
||||
|
||||
// An Object which is used a non-pointer
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/code-generator/cmd/deepcopy-gen/output_tests/otherpkg.Object
|
||||
// +k8s:deepcopy-gen:nonpointer-interfaces=true
|
||||
type StructNonPointerExplicitObject struct {
|
||||
x int //nolint:unused
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen=false
|
||||
type StructTypeMeta struct {
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/code-generator/cmd/deepcopy-gen/output_tests/otherpkg.Object
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/code-generator/cmd/deepcopy-gen/output_tests/otherpkg.List
|
||||
type StructObjectAndList struct {
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/code-generator/cmd/deepcopy-gen/output_tests/otherpkg.Object
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/code-generator/cmd/deepcopy-gen/output_tests/otherpkg.Object
|
||||
type StructObjectAndObject struct {
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/code-generator/cmd/deepcopy-gen/output_tests/wholepkg.Selector
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/code-generator/cmd/deepcopy-gen/output_tests/otherpkg.Object
|
||||
type StructExplicitSelectorExplicitObject struct {
|
||||
StructTypeMeta
|
||||
}
|
||||
|
||||
type StructInterfaces struct {
|
||||
ObjectField otherpkg.Object
|
||||
NilObjectField otherpkg.Object
|
||||
SelectorField Selector
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package wholepkg
|
||||
|
||||
// Another type in another file.
|
||||
type StructB struct{}
|
@ -0,0 +1,145 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package wholepkg
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
fuzz "github.com/google/gofuzz"
|
||||
)
|
||||
|
||||
func TestDeepCopyPrimitives(t *testing.T) {
|
||||
x := StructPrimitives{}
|
||||
y := StructPrimitives{}
|
||||
|
||||
if !reflect.DeepEqual(&x, &y) {
|
||||
t.Errorf("objects should be equal to start, but are not")
|
||||
}
|
||||
|
||||
fuzzer := fuzz.New()
|
||||
fuzzer.Fuzz(&x)
|
||||
fuzzer.Fuzz(&y)
|
||||
|
||||
if reflect.DeepEqual(&x, &y) {
|
||||
t.Errorf("objects should not be equal, but are")
|
||||
}
|
||||
|
||||
x.DeepCopyInto(&y)
|
||||
if !reflect.DeepEqual(&x, &y) {
|
||||
t.Errorf("objects should be equal, but are not")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeepCopyInterfaceFields(t *testing.T) {
|
||||
x := StructInterfaces{}
|
||||
y := StructInterfaces{}
|
||||
|
||||
if !reflect.DeepEqual(&x, &y) {
|
||||
t.Errorf("objects should be equal to start, but are not")
|
||||
}
|
||||
|
||||
fuzzer := fuzz.New()
|
||||
|
||||
obj := StructExplicitObject{}
|
||||
fuzzer.Fuzz(&obj)
|
||||
x.ObjectField = &obj
|
||||
|
||||
sel := StructExplicitSelectorExplicitObject{}
|
||||
fuzzer.Fuzz(&sel)
|
||||
x.SelectorField = &sel
|
||||
|
||||
if reflect.DeepEqual(&x, &y) {
|
||||
t.Errorf("objects should not be equal, but are")
|
||||
}
|
||||
|
||||
x.DeepCopyInto(&y)
|
||||
if !reflect.DeepEqual(&x, &y) {
|
||||
t.Errorf("objects should be equal, but are not")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNilCopy(t *testing.T) {
|
||||
var x *StructB
|
||||
y := x.DeepCopy()
|
||||
if y != nil {
|
||||
t.Errorf("Expected nil as deepcopy of nil, got %+v", y)
|
||||
}
|
||||
}
|
||||
|
||||
func assertMethod(t *testing.T, typ reflect.Type, name string) {
|
||||
if _, found := typ.MethodByName(name); !found {
|
||||
t.Errorf("StructExplicitObject must have %v method", name)
|
||||
}
|
||||
}
|
||||
|
||||
func assertNotMethod(t *testing.T, typ reflect.Type, name string) {
|
||||
if _, found := typ.MethodByName(name); found {
|
||||
t.Errorf("%v must not have %v method", typ, name)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterfaceTypes(t *testing.T) {
|
||||
explicitObject := reflect.TypeOf(&StructExplicitObject{})
|
||||
assertMethod(t, explicitObject, "DeepCopyObject")
|
||||
|
||||
typeMeta := reflect.TypeOf(&StructTypeMeta{})
|
||||
assertNotMethod(t, typeMeta, "DeepCopy")
|
||||
|
||||
objectAndList := reflect.TypeOf(&StructObjectAndList{})
|
||||
assertMethod(t, objectAndList, "DeepCopyObject")
|
||||
assertMethod(t, objectAndList, "DeepCopyList")
|
||||
|
||||
objectAndObject := reflect.TypeOf(&StructObjectAndObject{})
|
||||
assertMethod(t, objectAndObject, "DeepCopyObject")
|
||||
|
||||
explicitSelectorExplicitObject := reflect.TypeOf(&StructExplicitSelectorExplicitObject{})
|
||||
assertMethod(t, explicitSelectorExplicitObject, "DeepCopySelector")
|
||||
assertMethod(t, explicitSelectorExplicitObject, "DeepCopyObject")
|
||||
}
|
||||
|
||||
func TestInterfaceDeepCopy(t *testing.T) {
|
||||
x := StructExplicitObject{}
|
||||
|
||||
fuzzer := fuzz.New()
|
||||
fuzzer.Fuzz(&x)
|
||||
|
||||
yObj := x.DeepCopyObject()
|
||||
y, ok := yObj.(*StructExplicitObject)
|
||||
if !ok {
|
||||
t.Fatalf("epxected StructExplicitObject from StructExplicitObject.DeepCopyObject, got: %t", yObj)
|
||||
}
|
||||
if !reflect.DeepEqual(y, &x) {
|
||||
t.Error("objects should be equal, but are not")
|
||||
}
|
||||
}
|
||||
|
||||
func TestInterfaceNonPointerDeepCopy(t *testing.T) {
|
||||
x := StructNonPointerExplicitObject{}
|
||||
|
||||
fuzzer := fuzz.New()
|
||||
fuzzer.Fuzz(&x)
|
||||
|
||||
yObj := x.DeepCopyObject()
|
||||
y, ok := yObj.(StructNonPointerExplicitObject)
|
||||
if !ok {
|
||||
t.Fatalf("epxected StructNonPointerExplicitObject from StructNonPointerExplicitObject.DeepCopyObject, got: %t", yObj)
|
||||
}
|
||||
if !reflect.DeepEqual(y, x) {
|
||||
t.Error("objects should be equal, but are not")
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// This is a test package.
|
||||
package wholepkg
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package wholepkg
|
||||
|
||||
type Selector interface {
|
||||
DeepCopySelector() Selector
|
||||
}
|
761
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/wholepkg/zz_generated.deepcopy.go
generated
Normal file
761
staging/src/k8s.io/code-generator/cmd/deepcopy-gen/output_tests/wholepkg/zz_generated.deepcopy.go
generated
Normal file
@ -0,0 +1,761 @@
|
||||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package wholepkg
|
||||
|
||||
import (
|
||||
otherpkg "k8s.io/code-generator/cmd/deepcopy-gen/output_tests/otherpkg"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in ManualSlice) DeepCopyInto(out *ManualSlice) {
|
||||
{
|
||||
in := &in
|
||||
*out = in.DeepCopy()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ManualStruct) DeepCopyInto(out *ManualStruct) {
|
||||
*out = in.DeepCopy()
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ManualStructAlias) DeepCopyInto(out *ManualStructAlias) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ManualStructAlias.
|
||||
func (in *ManualStructAlias) DeepCopy() *ManualStructAlias {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ManualStructAlias)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructB) DeepCopyInto(out *StructB) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructB.
|
||||
func (in *StructB) DeepCopy() *StructB {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructB)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructEmbedInt) DeepCopyInto(out *StructEmbedInt) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructEmbedInt.
|
||||
func (in *StructEmbedInt) DeepCopy() *StructEmbedInt {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructEmbedInt)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructEmbedManualStruct) DeepCopyInto(out *StructEmbedManualStruct) {
|
||||
*out = *in
|
||||
out.ManualStruct = in.ManualStruct.DeepCopy()
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructEmbedManualStruct.
|
||||
func (in *StructEmbedManualStruct) DeepCopy() *StructEmbedManualStruct {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructEmbedManualStruct)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructEmbedPointer) DeepCopyInto(out *StructEmbedPointer) {
|
||||
*out = *in
|
||||
if in.int != nil {
|
||||
in, out := &in.int, &out.int
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructEmbedPointer.
|
||||
func (in *StructEmbedPointer) DeepCopy() *StructEmbedPointer {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructEmbedPointer)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructEmbedStructPrimitivePointers) DeepCopyInto(out *StructEmbedStructPrimitivePointers) {
|
||||
*out = *in
|
||||
in.StructPrimitivePointers.DeepCopyInto(&out.StructPrimitivePointers)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructEmbedStructPrimitivePointers.
|
||||
func (in *StructEmbedStructPrimitivePointers) DeepCopy() *StructEmbedStructPrimitivePointers {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructEmbedStructPrimitivePointers)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructEmbedStructPrimitives) DeepCopyInto(out *StructEmbedStructPrimitives) {
|
||||
*out = *in
|
||||
out.StructPrimitives = in.StructPrimitives
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructEmbedStructPrimitives.
|
||||
func (in *StructEmbedStructPrimitives) DeepCopy() *StructEmbedStructPrimitives {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructEmbedStructPrimitives)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructEmbedStructSlices) DeepCopyInto(out *StructEmbedStructSlices) {
|
||||
*out = *in
|
||||
in.StructSlices.DeepCopyInto(&out.StructSlices)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructEmbedStructSlices.
|
||||
func (in *StructEmbedStructSlices) DeepCopy() *StructEmbedStructSlices {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructEmbedStructSlices)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructEmpty) DeepCopyInto(out *StructEmpty) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructEmpty.
|
||||
func (in *StructEmpty) DeepCopy() *StructEmpty {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructEmpty)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructEverything) DeepCopyInto(out *StructEverything) {
|
||||
*out = *in
|
||||
out.StructField = in.StructField
|
||||
out.EmptyStructField = in.EmptyStructField
|
||||
out.ManualStructField = in.ManualStructField.DeepCopy()
|
||||
out.ManualStructAliasField = in.ManualStructAliasField
|
||||
if in.BoolPtrField != nil {
|
||||
in, out := &in.BoolPtrField, &out.BoolPtrField
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.IntPtrField != nil {
|
||||
in, out := &in.IntPtrField, &out.IntPtrField
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.StringPtrField != nil {
|
||||
in, out := &in.StringPtrField, &out.StringPtrField
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.FloatPtrField != nil {
|
||||
in, out := &in.FloatPtrField, &out.FloatPtrField
|
||||
*out = new(float64)
|
||||
**out = **in
|
||||
}
|
||||
in.PrimitivePointersField.DeepCopyInto(&out.PrimitivePointersField)
|
||||
if in.ManualStructPtrField != nil {
|
||||
in, out := &in.ManualStructPtrField, &out.ManualStructPtrField
|
||||
x := (*in).DeepCopy()
|
||||
*out = &x
|
||||
}
|
||||
if in.ManualStructAliasPtrField != nil {
|
||||
in, out := &in.ManualStructAliasPtrField, &out.ManualStructAliasPtrField
|
||||
*out = new(ManualStructAlias)
|
||||
**out = **in
|
||||
}
|
||||
if in.SliceBoolField != nil {
|
||||
in, out := &in.SliceBoolField, &out.SliceBoolField
|
||||
*out = make([]bool, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceByteField != nil {
|
||||
in, out := &in.SliceByteField, &out.SliceByteField
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceIntField != nil {
|
||||
in, out := &in.SliceIntField, &out.SliceIntField
|
||||
*out = make([]int, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStringField != nil {
|
||||
in, out := &in.SliceStringField, &out.SliceStringField
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceFloatField != nil {
|
||||
in, out := &in.SliceFloatField, &out.SliceFloatField
|
||||
*out = make([]float64, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
in.SlicesField.DeepCopyInto(&out.SlicesField)
|
||||
if in.SliceManualStructField != nil {
|
||||
in, out := &in.SliceManualStructField, &out.SliceManualStructField
|
||||
*out = make([]ManualStruct, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
out.ManualSliceField = in.ManualSliceField.DeepCopy()
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructEverything.
|
||||
func (in *StructEverything) DeepCopy() *StructEverything {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructEverything)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructExplicitObject) DeepCopyInto(out *StructExplicitObject) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructExplicitObject.
|
||||
func (in *StructExplicitObject) DeepCopy() *StructExplicitObject {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructExplicitObject)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new otherpkg.Object.
|
||||
func (in *StructExplicitObject) DeepCopyObject() otherpkg.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructExplicitSelectorExplicitObject) DeepCopyInto(out *StructExplicitSelectorExplicitObject) {
|
||||
*out = *in
|
||||
out.StructTypeMeta = in.StructTypeMeta
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructExplicitSelectorExplicitObject.
|
||||
func (in *StructExplicitSelectorExplicitObject) DeepCopy() *StructExplicitSelectorExplicitObject {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructExplicitSelectorExplicitObject)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new otherpkg.Object.
|
||||
func (in *StructExplicitSelectorExplicitObject) DeepCopyObject() otherpkg.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopySelector is an autogenerated deepcopy function, copying the receiver, creating a new Selector.
|
||||
func (in *StructExplicitSelectorExplicitObject) DeepCopySelector() Selector {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructInterfaces) DeepCopyInto(out *StructInterfaces) {
|
||||
*out = *in
|
||||
if in.ObjectField != nil {
|
||||
out.ObjectField = in.ObjectField.DeepCopyObject()
|
||||
}
|
||||
if in.NilObjectField != nil {
|
||||
out.NilObjectField = in.NilObjectField.DeepCopyObject()
|
||||
}
|
||||
if in.SelectorField != nil {
|
||||
out.SelectorField = in.SelectorField.DeepCopySelector()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructInterfaces.
|
||||
func (in *StructInterfaces) DeepCopy() *StructInterfaces {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructInterfaces)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructNonPointerExplicitObject) DeepCopyInto(out *StructNonPointerExplicitObject) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructNonPointerExplicitObject.
|
||||
func (in *StructNonPointerExplicitObject) DeepCopy() *StructNonPointerExplicitObject {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructNonPointerExplicitObject)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new otherpkg.Object.
|
||||
func (in StructNonPointerExplicitObject) DeepCopyObject() otherpkg.Object {
|
||||
return *in.DeepCopy()
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructObjectAndList) DeepCopyInto(out *StructObjectAndList) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructObjectAndList.
|
||||
func (in *StructObjectAndList) DeepCopy() *StructObjectAndList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructObjectAndList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyList is an autogenerated deepcopy function, copying the receiver, creating a new otherpkg.List.
|
||||
func (in *StructObjectAndList) DeepCopyList() otherpkg.List {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new otherpkg.Object.
|
||||
func (in *StructObjectAndList) DeepCopyObject() otherpkg.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructObjectAndObject) DeepCopyInto(out *StructObjectAndObject) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructObjectAndObject.
|
||||
func (in *StructObjectAndObject) DeepCopy() *StructObjectAndObject {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructObjectAndObject)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new otherpkg.Object.
|
||||
func (in *StructObjectAndObject) DeepCopyObject() otherpkg.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructPrimitivePointers) DeepCopyInto(out *StructPrimitivePointers) {
|
||||
*out = *in
|
||||
if in.BoolPtrField != nil {
|
||||
in, out := &in.BoolPtrField, &out.BoolPtrField
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.IntPtrField != nil {
|
||||
in, out := &in.IntPtrField, &out.IntPtrField
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.StringPtrField != nil {
|
||||
in, out := &in.StringPtrField, &out.StringPtrField
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.FloatPtrField != nil {
|
||||
in, out := &in.FloatPtrField, &out.FloatPtrField
|
||||
*out = new(float64)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructPrimitivePointers.
|
||||
func (in *StructPrimitivePointers) DeepCopy() *StructPrimitivePointers {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructPrimitivePointers)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructPrimitivePointersAlias) DeepCopyInto(out *StructPrimitivePointersAlias) {
|
||||
*out = *in
|
||||
if in.BoolPtrField != nil {
|
||||
in, out := &in.BoolPtrField, &out.BoolPtrField
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.IntPtrField != nil {
|
||||
in, out := &in.IntPtrField, &out.IntPtrField
|
||||
*out = new(int)
|
||||
**out = **in
|
||||
}
|
||||
if in.StringPtrField != nil {
|
||||
in, out := &in.StringPtrField, &out.StringPtrField
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.FloatPtrField != nil {
|
||||
in, out := &in.FloatPtrField, &out.FloatPtrField
|
||||
*out = new(float64)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructPrimitivePointersAlias.
|
||||
func (in *StructPrimitivePointersAlias) DeepCopy() *StructPrimitivePointersAlias {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructPrimitivePointersAlias)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructPrimitives) DeepCopyInto(out *StructPrimitives) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructPrimitives.
|
||||
func (in *StructPrimitives) DeepCopy() *StructPrimitives {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructPrimitives)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructPrimitivesAlias) DeepCopyInto(out *StructPrimitivesAlias) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructPrimitivesAlias.
|
||||
func (in *StructPrimitivesAlias) DeepCopy() *StructPrimitivesAlias {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructPrimitivesAlias)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructSlices) DeepCopyInto(out *StructSlices) {
|
||||
*out = *in
|
||||
if in.SliceBoolField != nil {
|
||||
in, out := &in.SliceBoolField, &out.SliceBoolField
|
||||
*out = make([]bool, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceByteField != nil {
|
||||
in, out := &in.SliceByteField, &out.SliceByteField
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceIntField != nil {
|
||||
in, out := &in.SliceIntField, &out.SliceIntField
|
||||
*out = make([]int, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStringField != nil {
|
||||
in, out := &in.SliceStringField, &out.SliceStringField
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceFloatField != nil {
|
||||
in, out := &in.SliceFloatField, &out.SliceFloatField
|
||||
*out = make([]float64, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStructPrimitivesField != nil {
|
||||
in, out := &in.SliceStructPrimitivesField, &out.SliceStructPrimitivesField
|
||||
*out = make([]StructPrimitives, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStructPrimitivesAliasField != nil {
|
||||
in, out := &in.SliceStructPrimitivesAliasField, &out.SliceStructPrimitivesAliasField
|
||||
*out = make([]StructPrimitivesAlias, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStructPrimitivePointersField != nil {
|
||||
in, out := &in.SliceStructPrimitivePointersField, &out.SliceStructPrimitivePointersField
|
||||
*out = make([]StructPrimitivePointers, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.SliceStructPrimitivePointersAliasField != nil {
|
||||
in, out := &in.SliceStructPrimitivePointersAliasField, &out.SliceStructPrimitivePointersAliasField
|
||||
*out = make([]StructPrimitivePointersAlias, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.SliceSliceIntField != nil {
|
||||
in, out := &in.SliceSliceIntField, &out.SliceSliceIntField
|
||||
*out = make([][]int, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = make([]int, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.SliceManualStructField != nil {
|
||||
in, out := &in.SliceManualStructField, &out.SliceManualStructField
|
||||
*out = make([]ManualStruct, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
out.ManualSliceField = in.ManualSliceField.DeepCopy()
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructSlices.
|
||||
func (in *StructSlices) DeepCopy() *StructSlices {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructSlices)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructSlicesAlias) DeepCopyInto(out *StructSlicesAlias) {
|
||||
*out = *in
|
||||
if in.SliceBoolField != nil {
|
||||
in, out := &in.SliceBoolField, &out.SliceBoolField
|
||||
*out = make([]bool, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceByteField != nil {
|
||||
in, out := &in.SliceByteField, &out.SliceByteField
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceIntField != nil {
|
||||
in, out := &in.SliceIntField, &out.SliceIntField
|
||||
*out = make([]int, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStringField != nil {
|
||||
in, out := &in.SliceStringField, &out.SliceStringField
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceFloatField != nil {
|
||||
in, out := &in.SliceFloatField, &out.SliceFloatField
|
||||
*out = make([]float64, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStructPrimitivesField != nil {
|
||||
in, out := &in.SliceStructPrimitivesField, &out.SliceStructPrimitivesField
|
||||
*out = make([]StructPrimitives, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStructPrimitivesAliasField != nil {
|
||||
in, out := &in.SliceStructPrimitivesAliasField, &out.SliceStructPrimitivesAliasField
|
||||
*out = make([]StructPrimitivesAlias, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SliceStructPrimitivePointersField != nil {
|
||||
in, out := &in.SliceStructPrimitivePointersField, &out.SliceStructPrimitivePointersField
|
||||
*out = make([]StructPrimitivePointers, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.SliceStructPrimitivePointersAliasField != nil {
|
||||
in, out := &in.SliceStructPrimitivePointersAliasField, &out.SliceStructPrimitivePointersAliasField
|
||||
*out = make([]StructPrimitivePointersAlias, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.SliceSliceIntField != nil {
|
||||
in, out := &in.SliceSliceIntField, &out.SliceSliceIntField
|
||||
*out = make([][]int, len(*in))
|
||||
for i := range *in {
|
||||
if (*in)[i] != nil {
|
||||
in, out := &(*in)[i], &(*out)[i]
|
||||
*out = make([]int, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
}
|
||||
}
|
||||
if in.SliceManualStructField != nil {
|
||||
in, out := &in.SliceManualStructField, &out.SliceManualStructField
|
||||
*out = make([]ManualStruct, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
out.ManualSliceField = in.ManualSliceField.DeepCopy()
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructSlicesAlias.
|
||||
func (in *StructSlicesAlias) DeepCopy() *StructSlicesAlias {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructSlicesAlias)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructStructPrimitivePointers) DeepCopyInto(out *StructStructPrimitivePointers) {
|
||||
*out = *in
|
||||
in.StructField.DeepCopyInto(&out.StructField)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructStructPrimitivePointers.
|
||||
func (in *StructStructPrimitivePointers) DeepCopy() *StructStructPrimitivePointers {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructStructPrimitivePointers)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructStructPrimitives) DeepCopyInto(out *StructStructPrimitives) {
|
||||
*out = *in
|
||||
out.StructField = in.StructField
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructStructPrimitives.
|
||||
func (in *StructStructPrimitives) DeepCopy() *StructStructPrimitives {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructStructPrimitives)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StructStructSlices) DeepCopyInto(out *StructStructSlices) {
|
||||
*out = *in
|
||||
in.StructField.DeepCopyInto(&out.StructField)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StructStructSlices.
|
||||
func (in *StructStructSlices) DeepCopy() *StructStructSlices {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StructStructSlices)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
Loading…
Reference in New Issue
Block a user