aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2015-10-30 13:19:14 -0700
committerColin Cross <ccross@android.com>2015-10-31 20:10:20 -0700
commit8169500cddbbfc89dc62381aaaa6fcff4fd6b4cc (patch)
tree50be7f02288130ed8fc4e8a85194290d6ce7d99f
parent0bc7e077ebfe716c6353c6fe5b9c01087867ee12 (diff)
downloadandroid_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--Blueprints1
-rw-r--r--build.ninja.in15
-rw-r--r--proptools/clone.go183
-rw-r--r--proptools/proptools.go164
4 files changed, 192 insertions, 171 deletions
diff --git a/Blueprints b/Blueprints
index 640e372..476b749 100644
--- a/Blueprints
+++ b/Blueprints
@@ -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, ",") {