Replace extendProperties with pathtools.AppendProperties
Blueprint has a generic AppendProperties/AppendMatchingProperties now,
use it, and replace all bool properties that might be modified by a
mutator with *bool, which provides the correct replace-if-set semantics
for append.
Also remove uses of ContainsProperty except when explicitly checking if
a property was set in a blueprints file.
Change-Id: If523af61d6b4630e79504d7fc2840f36e98571cc
diff --git a/Android.bp b/Android.bp
index 30cbf15..914d673 100644
--- a/Android.bp
+++ b/Android.bp
@@ -93,7 +93,6 @@
"common/config.go",
"common/defs.go",
"common/env.go",
- "common/extend.go",
"common/glob.go",
"common/module.go",
"common/paths.go",
diff --git a/cc/cc.go b/cc/cc.go
index c4e1d0e..a1b5a42 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -26,6 +26,7 @@
"github.com/google/blueprint"
"github.com/google/blueprint/pathtools"
+ "github.com/google/blueprint/proptools"
"android/soong"
"android/soong/common"
@@ -270,24 +271,24 @@
// modules cannot contain undefined symbols that are not satisified by their immediate
// dependencies. Set this flag to true to remove --no-undefined from the linker flags.
// This flag should only be necessary for compiling low-level libraries like libc.
- Allow_undefined_symbols bool
+ Allow_undefined_symbols *bool
// don't link in crt_begin and crt_end. This flag should only be necessary for
// compiling crt or libc.
- Nocrt bool `android:"arch_variant"`
+ Nocrt *bool `android:"arch_variant"`
// don't link in libgcc.a
- No_libgcc bool
+ No_libgcc *bool
// don't insert default compiler flags into asflags, cflags,
// cppflags, conlyflags, ldflags, or include_dirs
- No_default_compiler_flags bool
+ No_default_compiler_flags *bool
// compile module with clang instead of gcc
- Clang bool `android:"arch_variant"`
+ Clang *bool `android:"arch_variant"`
// pass -frtti instead of -fno-rtti
- Rtti bool
+ Rtti *bool
// -l arguments to pass to linker for host-provided shared libraries
Host_ldlibs []string `android:"arch_variant"`
@@ -323,7 +324,7 @@
Properties CCBaseProperties
unused struct {
- Native_coverage bool
+ Native_coverage *bool
Required []string
Sanitize []string `android:"arch_variant"`
Sanitize_recover []string
@@ -451,9 +452,9 @@
LdFlags: c.Properties.Ldflags,
AsFlags: c.Properties.Asflags,
YaccFlags: c.Properties.Yaccflags,
- Nocrt: c.Properties.Nocrt,
+ Nocrt: Bool(c.Properties.Nocrt),
Toolchain: toolchain,
- Clang: c.Properties.Clang,
+ Clang: Bool(c.Properties.Clang),
}
// Include dir cflags
@@ -473,7 +474,7 @@
includeFilesToFlags(rootIncludeFiles),
includeFilesToFlags(localIncludeFiles))
- if !c.Properties.No_default_compiler_flags {
+ if !Bool(c.Properties.No_default_compiler_flags) {
if c.Properties.Sdk_version == "" || ctx.Host() {
flags.GlobalFlags = append(flags.GlobalFlags,
"${commonGlobalIncludes}",
@@ -488,7 +489,7 @@
}...)
}
- if !ctx.ContainsProperty("clang") {
+ if c.Properties.Clang == nil {
if ctx.Host() {
flags.Clang = true
}
@@ -532,8 +533,8 @@
flags.LdFlags = append(flags.LdFlags, target, gccPrefix)
}
- if !c.Properties.No_default_compiler_flags {
- if ctx.Device() && !c.Properties.Allow_undefined_symbols {
+ if !Bool(c.Properties.No_default_compiler_flags) {
+ if ctx.Device() && !Bool(c.Properties.Allow_undefined_symbols) {
flags.LdFlags = append(flags.LdFlags, "-Wl,--no-undefined")
}
@@ -554,7 +555,7 @@
}
if ctx.Device() {
- if c.Properties.Rtti {
+ if Bool(c.Properties.Rtti) {
flags.CppFlags = append(flags.CppFlags, "-frtti")
} else {
flags.CppFlags = append(flags.CppFlags, "-fno-rtti")
@@ -743,11 +744,11 @@
if obj, ok := m.(ccObjectProvider); ok {
otherName := ctx.OtherModuleName(m)
if otherName == depNames.CrtBegin {
- if !c.Properties.Nocrt {
+ if !Bool(c.Properties.Nocrt) {
depPaths.CrtBegin = obj.object().outputFile()
}
} else if otherName == depNames.CrtEnd {
- if !c.Properties.Nocrt {
+ if !Bool(c.Properties.Nocrt) {
depPaths.CrtEnd = obj.object().outputFile()
}
} else {
@@ -780,7 +781,7 @@
}
func (c *CCLinked) systemSharedLibs(ctx common.AndroidBaseContext) []string {
- if ctx.ContainsProperty("system_shared_libs") {
+ if c.Properties.System_shared_libs != nil {
return c.Properties.System_shared_libs
} else if ctx.Device() && c.Properties.Sdk_version == "" {
return []string{"libc", "libm"}
@@ -941,7 +942,7 @@
if ctx.Device() {
// libgcc and libatomic have to be last on the command line
depNames.LateStaticLibs = append(depNames.LateStaticLibs, "libgcov", "libatomic")
- if !c.Properties.No_libgcc {
+ if !Bool(c.Properties.No_libgcc) {
depNames.LateStaticLibs = append(depNames.LateStaticLibs, "libgcc")
}
@@ -1328,7 +1329,7 @@
type CCBinaryProperties struct {
// compile executable with -static
- Static_executable bool
+ Static_executable *bool
// set the name of the output
Stem string `android:"arch_variant"`
@@ -1341,7 +1342,7 @@
// Create a separate binary for each source file. Useful when there is
// global state that can not be torn down and reset between each test suite.
- Test_per_src bool
+ Test_per_src *bool
}
type CCBinary struct {
@@ -1352,11 +1353,11 @@
}
func (c *CCBinary) buildStatic() bool {
- return c.BinaryProperties.Static_executable
+ return Bool(c.BinaryProperties.Static_executable)
}
func (c *CCBinary) buildShared() bool {
- return !c.BinaryProperties.Static_executable
+ return !Bool(c.BinaryProperties.Static_executable)
}
func (c *CCBinary) getStem(ctx common.AndroidModuleContext) string {
@@ -1372,14 +1373,14 @@
depNames = c.CCLinked.depNames(ctx, depNames)
if ctx.Device() {
if c.Properties.Sdk_version == "" {
- if c.BinaryProperties.Static_executable {
+ if Bool(c.BinaryProperties.Static_executable) {
depNames.CrtBegin = "crtbegin_static"
} else {
depNames.CrtBegin = "crtbegin_dynamic"
}
depNames.CrtEnd = "crtend_android"
} else {
- if c.BinaryProperties.Static_executable {
+ if Bool(c.BinaryProperties.Static_executable) {
depNames.CrtBegin = "ndk_crtbegin_static." + c.Properties.Sdk_version
} else {
depNames.CrtBegin = "ndk_crtbegin_dynamic." + c.Properties.Sdk_version
@@ -1387,7 +1388,7 @@
depNames.CrtEnd = "ndk_crtend_android." + c.Properties.Sdk_version
}
- if c.BinaryProperties.Static_executable {
+ if Bool(c.BinaryProperties.Static_executable) {
if c.stl(ctx) == "libc++_static" {
depNames.StaticLibs = append(depNames.StaticLibs, "libm", "libc", "libdl")
}
@@ -1419,9 +1420,9 @@
func (c *CCBinary) ModifyProperties(ctx common.AndroidBaseContext) {
if ctx.Darwin() {
- c.BinaryProperties.Static_executable = false
+ c.BinaryProperties.Static_executable = proptools.BoolPtr(false)
}
- if c.BinaryProperties.Static_executable {
+ if Bool(c.BinaryProperties.Static_executable) {
c.dynamicProperties.VariantIsStaticBinary = true
}
}
@@ -1432,7 +1433,7 @@
flags.CFlags = append(flags.CFlags, "-fpie")
if ctx.Device() {
- if c.BinaryProperties.Static_executable {
+ if Bool(c.BinaryProperties.Static_executable) {
// Clang driver needs -static to create static executable.
// However, bionic/linker uses -shared to overwrite.
// Linker for x86 targets does not allow coexistance of -static and -shared,
@@ -1471,7 +1472,7 @@
func (c *CCBinary) compileModule(ctx common.AndroidModuleContext,
flags CCFlags, deps CCDeps, objFiles []string) {
- if !c.BinaryProperties.Static_executable && inList("libc", c.Properties.Static_libs) {
+ if !Bool(c.BinaryProperties.Static_executable) && inList("libc", c.Properties.Static_libs) {
ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
"from static libs or set static_executable: true")
}
@@ -1504,7 +1505,7 @@
}
func (c *CCBinary) testPerSrc() bool {
- return c.BinaryProperties.Test_per_src
+ return Bool(c.BinaryProperties.Test_per_src)
}
func (c *CCBinary) binary() *CCBinary {
@@ -1938,3 +1939,5 @@
}
return list[totalSkip:]
}
+
+var Bool = proptools.Bool
diff --git a/common/arch.go b/common/arch.go
index 4dd01c3..0594567 100644
--- a/common/arch.go
+++ b/common/arch.go
@@ -426,6 +426,38 @@
var dashToUnderscoreReplacer = strings.NewReplacer("-", "_")
+func (a *AndroidModuleBase) appendProperties(ctx blueprint.EarlyMutatorContext,
+ dst, src interface{}, field, srcPrefix string) {
+
+ src = reflect.ValueOf(src).FieldByName(field).Elem().Interface()
+
+ filter := func(property string,
+ dstField, srcField reflect.StructField,
+ dstValue, srcValue interface{}) (bool, error) {
+
+ srcProperty := srcPrefix + "." + property
+
+ if !proptools.HasTag(dstField, "android", "arch_variant") {
+ if ctx.ContainsProperty(srcProperty) {
+ return false, fmt.Errorf("can't be specific to a build variant")
+ } else {
+ return false, nil
+ }
+ }
+
+ return true, nil
+ }
+
+ err := proptools.AppendProperties(dst, src, filter)
+ if err != nil {
+ if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
+ ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
+ } else {
+ panic(err)
+ }
+ }
+}
+
// Rewrite the module's properties structs to contain arch-specific values.
func (a *AndroidModuleBase) setArchProperties(ctx blueprint.EarlyMutatorContext) {
arch := a.commonProperties.CompileArch
@@ -435,13 +467,9 @@
return
}
- callback := func(srcPropertyName, dstPropertyName string) {
- a.extendedProperties[dstPropertyName] = struct{}{}
- }
-
for i := range a.generalProperties {
- generalPropsValue := []reflect.Value{reflect.ValueOf(a.generalProperties[i]).Elem()}
-
+ genProps := a.generalProperties[i]
+ archProps := a.archProperties[i]
// Handle arch-specific properties in the form:
// arch: {
// arm64: {
@@ -449,9 +477,10 @@
// },
// },
t := arch.ArchType
+
field := proptools.FieldNameForProperty(t.Name)
- extendProperties(ctx, "arch_variant", "arch."+t.Name, generalPropsValue,
- reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
+ prefix := "arch." + t.Name
+ a.appendProperties(ctx, genProps, archProps.Arch, field, prefix)
// Handle arch-variant-specific properties in the form:
// arch: {
@@ -462,8 +491,8 @@
v := dashToUnderscoreReplacer.Replace(arch.ArchVariant)
if v != "" {
field := proptools.FieldNameForProperty(v)
- extendProperties(ctx, "arch_variant", "arch."+v, generalPropsValue,
- reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
+ prefix := "arch." + v
+ a.appendProperties(ctx, genProps, archProps.Arch, field, prefix)
}
// Handle cpu-variant-specific properties in the form:
@@ -475,8 +504,8 @@
c := dashToUnderscoreReplacer.Replace(arch.CpuVariant)
if c != "" {
field := proptools.FieldNameForProperty(c)
- extendProperties(ctx, "arch_variant", "arch."+c, generalPropsValue,
- reflect.ValueOf(a.archProperties[i].Arch).FieldByName(field).Elem().Elem(), callback)
+ prefix := "arch." + c
+ a.appendProperties(ctx, genProps, archProps.Arch, field, prefix)
}
// Handle multilib-specific properties in the form:
@@ -485,9 +514,9 @@
// key: value,
// },
// },
- multilibField := proptools.FieldNameForProperty(t.Multilib)
- extendProperties(ctx, "arch_variant", "multilib."+t.Multilib, generalPropsValue,
- reflect.ValueOf(a.archProperties[i].Multilib).FieldByName(multilibField).Elem().Elem(), callback)
+ field = proptools.FieldNameForProperty(t.Multilib)
+ prefix = "multilib." + t.Multilib
+ a.appendProperties(ctx, genProps, archProps.Multilib, field, prefix)
// Handle host-or-device-specific properties in the form:
// target: {
@@ -496,9 +525,9 @@
// },
// },
hodProperty := hod.Property()
- hodField := proptools.FieldNameForProperty(hodProperty)
- extendProperties(ctx, "arch_variant", "target."+hodProperty, generalPropsValue,
- reflect.ValueOf(a.archProperties[i].Target).FieldByName(hodField).Elem().Elem(), callback)
+ field = proptools.FieldNameForProperty(hodProperty)
+ prefix = "target." + hodProperty
+ a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
// Handle host target properties in the form:
// target: {
@@ -527,15 +556,18 @@
if hod.Host() {
for _, v := range osList {
if v.goos == runtime.GOOS {
- extendProperties(ctx, "arch_variant", "target."+v.goos, generalPropsValue,
- reflect.ValueOf(a.archProperties[i].Target).FieldByName(v.field).Elem().Elem(), callback)
+ field := v.field
+ prefix := "target." + v.goos
+ a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
t := arch.ArchType
- extendProperties(ctx, "arch_variant", "target."+v.goos+"_"+t.Name, generalPropsValue,
- reflect.ValueOf(a.archProperties[i].Target).FieldByName(v.field+"_"+t.Name).Elem().Elem(), callback)
+ field = v.field + "_" + t.Name
+ prefix = "target." + v.goos + "_" + t.Name
+ a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
}
}
- extendProperties(ctx, "arch_variant", "target.not_windows", generalPropsValue,
- reflect.ValueOf(a.archProperties[i].Target).FieldByName("Not_windows").Elem().Elem(), callback)
+ field := "Not_windows"
+ prefix := "target.not_windows"
+ a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
}
// Handle 64-bit device properties in the form:
@@ -553,11 +585,13 @@
// debuggerd that need to know when they are a 32-bit process running on a 64-bit device
if hod.Device() {
if true /* && target_is_64_bit */ {
- extendProperties(ctx, "arch_variant", "target.android64", generalPropsValue,
- reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android64").Elem().Elem(), callback)
+ field := "Android64"
+ prefix := "target.android64"
+ a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
} else {
- extendProperties(ctx, "arch_variant", "target.android32", generalPropsValue,
- reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android32").Elem().Elem(), callback)
+ field := "Android32"
+ prefix := "target.android32"
+ a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
}
}
@@ -572,8 +606,9 @@
// },
if hod.Device() {
t := arch.ArchType
- extendProperties(ctx, "arch_variant", "target.android_"+t.Name, generalPropsValue,
- reflect.ValueOf(a.archProperties[i].Target).FieldByName("Android_"+t.Name).Elem().Elem(), callback)
+ field := "Android_" + t.Name
+ prefix := "target.android_" + t.Name
+ a.appendProperties(ctx, genProps, archProps.Target, field, prefix)
}
if ctx.Failed() {
diff --git a/common/extend.go b/common/extend.go
deleted file mode 100644
index f2d061b..0000000
--- a/common/extend.go
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2015 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 common
-
-import (
- "fmt"
- "reflect"
- "strings"
-
- "github.com/google/blueprint"
- "github.com/google/blueprint/proptools"
-)
-
-// TODO: move this to proptools
-func extendProperties(ctx blueprint.EarlyMutatorContext,
- requiredTag, srcPrefix string, dstValues []reflect.Value, srcValue reflect.Value,
- callback func(string, string)) {
- if srcPrefix != "" {
- srcPrefix += "."
- }
- extendPropertiesRecursive(ctx, requiredTag, srcValue, dstValues, srcPrefix, "", callback)
-}
-
-func extendPropertiesRecursive(ctx blueprint.EarlyMutatorContext, requiredTag string,
- srcValue reflect.Value, dstValues []reflect.Value, srcPrefix, dstPrefix string,
- callback func(string, string)) {
-
- typ := srcValue.Type()
- for i := 0; i < srcValue.NumField(); i++ {
- srcField := typ.Field(i)
- if srcField.PkgPath != "" {
- // The field is not exported so just skip it.
- continue
- }
-
- localPropertyName := proptools.PropertyNameForField(srcField.Name)
- srcPropertyName := srcPrefix + localPropertyName
- srcFieldValue := srcValue.Field(i)
-
- if !ctx.ContainsProperty(srcPropertyName) {
- continue
- }
-
- found := false
- for _, dstValue := range dstValues {
- dstField, ok := dstValue.Type().FieldByName(srcField.Name)
- if !ok {
- continue
- }
-
- dstFieldValue := dstValue.FieldByIndex(dstField.Index)
-
- if srcFieldValue.Type() != dstFieldValue.Type() {
- panic(fmt.Errorf("can't extend mismatching types for %q (%s <- %s)",
- srcPropertyName, dstFieldValue.Type(), srcFieldValue.Type()))
- }
-
- dstPropertyName := dstPrefix + localPropertyName
-
- if requiredTag != "" {
- tag := dstField.Tag.Get("android")
- tags := map[string]bool{}
- for _, entry := range strings.Split(tag, ",") {
- if entry != "" {
- tags[entry] = true
- }
- }
-
- if !tags[requiredTag] {
- ctx.PropertyErrorf(srcPropertyName, "property can't be specific to a build variant")
- continue
- }
- }
-
- if callback != nil {
- callback(srcPropertyName, dstPropertyName)
- }
-
- found = true
-
- switch srcFieldValue.Kind() {
- case reflect.Bool:
- // Replace the original value.
- dstFieldValue.Set(srcFieldValue)
- case reflect.String:
- // Append the extension string.
- dstFieldValue.SetString(dstFieldValue.String() +
- srcFieldValue.String())
- case reflect.Slice:
- dstFieldValue.Set(reflect.AppendSlice(dstFieldValue, srcFieldValue))
- case reflect.Interface:
- if dstFieldValue.IsNil() != srcFieldValue.IsNil() {
- panic(fmt.Errorf("can't extend field %q: nilitude mismatch", srcPropertyName))
- }
- if dstFieldValue.IsNil() {
- continue
- }
-
- dstFieldValue = dstFieldValue.Elem()
- srcFieldValue = srcFieldValue.Elem()
-
- if dstFieldValue.Type() != srcFieldValue.Type() {
- panic(fmt.Errorf("can't extend field %q: type mismatch", srcPropertyName))
- }
- if srcFieldValue.Kind() != reflect.Ptr {
- panic(fmt.Errorf("can't extend field %q: interface not a pointer", srcPropertyName))
- }
- fallthrough
- case reflect.Ptr:
- if dstFieldValue.IsNil() != srcFieldValue.IsNil() {
- panic(fmt.Errorf("can't extend field %q: nilitude mismatch", srcPropertyName))
- }
- if dstFieldValue.IsNil() {
- continue
- }
-
- dstFieldValue = dstFieldValue.Elem()
- srcFieldValue = srcFieldValue.Elem()
-
- if dstFieldValue.Type() != srcFieldValue.Type() {
- panic(fmt.Errorf("can't extend field %q: type mismatch", srcPropertyName))
- }
- if srcFieldValue.Kind() != reflect.Struct {
- panic(fmt.Errorf("can't extend field %q: pointer not to a struct", srcPropertyName))
- }
- fallthrough
- case reflect.Struct:
- // Recursively extend the struct's fields.
- extendPropertiesRecursive(ctx, requiredTag, srcFieldValue, []reflect.Value{dstFieldValue},
- srcPropertyName+".", srcPropertyName+".", callback)
- default:
- panic(fmt.Errorf("unexpected kind for property struct field %q: %s",
- srcPropertyName, srcFieldValue.Kind()))
- }
- }
- if !found {
- ctx.PropertyErrorf(srcPropertyName, "failed to find property to extend")
- }
- }
-}
diff --git a/common/module.go b/common/module.go
index feaba83..d31a9fc 100644
--- a/common/module.go
+++ b/common/module.go
@@ -123,7 +123,6 @@
base := m.base()
base.module = m
- base.extendedProperties = make(map[string]struct{})
propertyStructs = append(propertyStructs, &base.commonProperties, &base.variableProperties)
@@ -198,7 +197,6 @@
hostAndDeviceProperties hostAndDeviceProperties
generalProperties []interface{}
archProperties []*archProperties
- extendedProperties map[string]struct{}
noAddressSanitizer bool
installFiles []string
@@ -340,9 +338,8 @@
hod: a.commonProperties.CompileHostOrDevice,
config: ctx.Config().(Config),
},
- installDeps: a.computeInstallDeps(ctx),
- installFiles: a.installFiles,
- extendedProperties: a.extendedProperties,
+ installDeps: a.computeInstallDeps(ctx),
+ installFiles: a.installFiles,
}
if a.commonProperties.Disabled {
@@ -373,10 +370,9 @@
type androidModuleContext struct {
blueprint.ModuleContext
androidBaseContextImpl
- installDeps []string
- installFiles []string
- checkbuildFiles []string
- extendedProperties map[string]struct{}
+ installDeps []string
+ installFiles []string
+ checkbuildFiles []string
}
func (a *androidModuleContext) Build(pctx *blueprint.PackageContext, params blueprint.BuildParams) {
@@ -384,14 +380,6 @@
a.ModuleContext.Build(pctx, params)
}
-func (a *androidModuleContext) ContainsProperty(property string) bool {
- if a.ModuleContext.ContainsProperty(property) {
- return true
- }
- _, ok := a.extendedProperties[property]
- return ok
-}
-
func (a *androidBaseContextImpl) Arch() Arch {
return a.arch
}
diff --git a/common/variable.go b/common/variable.go
index 23a97a6..3949681 100644
--- a/common/variable.go
+++ b/common/variable.go
@@ -113,7 +113,7 @@
// TODO: depend on config variable, create variants, propagate variants up tree
a := module.base()
- variableValues := reflect.ValueOf(a.variableProperties.Product_variables)
+ variableValues := reflect.ValueOf(&a.variableProperties.Product_variables).Elem()
zeroValues := reflect.ValueOf(zeroProductVariables.Product_variables)
for i := 0; i < variableValues.NumField(); i++ {
@@ -147,16 +147,19 @@
func (a *AndroidModuleBase) setVariableProperties(ctx blueprint.EarlyMutatorContext,
prefix string, productVariablePropertyValue reflect.Value, variableValue interface{}) {
- generalPropertyValues := make([]reflect.Value, len(a.generalProperties))
- for i := range a.generalProperties {
- generalPropertyValues[i] = reflect.ValueOf(a.generalProperties[i]).Elem()
- }
-
if variableValue != nil {
printfIntoProperties(productVariablePropertyValue, variableValue)
}
- extendProperties(ctx, "", prefix, generalPropertyValues, productVariablePropertyValue, nil)
+ err := proptools.AppendMatchingProperties(a.generalProperties,
+ productVariablePropertyValue.Addr().Interface(), nil)
+ if err != nil {
+ if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
+ ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
+ } else {
+ panic(err)
+ }
+ }
}
func printfIntoProperties(productVariablePropertyValue reflect.Value, variableValue interface{}) {