a963b94cde
This allows using select statements with it. Bug: 323382414 Test: m nothing --no-skip-soong-tests Change-Id: I6f3efaaa3d82505e38a91ee4ba0e18e404360191 Merged-In: If355d24506e3f117d27b21442a6c02bca3402dc7
582 lines
24 KiB
Go
582 lines
24 KiB
Go
// Copyright 2015 Google Inc. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package android
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/google/blueprint"
|
|
"github.com/google/blueprint/proptools"
|
|
)
|
|
|
|
// BaseModuleContext is the same as blueprint.BaseModuleContext except that Config() returns
|
|
// a Config instead of an interface{}, and some methods have been wrapped to use an android.Module
|
|
// instead of a blueprint.Module, plus some extra methods that return Android-specific information
|
|
// about the current module.
|
|
type BaseModuleContext interface {
|
|
ArchModuleContext
|
|
EarlyModuleContext
|
|
|
|
blueprintBaseModuleContext() blueprint.BaseModuleContext
|
|
|
|
// OtherModuleName returns the name of another Module. See BaseModuleContext.ModuleName for more information.
|
|
// It is intended for use inside the visit functions of Visit* and WalkDeps.
|
|
OtherModuleName(m blueprint.Module) string
|
|
|
|
// OtherModuleDir returns the directory of another Module. See BaseModuleContext.ModuleDir for more information.
|
|
// It is intended for use inside the visit functions of Visit* and WalkDeps.
|
|
OtherModuleDir(m blueprint.Module) string
|
|
|
|
// OtherModuleErrorf reports an error on another Module. See BaseModuleContext.ModuleErrorf for more information.
|
|
// It is intended for use inside the visit functions of Visit* and WalkDeps.
|
|
OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
|
|
|
|
// OtherModuleDependencyTag returns the dependency tag used to depend on a module, or nil if there is no dependency
|
|
// on the module. When called inside a Visit* method with current module being visited, and there are multiple
|
|
// dependencies on the module being visited, it returns the dependency tag used for the current dependency.
|
|
OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
|
|
|
|
// OtherModuleExists returns true if a module with the specified name exists, as determined by the NameInterface
|
|
// passed to Context.SetNameInterface, or SimpleNameInterface if it was not called.
|
|
OtherModuleExists(name string) bool
|
|
|
|
// OtherModuleDependencyVariantExists returns true if a module with the
|
|
// specified name and variant exists. The variant must match the given
|
|
// variations. It must also match all the non-local variations of the current
|
|
// module. In other words, it checks for the module that AddVariationDependencies
|
|
// would add a dependency on with the same arguments.
|
|
OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool
|
|
|
|
// OtherModuleFarDependencyVariantExists returns true if a module with the
|
|
// specified name and variant exists. The variant must match the given
|
|
// variations, but not the non-local variations of the current module. In
|
|
// other words, it checks for the module that AddFarVariationDependencies
|
|
// would add a dependency on with the same arguments.
|
|
OtherModuleFarDependencyVariantExists(variations []blueprint.Variation, name string) bool
|
|
|
|
// OtherModuleReverseDependencyVariantExists returns true if a module with the
|
|
// specified name exists with the same variations as the current module. In
|
|
// other words, it checks for the module that AddReverseDependency would add a
|
|
// dependency on with the same argument.
|
|
OtherModuleReverseDependencyVariantExists(name string) bool
|
|
|
|
// OtherModuleType returns the type of another Module. See BaseModuleContext.ModuleType for more information.
|
|
// It is intended for use inside the visit functions of Visit* and WalkDeps.
|
|
OtherModuleType(m blueprint.Module) string
|
|
|
|
// otherModuleProvider returns the value for a provider for the given module. If the value is
|
|
// not set it returns nil and false. The value returned may be a deep copy of the value originally
|
|
// passed to SetProvider.
|
|
//
|
|
// This method shouldn't be used directly, prefer the type-safe android.OtherModuleProvider instead.
|
|
otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool)
|
|
|
|
// Provider returns the value for a provider for the current module. If the value is
|
|
// not set it returns nil and false. It panics if called before the appropriate
|
|
// mutator or GenerateBuildActions pass for the provider. The value returned may be a deep
|
|
// copy of the value originally passed to SetProvider.
|
|
//
|
|
// This method shouldn't be used directly, prefer the type-safe android.ModuleProvider instead.
|
|
provider(provider blueprint.AnyProviderKey) (any, bool)
|
|
|
|
// setProvider sets the value for a provider for the current module. It panics if not called
|
|
// during the appropriate mutator or GenerateBuildActions pass for the provider, if the value
|
|
// is not of the appropriate type, or if the value has already been set. The value should not
|
|
// be modified after being passed to SetProvider.
|
|
//
|
|
// This method shouldn't be used directly, prefer the type-safe android.SetProvider instead.
|
|
setProvider(provider blueprint.AnyProviderKey, value any)
|
|
|
|
GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module
|
|
|
|
// GetDirectDepWithTag returns the Module the direct dependency with the specified name, or nil if
|
|
// none exists. It panics if the dependency does not have the specified tag. It skips any
|
|
// dependencies that are not an android.Module.
|
|
GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module
|
|
|
|
// GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified
|
|
// name, or nil if none exists. If there are multiple dependencies on the same module it returns
|
|
// the first DependencyTag.
|
|
GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag)
|
|
|
|
// VisitDirectDepsBlueprint calls visit for each direct dependency. If there are multiple
|
|
// direct dependencies on the same module visit will be called multiple times on that module
|
|
// and OtherModuleDependencyTag will return a different tag for each.
|
|
//
|
|
// The Module passed to the visit function should not be retained outside of the visit
|
|
// function, it may be invalidated by future mutators.
|
|
VisitDirectDepsBlueprint(visit func(blueprint.Module))
|
|
|
|
// VisitDirectDepsIgnoreBlueprint calls visit for each direct dependency. If there are multiple
|
|
// direct dependencies on the same module visit will be called multiple times on that module
|
|
// and OtherModuleDependencyTag will return a different tag for each. It silently ignores any
|
|
// dependencies that are not an android.Module.
|
|
//
|
|
// The Module passed to the visit function should not be retained outside of the visit
|
|
// function, it may be invalidated by future mutators.
|
|
VisitDirectDepsIgnoreBlueprint(visit func(Module))
|
|
|
|
// VisitDirectDeps calls visit for each direct dependency. If there are multiple
|
|
// direct dependencies on the same module visit will be called multiple times on that module
|
|
// and OtherModuleDependencyTag will return a different tag for each. It raises an error if any of the
|
|
// dependencies are not an android.Module.
|
|
//
|
|
// The Module passed to the visit function should not be retained outside of the visit
|
|
// function, it may be invalidated by future mutators.
|
|
VisitDirectDeps(visit func(Module))
|
|
|
|
VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module))
|
|
|
|
// VisitDirectDepsIf calls pred for each direct dependency, and if pred returns true calls visit. If there are
|
|
// multiple direct dependencies on the same module pred and visit will be called multiple times on that module and
|
|
// OtherModuleDependencyTag will return a different tag for each. It skips any
|
|
// dependencies that are not an android.Module.
|
|
//
|
|
// The Module passed to the visit function should not be retained outside of the visit function, it may be
|
|
// invalidated by future mutators.
|
|
VisitDirectDepsIf(pred func(Module) bool, visit func(Module))
|
|
// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
|
|
VisitDepsDepthFirst(visit func(Module))
|
|
// Deprecated: use WalkDeps instead to support multiple dependency tags on the same module
|
|
VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
|
|
|
|
// WalkDeps calls visit for each transitive dependency, traversing the dependency tree in top down order. visit may
|
|
// be called multiple times for the same (child, parent) pair if there are multiple direct dependencies between the
|
|
// child and parent with different tags. OtherModuleDependencyTag will return the tag for the currently visited
|
|
// (child, parent) pair. If visit returns false WalkDeps will not continue recursing down to child. It skips
|
|
// any dependencies that are not an android.Module.
|
|
//
|
|
// The Modules passed to the visit function should not be retained outside of the visit function, they may be
|
|
// invalidated by future mutators.
|
|
WalkDeps(visit func(child, parent Module) bool)
|
|
|
|
// WalkDepsBlueprint calls visit for each transitive dependency, traversing the dependency
|
|
// tree in top down order. visit may be called multiple times for the same (child, parent)
|
|
// pair if there are multiple direct dependencies between the child and parent with different
|
|
// tags. OtherModuleDependencyTag will return the tag for the currently visited
|
|
// (child, parent) pair. If visit returns false WalkDeps will not continue recursing down
|
|
// to child.
|
|
//
|
|
// The Modules passed to the visit function should not be retained outside of the visit function, they may be
|
|
// invalidated by future mutators.
|
|
WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool)
|
|
|
|
// GetWalkPath is supposed to be called in visit function passed in WalkDeps()
|
|
// and returns a top-down dependency path from a start module to current child module.
|
|
GetWalkPath() []Module
|
|
|
|
// PrimaryModule returns the first variant of the current module. Variants of a module are always visited in
|
|
// order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from the
|
|
// Module returned by PrimaryModule without data races. This can be used to perform singleton actions that are
|
|
// only done once for all variants of a module.
|
|
PrimaryModule() Module
|
|
|
|
// FinalModule returns the last variant of the current module. Variants of a module are always visited in
|
|
// order by mutators and GenerateBuildActions, so the data created by the current mutator can be read from all
|
|
// variants using VisitAllModuleVariants if the current module == FinalModule(). This can be used to perform
|
|
// singleton actions that are only done once for all variants of a module.
|
|
FinalModule() Module
|
|
|
|
// VisitAllModuleVariants calls visit for each variant of the current module. Variants of a module are always
|
|
// visited in order by mutators and GenerateBuildActions, so the data created by the current mutator can be read
|
|
// from all variants if the current module == FinalModule(). Otherwise, care must be taken to not access any
|
|
// data modified by the current mutator.
|
|
VisitAllModuleVariants(visit func(Module))
|
|
|
|
// GetTagPath is supposed to be called in visit function passed in WalkDeps()
|
|
// and returns a top-down dependency tags path from a start module to current child module.
|
|
// It has one less entry than GetWalkPath() as it contains the dependency tags that
|
|
// exist between each adjacent pair of modules in the GetWalkPath().
|
|
// GetTagPath()[i] is the tag between GetWalkPath()[i] and GetWalkPath()[i+1]
|
|
GetTagPath() []blueprint.DependencyTag
|
|
|
|
// GetPathString is supposed to be called in visit function passed in WalkDeps()
|
|
// and returns a multi-line string showing the modules and dependency tags
|
|
// among them along the top-down dependency path from a start module to current child module.
|
|
// skipFirst when set to true, the output doesn't include the start module,
|
|
// which is already printed when this function is used along with ModuleErrorf().
|
|
GetPathString(skipFirst bool) string
|
|
|
|
AddMissingDependencies(missingDeps []string)
|
|
|
|
// getMissingDependencies returns the list of missing dependencies.
|
|
// Calling this function prevents adding new dependencies.
|
|
getMissingDependencies() []string
|
|
|
|
// EvaluateConfiguration makes ModuleContext a valid proptools.ConfigurableEvaluator, so this context
|
|
// can be used to evaluate the final value of Configurable properties.
|
|
EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue
|
|
}
|
|
|
|
type baseModuleContext struct {
|
|
bp blueprint.BaseModuleContext
|
|
earlyModuleContext
|
|
archModuleContext
|
|
|
|
walkPath []Module
|
|
tagPath []blueprint.DependencyTag
|
|
|
|
strictVisitDeps bool // If true, enforce that all dependencies are enabled
|
|
|
|
}
|
|
|
|
func (b *baseModuleContext) OtherModuleName(m blueprint.Module) string {
|
|
return b.bp.OtherModuleName(m)
|
|
}
|
|
func (b *baseModuleContext) OtherModuleDir(m blueprint.Module) string { return b.bp.OtherModuleDir(m) }
|
|
func (b *baseModuleContext) OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) {
|
|
b.bp.OtherModuleErrorf(m, fmt, args...)
|
|
}
|
|
func (b *baseModuleContext) OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag {
|
|
return b.bp.OtherModuleDependencyTag(m)
|
|
}
|
|
func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) }
|
|
func (b *baseModuleContext) OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool {
|
|
return b.bp.OtherModuleDependencyVariantExists(variations, name)
|
|
}
|
|
func (b *baseModuleContext) OtherModuleFarDependencyVariantExists(variations []blueprint.Variation, name string) bool {
|
|
return b.bp.OtherModuleFarDependencyVariantExists(variations, name)
|
|
}
|
|
func (b *baseModuleContext) OtherModuleReverseDependencyVariantExists(name string) bool {
|
|
return b.bp.OtherModuleReverseDependencyVariantExists(name)
|
|
}
|
|
func (b *baseModuleContext) OtherModuleType(m blueprint.Module) string {
|
|
return b.bp.OtherModuleType(m)
|
|
}
|
|
|
|
func (b *baseModuleContext) otherModuleProvider(m blueprint.Module, provider blueprint.AnyProviderKey) (any, bool) {
|
|
return b.bp.OtherModuleProvider(m, provider)
|
|
}
|
|
|
|
func (b *baseModuleContext) provider(provider blueprint.AnyProviderKey) (any, bool) {
|
|
return b.bp.Provider(provider)
|
|
}
|
|
|
|
func (b *baseModuleContext) setProvider(provider blueprint.AnyProviderKey, value any) {
|
|
b.bp.SetProvider(provider, value)
|
|
}
|
|
|
|
func (b *baseModuleContext) GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module {
|
|
return b.bp.GetDirectDepWithTag(name, tag)
|
|
}
|
|
|
|
func (b *baseModuleContext) blueprintBaseModuleContext() blueprint.BaseModuleContext {
|
|
return b.bp
|
|
}
|
|
|
|
func (b *baseModuleContext) AddMissingDependencies(deps []string) {
|
|
if deps != nil {
|
|
missingDeps := &b.Module().base().commonProperties.MissingDeps
|
|
*missingDeps = append(*missingDeps, deps...)
|
|
*missingDeps = FirstUniqueStrings(*missingDeps)
|
|
}
|
|
}
|
|
|
|
func (b *baseModuleContext) checkedMissingDeps() bool {
|
|
return b.Module().base().commonProperties.CheckedMissingDeps
|
|
}
|
|
|
|
func (b *baseModuleContext) getMissingDependencies() []string {
|
|
checked := &b.Module().base().commonProperties.CheckedMissingDeps
|
|
*checked = true
|
|
var missingDeps []string
|
|
missingDeps = append(missingDeps, b.Module().base().commonProperties.MissingDeps...)
|
|
missingDeps = append(missingDeps, b.bp.EarlyGetMissingDependencies()...)
|
|
missingDeps = FirstUniqueStrings(missingDeps)
|
|
return missingDeps
|
|
}
|
|
|
|
type AllowDisabledModuleDependency interface {
|
|
blueprint.DependencyTag
|
|
AllowDisabledModuleDependency(target Module) bool
|
|
}
|
|
|
|
type AlwaysAllowDisabledModuleDependencyTag struct{}
|
|
|
|
func (t AlwaysAllowDisabledModuleDependencyTag) AllowDisabledModuleDependency(Module) bool {
|
|
return true
|
|
}
|
|
|
|
func (b *baseModuleContext) validateAndroidModule(module blueprint.Module, tag blueprint.DependencyTag, strict bool, ignoreBlueprint bool) Module {
|
|
aModule, _ := module.(Module)
|
|
|
|
if !strict {
|
|
return aModule
|
|
}
|
|
|
|
if aModule == nil {
|
|
if !ignoreBlueprint {
|
|
b.ModuleErrorf("module %q (%#v) not an android module", b.OtherModuleName(module), tag)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
if !aModule.Enabled(b) {
|
|
if t, ok := tag.(AllowDisabledModuleDependency); !ok || !t.AllowDisabledModuleDependency(aModule) {
|
|
if b.Config().AllowMissingDependencies() {
|
|
b.AddMissingDependencies([]string{b.OtherModuleName(aModule)})
|
|
} else {
|
|
b.ModuleErrorf("depends on disabled module %q", b.OtherModuleName(aModule))
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
return aModule
|
|
}
|
|
|
|
type dep struct {
|
|
mod blueprint.Module
|
|
tag blueprint.DependencyTag
|
|
}
|
|
|
|
func (b *baseModuleContext) getDirectDepsInternal(name string, tag blueprint.DependencyTag) []dep {
|
|
var deps []dep
|
|
b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
|
|
if aModule, _ := module.(Module); aModule != nil {
|
|
if aModule.base().BaseModuleName() == name {
|
|
returnedTag := b.bp.OtherModuleDependencyTag(aModule)
|
|
if tag == nil || returnedTag == tag {
|
|
deps = append(deps, dep{aModule, returnedTag})
|
|
}
|
|
}
|
|
} else if b.bp.OtherModuleName(module) == name {
|
|
returnedTag := b.bp.OtherModuleDependencyTag(module)
|
|
if tag == nil || returnedTag == tag {
|
|
deps = append(deps, dep{module, returnedTag})
|
|
}
|
|
}
|
|
})
|
|
return deps
|
|
}
|
|
|
|
func (b *baseModuleContext) getDirectDepInternal(name string, tag blueprint.DependencyTag) (blueprint.Module, blueprint.DependencyTag) {
|
|
deps := b.getDirectDepsInternal(name, tag)
|
|
if len(deps) == 1 {
|
|
return deps[0].mod, deps[0].tag
|
|
} else if len(deps) >= 2 {
|
|
panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
|
|
name, b.ModuleName()))
|
|
} else {
|
|
return nil, nil
|
|
}
|
|
}
|
|
|
|
func (b *baseModuleContext) getDirectDepFirstTag(name string) (blueprint.Module, blueprint.DependencyTag) {
|
|
foundDeps := b.getDirectDepsInternal(name, nil)
|
|
deps := map[blueprint.Module]bool{}
|
|
for _, dep := range foundDeps {
|
|
deps[dep.mod] = true
|
|
}
|
|
if len(deps) == 1 {
|
|
return foundDeps[0].mod, foundDeps[0].tag
|
|
} else if len(deps) >= 2 {
|
|
// this could happen if two dependencies have the same name in different namespaces
|
|
// TODO(b/186554727): this should not occur if namespaces are handled within
|
|
// getDirectDepsInternal.
|
|
panic(fmt.Errorf("Multiple dependencies having same BaseModuleName() %q found from %q",
|
|
name, b.ModuleName()))
|
|
} else {
|
|
return nil, nil
|
|
}
|
|
}
|
|
|
|
func (b *baseModuleContext) GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module {
|
|
var deps []Module
|
|
b.VisitDirectDepsBlueprint(func(module blueprint.Module) {
|
|
if aModule, _ := module.(Module); aModule != nil {
|
|
if b.bp.OtherModuleDependencyTag(aModule) == tag {
|
|
deps = append(deps, aModule)
|
|
}
|
|
}
|
|
})
|
|
return deps
|
|
}
|
|
|
|
// GetDirectDep returns the Module and DependencyTag for the direct dependency with the specified
|
|
// name, or nil if none exists. If there are multiple dependencies on the same module it returns the
|
|
// first DependencyTag.
|
|
func (b *baseModuleContext) GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) {
|
|
return b.getDirectDepFirstTag(name)
|
|
}
|
|
|
|
func (b *baseModuleContext) VisitDirectDepsBlueprint(visit func(blueprint.Module)) {
|
|
b.bp.VisitDirectDeps(visit)
|
|
}
|
|
|
|
func (b *baseModuleContext) VisitDirectDeps(visit func(Module)) {
|
|
b.visitDirectDeps(visit, false)
|
|
}
|
|
|
|
func (b *baseModuleContext) VisitDirectDepsIgnoreBlueprint(visit func(Module)) {
|
|
b.visitDirectDeps(visit, true)
|
|
}
|
|
|
|
func (b *baseModuleContext) visitDirectDeps(visit func(Module), ignoreBlueprint bool) {
|
|
b.bp.VisitDirectDeps(func(module blueprint.Module) {
|
|
if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, ignoreBlueprint); aModule != nil {
|
|
visit(aModule)
|
|
}
|
|
})
|
|
}
|
|
|
|
func (b *baseModuleContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) {
|
|
b.bp.VisitDirectDeps(func(module blueprint.Module) {
|
|
if b.bp.OtherModuleDependencyTag(module) == tag {
|
|
if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, false); aModule != nil {
|
|
visit(aModule)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func (b *baseModuleContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) {
|
|
b.bp.VisitDirectDepsIf(
|
|
// pred
|
|
func(module blueprint.Module) bool {
|
|
if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, false); aModule != nil {
|
|
return pred(aModule)
|
|
} else {
|
|
return false
|
|
}
|
|
},
|
|
// visit
|
|
func(module blueprint.Module) {
|
|
visit(module.(Module))
|
|
})
|
|
}
|
|
|
|
func (b *baseModuleContext) VisitDepsDepthFirst(visit func(Module)) {
|
|
b.bp.VisitDepsDepthFirst(func(module blueprint.Module) {
|
|
if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, false); aModule != nil {
|
|
visit(aModule)
|
|
}
|
|
})
|
|
}
|
|
|
|
func (b *baseModuleContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) {
|
|
b.bp.VisitDepsDepthFirstIf(
|
|
// pred
|
|
func(module blueprint.Module) bool {
|
|
if aModule := b.validateAndroidModule(module, b.bp.OtherModuleDependencyTag(module), b.strictVisitDeps, false); aModule != nil {
|
|
return pred(aModule)
|
|
} else {
|
|
return false
|
|
}
|
|
},
|
|
// visit
|
|
func(module blueprint.Module) {
|
|
visit(module.(Module))
|
|
})
|
|
}
|
|
|
|
func (b *baseModuleContext) WalkDepsBlueprint(visit func(blueprint.Module, blueprint.Module) bool) {
|
|
b.bp.WalkDeps(visit)
|
|
}
|
|
|
|
func (b *baseModuleContext) WalkDeps(visit func(Module, Module) bool) {
|
|
b.walkPath = []Module{b.Module()}
|
|
b.tagPath = []blueprint.DependencyTag{}
|
|
b.bp.WalkDeps(func(child, parent blueprint.Module) bool {
|
|
childAndroidModule, _ := child.(Module)
|
|
parentAndroidModule, _ := parent.(Module)
|
|
if childAndroidModule != nil && parentAndroidModule != nil {
|
|
// record walkPath before visit
|
|
for b.walkPath[len(b.walkPath)-1] != parentAndroidModule {
|
|
b.walkPath = b.walkPath[0 : len(b.walkPath)-1]
|
|
b.tagPath = b.tagPath[0 : len(b.tagPath)-1]
|
|
}
|
|
b.walkPath = append(b.walkPath, childAndroidModule)
|
|
b.tagPath = append(b.tagPath, b.OtherModuleDependencyTag(childAndroidModule))
|
|
return visit(childAndroidModule, parentAndroidModule)
|
|
} else {
|
|
return false
|
|
}
|
|
})
|
|
}
|
|
|
|
func (b *baseModuleContext) GetWalkPath() []Module {
|
|
return b.walkPath
|
|
}
|
|
|
|
func (b *baseModuleContext) GetTagPath() []blueprint.DependencyTag {
|
|
return b.tagPath
|
|
}
|
|
|
|
func (b *baseModuleContext) VisitAllModuleVariants(visit func(Module)) {
|
|
b.bp.VisitAllModuleVariants(func(module blueprint.Module) {
|
|
visit(module.(Module))
|
|
})
|
|
}
|
|
|
|
func (b *baseModuleContext) PrimaryModule() Module {
|
|
return b.bp.PrimaryModule().(Module)
|
|
}
|
|
|
|
func (b *baseModuleContext) FinalModule() Module {
|
|
return b.bp.FinalModule().(Module)
|
|
}
|
|
|
|
// IsMetaDependencyTag returns true for cross-cutting metadata dependencies.
|
|
func IsMetaDependencyTag(tag blueprint.DependencyTag) bool {
|
|
if tag == licenseKindTag {
|
|
return true
|
|
} else if tag == licensesTag {
|
|
return true
|
|
} else if tag == acDepTag {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// A regexp for removing boilerplate from BaseDependencyTag from the string representation of
|
|
// a dependency tag.
|
|
var tagCleaner = regexp.MustCompile(`\QBaseDependencyTag:{}\E(, )?`)
|
|
|
|
// PrettyPrintTag returns string representation of the tag, but prefers
|
|
// custom String() method if available.
|
|
func PrettyPrintTag(tag blueprint.DependencyTag) string {
|
|
// Use tag's custom String() method if available.
|
|
if stringer, ok := tag.(fmt.Stringer); ok {
|
|
return stringer.String()
|
|
}
|
|
|
|
// Otherwise, get a default string representation of the tag's struct.
|
|
tagString := fmt.Sprintf("%T: %+v", tag, tag)
|
|
|
|
// Remove the boilerplate from BaseDependencyTag as it adds no value.
|
|
tagString = tagCleaner.ReplaceAllString(tagString, "")
|
|
return tagString
|
|
}
|
|
|
|
func (b *baseModuleContext) GetPathString(skipFirst bool) string {
|
|
sb := strings.Builder{}
|
|
tagPath := b.GetTagPath()
|
|
walkPath := b.GetWalkPath()
|
|
if !skipFirst {
|
|
sb.WriteString(walkPath[0].String())
|
|
}
|
|
for i, m := range walkPath[1:] {
|
|
sb.WriteString("\n")
|
|
sb.WriteString(fmt.Sprintf(" via tag %s\n", PrettyPrintTag(tagPath[i])))
|
|
sb.WriteString(fmt.Sprintf(" -> %s", m.String()))
|
|
}
|
|
return sb.String()
|
|
}
|
|
|
|
func (m *baseModuleContext) EvaluateConfiguration(condition proptools.ConfigurableCondition, property string) proptools.ConfigurableValue {
|
|
return m.Module().ConfigurableEvaluator(m).EvaluateConfiguration(condition, property)
|
|
}
|