Return dependency modules from dependency-adding methods.

The motivaion for this change is to allow writing code that uses the
newly added dependency module in the same mutator pass, for example to
add more dependencies. Like this:

  for _, m := range ctx.AddVariationDependencies(nil, tag, deps...) {
      if someModuleProperty(m); ok {
          ctx.AddVariationDependencies(nil, tag, otherDep)
      }
  }

Note that there is no guarantee that the returned module has already
been processed by the current mutator.

The patch does not add runtime overhead on findng dependency modules,
as this has already been done previously.

Test: go test
This commit is contained in:
Ulya Trafimovich 2020-08-27 11:20:23 +01:00
parent 4b3efdc5b8
commit 9577bbc922
2 changed files with 65 additions and 31 deletions

View file

@ -1591,13 +1591,13 @@ func findExactVariantOrSingle(module *moduleInfo, possible *moduleGroup, reverse
return found
}
func (c *Context) addDependency(module *moduleInfo, tag DependencyTag, depName string) []error {
func (c *Context) addDependency(module *moduleInfo, tag DependencyTag, depName string) (*moduleInfo, []error) {
if _, ok := tag.(BaseDependencyTag); ok {
panic("BaseDependencyTag is not allowed to be used directly!")
}
if depName == module.Name() {
return []error{&BlueprintError{
return nil, []error{&BlueprintError{
Err: fmt.Errorf("%q depends on itself", depName),
Pos: module.pos,
}}
@ -1605,21 +1605,21 @@ func (c *Context) addDependency(module *moduleInfo, tag DependencyTag, depName s
possibleDeps := c.moduleGroupFromName(depName, module.namespace())
if possibleDeps == nil {
return c.discoveredMissingDependencies(module, depName)
return nil, c.discoveredMissingDependencies(module, depName)
}
if m := findExactVariantOrSingle(module, possibleDeps, false); m != nil {
module.newDirectDeps = append(module.newDirectDeps, depInfo{m, tag})
atomic.AddUint32(&c.depsModified, 1)
return nil
return m, nil
}
if c.allowMissingDependencies {
// Allow missing variants.
return c.discoveredMissingDependencies(module, depName+c.prettyPrintVariant(module.variant.dependencyVariations))
return nil, c.discoveredMissingDependencies(module, depName+c.prettyPrintVariant(module.variant.dependencyVariations))
}
return []error{&BlueprintError{
return nil, []error{&BlueprintError{
Err: fmt.Errorf("dependency %q of %q missing variant:\n %s\navailable variants:\n %s",
depName, module.Name(),
c.prettyPrintVariant(module.variant.dependencyVariations),
@ -1705,14 +1705,14 @@ func findVariant(module *moduleInfo, possibleDeps *moduleGroup, variations []Var
}
func (c *Context) addVariationDependency(module *moduleInfo, variations []Variation,
tag DependencyTag, depName string, far bool) []error {
tag DependencyTag, depName string, far bool) (*moduleInfo, []error) {
if _, ok := tag.(BaseDependencyTag); ok {
panic("BaseDependencyTag is not allowed to be used directly!")
}
possibleDeps := c.moduleGroupFromName(depName, module.namespace())
if possibleDeps == nil {
return c.discoveredMissingDependencies(module, depName)
return nil, c.discoveredMissingDependencies(module, depName)
}
foundDep, newVariant := findVariant(module, possibleDeps, variations, far, false)
@ -1720,9 +1720,9 @@ func (c *Context) addVariationDependency(module *moduleInfo, variations []Variat
if foundDep == nil {
if c.allowMissingDependencies {
// Allow missing variants.
return c.discoveredMissingDependencies(module, depName+c.prettyPrintVariant(newVariant))
return nil, c.discoveredMissingDependencies(module, depName+c.prettyPrintVariant(newVariant))
}
return []error{&BlueprintError{
return nil, []error{&BlueprintError{
Err: fmt.Errorf("dependency %q of %q missing variant:\n %s\navailable variants:\n %s",
depName, module.Name(),
c.prettyPrintVariant(newVariant),
@ -1732,7 +1732,7 @@ func (c *Context) addVariationDependency(module *moduleInfo, variations []Variat
}
if module == foundDep {
return []error{&BlueprintError{
return nil, []error{&BlueprintError{
Err: fmt.Errorf("%q depends on itself", depName),
Pos: module.pos,
}}
@ -1741,18 +1741,18 @@ func (c *Context) addVariationDependency(module *moduleInfo, variations []Variat
// that module is earlier in the module list than this one, since we always
// run GenerateBuildActions in order for the variants of a module
if foundDep.group == module.group && beforeInModuleList(module, foundDep, module.group.modules) {
return []error{&BlueprintError{
return nil, []error{&BlueprintError{
Err: fmt.Errorf("%q depends on later version of itself", depName),
Pos: module.pos,
}}
}
module.newDirectDeps = append(module.newDirectDeps, depInfo{foundDep, tag})
atomic.AddUint32(&c.depsModified, 1)
return nil
return foundDep, nil
}
func (c *Context) addInterVariantDependency(origModule *moduleInfo, tag DependencyTag,
from, to Module) {
from, to Module) *moduleInfo {
if _, ok := tag.(BaseDependencyTag); ok {
panic("BaseDependencyTag is not allowed to be used directly!")
}
@ -1779,6 +1779,7 @@ func (c *Context) addInterVariantDependency(origModule *moduleInfo, tag Dependen
fromInfo.newDirectDeps = append(fromInfo.newDirectDeps, depInfo{toInfo, tag})
atomic.AddUint32(&c.depsModified, 1)
return toInfo
}
// findBlueprintDescendants returns a map linking parent Blueprints files to child Blueprints files

View file

@ -775,10 +775,15 @@ type TopDownMutatorContext interface {
type BottomUpMutatorContext interface {
BaseMutatorContext
// AddDependency adds a dependency to the given module.
// Does not affect the ordering of the current mutator pass, but will be ordered
// correctly for all future mutator passes.
AddDependency(module Module, tag DependencyTag, name ...string)
// AddDependency adds a dependency to the given module. It returns a slice of modules for each
// dependency (some entries may be nil). Does not affect the ordering of the current mutator
// pass, but will be ordered correctly for all future mutator passes.
//
// If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
// new dependencies have had the current mutator called on them. If the mutator is not
// parallel this method does not affect the ordering of the current mutator pass, but will
// be ordered correctly for all future mutator passes.
AddDependency(module Module, tag DependencyTag, name ...string) []Module
// AddReverseDependency adds a dependency from the destination to the given module.
// Does not affect the ordering of the current mutator pass, but will be ordered
@ -818,19 +823,30 @@ type BottomUpMutatorContext interface {
SetDefaultDependencyVariation(*string)
// AddVariationDependencies adds deps as dependencies of the current module, but uses the variations
// argument to select which variant of the dependency to use. A variant of the dependency must
// exist that matches the all of the non-local variations of the current module, plus the variations
// argument.
AddVariationDependencies([]Variation, DependencyTag, ...string)
// argument to select which variant of the dependency to use. It returns a slice of modules for
// each dependency (some entries may be nil). A variant of the dependency must exist that matches
// the all of the non-local variations of the current module, plus the variations argument.
//
// If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
// new dependencies have had the current mutator called on them. If the mutator is not
// parallel this method does not affect the ordering of the current mutator pass, but will
// be ordered correctly for all future mutator passes.
AddVariationDependencies([]Variation, DependencyTag, ...string) []Module
// AddFarVariationDependencies adds deps as dependencies of the current module, but uses the
// variations argument to select which variant of the dependency to use. A variant of the
// dependency must exist that matches the variations argument, but may also have other variations.
// variations argument to select which variant of the dependency to use. It returns a slice of
// modules for each dependency (some entries may be nil). A variant of the dependency must
// exist that matches the variations argument, but may also have other variations.
// For any unspecified variation the first variant will be used.
//
// Unlike AddVariationDependencies, the variations of the current module are ignored - the
// dependency only needs to match the supplied variations.
AddFarVariationDependencies([]Variation, DependencyTag, ...string)
//
// If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
// new dependencies have had the current mutator called on them. If the mutator is not
// parallel this method does not affect the ordering of the current mutator pass, but will
// be ordered correctly for all future mutator passes.
AddFarVariationDependencies([]Variation, DependencyTag, ...string) []Module
// AddInterVariantDependency adds a dependency between two variants of the same module. Variants are always
// ordered in the same orderas they were listed in CreateVariations, and AddInterVariantDependency does not change
@ -1008,14 +1024,17 @@ func (mctx *mutatorContext) Module() Module {
return mctx.module.logicModule
}
func (mctx *mutatorContext) AddDependency(module Module, tag DependencyTag, deps ...string) {
func (mctx *mutatorContext) AddDependency(module Module, tag DependencyTag, deps ...string) []Module {
depInfos := make([]Module, 0, len(deps))
for _, dep := range deps {
modInfo := mctx.context.moduleInfo[module]
errs := mctx.context.addDependency(modInfo, tag, dep)
depInfo, errs := mctx.context.addDependency(modInfo, tag, dep)
if len(errs) > 0 {
mctx.errs = append(mctx.errs, errs...)
}
depInfos = append(depInfos, maybeLogicModule(depInfo))
}
return depInfos
}
func (mctx *mutatorContext) AddReverseDependency(module Module, tag DependencyTag, destName string) {
@ -1036,25 +1055,31 @@ func (mctx *mutatorContext) AddReverseDependency(module Module, tag DependencyTa
}
func (mctx *mutatorContext) AddVariationDependencies(variations []Variation, tag DependencyTag,
deps ...string) {
deps ...string) []Module {
depInfos := make([]Module, 0, len(deps))
for _, dep := range deps {
errs := mctx.context.addVariationDependency(mctx.module, variations, tag, dep, false)
depInfo, errs := mctx.context.addVariationDependency(mctx.module, variations, tag, dep, false)
if len(errs) > 0 {
mctx.errs = append(mctx.errs, errs...)
}
depInfos = append(depInfos, maybeLogicModule(depInfo))
}
return depInfos
}
func (mctx *mutatorContext) AddFarVariationDependencies(variations []Variation, tag DependencyTag,
deps ...string) {
deps ...string) []Module {
depInfos := make([]Module, 0, len(deps))
for _, dep := range deps {
errs := mctx.context.addVariationDependency(mctx.module, variations, tag, dep, true)
depInfo, errs := mctx.context.addVariationDependency(mctx.module, variations, tag, dep, true)
if len(errs) > 0 {
mctx.errs = append(mctx.errs, errs...)
}
depInfos = append(depInfos, maybeLogicModule(depInfo))
}
return depInfos
}
func (mctx *mutatorContext) AddInterVariantDependency(tag DependencyTag, from, to Module) {
@ -1258,3 +1283,11 @@ func CheckBlueprintSyntax(moduleFactories map[string]ModuleFactory, filename str
return errs
}
func maybeLogicModule(module *moduleInfo) Module {
if module != nil {
return module.logicModule
} else {
return nil
}
}