diff options
author | Colin Cross <ccross@android.com> | 2015-10-30 13:19:14 -0700 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2015-10-31 20:10:20 -0700 |
commit | 8169500cddbbfc89dc62381aaaa6fcff4fd6b4cc (patch) | |
tree | 50be7f02288130ed8fc4e8a85194290d6ce7d99f | |
parent | 0bc7e077ebfe716c6353c6fe5b9c01087867ee12 (diff) | |
download | android_build_blueprint-8169500cddbbfc89dc62381aaaa6fcff4fd6b4cc.tar.gz android_build_blueprint-8169500cddbbfc89dc62381aaaa6fcff4fd6b4cc.tar.bz2 android_build_blueprint-8169500cddbbfc89dc62381aaaa6fcff4fd6b4cc.zip |
Move CloneProperties to clone.go
Move CloneProperties, CloneEmptyProperties, and ZeroProperties from
proptools/proptools.go to proptools/clone.go.
-rw-r--r-- | Blueprints | 1 | ||||
-rw-r--r-- | build.ninja.in | 15 | ||||
-rw-r--r-- | proptools/clone.go | 183 | ||||
-rw-r--r-- | proptools/proptools.go | 164 |
4 files changed, 192 insertions, 171 deletions
@@ -65,6 +65,7 @@ bootstrap_go_package( name = "blueprint-proptools", pkgPath = "github.com/google/blueprint/proptools", srcs = [ + "proptools/clone.go", "proptools/extend.go", "proptools/proptools.go", ], diff --git a/build.ninja.in b/build.ninja.in index 635b77b..1274146 100644 --- a/build.ninja.in +++ b/build.ninja.in @@ -81,7 +81,7 @@ default $ # Variant: # Type: bootstrap_go_package # Factory: github.com/google/blueprint/bootstrap.func·003 -# Defined: Blueprints:76:1 +# Defined: Blueprints:77:1 build $ ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap/pkg/github.com/google/blueprint/bootstrap.a $ @@ -108,7 +108,7 @@ default $ # Variant: # Type: bootstrap_go_package # Factory: github.com/google/blueprint/bootstrap.func·003 -# Defined: Blueprints:95:1 +# Defined: Blueprints:96:1 build $ ${g.bootstrap.buildDir}/.bootstrap/blueprint-bootstrap-bpdoc/pkg/github.com/google/blueprint/bootstrap/bpdoc.a $ @@ -179,7 +179,8 @@ default $ build $ ${g.bootstrap.buildDir}/.bootstrap/blueprint-proptools/pkg/github.com/google/blueprint/proptools.a $ - : g.bootstrap.compile ${g.bootstrap.srcDir}/proptools/extend.go $ + : g.bootstrap.compile ${g.bootstrap.srcDir}/proptools/clone.go $ + ${g.bootstrap.srcDir}/proptools/extend.go $ ${g.bootstrap.srcDir}/proptools/proptools.go | $ ${g.bootstrap.compileCmd} pkgPath = github.com/google/blueprint/proptools @@ -191,7 +192,7 @@ default $ # Variant: # Type: bootstrap_core_go_binary # Factory: github.com/google/blueprint/bootstrap.func·005 -# Defined: Blueprints:138:1 +# Defined: Blueprints:139:1 build ${g.bootstrap.buildDir}/.bootstrap/choosestage/obj/choosestage.a: $ g.bootstrap.compile ${g.bootstrap.srcDir}/choosestage/choosestage.go | $ @@ -213,7 +214,7 @@ default ${g.bootstrap.BinDir}/choosestage # Variant: # Type: bootstrap_core_go_binary # Factory: github.com/google/blueprint/bootstrap.func·005 -# Defined: Blueprints:128:1 +# Defined: Blueprints:129:1 build ${g.bootstrap.buildDir}/.bootstrap/gotestmain/obj/gotestmain.a: $ g.bootstrap.compile ${g.bootstrap.srcDir}/gotestmain/gotestmain.go | $ @@ -235,7 +236,7 @@ default ${g.bootstrap.BinDir}/gotestmain # Variant: # Type: bootstrap_core_go_binary # Factory: github.com/google/blueprint/bootstrap.func·005 -# Defined: Blueprints:133:1 +# Defined: Blueprints:134:1 build ${g.bootstrap.buildDir}/.bootstrap/gotestrunner/obj/gotestrunner.a: $ g.bootstrap.compile ${g.bootstrap.srcDir}/gotestrunner/gotestrunner.go $ @@ -257,7 +258,7 @@ default ${g.bootstrap.BinDir}/gotestrunner # Variant: # Type: bootstrap_core_go_binary # Factory: github.com/google/blueprint/bootstrap.func·005 -# Defined: Blueprints:107:1 +# Defined: Blueprints:108:1 build ${g.bootstrap.buildDir}/.bootstrap/minibp/obj/minibp.a: $ g.bootstrap.compile ${g.bootstrap.srcDir}/bootstrap/minibp/main.go | $ diff --git a/proptools/clone.go b/proptools/clone.go new file mode 100644 index 0000000..519c17d --- /dev/null +++ b/proptools/clone.go @@ -0,0 +1,183 @@ +// Copyright 2014 Google Inc. All rights reserved. +// +// 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 proptools + +import ( + "fmt" + "reflect" +) + +func CloneProperties(structValue reflect.Value) reflect.Value { + result := reflect.New(structValue.Type()) + CopyProperties(result.Elem(), structValue) + return result +} + +func CopyProperties(dstValue, srcValue reflect.Value) { + typ := dstValue.Type() + if srcValue.Type() != typ { + panic(fmt.Errorf("can't copy mismatching types (%s <- %s)", + dstValue.Kind(), srcValue.Kind())) + } + + for i := 0; i < srcValue.NumField(); i++ { + field := typ.Field(i) + if field.PkgPath != "" { + // The field is not exported so just skip it. + continue + } + + srcFieldValue := srcValue.Field(i) + dstFieldValue := dstValue.Field(i) + + switch srcFieldValue.Kind() { + case reflect.Bool, reflect.String, reflect.Int, reflect.Uint: + dstFieldValue.Set(srcFieldValue) + case reflect.Struct: + CopyProperties(dstFieldValue, srcFieldValue) + case reflect.Slice: + if !srcFieldValue.IsNil() { + if field.Type.Elem().Kind() != reflect.String { + panic(fmt.Errorf("can't copy field %q: slice elements are "+ + "not strings", field.Name)) + } + if srcFieldValue != dstFieldValue { + newSlice := reflect.MakeSlice(field.Type, srcFieldValue.Len(), + srcFieldValue.Len()) + reflect.Copy(newSlice, srcFieldValue) + dstFieldValue.Set(newSlice) + } + } else { + dstFieldValue.Set(srcFieldValue) + } + case reflect.Ptr, reflect.Interface: + if !srcFieldValue.IsNil() { + if dstFieldValue.IsNil() || + dstFieldValue.Type() != srcFieldValue.Type() { + + // We can't use the existing destination allocation, so + // clone a new one. + elem := srcFieldValue.Elem() + if srcFieldValue.Kind() == reflect.Interface { + if elem.Kind() != reflect.Ptr { + panic(fmt.Errorf("can't clone field %q: interface "+ + "refers to a non-pointer", field.Name)) + } + elem = elem.Elem() + } + if elem.Kind() != reflect.Struct { + panic(fmt.Errorf("can't clone field %q: points to a "+ + "non-struct", field.Name)) + } + dstFieldValue.Set(CloneProperties(elem)) + } else { + // Re-use the existing allocation. + CopyProperties(dstFieldValue.Elem().Elem(), srcFieldValue.Elem().Elem()) + } + } else { + dstFieldValue.Set(srcFieldValue) + } + default: + panic(fmt.Errorf("unexpected kind for property struct field %q: %s", + field.Name, srcFieldValue.Kind())) + } + } +} + +func ZeroProperties(structValue reflect.Value) { + typ := structValue.Type() + + for i := 0; i < structValue.NumField(); i++ { + field := typ.Field(i) + if field.PkgPath != "" { + // The field is not exported so just skip it. + continue + } + + fieldValue := structValue.Field(i) + + switch fieldValue.Kind() { + case reflect.Bool, reflect.String, reflect.Struct, reflect.Slice, reflect.Int, reflect.Uint: + fieldValue.Set(reflect.Zero(fieldValue.Type())) + case reflect.Ptr, reflect.Interface: + if !fieldValue.IsNil() { + // We leave the pointer intact and zero out the struct that's + // pointed to. + elem := fieldValue.Elem() + if fieldValue.Kind() == reflect.Interface { + if elem.Kind() != reflect.Ptr { + panic(fmt.Errorf("can't zero field %q: interface "+ + "refers to a non-pointer", field.Name)) + } + elem = elem.Elem() + } + if elem.Kind() != reflect.Struct { + panic(fmt.Errorf("can't zero field %q: points to a "+ + "non-struct", field.Name)) + } + ZeroProperties(elem) + } + default: + panic(fmt.Errorf("unexpected kind for property struct field %q: %s", + field.Name, fieldValue.Kind())) + } + } +} + +func CloneEmptyProperties(structValue reflect.Value) reflect.Value { + result := reflect.New(structValue.Type()) + cloneEmptyProperties(result.Elem(), structValue) + return result +} + +func cloneEmptyProperties(dstValue, srcValue reflect.Value) { + typ := srcValue.Type() + for i := 0; i < srcValue.NumField(); i++ { + field := typ.Field(i) + if field.PkgPath != "" { + // The field is not exported so just skip it. + continue + } + + srcFieldValue := srcValue.Field(i) + dstFieldValue := dstValue.Field(i) + + switch srcFieldValue.Kind() { + case reflect.Bool, reflect.String, reflect.Slice, reflect.Int, reflect.Uint: + // Nothing + case reflect.Struct: + cloneEmptyProperties(dstFieldValue, srcFieldValue) + case reflect.Ptr, reflect.Interface: + if !srcFieldValue.IsNil() { + elem := srcFieldValue.Elem() + if srcFieldValue.Kind() == reflect.Interface { + if elem.Kind() != reflect.Ptr { + panic(fmt.Errorf("can't clone field %q: interface "+ + "refers to a non-pointer", field.Name)) + } + elem = elem.Elem() + } + if elem.Elem().Kind() != reflect.Struct { + panic(fmt.Errorf("can't clone field %q: points to a "+ + "non-struct", field.Name)) + } + dstFieldValue.Set(CloneEmptyProperties(elem.Elem())) + } + default: + panic(fmt.Errorf("unexpected kind for property struct field %q: %s", + field.Name, srcFieldValue.Kind())) + } + } +} diff --git a/proptools/proptools.go b/proptools/proptools.go index e761926..79c4f6d 100644 --- a/proptools/proptools.go +++ b/proptools/proptools.go @@ -15,7 +15,6 @@ package proptools import ( - "fmt" "reflect" "strings" "unicode" @@ -40,169 +39,6 @@ func FieldNameForProperty(propertyName string) string { return fieldName } -func CloneProperties(structValue reflect.Value) reflect.Value { - result := reflect.New(structValue.Type()) - CopyProperties(result.Elem(), structValue) - return result -} - -func CopyProperties(dstValue, srcValue reflect.Value) { - typ := dstValue.Type() - if srcValue.Type() != typ { - panic(fmt.Errorf("can't copy mismatching types (%s <- %s)", - dstValue.Kind(), srcValue.Kind())) - } - - for i := 0; i < srcValue.NumField(); i++ { - field := typ.Field(i) - if field.PkgPath != "" { - // The field is not exported so just skip it. - continue - } - - srcFieldValue := srcValue.Field(i) - dstFieldValue := dstValue.Field(i) - - switch srcFieldValue.Kind() { - case reflect.Bool, reflect.String, reflect.Int, reflect.Uint: - dstFieldValue.Set(srcFieldValue) - case reflect.Struct: - CopyProperties(dstFieldValue, srcFieldValue) - case reflect.Slice: - if !srcFieldValue.IsNil() { - if field.Type.Elem().Kind() != reflect.String { - panic(fmt.Errorf("can't copy field %q: slice elements are "+ - "not strings", field.Name)) - } - if srcFieldValue != dstFieldValue { - newSlice := reflect.MakeSlice(field.Type, srcFieldValue.Len(), - srcFieldValue.Len()) - reflect.Copy(newSlice, srcFieldValue) - dstFieldValue.Set(newSlice) - } - } else { - dstFieldValue.Set(srcFieldValue) - } - case reflect.Ptr, reflect.Interface: - if !srcFieldValue.IsNil() { - if dstFieldValue.IsNil() || - dstFieldValue.Type() != srcFieldValue.Type() { - - // We can't use the existing destination allocation, so - // clone a new one. - elem := srcFieldValue.Elem() - if srcFieldValue.Kind() == reflect.Interface { - if elem.Kind() != reflect.Ptr { - panic(fmt.Errorf("can't clone field %q: interface "+ - "refers to a non-pointer", field.Name)) - } - elem = elem.Elem() - } - if elem.Kind() != reflect.Struct { - panic(fmt.Errorf("can't clone field %q: points to a "+ - "non-struct", field.Name)) - } - dstFieldValue.Set(CloneProperties(elem)) - } else { - // Re-use the existing allocation. - CopyProperties(dstFieldValue.Elem().Elem(), srcFieldValue.Elem().Elem()) - } - } else { - dstFieldValue.Set(srcFieldValue) - } - default: - panic(fmt.Errorf("unexpected kind for property struct field %q: %s", - field.Name, srcFieldValue.Kind())) - } - } -} - -func ZeroProperties(structValue reflect.Value) { - typ := structValue.Type() - - for i := 0; i < structValue.NumField(); i++ { - field := typ.Field(i) - if field.PkgPath != "" { - // The field is not exported so just skip it. - continue - } - - fieldValue := structValue.Field(i) - - switch fieldValue.Kind() { - case reflect.Bool, reflect.String, reflect.Struct, reflect.Slice, reflect.Int, reflect.Uint: - fieldValue.Set(reflect.Zero(fieldValue.Type())) - case reflect.Ptr, reflect.Interface: - if !fieldValue.IsNil() { - // We leave the pointer intact and zero out the struct that's - // pointed to. - elem := fieldValue.Elem() - if fieldValue.Kind() == reflect.Interface { - if elem.Kind() != reflect.Ptr { - panic(fmt.Errorf("can't zero field %q: interface "+ - "refers to a non-pointer", field.Name)) - } - elem = elem.Elem() - } - if elem.Kind() != reflect.Struct { - panic(fmt.Errorf("can't zero field %q: points to a "+ - "non-struct", field.Name)) - } - ZeroProperties(elem) - } - default: - panic(fmt.Errorf("unexpected kind for property struct field %q: %s", - field.Name, fieldValue.Kind())) - } - } -} - -func CloneEmptyProperties(structValue reflect.Value) reflect.Value { - result := reflect.New(structValue.Type()) - cloneEmptyProperties(result.Elem(), structValue) - return result -} - -func cloneEmptyProperties(dstValue, srcValue reflect.Value) { - typ := srcValue.Type() - for i := 0; i < srcValue.NumField(); i++ { - field := typ.Field(i) - if field.PkgPath != "" { - // The field is not exported so just skip it. - continue - } - - srcFieldValue := srcValue.Field(i) - dstFieldValue := dstValue.Field(i) - - switch srcFieldValue.Kind() { - case reflect.Bool, reflect.String, reflect.Slice, reflect.Int, reflect.Uint: - // Nothing - case reflect.Struct: - cloneEmptyProperties(dstFieldValue, srcFieldValue) - case reflect.Ptr, reflect.Interface: - if !srcFieldValue.IsNil() { - elem := srcFieldValue.Elem() - if srcFieldValue.Kind() == reflect.Interface { - if elem.Kind() != reflect.Ptr { - panic(fmt.Errorf("can't clone field %q: interface "+ - "refers to a non-pointer", field.Name)) - } - elem = elem.Elem() - } - if elem.Elem().Kind() != reflect.Struct { - panic(fmt.Errorf("can't clone field %q: points to a "+ - "non-struct", field.Name)) - } - dstFieldValue.Set(CloneEmptyProperties(elem.Elem())) - } - default: - panic(fmt.Errorf("unexpected kind for property struct field %q: %s", - field.Name, srcFieldValue.Kind())) - } - } -} - func HasTag(field reflect.StructField, name, value string) bool { tag := field.Tag.Get(name) for _, entry := range strings.Split(tag, ",") { |