A few minor changes.
- Make module 'new' functions return slices of properties structs rather than
just one.
- Fix a couple places where errors were being reported incorrectly.
- Add ModuleContext methods for dealing with other modules.
- Make property value unpacking skip unexported struct fields rather than
panicing.
Change-Id: I4775ef77ff0514fc2ce5abccbe2ce534c05272f4
diff --git a/blueprint/bootstrap/bootstrap.go b/blueprint/bootstrap/bootstrap.go
index b18b866..fbdc99c 100644
--- a/blueprint/bootstrap/bootstrap.go
+++ b/blueprint/bootstrap/bootstrap.go
@@ -131,9 +131,9 @@
var _ goPackageProducer = (*goPackage)(nil)
-func newGoPackage() (blueprint.Module, interface{}) {
+func newGoPackage() (blueprint.Module, []interface{}) {
module := &goPackage{}
- return module, &module.properties
+ return module, []interface{}{&module.properties}
}
func (g *goPackage) GoPkgRoot() string {
@@ -177,9 +177,9 @@
}
}
-func newGoBinary() (blueprint.Module, interface{}) {
+func newGoBinary() (blueprint.Module, []interface{}) {
module := &goBinary{}
- return module, &module.properties
+ return module, []interface{}{&module.properties}
}
func (g *goBinary) GenerateBuildActions(ctx blueprint.ModuleContext) {
diff --git a/blueprint/context.go b/blueprint/context.go
index 76412a3..9159f8f 100644
--- a/blueprint/context.go
+++ b/blueprint/context.go
@@ -452,8 +452,12 @@
return nil
}
- err := fmt.Errorf("unrecognized module type %q", typeName)
- return []error{err}
+ return []error{
+ &Error{
+ Err: fmt.Errorf("unrecognized module type %q", typeName),
+ Pos: moduleDef.Pos,
+ },
+ }
}
module, properties := typ.new()
@@ -463,8 +467,9 @@
relBlueprintsFile: relBlueprintsFile,
}
- errs := unpackProperties(moduleDef.Properties, &info.properties,
- properties)
+ properties = append(properties, &info.properties)
+
+ errs := unpackProperties(moduleDef.Properties, properties...)
if len(errs) > 0 {
return errs
}
diff --git a/blueprint/globals.go b/blueprint/globals.go
index d888db6..2b2a62c 100644
--- a/blueprint/globals.go
+++ b/blueprint/globals.go
@@ -718,13 +718,13 @@
type ModuleType interface {
pkg() *pkg
name() string
- new() (m Module, properties interface{})
+ new() (m Module, properties []interface{})
}
type moduleTypeFunc struct {
pkg_ *pkg
name_ string
- new_ func() (Module, interface{})
+ new_ func() (Module, []interface{})
}
// MakeModuleType returns a new ModuleType object that will instantiate new
@@ -742,14 +742,14 @@
// instantiate modules of this type.
//
// The new function passed to MakeModuleType returns two values. The first is
-// the newly created Module object. The second is a pointer to that Module
-// object's properties struct. This properties struct is examined when parsing
-// a module definition of this type in a Blueprints file. Exported fields of
-// the properties struct are automatically set to the property values specified
-// in the Blueprints file. The properties struct field names determine the name
-// of the Blueprints file properties that are used - the Blueprints property
-// name matches that of the properties struct field name with the first letter
-// converted to lower-case.
+// the newly created Module object. The second is a slice of pointers to that
+// Module object's properties structs. Each properties struct is examined when
+// parsing a module definition of this type in a Blueprints file. Exported
+// fields of the properties structs are automatically set to the property values
+// specified in the Blueprints file. The properties struct field names
+// determine the name of the Blueprints file properties that are used - the
+// Blueprints property name matches that of the properties struct field name
+// with the first letter converted to lower-case.
//
// The fields of the properties struct must either []string, a string, or bool.
// The Context will panic if a Module gets instantiated with a properties struct
@@ -771,10 +771,10 @@
// }
// }
//
-// func newMyModule() (blueprint.Module, interface{}) {
+// func newMyModule() (blueprint.Module, []interface{}) {
// module := new(myModule)
// properties := &module.properties
-// return module, properties
+// return module, []interface{}{properties}
// }
//
// func main() {
@@ -792,7 +792,7 @@
// }
//
func MakeModuleType(name string,
- new func() (m Module, properties interface{})) ModuleType {
+ new func() (m Module, propertyStructs []interface{})) ModuleType {
pkg := callerPackage()
return &moduleTypeFunc{pkg, name, new}
@@ -806,6 +806,6 @@
return m.pkg_.pkgPath + "." + m.name_
}
-func (m *moduleTypeFunc) new() (Module, interface{}) {
+func (m *moduleTypeFunc) new() (Module, []interface{}) {
return m.new_()
}
diff --git a/blueprint/module_ctx.go b/blueprint/module_ctx.go
index 19f6d10..f664c93 100644
--- a/blueprint/module_ctx.go
+++ b/blueprint/module_ctx.go
@@ -11,11 +11,13 @@
type ModuleContext interface {
ModuleName() string
+ OtherModuleName(m Module) string
ModuleDir() string
Config() interface{}
ModuleErrorf(fmt string, args ...interface{})
PropertyErrorf(property, fmt string, args ...interface{})
+ OtherModuleErrorf(m Module, fmt string, args ...interface{})
Variable(name, value string)
Rule(name string, params RuleParams, argNames ...string) Rule
@@ -43,6 +45,11 @@
return m.info.properties.Name
}
+func (m *moduleContext) OtherModuleName(module Module) string {
+ info := m.context.moduleInfo[module]
+ return info.properties.Name
+}
+
func (m *moduleContext) ModuleDir() string {
return filepath.Dir(m.info.relBlueprintsFile)
}
@@ -72,6 +79,16 @@
})
}
+func (m *moduleContext) OtherModuleErrorf(module Module, format string,
+ args ...interface{}) {
+
+ info := m.context.moduleInfo[module]
+ m.errs = append(m.errs, &Error{
+ Err: fmt.Errorf(format, args...),
+ Pos: info.pos,
+ })
+}
+
func (m *moduleContext) Variable(name, value string) {
v, err := m.scope.AddLocalVariable(name, value)
if err != nil {
diff --git a/blueprint/unpack.go b/blueprint/unpack.go
index 98f0fe2..ed98db5 100644
--- a/blueprint/unpack.go
+++ b/blueprint/unpack.go
@@ -25,7 +25,7 @@
Pos: propertyDef.Pos,
})
errs = append(errs, &Error{
- Err: fmt.Errorf("--> previous definition here"),
+ Err: fmt.Errorf("<-- previous definition here"),
Pos: first.property.Pos,
})
if len(errs) >= maxErrors {
@@ -84,6 +84,11 @@
fieldValue := structValue.Field(i)
field := structType.Field(i)
+ if field.PkgPath != "" {
+ // This is an unexported field, so just skip it.
+ continue
+ }
+
if !fieldValue.CanSet() {
panic(fmt.Errorf("field %s is not settable", field.Name))
}