Merge pull request #12556 from uluyol/copynilinterface

Properly handle nil interfaces in DeepCopy.
This commit is contained in:
Piotr Szczesniak 2015-08-12 09:54:02 +02:00
commit eb01d49783
4 changed files with 23 additions and 0 deletions

View File

@ -737,6 +737,8 @@ func deepCopy_api_List(in List, out *List, c *conversion.Cloner) error {
for i := range in.Items {
if newVal, err := c.DeepCopy(in.Items[i]); err != nil {
return err
} else if newVal == nil {
out.Items[i] = nil
} else {
out.Items[i] = newVal.(runtime.Object)
}
@ -759,11 +761,15 @@ func deepCopy_api_ListOptions(in ListOptions, out *ListOptions, c *conversion.Cl
}
if newVal, err := c.DeepCopy(in.LabelSelector); err != nil {
return err
} else if newVal == nil {
out.LabelSelector = nil
} else {
out.LabelSelector = newVal.(labels.Selector)
}
if newVal, err := c.DeepCopy(in.FieldSelector); err != nil {
return err
} else if newVal == nil {
out.FieldSelector = nil
} else {
out.FieldSelector = newVal.(fields.Selector)
}
@ -2125,6 +2131,8 @@ func deepCopy_resource_Quantity(in resource.Quantity, out *resource.Quantity, c
if in.Amount != nil {
if newVal, err := c.DeepCopy(in.Amount); err != nil {
return err
} else if newVal == nil {
out.Amount = nil
} else {
out.Amount = newVal.(*inf.Dec)
}

View File

@ -32,6 +32,8 @@ func deepCopy_resource_Quantity(in resource.Quantity, out *resource.Quantity, c
if in.Amount != nil {
if newVal, err := c.DeepCopy(in.Amount); err != nil {
return err
} else if newVal == nil {
out.Amount = nil
} else {
out.Amount = newVal.(*inf.Dec)
}

View File

@ -117,6 +117,13 @@ func (c *Cloner) RegisterGeneratedDeepCopyFunc(deepCopyFunc interface{}) error {
// DeepCopy will perform a deep copy of a given object.
func (c *Cloner) DeepCopy(in interface{}) (interface{}, error) {
// Can be invalid if we run DeepCopy(X) where X is a nil interface type.
// For example, we get an invalid value when someone tries to deep-copy
// a nil labels.Selector.
// This does not occur if X is nil and is a pointer to a concrete type.
if in == nil {
return nil, nil
}
inValue := reflect.ValueOf(in)
outValue, err := c.deepCopy(inValue)
if err != nil {

View File

@ -420,6 +420,8 @@ func (g *deepCopyGenerator) writeDeepCopyForPtr(b *buffer, inField reflect.Struc
ifStmt := fmt.Sprintf(ifFormat, inField.Name)
b.addLine(ifStmt, indent+1)
b.addLine("return err\n", indent+2)
b.addLine("} else if newVal == nil {\n", indent+1)
b.addLine(fmt.Sprintf("out.%s = nil\n", inField.Name), indent+2)
b.addLine("} else {\n", indent+1)
assignFormat := "out.%s = newVal.(%s)\n"
assignStmt := fmt.Sprintf(assignFormat, inField.Name, g.typeName(inField.Type))
@ -467,6 +469,8 @@ func (g *deepCopyGenerator) writeDeepCopyForSlice(b *buffer, inField reflect.Str
ifStmt := fmt.Sprintf(ifFormat, inField.Name)
b.addLine(ifStmt, indent+2)
b.addLine("return err\n", indent+3)
b.addLine("} else if newVal == nil {\n", indent+2)
b.addLine(fmt.Sprintf("out.%s[i] = nil\n", inField.Name), indent+3)
b.addLine("} else {\n", indent+2)
assignFormat := "out.%s[i] = newVal.(%s)\n"
assignStmt := fmt.Sprintf(assignFormat, inField.Name, g.typeName(inField.Type.Elem()))
@ -508,6 +512,8 @@ func (g *deepCopyGenerator) writeDeepCopyForStruct(b *buffer, inType reflect.Typ
ifStmt := fmt.Sprintf(ifFormat, inField.Name)
b.addLine(ifStmt, indent)
b.addLine("return err\n", indent+1)
b.addLine("} else if newVal == nil {\n", indent)
b.addLine(fmt.Sprintf("out.%s = nil\n", inField.Name), indent+1)
b.addLine("} else {\n", indent)
copyFormat := "out.%s = newVal.(%s)\n"
copyStmt := fmt.Sprintf(copyFormat, inField.Name, g.typeName(inField.Type))