Merge "Deterministically report path errors to all callers of dexpreopt.GetGlobalConfig"

This commit is contained in:
Colin Cross 2022-06-02 17:44:17 +00:00 committed by Gerrit Code Review
commit ff85bf9a75

View file

@ -250,8 +250,9 @@ func ParseGlobalConfig(ctx android.PathContext, data []byte) (*GlobalConfig, err
}
type globalConfigAndRaw struct {
global *GlobalConfig
data []byte
global *GlobalConfig
data []byte
pathErrors []error
}
// GetGlobalConfig returns the global dexpreopt.config that's created in the
@ -272,16 +273,26 @@ func GetGlobalConfigRawData(ctx android.PathContext) []byte {
var globalConfigOnceKey = android.NewOnceKey("DexpreoptGlobalConfig")
var testGlobalConfigOnceKey = android.NewOnceKey("TestDexpreoptGlobalConfig")
type pathContextErrorCollector struct {
android.PathContext
errors []error
}
func (p *pathContextErrorCollector) Errorf(format string, args ...interface{}) {
p.errors = append(p.errors, fmt.Errorf(format, args...))
}
func getGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw {
return ctx.Config().Once(globalConfigOnceKey, func() interface{} {
config := ctx.Config().Once(globalConfigOnceKey, func() interface{} {
if data, err := ctx.Config().DexpreoptGlobalConfig(ctx); err != nil {
panic(err)
} else if data != nil {
globalConfig, err := ParseGlobalConfig(ctx, data)
pathErrorCollectorCtx := &pathContextErrorCollector{PathContext: ctx}
globalConfig, err := ParseGlobalConfig(pathErrorCollectorCtx, data)
if err != nil {
panic(err)
}
return globalConfigAndRaw{globalConfig, data}
return globalConfigAndRaw{globalConfig, data, pathErrorCollectorCtx.errors}
}
// No global config filename set, see if there is a test config set
@ -291,16 +302,35 @@ func getGlobalConfigRaw(ctx android.PathContext) globalConfigAndRaw {
DisablePreopt: true,
DisablePreoptBootImages: true,
DisableGenerateProfile: true,
}, nil}
}, nil, nil}
})
}).(globalConfigAndRaw)
// Avoid non-deterministic errors by reporting cached path errors on all callers.
for _, err := range config.pathErrors {
if ctx.Config().AllowMissingDependencies() {
// When AllowMissingDependencies it set, report errors through AddMissingDependencies.
// If AddMissingDependencies doesn't exist on the current context (for example when
// called with a SingletonContext), just swallow the errors since there is no way to
// report them.
if missingDepsCtx, ok := ctx.(interface {
AddMissingDependencies(missingDeps []string)
}); ok {
missingDepsCtx.AddMissingDependencies([]string{err.Error()})
}
} else {
android.ReportPathErrorf(ctx, "%w", err)
}
}
return config
}
// SetTestGlobalConfig sets a GlobalConfig that future calls to GetGlobalConfig
// will return. It must be called before the first call to GetGlobalConfig for
// the config.
func SetTestGlobalConfig(config android.Config, globalConfig *GlobalConfig) {
config.Once(testGlobalConfigOnceKey, func() interface{} { return globalConfigAndRaw{globalConfig, nil} })
config.Once(testGlobalConfigOnceKey, func() interface{} { return globalConfigAndRaw{globalConfig, nil, nil} })
}
// This struct is required to convert ModuleConfig from/to JSON.