Merge "Refactor prebuilt to use srcs supplier function"
This commit is contained in:
@@ -50,12 +50,9 @@ type PrebuiltProperties struct {
|
|||||||
|
|
||||||
type Prebuilt struct {
|
type Prebuilt struct {
|
||||||
properties PrebuiltProperties
|
properties PrebuiltProperties
|
||||||
module Module
|
|
||||||
srcs *[]string
|
|
||||||
|
|
||||||
// Metadata for single source Prebuilt modules.
|
srcsSupplier PrebuiltSrcsSupplier
|
||||||
srcProps reflect.Value
|
srcsPropertyName string
|
||||||
srcField reflect.StructField
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Prebuilt) Name(name string) string {
|
func (p *Prebuilt) Name(name string) string {
|
||||||
@@ -72,31 +69,26 @@ func (p *Prebuilt) ForcePrefer() {
|
|||||||
// preference configs. We'll want to add native support for dynamic source cases if we end up having
|
// preference configs. We'll want to add native support for dynamic source cases if we end up having
|
||||||
// more modules like this.
|
// more modules like this.
|
||||||
func (p *Prebuilt) SingleSourcePath(ctx ModuleContext) Path {
|
func (p *Prebuilt) SingleSourcePath(ctx ModuleContext) Path {
|
||||||
if p.srcs != nil {
|
if p.srcsSupplier != nil {
|
||||||
if len(*p.srcs) == 0 {
|
srcs := p.srcsSupplier()
|
||||||
ctx.PropertyErrorf("srcs", "missing prebuilt source file")
|
|
||||||
|
if len(srcs) == 0 {
|
||||||
|
ctx.PropertyErrorf(p.srcsPropertyName, "missing prebuilt source file")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(*p.srcs) > 1 {
|
if len(srcs) > 1 {
|
||||||
ctx.PropertyErrorf("srcs", "multiple prebuilt source files")
|
ctx.PropertyErrorf(p.srcsPropertyName, "multiple prebuilt source files")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the singleton source after expanding any filegroup in the
|
// Return the singleton source after expanding any filegroup in the
|
||||||
// sources.
|
// sources.
|
||||||
return PathForModuleSrc(ctx, (*p.srcs)[0])
|
src := srcs[0]
|
||||||
} else {
|
|
||||||
if !p.srcProps.IsValid() {
|
|
||||||
ctx.ModuleErrorf("prebuilt source was not set")
|
|
||||||
}
|
|
||||||
src := p.getSingleSourceFieldValue()
|
|
||||||
if src == "" {
|
|
||||||
ctx.PropertyErrorf(proptools.FieldNameForProperty(p.srcField.Name),
|
|
||||||
"missing prebuilt source file")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return PathForModuleSrc(ctx, src)
|
return PathForModuleSrc(ctx, src)
|
||||||
|
} else {
|
||||||
|
ctx.ModuleErrorf("prebuilt source was not set")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,18 +96,80 @@ func (p *Prebuilt) UsePrebuilt() bool {
|
|||||||
return p.properties.UsePrebuilt
|
return p.properties.UsePrebuilt
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) {
|
// Called to provide the srcs value for the prebuilt module.
|
||||||
|
//
|
||||||
|
// Return the src value or nil if it is not available.
|
||||||
|
type PrebuiltSrcsSupplier func() []string
|
||||||
|
|
||||||
|
// Initialize the module as a prebuilt module that uses the provided supplier to access the
|
||||||
|
// prebuilt sources of the module.
|
||||||
|
//
|
||||||
|
// The supplier will be called multiple times and must return the same values each time it
|
||||||
|
// is called. If it returns an empty array (or nil) then the prebuilt module will not be used
|
||||||
|
// as a replacement for a source module with the same name even if prefer = true.
|
||||||
|
//
|
||||||
|
// If the Prebuilt.SingleSourcePath() is called on the module then this must return an array
|
||||||
|
// containing exactly one source file.
|
||||||
|
//
|
||||||
|
// The provided property name is used to provide helpful error messages in the event that
|
||||||
|
// a problem arises, e.g. calling SingleSourcePath() when more than one source is provided.
|
||||||
|
func InitPrebuiltModuleWithSrcSupplier(module PrebuiltInterface, srcsSupplier PrebuiltSrcsSupplier, srcsPropertyName string) {
|
||||||
p := module.Prebuilt()
|
p := module.Prebuilt()
|
||||||
module.AddProperties(&p.properties)
|
module.AddProperties(&p.properties)
|
||||||
p.srcs = srcs
|
|
||||||
|
if srcsSupplier == nil {
|
||||||
|
panic(fmt.Errorf("srcsSupplier must not be nil"))
|
||||||
|
}
|
||||||
|
if srcsPropertyName == "" {
|
||||||
|
panic(fmt.Errorf("srcsPropertyName must not be empty"))
|
||||||
|
}
|
||||||
|
|
||||||
|
p.srcsSupplier = srcsSupplier
|
||||||
|
p.srcsPropertyName = srcsPropertyName
|
||||||
|
}
|
||||||
|
|
||||||
|
func InitPrebuiltModule(module PrebuiltInterface, srcs *[]string) {
|
||||||
|
if srcs == nil {
|
||||||
|
panic(fmt.Errorf("srcs must not be nil"))
|
||||||
|
}
|
||||||
|
|
||||||
|
srcsSupplier := func() []string {
|
||||||
|
return *srcs
|
||||||
|
}
|
||||||
|
|
||||||
|
InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "srcs")
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitSingleSourcePrebuiltModule(module PrebuiltInterface, srcProps interface{}, srcField string) {
|
func InitSingleSourcePrebuiltModule(module PrebuiltInterface, srcProps interface{}, srcField string) {
|
||||||
p := module.Prebuilt()
|
srcPropsValue := reflect.ValueOf(srcProps).Elem()
|
||||||
module.AddProperties(&p.properties)
|
srcStructField, _ := srcPropsValue.Type().FieldByName(srcField)
|
||||||
p.srcProps = reflect.ValueOf(srcProps).Elem()
|
if !srcPropsValue.IsValid() || srcStructField.Name == "" {
|
||||||
p.srcField, _ = p.srcProps.Type().FieldByName(srcField)
|
panic(fmt.Errorf("invalid single source prebuilt %+v", module))
|
||||||
p.checkSingleSourceProperties()
|
}
|
||||||
|
|
||||||
|
if srcPropsValue.Kind() != reflect.Struct && srcPropsValue.Kind() != reflect.Interface {
|
||||||
|
panic(fmt.Errorf("invalid single source prebuilt %+v", srcProps))
|
||||||
|
}
|
||||||
|
|
||||||
|
srcFieldIndex := srcStructField.Index
|
||||||
|
srcPropertyName := proptools.PropertyNameForField(srcField)
|
||||||
|
|
||||||
|
srcsSupplier := func() []string {
|
||||||
|
value := srcPropsValue.FieldByIndex(srcFieldIndex)
|
||||||
|
if value.Kind() == reflect.Ptr {
|
||||||
|
value = value.Elem()
|
||||||
|
}
|
||||||
|
if value.Kind() != reflect.String {
|
||||||
|
panic(fmt.Errorf("prebuilt src field %q should be a string or a pointer to one but was %d %q", srcPropertyName, value.Kind(), value))
|
||||||
|
}
|
||||||
|
src := value.String()
|
||||||
|
if src == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return []string{src}
|
||||||
|
}
|
||||||
|
|
||||||
|
InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, srcPropertyName)
|
||||||
}
|
}
|
||||||
|
|
||||||
type PrebuiltInterface interface {
|
type PrebuiltInterface interface {
|
||||||
@@ -152,7 +206,7 @@ func PrebuiltMutator(ctx BottomUpMutatorContext) {
|
|||||||
func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
|
func PrebuiltSelectModuleMutator(ctx TopDownMutatorContext) {
|
||||||
if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil {
|
if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil {
|
||||||
p := m.Prebuilt()
|
p := m.Prebuilt()
|
||||||
if p.srcs == nil && !p.srcProps.IsValid() {
|
if p.srcsSupplier == nil {
|
||||||
panic(fmt.Errorf("prebuilt module did not have InitPrebuiltModule called on it"))
|
panic(fmt.Errorf("prebuilt module did not have InitPrebuiltModule called on it"))
|
||||||
}
|
}
|
||||||
if !p.properties.SourceExists {
|
if !p.properties.SourceExists {
|
||||||
@@ -191,11 +245,7 @@ func PrebuiltPostDepsMutator(ctx BottomUpMutatorContext) {
|
|||||||
// usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt
|
// usePrebuilt returns true if a prebuilt should be used instead of the source module. The prebuilt
|
||||||
// will be used if it is marked "prefer" or if the source module is disabled.
|
// will be used if it is marked "prefer" or if the source module is disabled.
|
||||||
func (p *Prebuilt) usePrebuilt(ctx TopDownMutatorContext, source Module) bool {
|
func (p *Prebuilt) usePrebuilt(ctx TopDownMutatorContext, source Module) bool {
|
||||||
if p.srcs != nil && len(*p.srcs) == 0 {
|
if p.srcsSupplier != nil && len(p.srcsSupplier()) == 0 {
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.srcProps.IsValid() && p.getSingleSourceFieldValue() == "" {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -210,24 +260,3 @@ func (p *Prebuilt) usePrebuilt(ctx TopDownMutatorContext, source Module) bool {
|
|||||||
func (p *Prebuilt) SourceExists() bool {
|
func (p *Prebuilt) SourceExists() bool {
|
||||||
return p.properties.SourceExists
|
return p.properties.SourceExists
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Prebuilt) checkSingleSourceProperties() {
|
|
||||||
if !p.srcProps.IsValid() || p.srcField.Name == "" {
|
|
||||||
panic(fmt.Errorf("invalid single source prebuilt %+v", p))
|
|
||||||
}
|
|
||||||
|
|
||||||
if p.srcProps.Kind() != reflect.Struct && p.srcProps.Kind() != reflect.Interface {
|
|
||||||
panic(fmt.Errorf("invalid single source prebuilt %+v", p.srcProps))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Prebuilt) getSingleSourceFieldValue() string {
|
|
||||||
value := p.srcProps.FieldByIndex(p.srcField.Index)
|
|
||||||
if value.Kind() == reflect.Ptr {
|
|
||||||
value = value.Elem()
|
|
||||||
}
|
|
||||||
if value.Kind() != reflect.String {
|
|
||||||
panic(fmt.Errorf("prebuilt src field %q should be a string or a pointer to one", p.srcField.Name))
|
|
||||||
}
|
|
||||||
return value.String()
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user