diff --git a/context.go b/context.go index ee9beb6..1460b1b 100644 --- a/context.go +++ b/context.go @@ -1149,9 +1149,9 @@ func (c *Context) addDependency(module *moduleInfo, depName string) []error { }} } -func (c *Context) addReverseDependency(module *moduleInfo, destName string) []error { +func (c *Context) findReverseDependency(module *moduleInfo, destName string) (*moduleInfo, []error) { if destName == module.properties.Name { - return []error{&Error{ + return nil, []error{&Error{ Err: fmt.Errorf("%q depends on itself", destName), Pos: module.pos, }} @@ -1159,7 +1159,7 @@ func (c *Context) addReverseDependency(module *moduleInfo, destName string) []er destInfo, ok := c.moduleGroups[destName] if !ok { - return []error{&Error{ + return nil, []error{&Error{ Err: fmt.Errorf("%q has a reverse dependency on undefined module %q", module.properties.Name, destName), Pos: module.pos, @@ -1167,11 +1167,10 @@ func (c *Context) addReverseDependency(module *moduleInfo, destName string) []er } if m := c.findMatchingVariant(module, destInfo); m != nil { - m.directDeps = append(m.directDeps, module) - return nil + return m, nil } - return []error{&Error{ + return nil, []error{&Error{ Err: fmt.Errorf("reverse dependency %q of %q missing variant %q", destName, module.properties.Name, c.prettyPrintVariant(module.dependencyVariant)), @@ -1541,6 +1540,8 @@ func (c *Context) runTopDownMutator(config interface{}, func (c *Context) runBottomUpMutator(config interface{}, name string, mutator BottomUpMutator) (errs []error) { + reverseDeps := make(map[*moduleInfo][]*moduleInfo) + for _, module := range c.modulesSorted { newModules := make([]*moduleInfo, 0, 1) @@ -1554,7 +1555,8 @@ func (c *Context) runBottomUpMutator(config interface{}, config: config, module: module, }, - name: name, + name: name, + reverseDeps: reverseDeps, } mutator(mctx) @@ -1580,6 +1582,11 @@ func (c *Context) runBottomUpMutator(config interface{}, module.group.modules = spliceModules(module.group.modules, module, newModules) } + for module, deps := range reverseDeps { + sort.Sort(moduleSorter(deps)) + module.directDeps = append(module.directDeps, deps...) + } + errs = c.updateDependencies() if len(errs) > 0 { return errs diff --git a/module_ctx.go b/module_ctx.go index 5fd04d0..ce3cb8a 100644 --- a/module_ctx.go +++ b/module_ctx.go @@ -328,7 +328,8 @@ func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) { type mutatorContext struct { baseModuleContext - name string + name string + reverseDeps map[*moduleInfo][]*moduleInfo } type baseMutatorContext interface { @@ -453,12 +454,18 @@ func (mctx *mutatorContext) AddDependency(module Module, deps ...string) { // Add a dependency from the destination to the given module. // Does not affect the ordering of the current mutator pass, but will be ordered -// correctly for all future mutator passes. +// correctly for all future mutator passes. All reverse dependencies for a destination module are +// collected until the end of the mutator pass, sorted by name, and then appended to the destination +// module's dependency list. func (mctx *mutatorContext) AddReverseDependency(module Module, destName string) { - errs := mctx.context.addReverseDependency(mctx.module, destName) + destModule, errs := mctx.context.findReverseDependency(mctx.context.moduleInfo[module], destName) if len(errs) > 0 { mctx.errs = append(mctx.errs, errs...) + return } + + mctx.reverseDeps[destModule] = append(mctx.reverseDeps[destModule], + mctx.context.moduleInfo[module]) } // AddVariationDependencies adds deps as dependencies of the current module, but uses the variations