aboutsummaryrefslogtreecommitdiffstats
path: root/context.go
diff options
context:
space:
mode:
authorcolincross <github@colincross.com>2017-09-20 14:09:15 -0700
committerGitHub <noreply@github.com>2017-09-20 14:09:15 -0700
commitb67c1d433cf9359a4fb5e30babfa7df10c965bf0 (patch)
tree681b680bd1c4f25ed83ff6145ca11e3a52c77f77 /context.go
parent05dc49bcadf59252660610d52038f98c50db3d40 (diff)
parentd40859438ebe92b256856999210a0fcced10bae5 (diff)
downloadandroid_build_blueprint-b67c1d433cf9359a4fb5e30babfa7df10c965bf0.tar.gz
android_build_blueprint-b67c1d433cf9359a4fb5e30babfa7df10c965bf0.tar.bz2
android_build_blueprint-b67c1d433cf9359a4fb5e30babfa7df10c965bf0.zip
Merge pull request #166 from colincross/create
Add TopDownMutatorContext.CreateModule
Diffstat (limited to 'context.go')
-rw-r--r--context.go151
1 files changed, 88 insertions, 63 deletions
diff --git a/context.go b/context.go
index 4b9ea72..414871d 100644
--- a/context.go
+++ b/context.go
@@ -158,6 +158,7 @@ type moduleGroup struct {
type moduleInfo struct {
// set during Parse
typeName string
+ factory ModuleFactory
relBlueprintsFile string
pos scanner.Position
propertyPos map[string]scanner.Position
@@ -166,9 +167,9 @@ type moduleInfo struct {
variant variationMap
dependencyVariant variationMap
- logicModule Module
- group *moduleGroup
- moduleProperties []interface{}
+ logicModule Module
+ group *moduleGroup
+ properties []interface{}
// set during ResolveDependencies
directDeps []depInfo
@@ -261,12 +262,8 @@ type mutatorInfo struct {
parallel bool
}
-// NewContext creates a new Context object. The created context initially has
-// no module or singleton factories registered, so the RegisterModuleFactory and
-// RegisterSingletonFactory methods must be called before it can do anything
-// useful.
-func NewContext() *Context {
- ctx := &Context{
+func newContext() *Context {
+ return &Context{
moduleFactories: make(map[string]ModuleFactory),
moduleNames: make(map[string]*moduleGroup),
moduleInfo: make(map[Module]*moduleInfo),
@@ -274,6 +271,14 @@ func NewContext() *Context {
globs: make(map[string]GlobPath),
fs: pathtools.OsFs,
}
+}
+
+// NewContext creates a new Context object. The created context initially has
+// no module or singleton factories registered, so the RegisterModuleFactory and
+// RegisterSingletonFactory methods must be called before it can do anything
+// useful.
+func NewContext() *Context {
+ ctx := newContext()
ctx.RegisterBottomUpMutator("blueprint_deps", blueprintDepsMutator)
@@ -958,21 +963,15 @@ func getStringFromScope(scope *parser.Scope, v string) (string, scanner.Position
// property values. Any values stored in the module object that are not stored in properties
// structs will be lost.
func (c *Context) cloneLogicModule(origModule *moduleInfo) (Module, []interface{}) {
- typeName := origModule.typeName
- factory, ok := c.moduleFactories[typeName]
- if !ok {
- panic(fmt.Sprintf("unrecognized module type %q during cloning", typeName))
- }
-
- newLogicModule, newProperties := factory()
+ newLogicModule, newProperties := origModule.factory()
- if len(newProperties) != len(origModule.moduleProperties) {
+ if len(newProperties) != len(origModule.properties) {
panic("mismatched properties array length in " + origModule.Name())
}
for i := range newProperties {
dst := reflect.ValueOf(newProperties[i]).Elem()
- src := reflect.ValueOf(origModule.moduleProperties[i]).Elem()
+ src := reflect.ValueOf(origModule.properties[i]).Elem()
proptools.CopyProperties(dst, src)
}
@@ -1000,7 +999,7 @@ func (c *Context) createVariations(origModule *moduleInfo, mutatorName string,
// Reuse the existing module for the first new variant
// This both saves creating a new module, and causes the insertion in c.moduleInfo below
// with logicModule as the key to replace the original entry in c.moduleInfo
- newLogicModule, newProperties = origModule.logicModule, origModule.moduleProperties
+ newLogicModule, newProperties = origModule.logicModule, origModule.properties
} else {
newLogicModule, newProperties = c.cloneLogicModule(origModule)
}
@@ -1014,7 +1013,7 @@ func (c *Context) createVariations(origModule *moduleInfo, mutatorName string,
newModule.logicModule = newLogicModule
newModule.variant = newVariant
newModule.dependencyVariant = origModule.dependencyVariant.clone()
- newModule.moduleProperties = newProperties
+ newModule.properties = newProperties
if variationName != "" {
if newModule.variantName == "" {
@@ -1080,6 +1079,19 @@ func (c *Context) prettyPrintVariant(variant variationMap) string {
return strings.Join(names, ", ")
}
+func (c *Context) newModule(factory ModuleFactory) *moduleInfo {
+ logicModule, properties := factory()
+
+ module := &moduleInfo{
+ logicModule: logicModule,
+ factory: factory,
+ }
+
+ module.properties = properties
+
+ return module
+}
+
func (c *Context) processModuleDef(moduleDef *parser.Module,
relBlueprintsFile string) (*moduleInfo, []error) {
@@ -1097,17 +1109,12 @@ func (c *Context) processModuleDef(moduleDef *parser.Module,
}
}
- logicModule, properties := factory()
-
- module := &moduleInfo{
- logicModule: logicModule,
- typeName: moduleDef.Type,
- relBlueprintsFile: relBlueprintsFile,
- }
+ module := c.newModule(factory)
+ module.typeName = moduleDef.Type
- module.moduleProperties = properties
+ module.relBlueprintsFile = relBlueprintsFile
- propertyMap, errs := unpackProperties(moduleDef.Properties, properties...)
+ propertyMap, errs := unpackProperties(moduleDef.Properties, module.properties...)
if len(errs) > 0 {
return nil, errs
}
@@ -1163,21 +1170,21 @@ func (c *Context) addModule(module *moduleInfo) []error {
// modules defined in the parsed Blueprints files are valid. This means that
// the modules depended upon are defined and that no circular dependencies
// exist.
-func (c *Context) ResolveDependencies(config interface{}) []error {
- errs := c.updateDependencies()
+func (c *Context) ResolveDependencies(config interface{}) (deps []string, errs []error) {
+ errs = c.updateDependencies()
if len(errs) > 0 {
- return errs
+ return nil, errs
}
- errs = c.runMutators(config)
+ deps, errs = c.runMutators(config)
if len(errs) > 0 {
- return errs
+ return nil, errs
}
c.cloneModules()
c.dependenciesReady = true
- return nil
+ return deps, nil
}
// Default dependencies handling. If the module implements the (deprecated)
@@ -1644,10 +1651,11 @@ func (c *Context) PrepareBuildActions(config interface{}) (deps []string, errs [
c.buildActionsReady = false
if !c.dependenciesReady {
- errs := c.ResolveDependencies(config)
+ extraDeps, errs := c.ResolveDependencies(config)
if len(errs) > 0 {
return nil, errs
}
+ deps = append(deps, extraDeps...)
}
liveGlobals := newLiveTracker(config)
@@ -1664,7 +1672,8 @@ func (c *Context) PrepareBuildActions(config interface{}) (deps []string, errs [
return nil, errs
}
- deps = append(depsModules, depsSingletons...)
+ deps = append(deps, depsModules...)
+ deps = append(deps, depsSingletons...)
if c.ninjaBuildDir != nil {
liveGlobals.addNinjaStringDeps(c.ninjaBuildDir)
@@ -1687,26 +1696,28 @@ func (c *Context) PrepareBuildActions(config interface{}) (deps []string, errs [
return deps, nil
}
-func (c *Context) runMutators(config interface{}) (errs []error) {
+func (c *Context) runMutators(config interface{}) (deps []string, errs []error) {
var mutators []*mutatorInfo
mutators = append(mutators, c.earlyMutatorInfo...)
mutators = append(mutators, c.mutatorInfo...)
for _, mutator := range mutators {
+ var newDeps []string
if mutator.topDownMutator != nil {
- errs = c.runMutator(config, mutator, topDownMutator)
+ newDeps, errs = c.runMutator(config, mutator, topDownMutator)
} else if mutator.bottomUpMutator != nil {
- errs = c.runMutator(config, mutator, bottomUpMutator)
+ newDeps, errs = c.runMutator(config, mutator, bottomUpMutator)
} else {
panic("no mutator set on " + mutator.name)
}
if len(errs) > 0 {
- return errs
+ return nil, errs
}
+ deps = append(deps, newDeps...)
}
- return nil
+ return deps, nil
}
type mutatorDirection interface {
@@ -1754,7 +1765,7 @@ type reverseDep struct {
}
func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
- direction mutatorDirection) (errs []error) {
+ direction mutatorDirection) (deps []string, errs []error) {
newModuleInfo := make(map[Module]*moduleInfo)
for k, v := range c.moduleInfo {
@@ -1762,18 +1773,21 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
}
type globalStateChange struct {
- reverse []reverseDep
- rename []rename
- replace []replace
+ reverse []reverseDep
+ rename []rename
+ replace []replace
+ newModules []*moduleInfo
+ deps []string
}
reverseDeps := make(map[*moduleInfo][]depInfo)
var rename []rename
var replace []replace
+ var newModules []*moduleInfo
errsCh := make(chan []error)
globalStateCh := make(chan globalStateChange)
- newModulesCh := make(chan []*moduleInfo)
+ newVariationsCh := make(chan []*moduleInfo)
done := make(chan bool)
c.depsModified = 0
@@ -1812,15 +1826,17 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
return true
}
- if len(mctx.newModules) > 0 {
- newModulesCh <- mctx.newModules
+ if len(mctx.newVariations) > 0 {
+ newVariationsCh <- mctx.newVariations
}
- if len(mctx.reverseDeps) > 0 || len(mctx.replace) > 0 || len(mctx.rename) > 0 {
+ if len(mctx.reverseDeps) > 0 || len(mctx.replace) > 0 || len(mctx.rename) > 0 || len(mctx.newModules) > 0 {
globalStateCh <- globalStateChange{
- reverse: mctx.reverseDeps,
- replace: mctx.replace,
- rename: mctx.rename,
+ reverse: mctx.reverseDeps,
+ replace: mctx.replace,
+ rename: mctx.rename,
+ newModules: mctx.newModules,
+ deps: mctx.ninjaFileDeps,
}
}
@@ -1839,8 +1855,10 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
}
replace = append(replace, globalStateChange.replace...)
rename = append(rename, globalStateChange.rename...)
- case newModules := <-newModulesCh:
- for _, m := range newModules {
+ newModules = append(newModules, globalStateChange.newModules...)
+ deps = append(deps, globalStateChange.deps...)
+ case newVariations := <-newVariationsCh:
+ for _, m := range newVariations {
newModuleInfo[m.logicModule] = m
}
case <-done:
@@ -1858,7 +1876,7 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
done <- true
if len(errs) > 0 {
- return errs
+ return nil, errs
}
c.moduleInfo = newModuleInfo
@@ -1888,24 +1906,32 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
c.depsModified++
}
+ for _, module := range newModules {
+ errs = c.addModule(module)
+ if len(errs) > 0 {
+ return nil, errs
+ }
+ atomic.AddUint32(&c.depsModified, 1)
+ }
+
errs = c.handleRenames(rename)
if len(errs) > 0 {
- return errs
+ return nil, errs
}
errs = c.handleReplacements(replace)
if len(errs) > 0 {
- return errs
+ return nil, errs
}
if c.depsModified > 0 {
errs = c.updateDependencies()
if len(errs) > 0 {
- return errs
+ return nil, errs
}
}
- return errs
+ return deps, errs
}
// Replaces every build logic module with a clone of itself. Prevents introducing problems where
@@ -1921,7 +1947,7 @@ func (c *Context) cloneModules() {
for _, m := range c.modulesSorted {
go func(m *moduleInfo) {
origLogicModule := m.logicModule
- m.logicModule, m.moduleProperties = c.cloneLogicModule(m)
+ m.logicModule, m.properties = c.cloneLogicModule(m)
ch <- update{origLogicModule, m}
}(m)
}
@@ -3025,8 +3051,7 @@ func (c *Context) writeAllModuleActions(nw *ninjaWriter) error {
relPos.Filename = module.relBlueprintsFile
// Get the name and location of the factory function for the module.
- factory := c.moduleFactories[module.typeName]
- factoryFunc := runtime.FuncForPC(reflect.ValueOf(factory).Pointer())
+ factoryFunc := runtime.FuncForPC(reflect.ValueOf(module.factory).Pointer())
factoryName := factoryFunc.Name()
infoMap := map[string]interface{}{