blob: 76d3977b083d712ff91f587c2e60844169b6e961 [file] [log] [blame]
Colin Cross8e0c5112015-01-23 14:15:10 -08001// Copyright 2014 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Jamie Gennis1bc967e2014-05-27 16:34:41 -070015package blueprint
16
17import (
18 "fmt"
19 "path/filepath"
Jamie Gennis6a40c192014-07-02 16:40:31 -070020 "text/scanner"
Jamie Gennis1bc967e2014-05-27 16:34:41 -070021)
22
Jamie Gennisb9e87f62014-09-24 20:28:11 -070023// A Module handles generating all of the Ninja build actions needed to build a
Colin Crossc9028482014-12-18 16:28:54 -080024// single module based on properties defined in a Blueprints file. Module
25// objects are initially created during the parse phase of a Context using one
26// of the registered module types (and the associated ModuleFactory function).
27// The Module's properties struct is automatically filled in with the property
28// values specified in the Blueprints file (see Context.RegisterModuleType for more
Jamie Gennisb9e87f62014-09-24 20:28:11 -070029// information on this).
30//
Colin Crossc9028482014-12-18 16:28:54 -080031// A Module can be split into multiple Modules by a Mutator. All existing
32// properties set on the module will be duplicated to the new Module, and then
33// modified as necessary by the Mutator.
34//
Jamie Gennisb9e87f62014-09-24 20:28:11 -070035// The Module implementation can access the build configuration as well as any
36// modules on which on which it depends (as defined by the "deps" property
37// specified in the Blueprints file or dynamically added by implementing the
38// DynamicDependerModule interface) using the ModuleContext passed to
39// GenerateBuildActions. This ModuleContext is also used to create Ninja build
40// actions and to report errors to the user.
41//
42// In addition to implementing the GenerateBuildActions method, a Module should
43// implement methods that provide dependant modules and singletons information
44// they need to generate their build actions. These methods will only be called
45// after GenerateBuildActions is called because the Context calls
46// GenerateBuildActions in dependency-order (and singletons are invoked after
47// all the Modules). The set of methods a Module supports will determine how
48// dependant Modules interact with it.
49//
50// For example, consider a Module that is responsible for generating a library
51// that other modules can link against. The library Module might implement the
52// following interface:
53//
54// type LibraryProducer interface {
55// LibraryFileName() string
56// }
57//
58// func IsLibraryProducer(module blueprint.Module) {
59// _, ok := module.(LibraryProducer)
60// return ok
61// }
62//
63// A binary-producing Module that depends on the library Module could then do:
64//
65// func (m *myBinaryModule) GenerateBuildActions(ctx blueprint.ModuleContext) {
66// ...
67// var libraryFiles []string
68// ctx.VisitDepsDepthFirstIf(IsLibraryProducer,
69// func(module blueprint.Module) {
70// libProducer := module.(LibraryProducer)
71// libraryFiles = append(libraryFiles, libProducer.LibraryFileName())
72// })
73// ...
74// }
75//
76// to build the list of library file names that should be included in its link
77// command.
Colin Cross691a60d2015-01-07 18:08:56 -080078//
79// GenerateBuildActions may be called from multiple threads. It is guaranteed to
80// be called after it has finished being called on all dependencies and on all
81// variants of that appear earlier in the ModuleContext.VisitAllModuleVariants list.
82// Any accesses to global variables or to Module objects that are not dependencies
83// or variants of the current Module must be synchronized by the implementation of
84// GenerateBuildActions.
Jamie Gennis1bc967e2014-05-27 16:34:41 -070085type Module interface {
Jamie Gennisb9e87f62014-09-24 20:28:11 -070086 // GenerateBuildActions is called by the Context that created the Module
87 // during its generate phase. This call should generate all Ninja build
88 // actions (rules, pools, and build statements) needed to build the module.
Jamie Gennis1bc967e2014-05-27 16:34:41 -070089 GenerateBuildActions(ModuleContext)
90}
91
Jamie Gennisb9e87f62014-09-24 20:28:11 -070092// A DynamicDependerModule is a Module that may add dependencies that do not
93// appear in its "deps" property. Any Module that implements this interface
94// will have its DynamicDependencies method called by the Context that created
95// it during generate phase.
96type DynamicDependerModule interface {
97 Module
98
99 // DynamicDependencies is called by the Context that created the
100 // DynamicDependerModule during its generate phase. This call should return
101 // the list of module names that the DynamicDependerModule depends on
102 // dynamically. Module names that already appear in the "deps" property may
103 // but do not need to be included in the returned list.
104 DynamicDependencies(DynamicDependerModuleContext) []string
105}
106
Colin Crossbe1a9a12014-12-18 11:05:45 -0800107type BaseModuleContext interface {
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700108 ModuleName() string
109 ModuleDir() string
Jamie Gennis6eb4d242014-06-11 18:31:16 -0700110 Config() interface{}
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700111
David Allison701fbad2014-10-29 14:51:13 -0700112 ContainsProperty(name string) bool
Jamie Gennis6a40c192014-07-02 16:40:31 -0700113 Errorf(pos scanner.Position, fmt string, args ...interface{})
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700114 ModuleErrorf(fmt string, args ...interface{})
115 PropertyErrorf(property, fmt string, args ...interface{})
Jamie Gennis6a40c192014-07-02 16:40:31 -0700116 Failed() bool
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700117}
118
Colin Crossbe1a9a12014-12-18 11:05:45 -0800119type DynamicDependerModuleContext interface {
120 BaseModuleContext
Colin Cross65569e42015-03-10 20:08:19 -0700121
Colin Crossf5e34b92015-03-13 16:02:36 -0700122 AddVariationDependencies([]Variation, ...string)
Colin Cross89486232015-05-08 11:14:54 -0700123 AddFarVariationDependencies([]Variation, ...string)
Colin Crossbe1a9a12014-12-18 11:05:45 -0800124}
125
Colin Cross1455a0f2014-12-17 13:23:56 -0800126type ModuleContext interface {
Colin Crossbe1a9a12014-12-18 11:05:45 -0800127 BaseModuleContext
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700128
129 OtherModuleName(m Module) string
130 OtherModuleErrorf(m Module, fmt string, args ...interface{})
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700131
Colin Crossc7ffa302015-02-10 11:24:52 -0800132 VisitDirectDeps(visit func(Module))
133 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
Colin Crossb2e7b5d2014-11-11 14:18:53 -0800134 VisitDepsDepthFirst(visit func(Module))
135 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
Colin Crossb2e7b5d2014-11-11 14:18:53 -0800136
Colin Crossc9028482014-12-18 16:28:54 -0800137 ModuleSubDir() string
138
Jamie Gennis2fb20952014-10-03 02:49:58 -0700139 Variable(pctx *PackageContext, name, value string)
140 Rule(pctx *PackageContext, name string, params RuleParams, argNames ...string) Rule
141 Build(pctx *PackageContext, params BuildParams)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700142
Mathias Agopian5b8477d2014-06-25 17:21:54 -0700143 AddNinjaFileDeps(deps ...string)
Colin Crossc9028482014-12-18 16:28:54 -0800144
145 PrimaryModule() Module
Colin Cross80ad04d2015-01-06 16:19:59 -0800146 FinalModule() Module
147 VisitAllModuleVariants(visit func(Module))
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700148}
149
Colin Crossbe1a9a12014-12-18 11:05:45 -0800150var _ BaseModuleContext = (*baseModuleContext)(nil)
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700151
Colin Crossbe1a9a12014-12-18 11:05:45 -0800152type baseModuleContext struct {
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700153 context *Context
154 config interface{}
Colin Crossed342d92015-03-11 00:57:25 -0700155 module *moduleInfo
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700156 errs []error
157}
158
Colin Crossbe1a9a12014-12-18 11:05:45 -0800159func (d *baseModuleContext) ModuleName() string {
Colin Crossed342d92015-03-11 00:57:25 -0700160 return d.module.properties.Name
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700161}
162
Colin Crossbe1a9a12014-12-18 11:05:45 -0800163func (d *baseModuleContext) ContainsProperty(name string) bool {
Colin Crossed342d92015-03-11 00:57:25 -0700164 _, ok := d.module.propertyPos[name]
David Allison701fbad2014-10-29 14:51:13 -0700165 return ok
166}
167
Colin Crossbe1a9a12014-12-18 11:05:45 -0800168func (d *baseModuleContext) ModuleDir() string {
Colin Crossed342d92015-03-11 00:57:25 -0700169 return filepath.Dir(d.module.relBlueprintsFile)
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700170}
171
Colin Crossbe1a9a12014-12-18 11:05:45 -0800172func (d *baseModuleContext) Config() interface{} {
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700173 return d.config
174}
175
Colin Crossbe1a9a12014-12-18 11:05:45 -0800176func (d *baseModuleContext) Errorf(pos scanner.Position,
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700177 format string, args ...interface{}) {
178
179 d.errs = append(d.errs, &Error{
180 Err: fmt.Errorf(format, args...),
181 Pos: pos,
182 })
183}
184
Colin Crossbe1a9a12014-12-18 11:05:45 -0800185func (d *baseModuleContext) ModuleErrorf(format string,
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700186 args ...interface{}) {
187
188 d.errs = append(d.errs, &Error{
189 Err: fmt.Errorf(format, args...),
Colin Crossed342d92015-03-11 00:57:25 -0700190 Pos: d.module.pos,
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700191 })
192}
193
Colin Crossbe1a9a12014-12-18 11:05:45 -0800194func (d *baseModuleContext) PropertyErrorf(property, format string,
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700195 args ...interface{}) {
196
Colin Crossed342d92015-03-11 00:57:25 -0700197 pos, ok := d.module.propertyPos[property]
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700198 if !ok {
199 panic(fmt.Errorf("property %q was not set for this module", property))
200 }
201
202 d.errs = append(d.errs, &Error{
203 Err: fmt.Errorf(format, args...),
204 Pos: pos,
205 })
206}
207
Colin Crossbe1a9a12014-12-18 11:05:45 -0800208func (d *baseModuleContext) Failed() bool {
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700209 return len(d.errs) > 0
210}
211
Colin Cross1455a0f2014-12-17 13:23:56 -0800212var _ ModuleContext = (*moduleContext)(nil)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700213
Colin Cross1455a0f2014-12-17 13:23:56 -0800214type moduleContext struct {
Colin Crossbe1a9a12014-12-18 11:05:45 -0800215 baseModuleContext
Colin Cross1455a0f2014-12-17 13:23:56 -0800216 scope *localScope
217 ninjaFileDeps []string
218 actionDefs localBuildActions
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700219}
220
Colin Crossed342d92015-03-11 00:57:25 -0700221func (m *moduleContext) OtherModuleName(logicModule Module) string {
222 module := m.context.moduleInfo[logicModule]
223 return module.properties.Name
Jamie Gennisd4c53d82014-06-22 17:02:55 -0700224}
225
Colin Crossed342d92015-03-11 00:57:25 -0700226func (m *moduleContext) OtherModuleErrorf(logicModule Module, format string,
Jamie Gennisd4c53d82014-06-22 17:02:55 -0700227 args ...interface{}) {
228
Colin Crossed342d92015-03-11 00:57:25 -0700229 module := m.context.moduleInfo[logicModule]
Jamie Gennisd4c53d82014-06-22 17:02:55 -0700230 m.errs = append(m.errs, &Error{
231 Err: fmt.Errorf(format, args...),
Colin Crossed342d92015-03-11 00:57:25 -0700232 Pos: module.pos,
Jamie Gennisd4c53d82014-06-22 17:02:55 -0700233 })
234}
235
Colin Crossc7ffa302015-02-10 11:24:52 -0800236func (m *moduleContext) VisitDirectDeps(visit func(Module)) {
237 m.context.visitDirectDeps(m.module, visit)
238}
239
240func (m *moduleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
241 m.context.visitDirectDepsIf(m.module, pred, visit)
242}
243
Colin Cross1455a0f2014-12-17 13:23:56 -0800244func (m *moduleContext) VisitDepsDepthFirst(visit func(Module)) {
Colin Crossb2e7b5d2014-11-11 14:18:53 -0800245 m.context.visitDepsDepthFirst(m.module, visit)
246}
247
Colin Cross1455a0f2014-12-17 13:23:56 -0800248func (m *moduleContext) VisitDepsDepthFirstIf(pred func(Module) bool,
Colin Crossb2e7b5d2014-11-11 14:18:53 -0800249 visit func(Module)) {
250
251 m.context.visitDepsDepthFirstIf(m.module, pred, visit)
252}
253
Colin Crossc9028482014-12-18 16:28:54 -0800254func (m *moduleContext) ModuleSubDir() string {
Colin Crosse7daa222015-03-11 14:35:41 -0700255 return m.module.variantName
Colin Crossc9028482014-12-18 16:28:54 -0800256}
257
Jamie Gennis2fb20952014-10-03 02:49:58 -0700258func (m *moduleContext) Variable(pctx *PackageContext, name, value string) {
259 m.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700260
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700261 v, err := m.scope.AddLocalVariable(name, value)
262 if err != nil {
263 panic(err)
264 }
265
266 m.actionDefs.variables = append(m.actionDefs.variables, v)
267}
268
Jamie Gennis2fb20952014-10-03 02:49:58 -0700269func (m *moduleContext) Rule(pctx *PackageContext, name string,
270 params RuleParams, argNames ...string) Rule {
Jamie Genniscbc6f862014-06-05 20:00:22 -0700271
Jamie Gennis2fb20952014-10-03 02:49:58 -0700272 m.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700273
Jamie Genniscbc6f862014-06-05 20:00:22 -0700274 r, err := m.scope.AddLocalRule(name, &params, argNames...)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700275 if err != nil {
276 panic(err)
277 }
278
279 m.actionDefs.rules = append(m.actionDefs.rules, r)
280
281 return r
282}
283
Jamie Gennis2fb20952014-10-03 02:49:58 -0700284func (m *moduleContext) Build(pctx *PackageContext, params BuildParams) {
285 m.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700286
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700287 def, err := parseBuildParams(m.scope, &params)
288 if err != nil {
289 panic(err)
290 }
291
292 m.actionDefs.buildDefs = append(m.actionDefs.buildDefs, def)
293}
294
Mathias Agopian5b8477d2014-06-25 17:21:54 -0700295func (m *moduleContext) AddNinjaFileDeps(deps ...string) {
296 m.ninjaFileDeps = append(m.ninjaFileDeps, deps...)
297}
Colin Crossc9028482014-12-18 16:28:54 -0800298
299func (m *moduleContext) PrimaryModule() Module {
Colin Cross80ad04d2015-01-06 16:19:59 -0800300 return m.module.group.modules[0].logicModule
301}
302
303func (m *moduleContext) FinalModule() Module {
304 return m.module.group.modules[len(m.module.group.modules)-1].logicModule
305}
306
307func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) {
308 for _, module := range m.module.group.modules {
309 visit(module.logicModule)
310 }
Colin Crossc9028482014-12-18 16:28:54 -0800311}
312
313//
Colin Cross65569e42015-03-10 20:08:19 -0700314// DynamicDependerModuleContext
315//
316
317type dynamicDependerModuleContext struct {
318 baseModuleContext
319
320 module *moduleInfo
321}
322
Colin Crossf5e34b92015-03-13 16:02:36 -0700323// AddVariationDependencies adds deps as dependencies of the current module, but uses the variations
324// argument to select which variant of the dependency to use. A variant of the dependency must
325// exist that matches the all of the non-local variations of the current module, plus the variations
326// argument.
327func (mctx *dynamicDependerModuleContext) AddVariationDependencies(variations []Variation,
328 deps ...string) {
329
Colin Cross65569e42015-03-10 20:08:19 -0700330 for _, dep := range deps {
Colin Cross89486232015-05-08 11:14:54 -0700331 errs := mctx.context.addVariationDependency(mctx.module, variations, dep, false)
332 if len(errs) > 0 {
333 mctx.errs = append(mctx.errs, errs...)
334 }
335 }
336}
337
338// AddFarVariationDependencies adds deps as dependencies of the current module, but uses the
339// variations argument to select which variant of the dependency to use. A variant of the
340// dependency must exist that matches the variations argument, but may also have other variations.
341// For any unspecified variation the first variant will be used.
342//
343// Unlike AddVariationDependencies, the variations of the current module are ignored - the
344// depdendency only needs to match the supplied variations.
345func (mctx *dynamicDependerModuleContext) AddFarVariationDependencies(variations []Variation,
346 deps ...string) {
347
348 for _, dep := range deps {
349 errs := mctx.context.addVariationDependency(mctx.module, variations, dep, true)
Colin Cross65569e42015-03-10 20:08:19 -0700350 if len(errs) > 0 {
351 mctx.errs = append(mctx.errs, errs...)
352 }
353 }
354}
355
356//
Colin Crossc9028482014-12-18 16:28:54 -0800357// MutatorContext
358//
359
360type mutatorContext struct {
361 baseModuleContext
Colin Crossc9028482014-12-18 16:28:54 -0800362 name string
363 dependenciesModified bool
364}
365
366type baseMutatorContext interface {
367 BaseModuleContext
368
369 Module() Module
370}
371
Colin Cross65569e42015-03-10 20:08:19 -0700372type EarlyMutatorContext interface {
373 baseMutatorContext
374
Colin Crossf5e34b92015-03-13 16:02:36 -0700375 CreateVariations(...string) []Module
376 CreateLocalVariations(...string) []Module
Colin Cross65569e42015-03-10 20:08:19 -0700377}
378
Colin Crossc9028482014-12-18 16:28:54 -0800379type TopDownMutatorContext interface {
380 baseMutatorContext
381
382 VisitDirectDeps(visit func(Module))
383 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
384 VisitDepsDepthFirst(visit func(Module))
385 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
386}
387
388type BottomUpMutatorContext interface {
389 baseMutatorContext
390
391 AddDependency(module Module, name string)
Colin Crossf5e34b92015-03-13 16:02:36 -0700392 CreateVariations(...string) []Module
Jamie Gennis6a5825e2015-05-19 11:26:11 -0700393 CreateLocalVariations(...string) []Module
Colin Crossf5e34b92015-03-13 16:02:36 -0700394 SetDependencyVariation(string)
Colin Crossc9028482014-12-18 16:28:54 -0800395}
396
397// A Mutator function is called for each Module, and can use
Colin Crossf5e34b92015-03-13 16:02:36 -0700398// MutatorContext.CreateVariations to split a Module into multiple Modules,
Colin Crossc9028482014-12-18 16:28:54 -0800399// modifying properties on the new modules to differentiate them. It is called
400// after parsing all Blueprint files, but before generating any build rules,
401// and is always called on dependencies before being called on the depending module.
402//
403// The Mutator function should only modify members of properties structs, and not
404// members of the module struct itself, to ensure the modified values are copied
405// if a second Mutator chooses to split the module a second time.
406type TopDownMutator func(mctx TopDownMutatorContext)
407type BottomUpMutator func(mctx BottomUpMutatorContext)
Colin Cross65569e42015-03-10 20:08:19 -0700408type EarlyMutator func(mctx EarlyMutatorContext)
Colin Crossc9028482014-12-18 16:28:54 -0800409
Colin Crossf5e34b92015-03-13 16:02:36 -0700410// Split a module into mulitple variants, one for each name in the variationNames
411// parameter. It returns a list of new modules in the same order as the variationNames
Colin Crossc9028482014-12-18 16:28:54 -0800412// list.
413//
414// If any of the dependencies of the module being operated on were already split
Colin Crossf5e34b92015-03-13 16:02:36 -0700415// by calling CreateVariations with the same name, the dependency will automatically
Colin Crossc9028482014-12-18 16:28:54 -0800416// be updated to point the matching variant.
417//
418// If a module is split, and then a module depending on the first module is not split
419// when the Mutator is later called on it, the dependency of the depending module will
420// automatically be updated to point to the first variant.
Colin Crossf5e34b92015-03-13 16:02:36 -0700421func (mctx *mutatorContext) CreateVariations(variationNames ...string) []Module {
422 return mctx.createVariations(variationNames, false)
Colin Cross65569e42015-03-10 20:08:19 -0700423}
424
425// Split a module into mulitple variants, one for each name in the variantNames
426// parameter. It returns a list of new modules in the same order as the variantNames
427// list.
428//
Colin Crossf5e34b92015-03-13 16:02:36 -0700429// Local variations do not affect automatic dependency resolution - dependencies added
Colin Cross65569e42015-03-10 20:08:19 -0700430// to the split module via deps or DynamicDependerModule must exactly match a variant
Colin Crossf5e34b92015-03-13 16:02:36 -0700431// that contains all the non-local variations.
432func (mctx *mutatorContext) CreateLocalVariations(variationNames ...string) []Module {
433 return mctx.createVariations(variationNames, true)
Colin Cross65569e42015-03-10 20:08:19 -0700434}
435
Colin Crossf5e34b92015-03-13 16:02:36 -0700436func (mctx *mutatorContext) createVariations(variationNames []string, local bool) []Module {
Colin Crossc9028482014-12-18 16:28:54 -0800437 ret := []Module{}
Colin Crossf5e34b92015-03-13 16:02:36 -0700438 modules, errs := mctx.context.createVariations(mctx.module, mctx.name, variationNames)
Colin Cross174ae052015-03-03 17:37:03 -0800439 if len(errs) > 0 {
440 mctx.errs = append(mctx.errs, errs...)
441 }
Colin Crossc9028482014-12-18 16:28:54 -0800442
Colin Cross65569e42015-03-10 20:08:19 -0700443 for i, module := range modules {
Colin Crossc9028482014-12-18 16:28:54 -0800444 ret = append(ret, module.logicModule)
Colin Cross65569e42015-03-10 20:08:19 -0700445 if !local {
Colin Crossf5e34b92015-03-13 16:02:36 -0700446 module.dependencyVariant[mctx.name] = variationNames[i]
Colin Cross65569e42015-03-10 20:08:19 -0700447 }
Colin Crossc9028482014-12-18 16:28:54 -0800448 }
449
Colin Crossf5e34b92015-03-13 16:02:36 -0700450 if len(ret) != len(variationNames) {
Colin Crossc9028482014-12-18 16:28:54 -0800451 panic("oops!")
452 }
453
454 return ret
455}
456
Colin Crossf5e34b92015-03-13 16:02:36 -0700457// Set all dangling dependencies on the current module to point to the variation
Colin Crossc9028482014-12-18 16:28:54 -0800458// with given name.
Colin Crossf5e34b92015-03-13 16:02:36 -0700459func (mctx *mutatorContext) SetDependencyVariation(variationName string) {
460 mctx.context.convertDepsToVariation(mctx.module, mctx.name, variationName)
Colin Crossc9028482014-12-18 16:28:54 -0800461}
462
463func (mctx *mutatorContext) Module() Module {
464 return mctx.module.logicModule
465}
466
467// Add a dependency to the given module. The depender can be a specific variant
Colin Crossf5e34b92015-03-13 16:02:36 -0700468// of a module, but the dependee must be a module that has no variations.
Colin Crossc9028482014-12-18 16:28:54 -0800469// Does not affect the ordering of the current mutator pass, but will be ordered
470// correctly for all future mutator passes.
471func (mctx *mutatorContext) AddDependency(module Module, depName string) {
Colin Cross65569e42015-03-10 20:08:19 -0700472 errs := mctx.context.addDependency(mctx.context.moduleInfo[module], depName)
473 if len(errs) > 0 {
474 mctx.errs = append(mctx.errs, errs...)
475 }
Colin Crossc9028482014-12-18 16:28:54 -0800476 mctx.dependenciesModified = true
477}
478
479func (mctx *mutatorContext) VisitDirectDeps(visit func(Module)) {
480 mctx.context.visitDirectDeps(mctx.module, visit)
481}
482
483func (mctx *mutatorContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
484 mctx.context.visitDirectDepsIf(mctx.module, pred, visit)
485}
486
487func (mctx *mutatorContext) VisitDepsDepthFirst(visit func(Module)) {
488 mctx.context.visitDepsDepthFirst(mctx.module, visit)
489}
490
491func (mctx *mutatorContext) VisitDepsDepthFirstIf(pred func(Module) bool,
492 visit func(Module)) {
493
494 mctx.context.visitDepsDepthFirstIf(mctx.module, pred, visit)
495}