blob: 754c2d2ddcf9cab13f90b2053fcff85debb5cd5d [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
Colin Cross763b6f12015-10-29 15:32:56 -070037// specified in the Blueprints file, dynamically added by implementing the
38// (deprecated) DynamicDependerModule interface, or dynamically added by a
39// BottomUpMutator) using the ModuleContext passed to GenerateBuildActions.
40// This ModuleContext is also used to create Ninja build actions and to report
41// errors to the user.
Jamie Gennisb9e87f62014-09-24 20:28:11 -070042//
43// In addition to implementing the GenerateBuildActions method, a Module should
44// implement methods that provide dependant modules and singletons information
45// they need to generate their build actions. These methods will only be called
46// after GenerateBuildActions is called because the Context calls
47// GenerateBuildActions in dependency-order (and singletons are invoked after
48// all the Modules). The set of methods a Module supports will determine how
49// dependant Modules interact with it.
50//
51// For example, consider a Module that is responsible for generating a library
52// that other modules can link against. The library Module might implement the
53// following interface:
54//
55// type LibraryProducer interface {
56// LibraryFileName() string
57// }
58//
59// func IsLibraryProducer(module blueprint.Module) {
60// _, ok := module.(LibraryProducer)
61// return ok
62// }
63//
64// A binary-producing Module that depends on the library Module could then do:
65//
66// func (m *myBinaryModule) GenerateBuildActions(ctx blueprint.ModuleContext) {
67// ...
68// var libraryFiles []string
69// ctx.VisitDepsDepthFirstIf(IsLibraryProducer,
70// func(module blueprint.Module) {
71// libProducer := module.(LibraryProducer)
72// libraryFiles = append(libraryFiles, libProducer.LibraryFileName())
73// })
74// ...
75// }
76//
77// to build the list of library file names that should be included in its link
78// command.
Colin Cross691a60d2015-01-07 18:08:56 -080079//
80// GenerateBuildActions may be called from multiple threads. It is guaranteed to
81// be called after it has finished being called on all dependencies and on all
82// variants of that appear earlier in the ModuleContext.VisitAllModuleVariants list.
83// Any accesses to global variables or to Module objects that are not dependencies
84// or variants of the current Module must be synchronized by the implementation of
85// GenerateBuildActions.
Jamie Gennis1bc967e2014-05-27 16:34:41 -070086type Module interface {
Jamie Gennisb9e87f62014-09-24 20:28:11 -070087 // GenerateBuildActions is called by the Context that created the Module
88 // during its generate phase. This call should generate all Ninja build
89 // actions (rules, pools, and build statements) needed to build the module.
Jamie Gennis1bc967e2014-05-27 16:34:41 -070090 GenerateBuildActions(ModuleContext)
91}
92
Jamie Gennisb9e87f62014-09-24 20:28:11 -070093// A DynamicDependerModule is a Module that may add dependencies that do not
94// appear in its "deps" property. Any Module that implements this interface
95// will have its DynamicDependencies method called by the Context that created
96// it during generate phase.
Colin Cross763b6f12015-10-29 15:32:56 -070097//
98// Deprecated, use a BottomUpMutator instead
Jamie Gennisb9e87f62014-09-24 20:28:11 -070099type DynamicDependerModule interface {
100 Module
101
102 // DynamicDependencies is called by the Context that created the
103 // DynamicDependerModule during its generate phase. This call should return
104 // the list of module names that the DynamicDependerModule depends on
105 // dynamically. Module names that already appear in the "deps" property may
106 // but do not need to be included in the returned list.
107 DynamicDependencies(DynamicDependerModuleContext) []string
108}
109
Colin Crossbe1a9a12014-12-18 11:05:45 -0800110type BaseModuleContext interface {
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700111 ModuleName() string
112 ModuleDir() string
Jamie Gennis6eb4d242014-06-11 18:31:16 -0700113 Config() interface{}
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700114
David Allison701fbad2014-10-29 14:51:13 -0700115 ContainsProperty(name string) bool
Jamie Gennis6a40c192014-07-02 16:40:31 -0700116 Errorf(pos scanner.Position, fmt string, args ...interface{})
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700117 ModuleErrorf(fmt string, args ...interface{})
118 PropertyErrorf(property, fmt string, args ...interface{})
Jamie Gennis6a40c192014-07-02 16:40:31 -0700119 Failed() bool
Colin Cross763b6f12015-10-29 15:32:56 -0700120
121 moduleInfo() *moduleInfo
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700122}
123
Colin Cross763b6f12015-10-29 15:32:56 -0700124type DynamicDependerModuleContext BottomUpMutatorContext
Colin Crossbe1a9a12014-12-18 11:05:45 -0800125
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))
Yuchen Wu222e2452015-10-06 14:03:27 -0700136 WalkDeps(visit func(Module, Module) bool)
Colin Crossb2e7b5d2014-11-11 14:18:53 -0800137
Colin Crossc9028482014-12-18 16:28:54 -0800138 ModuleSubDir() string
139
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800140 Variable(pctx PackageContext, name, value string)
141 Rule(pctx PackageContext, name string, params RuleParams, argNames ...string) Rule
142 Build(pctx PackageContext, params BuildParams)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700143
Mathias Agopian5b8477d2014-06-25 17:21:54 -0700144 AddNinjaFileDeps(deps ...string)
Colin Crossc9028482014-12-18 16:28:54 -0800145
146 PrimaryModule() Module
Colin Cross80ad04d2015-01-06 16:19:59 -0800147 FinalModule() Module
148 VisitAllModuleVariants(visit func(Module))
Colin Cross036a1df2015-12-17 15:49:30 -0800149
150 GetMissingDependencies() []string
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700151}
152
Colin Crossbe1a9a12014-12-18 11:05:45 -0800153var _ BaseModuleContext = (*baseModuleContext)(nil)
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700154
Colin Crossbe1a9a12014-12-18 11:05:45 -0800155type baseModuleContext struct {
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700156 context *Context
157 config interface{}
Colin Crossed342d92015-03-11 00:57:25 -0700158 module *moduleInfo
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700159 errs []error
160}
161
Colin Cross763b6f12015-10-29 15:32:56 -0700162func (d *baseModuleContext) moduleInfo() *moduleInfo {
163 return d.module
164}
165
Colin Crossbe1a9a12014-12-18 11:05:45 -0800166func (d *baseModuleContext) ModuleName() string {
Colin Crossed342d92015-03-11 00:57:25 -0700167 return d.module.properties.Name
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700168}
169
Colin Crossbe1a9a12014-12-18 11:05:45 -0800170func (d *baseModuleContext) ContainsProperty(name string) bool {
Colin Crossed342d92015-03-11 00:57:25 -0700171 _, ok := d.module.propertyPos[name]
David Allison701fbad2014-10-29 14:51:13 -0700172 return ok
173}
174
Colin Crossbe1a9a12014-12-18 11:05:45 -0800175func (d *baseModuleContext) ModuleDir() string {
Colin Crossed342d92015-03-11 00:57:25 -0700176 return filepath.Dir(d.module.relBlueprintsFile)
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700177}
178
Colin Crossbe1a9a12014-12-18 11:05:45 -0800179func (d *baseModuleContext) Config() interface{} {
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700180 return d.config
181}
182
Colin Crossbe1a9a12014-12-18 11:05:45 -0800183func (d *baseModuleContext) Errorf(pos scanner.Position,
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700184 format string, args ...interface{}) {
185
186 d.errs = append(d.errs, &Error{
187 Err: fmt.Errorf(format, args...),
188 Pos: pos,
189 })
190}
191
Colin Crossbe1a9a12014-12-18 11:05:45 -0800192func (d *baseModuleContext) ModuleErrorf(format string,
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700193 args ...interface{}) {
194
195 d.errs = append(d.errs, &Error{
196 Err: fmt.Errorf(format, args...),
Colin Crossed342d92015-03-11 00:57:25 -0700197 Pos: d.module.pos,
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700198 })
199}
200
Colin Crossbe1a9a12014-12-18 11:05:45 -0800201func (d *baseModuleContext) PropertyErrorf(property, format string,
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700202 args ...interface{}) {
203
Colin Crossa2ca92c2015-11-02 16:10:23 -0800204 pos := d.module.propertyPos[property]
205
206 if !pos.IsValid() {
207 pos = d.module.pos
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700208 }
209
Colin Crossa2ca92c2015-11-02 16:10:23 -0800210 format = property + ": " + format
211
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700212 d.errs = append(d.errs, &Error{
213 Err: fmt.Errorf(format, args...),
214 Pos: pos,
215 })
216}
217
Colin Crossbe1a9a12014-12-18 11:05:45 -0800218func (d *baseModuleContext) Failed() bool {
Jamie Gennisb9e87f62014-09-24 20:28:11 -0700219 return len(d.errs) > 0
220}
221
Colin Cross1455a0f2014-12-17 13:23:56 -0800222var _ ModuleContext = (*moduleContext)(nil)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700223
Colin Cross1455a0f2014-12-17 13:23:56 -0800224type moduleContext struct {
Colin Crossbe1a9a12014-12-18 11:05:45 -0800225 baseModuleContext
Colin Cross036a1df2015-12-17 15:49:30 -0800226 scope *localScope
227 ninjaFileDeps []string
228 actionDefs localBuildActions
229 handledMissingDeps bool
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700230}
231
Colin Crossed342d92015-03-11 00:57:25 -0700232func (m *moduleContext) OtherModuleName(logicModule Module) string {
233 module := m.context.moduleInfo[logicModule]
234 return module.properties.Name
Jamie Gennisd4c53d82014-06-22 17:02:55 -0700235}
236
Colin Crossed342d92015-03-11 00:57:25 -0700237func (m *moduleContext) OtherModuleErrorf(logicModule Module, format string,
Jamie Gennisd4c53d82014-06-22 17:02:55 -0700238 args ...interface{}) {
239
Colin Crossed342d92015-03-11 00:57:25 -0700240 module := m.context.moduleInfo[logicModule]
Jamie Gennisd4c53d82014-06-22 17:02:55 -0700241 m.errs = append(m.errs, &Error{
242 Err: fmt.Errorf(format, args...),
Colin Crossed342d92015-03-11 00:57:25 -0700243 Pos: module.pos,
Jamie Gennisd4c53d82014-06-22 17:02:55 -0700244 })
245}
246
Colin Crossc7ffa302015-02-10 11:24:52 -0800247func (m *moduleContext) VisitDirectDeps(visit func(Module)) {
248 m.context.visitDirectDeps(m.module, visit)
249}
250
251func (m *moduleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
252 m.context.visitDirectDepsIf(m.module, pred, visit)
253}
254
Colin Cross1455a0f2014-12-17 13:23:56 -0800255func (m *moduleContext) VisitDepsDepthFirst(visit func(Module)) {
Colin Crossb2e7b5d2014-11-11 14:18:53 -0800256 m.context.visitDepsDepthFirst(m.module, visit)
257}
258
Colin Cross1455a0f2014-12-17 13:23:56 -0800259func (m *moduleContext) VisitDepsDepthFirstIf(pred func(Module) bool,
Colin Crossb2e7b5d2014-11-11 14:18:53 -0800260 visit func(Module)) {
261
262 m.context.visitDepsDepthFirstIf(m.module, pred, visit)
263}
264
Yuchen Wu222e2452015-10-06 14:03:27 -0700265func (m *moduleContext) WalkDeps(visit func(Module, Module) bool) {
266 m.context.walkDeps(m.module, visit)
267}
268
Colin Crossc9028482014-12-18 16:28:54 -0800269func (m *moduleContext) ModuleSubDir() string {
Colin Crosse7daa222015-03-11 14:35:41 -0700270 return m.module.variantName
Colin Crossc9028482014-12-18 16:28:54 -0800271}
272
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800273func (m *moduleContext) Variable(pctx PackageContext, name, value string) {
Jamie Gennis2fb20952014-10-03 02:49:58 -0700274 m.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700275
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700276 v, err := m.scope.AddLocalVariable(name, value)
277 if err != nil {
278 panic(err)
279 }
280
281 m.actionDefs.variables = append(m.actionDefs.variables, v)
282}
283
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800284func (m *moduleContext) Rule(pctx PackageContext, name string,
Jamie Gennis2fb20952014-10-03 02:49:58 -0700285 params RuleParams, argNames ...string) Rule {
Jamie Genniscbc6f862014-06-05 20:00:22 -0700286
Jamie Gennis2fb20952014-10-03 02:49:58 -0700287 m.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700288
Jamie Genniscbc6f862014-06-05 20:00:22 -0700289 r, err := m.scope.AddLocalRule(name, &params, argNames...)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700290 if err != nil {
291 panic(err)
292 }
293
294 m.actionDefs.rules = append(m.actionDefs.rules, r)
295
296 return r
297}
298
Dan Willemsenaeffbf72015-11-25 15:29:32 -0800299func (m *moduleContext) Build(pctx PackageContext, params BuildParams) {
Jamie Gennis2fb20952014-10-03 02:49:58 -0700300 m.scope.ReparentTo(pctx)
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700301
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700302 def, err := parseBuildParams(m.scope, &params)
303 if err != nil {
304 panic(err)
305 }
306
307 m.actionDefs.buildDefs = append(m.actionDefs.buildDefs, def)
308}
309
Mathias Agopian5b8477d2014-06-25 17:21:54 -0700310func (m *moduleContext) AddNinjaFileDeps(deps ...string) {
311 m.ninjaFileDeps = append(m.ninjaFileDeps, deps...)
312}
Colin Crossc9028482014-12-18 16:28:54 -0800313
314func (m *moduleContext) PrimaryModule() Module {
Colin Cross80ad04d2015-01-06 16:19:59 -0800315 return m.module.group.modules[0].logicModule
316}
317
318func (m *moduleContext) FinalModule() Module {
319 return m.module.group.modules[len(m.module.group.modules)-1].logicModule
320}
321
322func (m *moduleContext) VisitAllModuleVariants(visit func(Module)) {
323 for _, module := range m.module.group.modules {
324 visit(module.logicModule)
325 }
Colin Crossc9028482014-12-18 16:28:54 -0800326}
327
Colin Cross036a1df2015-12-17 15:49:30 -0800328func (m *moduleContext) GetMissingDependencies() []string {
329 m.handledMissingDeps = true
330 return m.module.missingDeps
331}
332
Colin Crossc9028482014-12-18 16:28:54 -0800333//
334// MutatorContext
335//
336
337type mutatorContext struct {
338 baseModuleContext
Colin Cross8d8a7af2015-11-03 16:41:29 -0800339 name string
340 reverseDeps map[*moduleInfo][]*moduleInfo
Colin Crossc9028482014-12-18 16:28:54 -0800341}
342
343type baseMutatorContext interface {
344 BaseModuleContext
345
346 Module() Module
347}
348
Colin Cross65569e42015-03-10 20:08:19 -0700349type EarlyMutatorContext interface {
350 baseMutatorContext
351
Colin Crossf5e34b92015-03-13 16:02:36 -0700352 CreateVariations(...string) []Module
353 CreateLocalVariations(...string) []Module
Colin Cross65569e42015-03-10 20:08:19 -0700354}
355
Colin Crossc9028482014-12-18 16:28:54 -0800356type TopDownMutatorContext interface {
357 baseMutatorContext
358
Colin Cross8d222332015-11-02 16:11:32 -0800359 OtherModuleName(m Module) string
360 OtherModuleErrorf(m Module, fmt string, args ...interface{})
361
Colin Crossc9028482014-12-18 16:28:54 -0800362 VisitDirectDeps(visit func(Module))
363 VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
364 VisitDepsDepthFirst(visit func(Module))
365 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
Yuchen Wu222e2452015-10-06 14:03:27 -0700366 WalkDeps(visit func(Module, Module) bool)
Colin Crossc9028482014-12-18 16:28:54 -0800367}
368
369type BottomUpMutatorContext interface {
370 baseMutatorContext
371
Colin Cross763b6f12015-10-29 15:32:56 -0700372 AddDependency(module Module, name ...string)
Dan Willemsenfdeb7242015-07-24 16:53:27 -0700373 AddReverseDependency(module Module, name string)
Colin Crossf5e34b92015-03-13 16:02:36 -0700374 CreateVariations(...string) []Module
Jamie Gennis6a5825e2015-05-19 11:26:11 -0700375 CreateLocalVariations(...string) []Module
Colin Crossf5e34b92015-03-13 16:02:36 -0700376 SetDependencyVariation(string)
Colin Cross763b6f12015-10-29 15:32:56 -0700377 AddVariationDependencies([]Variation, ...string)
378 AddFarVariationDependencies([]Variation, ...string)
Colin Crossc9028482014-12-18 16:28:54 -0800379}
380
381// A Mutator function is called for each Module, and can use
Colin Crossf5e34b92015-03-13 16:02:36 -0700382// MutatorContext.CreateVariations to split a Module into multiple Modules,
Colin Crossc9028482014-12-18 16:28:54 -0800383// modifying properties on the new modules to differentiate them. It is called
384// after parsing all Blueprint files, but before generating any build rules,
385// and is always called on dependencies before being called on the depending module.
386//
387// The Mutator function should only modify members of properties structs, and not
388// members of the module struct itself, to ensure the modified values are copied
389// if a second Mutator chooses to split the module a second time.
390type TopDownMutator func(mctx TopDownMutatorContext)
391type BottomUpMutator func(mctx BottomUpMutatorContext)
Colin Cross65569e42015-03-10 20:08:19 -0700392type EarlyMutator func(mctx EarlyMutatorContext)
Colin Crossc9028482014-12-18 16:28:54 -0800393
Colin Crossf5e34b92015-03-13 16:02:36 -0700394// Split a module into mulitple variants, one for each name in the variationNames
395// parameter. It returns a list of new modules in the same order as the variationNames
Colin Crossc9028482014-12-18 16:28:54 -0800396// list.
397//
398// If any of the dependencies of the module being operated on were already split
Colin Crossf5e34b92015-03-13 16:02:36 -0700399// by calling CreateVariations with the same name, the dependency will automatically
Colin Crossc9028482014-12-18 16:28:54 -0800400// be updated to point the matching variant.
401//
402// If a module is split, and then a module depending on the first module is not split
403// when the Mutator is later called on it, the dependency of the depending module will
404// automatically be updated to point to the first variant.
Colin Crossf5e34b92015-03-13 16:02:36 -0700405func (mctx *mutatorContext) CreateVariations(variationNames ...string) []Module {
406 return mctx.createVariations(variationNames, false)
Colin Cross65569e42015-03-10 20:08:19 -0700407}
408
409// Split a module into mulitple variants, one for each name in the variantNames
410// parameter. It returns a list of new modules in the same order as the variantNames
411// list.
412//
Colin Crossf5e34b92015-03-13 16:02:36 -0700413// Local variations do not affect automatic dependency resolution - dependencies added
Colin Cross65569e42015-03-10 20:08:19 -0700414// to the split module via deps or DynamicDependerModule must exactly match a variant
Colin Crossf5e34b92015-03-13 16:02:36 -0700415// that contains all the non-local variations.
416func (mctx *mutatorContext) CreateLocalVariations(variationNames ...string) []Module {
417 return mctx.createVariations(variationNames, true)
Colin Cross65569e42015-03-10 20:08:19 -0700418}
419
Colin Crossf5e34b92015-03-13 16:02:36 -0700420func (mctx *mutatorContext) createVariations(variationNames []string, local bool) []Module {
Colin Crossc9028482014-12-18 16:28:54 -0800421 ret := []Module{}
Colin Crossf5e34b92015-03-13 16:02:36 -0700422 modules, errs := mctx.context.createVariations(mctx.module, mctx.name, variationNames)
Colin Cross174ae052015-03-03 17:37:03 -0800423 if len(errs) > 0 {
424 mctx.errs = append(mctx.errs, errs...)
425 }
Colin Crossc9028482014-12-18 16:28:54 -0800426
Colin Cross65569e42015-03-10 20:08:19 -0700427 for i, module := range modules {
Colin Crossc9028482014-12-18 16:28:54 -0800428 ret = append(ret, module.logicModule)
Colin Cross65569e42015-03-10 20:08:19 -0700429 if !local {
Colin Crossf5e34b92015-03-13 16:02:36 -0700430 module.dependencyVariant[mctx.name] = variationNames[i]
Colin Cross65569e42015-03-10 20:08:19 -0700431 }
Colin Crossc9028482014-12-18 16:28:54 -0800432 }
433
Colin Crossf5e34b92015-03-13 16:02:36 -0700434 if len(ret) != len(variationNames) {
Colin Crossc9028482014-12-18 16:28:54 -0800435 panic("oops!")
436 }
437
438 return ret
439}
440
Colin Crossf5e34b92015-03-13 16:02:36 -0700441// Set all dangling dependencies on the current module to point to the variation
Colin Crossc9028482014-12-18 16:28:54 -0800442// with given name.
Colin Crossf5e34b92015-03-13 16:02:36 -0700443func (mctx *mutatorContext) SetDependencyVariation(variationName string) {
444 mctx.context.convertDepsToVariation(mctx.module, mctx.name, variationName)
Colin Crossc9028482014-12-18 16:28:54 -0800445}
446
447func (mctx *mutatorContext) Module() Module {
448 return mctx.module.logicModule
449}
450
Dan Willemsenfdeb7242015-07-24 16:53:27 -0700451// Add a dependency to the given module.
Colin Crossc9028482014-12-18 16:28:54 -0800452// Does not affect the ordering of the current mutator pass, but will be ordered
453// correctly for all future mutator passes.
Colin Cross763b6f12015-10-29 15:32:56 -0700454func (mctx *mutatorContext) AddDependency(module Module, deps ...string) {
455 for _, dep := range deps {
456 errs := mctx.context.addDependency(mctx.context.moduleInfo[module], dep)
457 if len(errs) > 0 {
458 mctx.errs = append(mctx.errs, errs...)
459 }
Colin Cross65569e42015-03-10 20:08:19 -0700460 }
Dan Willemsenfdeb7242015-07-24 16:53:27 -0700461}
462
463// Add a dependency from the destination to the given module.
464// Does not affect the ordering of the current mutator pass, but will be ordered
Colin Cross8d8a7af2015-11-03 16:41:29 -0800465// correctly for all future mutator passes. All reverse dependencies for a destination module are
466// collected until the end of the mutator pass, sorted by name, and then appended to the destination
467// module's dependency list.
Dan Willemsenfdeb7242015-07-24 16:53:27 -0700468func (mctx *mutatorContext) AddReverseDependency(module Module, destName string) {
Colin Cross8d8a7af2015-11-03 16:41:29 -0800469 destModule, errs := mctx.context.findReverseDependency(mctx.context.moduleInfo[module], destName)
Dan Willemsenfdeb7242015-07-24 16:53:27 -0700470 if len(errs) > 0 {
471 mctx.errs = append(mctx.errs, errs...)
Colin Cross8d8a7af2015-11-03 16:41:29 -0800472 return
Dan Willemsenfdeb7242015-07-24 16:53:27 -0700473 }
Colin Cross8d8a7af2015-11-03 16:41:29 -0800474
475 mctx.reverseDeps[destModule] = append(mctx.reverseDeps[destModule],
476 mctx.context.moduleInfo[module])
Colin Crossc9028482014-12-18 16:28:54 -0800477}
478
Colin Cross763b6f12015-10-29 15:32:56 -0700479// AddVariationDependencies adds deps as dependencies of the current module, but uses the variations
480// argument to select which variant of the dependency to use. A variant of the dependency must
481// exist that matches the all of the non-local variations of the current module, plus the variations
482// argument.
483func (mctx *mutatorContext) AddVariationDependencies(variations []Variation,
484 deps ...string) {
485
486 for _, dep := range deps {
487 errs := mctx.context.addVariationDependency(mctx.module, variations, dep, false)
488 if len(errs) > 0 {
489 mctx.errs = append(mctx.errs, errs...)
490 }
491 }
492}
493
494// AddFarVariationDependencies adds deps as dependencies of the current module, but uses the
495// variations argument to select which variant of the dependency to use. A variant of the
496// dependency must exist that matches the variations argument, but may also have other variations.
497// For any unspecified variation the first variant will be used.
498//
499// Unlike AddVariationDependencies, the variations of the current module are ignored - the
500// depdendency only needs to match the supplied variations.
501func (mctx *mutatorContext) AddFarVariationDependencies(variations []Variation,
502 deps ...string) {
503
504 for _, dep := range deps {
505 errs := mctx.context.addVariationDependency(mctx.module, variations, dep, true)
506 if len(errs) > 0 {
507 mctx.errs = append(mctx.errs, errs...)
508 }
509 }
510}
511
Colin Cross8d222332015-11-02 16:11:32 -0800512func (mctx *mutatorContext) OtherModuleName(logicModule Module) string {
513 module := mctx.context.moduleInfo[logicModule]
514 return module.properties.Name
515}
516
517func (mctx *mutatorContext) OtherModuleErrorf(logicModule Module, format string,
518 args ...interface{}) {
519
520 module := mctx.context.moduleInfo[logicModule]
521 mctx.errs = append(mctx.errs, &Error{
522 Err: fmt.Errorf(format, args...),
523 Pos: module.pos,
524 })
525}
526
Colin Crossc9028482014-12-18 16:28:54 -0800527func (mctx *mutatorContext) VisitDirectDeps(visit func(Module)) {
528 mctx.context.visitDirectDeps(mctx.module, visit)
529}
530
531func (mctx *mutatorContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
532 mctx.context.visitDirectDepsIf(mctx.module, pred, visit)
533}
534
535func (mctx *mutatorContext) VisitDepsDepthFirst(visit func(Module)) {
536 mctx.context.visitDepsDepthFirst(mctx.module, visit)
537}
538
539func (mctx *mutatorContext) VisitDepsDepthFirstIf(pred func(Module) bool,
540 visit func(Module)) {
541
542 mctx.context.visitDepsDepthFirstIf(mctx.module, pred, visit)
543}
Yuchen Wu222e2452015-10-06 14:03:27 -0700544
545func (mctx *mutatorContext) WalkDeps(visit func(Module, Module) bool) {
546 mctx.context.walkDeps(mctx.module, visit)
547}