Merge changes I4bb1a17f,I05ffdf6d,I5dc201f4,If16ee798,I2e42c0d6, ... into main am: a6074ea049
Original change: https://android-review.googlesource.com/c/platform/build/blueprint/+/3017628 Change-Id: I75011814dcdd38e9a0253a139e14c662419d82c2 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
commit
a295d7b965
9 changed files with 153 additions and 114 deletions
|
@ -20,6 +20,7 @@ import (
|
|||
"go/doc"
|
||||
"html/template"
|
||||
"reflect"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
@ -34,7 +35,7 @@ import (
|
|||
|
||||
func (ps *PropertyStruct) Clone() *PropertyStruct {
|
||||
ret := *ps
|
||||
ret.Properties = append([]Property(nil), ret.Properties...)
|
||||
ret.Properties = slices.Clone(ret.Properties)
|
||||
for i, prop := range ret.Properties {
|
||||
ret.Properties[i] = prop.Clone()
|
||||
}
|
||||
|
@ -44,7 +45,7 @@ func (ps *PropertyStruct) Clone() *PropertyStruct {
|
|||
|
||||
func (p *Property) Clone() Property {
|
||||
ret := *p
|
||||
ret.Properties = append([]Property(nil), ret.Properties...)
|
||||
ret.Properties = slices.Clone(ret.Properties)
|
||||
for i, prop := range ret.Properties {
|
||||
ret.Properties[i] = prop.Clone()
|
||||
}
|
||||
|
|
194
context.go
194
context.go
|
@ -24,6 +24,7 @@ import (
|
|||
"hash/fnv"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"maps"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
|
@ -343,13 +344,18 @@ type moduleInfo struct {
|
|||
waitingCount int
|
||||
|
||||
// set during each runMutator
|
||||
splitModules modulesOrAliases
|
||||
splitModules modulesOrAliases
|
||||
obsoletedByNewVariants bool
|
||||
|
||||
// Used by TransitionMutator implementations
|
||||
transitionVariations []string
|
||||
currentTransitionMutator string
|
||||
requiredVariationsLock sync.Mutex
|
||||
|
||||
// outgoingTransitionCache stores the final variation for each dependency, indexed by the source variation
|
||||
// index in transitionVariations and then by the index of the dependency in directDeps
|
||||
outgoingTransitionCache [][]string
|
||||
|
||||
// set during PrepareBuildActions
|
||||
actionDefs localBuildActions
|
||||
|
||||
|
@ -418,15 +424,7 @@ type Variation struct {
|
|||
type variationMap map[string]string
|
||||
|
||||
func (vm variationMap) clone() variationMap {
|
||||
if vm == nil {
|
||||
return nil
|
||||
}
|
||||
newVm := make(variationMap)
|
||||
for k, v := range vm {
|
||||
newVm[k] = v
|
||||
}
|
||||
|
||||
return newVm
|
||||
return maps.Clone(vm)
|
||||
}
|
||||
|
||||
// Compare this variationMap to another one. Returns true if the every entry in this map
|
||||
|
@ -441,10 +439,7 @@ func (vm variationMap) subsetOf(other variationMap) bool {
|
|||
}
|
||||
|
||||
func (vm variationMap) equal(other variationMap) bool {
|
||||
if len(vm) != len(other) {
|
||||
return false
|
||||
}
|
||||
return vm.subsetOf(other)
|
||||
return maps.Equal(vm, other)
|
||||
}
|
||||
|
||||
type singletonInfo struct {
|
||||
|
@ -694,6 +689,14 @@ type IncomingTransitionContext interface {
|
|||
// Config returns the config object that was passed to
|
||||
// Context.PrepareBuildActions.
|
||||
Config() interface{}
|
||||
|
||||
// Provider returns the value for a provider for the target of the dependency edge for which the
|
||||
// transition is being computed. 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 AnyProviderKey) (any, bool)
|
||||
}
|
||||
|
||||
type OutgoingTransitionContext interface {
|
||||
|
@ -708,6 +711,14 @@ type OutgoingTransitionContext interface {
|
|||
// Config returns the config object that was passed to
|
||||
// Context.PrepareBuildActions.
|
||||
Config() interface{}
|
||||
|
||||
// Provider returns the value for a provider for the source of the dependency edge for which the
|
||||
// transition is being computed. 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 AnyProviderKey) (any, bool)
|
||||
}
|
||||
|
||||
// TransitionMutator implements a top-down mechanism where a module tells its
|
||||
|
@ -800,15 +811,10 @@ type transitionMutatorImpl struct {
|
|||
|
||||
// Adds each argument in items to l if it's not already there.
|
||||
func addToStringListIfNotPresent(l []string, items ...string) []string {
|
||||
OUTER:
|
||||
for _, i := range items {
|
||||
for _, existing := range l {
|
||||
if existing == i {
|
||||
continue OUTER
|
||||
}
|
||||
if !slices.Contains(l, i) {
|
||||
l = append(l, i)
|
||||
}
|
||||
|
||||
l = append(l, i)
|
||||
}
|
||||
|
||||
return l
|
||||
|
@ -843,19 +849,25 @@ func (t *transitionMutatorImpl) topDownMutator(mctx TopDownMutatorContext) {
|
|||
module.transitionVariations = addToStringListIfNotPresent(module.transitionVariations, mutatorSplits...)
|
||||
sort.Strings(module.transitionVariations)
|
||||
|
||||
for _, srcVariation := range module.transitionVariations {
|
||||
for _, dep := range module.directDeps {
|
||||
finalVariation := t.transition(mctx)(mctx.Module(), srcVariation, dep.module.logicModule, dep.tag)
|
||||
outgoingTransitionCache := make([][]string, len(module.transitionVariations))
|
||||
for srcVariationIndex, srcVariation := range module.transitionVariations {
|
||||
srcVariationTransitionCache := make([]string, len(module.directDeps))
|
||||
for depIndex, dep := range module.directDeps {
|
||||
finalVariation := t.transition(mctx)(mctx.moduleInfo(), srcVariation, dep.module, dep.tag)
|
||||
srcVariationTransitionCache[depIndex] = finalVariation
|
||||
t.addRequiredVariation(dep.module, finalVariation)
|
||||
}
|
||||
outgoingTransitionCache[srcVariationIndex] = srcVariationTransitionCache
|
||||
}
|
||||
module.outgoingTransitionCache = outgoingTransitionCache
|
||||
}
|
||||
|
||||
type transitionContextImpl struct {
|
||||
source Module
|
||||
dep Module
|
||||
depTag DependencyTag
|
||||
config interface{}
|
||||
context *Context
|
||||
source *moduleInfo
|
||||
dep *moduleInfo
|
||||
depTag DependencyTag
|
||||
config interface{}
|
||||
}
|
||||
|
||||
func (c *transitionContextImpl) DepTag() DependencyTag {
|
||||
|
@ -871,7 +883,11 @@ type outgoingTransitionContextImpl struct {
|
|||
}
|
||||
|
||||
func (c *outgoingTransitionContextImpl) Module() Module {
|
||||
return c.source
|
||||
return c.source.logicModule
|
||||
}
|
||||
|
||||
func (c *outgoingTransitionContextImpl) Provider(provider AnyProviderKey) (any, bool) {
|
||||
return c.context.provider(c.source, provider.provider())
|
||||
}
|
||||
|
||||
type incomingTransitionContextImpl struct {
|
||||
|
@ -879,13 +895,26 @@ type incomingTransitionContextImpl struct {
|
|||
}
|
||||
|
||||
func (c *incomingTransitionContextImpl) Module() Module {
|
||||
return c.dep
|
||||
return c.dep.logicModule
|
||||
}
|
||||
|
||||
func (t *transitionMutatorImpl) transition(mctx BaseMutatorContext) Transition {
|
||||
return func(source Module, sourceVariation string, dep Module, depTag DependencyTag) string {
|
||||
tc := transitionContextImpl{source: source, dep: dep, depTag: depTag, config: mctx.Config()}
|
||||
func (c *incomingTransitionContextImpl) Provider(provider AnyProviderKey) (any, bool) {
|
||||
return c.context.provider(c.dep, provider.provider())
|
||||
}
|
||||
|
||||
func (t *transitionMutatorImpl) transition(mctx BaseModuleContext) Transition {
|
||||
return func(source *moduleInfo, sourceVariation string, dep *moduleInfo, depTag DependencyTag) string {
|
||||
tc := transitionContextImpl{
|
||||
context: mctx.base().context,
|
||||
source: source,
|
||||
dep: dep,
|
||||
depTag: depTag,
|
||||
config: mctx.Config(),
|
||||
}
|
||||
outgoingVariation := t.mutator.OutgoingTransition(&outgoingTransitionContextImpl{tc}, sourceVariation)
|
||||
if mctx.Failed() {
|
||||
return outgoingVariation
|
||||
}
|
||||
finalVariation := t.mutator.IncomingTransition(&incomingTransitionContextImpl{tc}, outgoingVariation)
|
||||
return finalVariation
|
||||
}
|
||||
|
@ -897,7 +926,9 @@ func (t *transitionMutatorImpl) bottomUpMutator(mctx BottomUpMutatorContext) {
|
|||
// only time interaction between multiple modules is required is during the
|
||||
// computation of the variations required by a given module.
|
||||
variations := mc.module.transitionVariations
|
||||
outgoingTransitionCache := mc.module.outgoingTransitionCache
|
||||
mc.module.transitionVariations = nil
|
||||
mc.module.outgoingTransitionCache = nil
|
||||
mc.module.currentTransitionMutator = ""
|
||||
|
||||
if len(variations) < 1 {
|
||||
|
@ -907,9 +938,10 @@ func (t *transitionMutatorImpl) bottomUpMutator(mctx BottomUpMutatorContext) {
|
|||
|
||||
if len(variations) == 1 && variations[0] == "" {
|
||||
// Module is not split, just apply the transition
|
||||
mc.applyTransition(t.transition(mctx))
|
||||
mc.context.convertDepsToVariation(mc.module, 0,
|
||||
chooseDepByIndexes(mc.mutator.name, outgoingTransitionCache))
|
||||
} else {
|
||||
mc.createVariationsWithTransition(t.transition(mctx), variations...)
|
||||
mc.createVariationsWithTransition(variations, outgoingTransitionCache)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1719,12 +1751,12 @@ func newVariant(module *moduleInfo, mutatorName string, variationName string,
|
|||
return variant{newVariantName, newVariations, newDependencyVariations}
|
||||
}
|
||||
|
||||
func (c *Context) createVariations(origModule *moduleInfo, mutatorName string,
|
||||
func (c *Context) createVariations(origModule *moduleInfo, mutator *mutatorInfo,
|
||||
depChooser depChooser, variationNames []string, local bool) (modulesOrAliases, []error) {
|
||||
|
||||
if len(variationNames) == 0 {
|
||||
panic(fmt.Errorf("mutator %q passed zero-length variation list for module %q",
|
||||
mutatorName, origModule.Name()))
|
||||
mutator.name, origModule.Name()))
|
||||
}
|
||||
|
||||
var newModules modulesOrAliases
|
||||
|
@ -1746,18 +1778,18 @@ func (c *Context) createVariations(origModule *moduleInfo, mutatorName string,
|
|||
|
||||
m := *origModule
|
||||
newModule := &m
|
||||
newModule.directDeps = append([]depInfo(nil), origModule.directDeps...)
|
||||
newModule.directDeps = slices.Clone(origModule.directDeps)
|
||||
newModule.reverseDeps = nil
|
||||
newModule.forwardDeps = nil
|
||||
newModule.logicModule = newLogicModule
|
||||
newModule.variant = newVariant(origModule, mutatorName, variationName, local)
|
||||
newModule.variant = newVariant(origModule, mutator.name, variationName, local)
|
||||
newModule.properties = newProperties
|
||||
newModule.providers = append([]interface{}(nil), origModule.providers...)
|
||||
newModule.providerInitialValueHashes = append([]uint64(nil), origModule.providerInitialValueHashes...)
|
||||
newModule.providers = slices.Clone(origModule.providers)
|
||||
newModule.providerInitialValueHashes = slices.Clone(origModule.providerInitialValueHashes)
|
||||
|
||||
newModules = append(newModules, newModule)
|
||||
|
||||
newErrs := c.convertDepsToVariation(newModule, depChooser)
|
||||
newErrs := c.convertDepsToVariation(newModule, i, depChooser)
|
||||
if len(newErrs) > 0 {
|
||||
errs = append(errs, newErrs...)
|
||||
}
|
||||
|
@ -1765,7 +1797,7 @@ func (c *Context) createVariations(origModule *moduleInfo, mutatorName string,
|
|||
|
||||
// Mark original variant as invalid. Modules that depend on this module will still
|
||||
// depend on origModule, but we'll fix it when the mutator is called on them.
|
||||
origModule.logicModule = nil
|
||||
origModule.obsoletedByNewVariants = true
|
||||
origModule.splitModules = newModules
|
||||
|
||||
atomic.AddUint32(&c.depsModified, 1)
|
||||
|
@ -1773,37 +1805,12 @@ func (c *Context) createVariations(origModule *moduleInfo, mutatorName string,
|
|||
return newModules, errs
|
||||
}
|
||||
|
||||
type depChooser func(source *moduleInfo, dep depInfo) (*moduleInfo, string)
|
||||
type depChooser func(source *moduleInfo, variationIndex, depIndex int, dep depInfo) (*moduleInfo, string)
|
||||
|
||||
// This function is called for every dependency edge to determine which
|
||||
// variation of the dependency is needed. Its inputs are the depending module,
|
||||
// its variation, the dependency and the dependency tag.
|
||||
type Transition func(source Module, sourceVariation string, dep Module, depTag DependencyTag) string
|
||||
|
||||
func chooseDepByTransition(mutatorName string, transition Transition) depChooser {
|
||||
return func(source *moduleInfo, dep depInfo) (*moduleInfo, string) {
|
||||
sourceVariation := source.variant.variations[mutatorName]
|
||||
depLogicModule := dep.module.logicModule
|
||||
if depLogicModule == nil {
|
||||
// This is really a lie because the original dependency before the split
|
||||
// went away when it was split. We choose an arbitrary split module
|
||||
// instead and hope that whatever information the transition wants from it
|
||||
// is the same as in the original one
|
||||
// TODO(lberki): this can be fixed by calling transition() once and saving
|
||||
// its results somewhere
|
||||
depLogicModule = dep.module.splitModules[0].moduleOrAliasTarget().logicModule
|
||||
}
|
||||
|
||||
desiredVariation := transition(source.logicModule, sourceVariation, depLogicModule, dep.tag)
|
||||
for _, m := range dep.module.splitModules {
|
||||
if m.moduleOrAliasVariant().variations[mutatorName] == desiredVariation {
|
||||
return m.moduleOrAliasTarget(), ""
|
||||
}
|
||||
}
|
||||
|
||||
return nil, desiredVariation
|
||||
}
|
||||
}
|
||||
type Transition func(source *moduleInfo, sourceVariation string, dep *moduleInfo, depTag DependencyTag) string
|
||||
|
||||
func chooseDep(candidates modulesOrAliases, mutatorName, variationName string, defaultVariationName *string) (*moduleInfo, string) {
|
||||
for _, m := range candidates {
|
||||
|
@ -1824,24 +1831,31 @@ func chooseDep(candidates modulesOrAliases, mutatorName, variationName string, d
|
|||
return nil, variationName
|
||||
}
|
||||
|
||||
func chooseDepByIndexes(mutatorName string, variations [][]string) depChooser {
|
||||
return func(source *moduleInfo, variationIndex, depIndex int, dep depInfo) (*moduleInfo, string) {
|
||||
desiredVariation := variations[variationIndex][depIndex]
|
||||
return chooseDep(dep.module.splitModules, mutatorName, desiredVariation, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func chooseDepExplicit(mutatorName string,
|
||||
variationName string, defaultVariationName *string) depChooser {
|
||||
return func(source *moduleInfo, dep depInfo) (*moduleInfo, string) {
|
||||
return func(source *moduleInfo, variationIndex, depIndex int, dep depInfo) (*moduleInfo, string) {
|
||||
return chooseDep(dep.module.splitModules, mutatorName, variationName, defaultVariationName)
|
||||
}
|
||||
}
|
||||
|
||||
func chooseDepInherit(mutatorName string, defaultVariationName *string) depChooser {
|
||||
return func(source *moduleInfo, dep depInfo) (*moduleInfo, string) {
|
||||
return func(source *moduleInfo, variationIndex, depIndex int, dep depInfo) (*moduleInfo, string) {
|
||||
sourceVariation := source.variant.variations[mutatorName]
|
||||
return chooseDep(dep.module.splitModules, mutatorName, sourceVariation, defaultVariationName)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Context) convertDepsToVariation(module *moduleInfo, depChooser depChooser) (errs []error) {
|
||||
func (c *Context) convertDepsToVariation(module *moduleInfo, variationIndex int, depChooser depChooser) (errs []error) {
|
||||
for i, dep := range module.directDeps {
|
||||
if dep.module.logicModule == nil {
|
||||
newDep, missingVariation := depChooser(module, dep)
|
||||
if dep.module.obsoletedByNewVariants {
|
||||
newDep, missingVariation := depChooser(module, variationIndex, i, dep)
|
||||
if newDep == nil {
|
||||
errs = append(errs, &BlueprintError{
|
||||
Err: fmt.Errorf("failed to find variation %q for module %q needed by %q",
|
||||
|
@ -3072,6 +3086,11 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
|
|||
deps []string
|
||||
}
|
||||
|
||||
type newVariationPair struct {
|
||||
newVariations modulesOrAliases
|
||||
origLogicModule Module
|
||||
}
|
||||
|
||||
reverseDeps := make(map[*moduleInfo][]depInfo)
|
||||
var rename []rename
|
||||
var replace []replace
|
||||
|
@ -3079,7 +3098,7 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
|
|||
|
||||
errsCh := make(chan []error)
|
||||
globalStateCh := make(chan globalStateChange)
|
||||
newVariationsCh := make(chan modulesOrAliases)
|
||||
newVariationsCh := make(chan newVariationPair)
|
||||
done := make(chan bool)
|
||||
|
||||
c.depsModified = 0
|
||||
|
@ -3095,10 +3114,12 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
|
|||
config: config,
|
||||
module: module,
|
||||
},
|
||||
name: mutator.name,
|
||||
mutator: mutator,
|
||||
pauseCh: pause,
|
||||
}
|
||||
|
||||
origLogicModule := module.logicModule
|
||||
|
||||
module.startedMutator = mutator
|
||||
|
||||
func() {
|
||||
|
@ -3124,7 +3145,7 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
|
|||
}
|
||||
|
||||
if len(mctx.newVariations) > 0 {
|
||||
newVariationsCh <- mctx.newVariations
|
||||
newVariationsCh <- newVariationPair{mctx.newVariations, origLogicModule}
|
||||
}
|
||||
|
||||
if len(mctx.reverseDeps) > 0 || len(mctx.replace) > 0 || len(mctx.rename) > 0 || len(mctx.newModules) > 0 || len(mctx.ninjaFileDeps) > 0 {
|
||||
|
@ -3140,6 +3161,8 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
|
|||
return false
|
||||
}
|
||||
|
||||
var obsoleteLogicModules []Module
|
||||
|
||||
// Process errs and reverseDeps in a single goroutine
|
||||
go func() {
|
||||
for {
|
||||
|
@ -3155,7 +3178,10 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
|
|||
newModules = append(newModules, globalStateChange.newModules...)
|
||||
deps = append(deps, globalStateChange.deps...)
|
||||
case newVariations := <-newVariationsCh:
|
||||
for _, moduleOrAlias := range newVariations {
|
||||
if newVariations.origLogicModule != newVariations.newVariations[0].module().logicModule {
|
||||
obsoleteLogicModules = append(obsoleteLogicModules, newVariations.origLogicModule)
|
||||
}
|
||||
for _, moduleOrAlias := range newVariations.newVariations {
|
||||
if m := moduleOrAlias.module(); m != nil {
|
||||
newModuleInfo[m.logicModule] = m
|
||||
}
|
||||
|
@ -3187,6 +3213,10 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
|
|||
return nil, errs
|
||||
}
|
||||
|
||||
for _, obsoleteLogicModule := range obsoleteLogicModules {
|
||||
delete(newModuleInfo, obsoleteLogicModule)
|
||||
}
|
||||
|
||||
c.moduleInfo = newModuleInfo
|
||||
|
||||
for _, group := range c.moduleGroups {
|
||||
|
@ -3205,12 +3235,12 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
|
|||
// Fix up any remaining dependencies on modules that were split into variants
|
||||
// by replacing them with the first variant
|
||||
for j, dep := range module.directDeps {
|
||||
if dep.module.logicModule == nil {
|
||||
if dep.module.obsoletedByNewVariants {
|
||||
module.directDeps[j].module = dep.module.splitModules.firstModule()
|
||||
}
|
||||
}
|
||||
|
||||
if module.createdBy != nil && module.createdBy.logicModule == nil {
|
||||
if module.createdBy != nil && module.createdBy.obsoletedByNewVariants {
|
||||
module.createdBy = module.createdBy.splitModules.firstModule()
|
||||
}
|
||||
|
||||
|
@ -3235,7 +3265,7 @@ func (c *Context) runMutator(config interface{}, mutator *mutatorInfo,
|
|||
// change inside the loop
|
||||
for i := 0; i < len(group.modules); i++ {
|
||||
if alias := group.modules[i].alias(); alias != nil {
|
||||
if alias.target.logicModule == nil {
|
||||
if alias.target.obsoletedByNewVariants {
|
||||
newTarget := findAliasTarget(alias.target.variant)
|
||||
if newTarget != nil {
|
||||
alias.target = newTarget
|
||||
|
|
9
glob.go
9
glob.go
|
@ -16,6 +16,7 @@ package blueprint
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
|
@ -40,7 +41,7 @@ func verifyGlob(key globKey, pattern string, excludes []string, g pathtools.Glob
|
|||
func (c *Context) glob(pattern string, excludes []string) ([]string, error) {
|
||||
// Sort excludes so that two globs with the same excludes in a different order reuse the same
|
||||
// key. Make a copy first to avoid modifying the caller's version.
|
||||
excludes = append([]string(nil), excludes...)
|
||||
excludes = slices.Clone(excludes)
|
||||
sort.Strings(excludes)
|
||||
|
||||
key := globToKey(pattern, excludes)
|
||||
|
@ -54,7 +55,7 @@ func (c *Context) glob(pattern string, excludes []string) ([]string, error) {
|
|||
// Glob has already been done, double check it is identical
|
||||
verifyGlob(key, pattern, excludes, g)
|
||||
// Return a copy so that modifications don't affect the cached value.
|
||||
return append([]string(nil), g.Matches...), nil
|
||||
return slices.Clone(g.Matches), nil
|
||||
}
|
||||
|
||||
// Get a globbed file list
|
||||
|
@ -74,11 +75,11 @@ func (c *Context) glob(pattern string, excludes []string) ([]string, error) {
|
|||
// Getting the list raced with another goroutine, throw away the results and use theirs
|
||||
verifyGlob(key, pattern, excludes, g)
|
||||
// Return a copy so that modifications don't affect the cached value.
|
||||
return append([]string(nil), g.Matches...), nil
|
||||
return slices.Clone(g.Matches), nil
|
||||
}
|
||||
|
||||
// Return a copy so that modifications don't affect the cached value.
|
||||
return append([]string(nil), result.Matches...), nil
|
||||
return slices.Clone(result.Matches), nil
|
||||
}
|
||||
|
||||
func (c *Context) Globs() pathtools.MultipleGlobResults {
|
||||
|
|
|
@ -360,6 +360,8 @@ type BaseModuleContext interface {
|
|||
SetProvider(provider AnyProviderKey, value any)
|
||||
|
||||
EarlyGetMissingDependencies() []string
|
||||
|
||||
base() *baseModuleContext
|
||||
}
|
||||
|
||||
type DynamicDependerModuleContext BottomUpMutatorContext
|
||||
|
@ -751,6 +753,10 @@ func (m *baseModuleContext) ModuleFactories() map[string]ModuleFactory {
|
|||
return ret
|
||||
}
|
||||
|
||||
func (m *baseModuleContext) base() *baseModuleContext {
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *moduleContext) ModuleSubDir() string {
|
||||
return m.module.variant.name
|
||||
}
|
||||
|
@ -807,7 +813,7 @@ func (m *baseModuleContext) EarlyGetMissingDependencies() []string {
|
|||
|
||||
type mutatorContext struct {
|
||||
baseModuleContext
|
||||
name string
|
||||
mutator *mutatorInfo
|
||||
reverseDeps []reverseDep
|
||||
rename []rename
|
||||
replace []replace
|
||||
|
@ -984,20 +990,20 @@ func (BaseDependencyTag) dependencyTag(DependencyTag) {
|
|||
var _ DependencyTag = BaseDependencyTag{}
|
||||
|
||||
func (mctx *mutatorContext) MutatorName() string {
|
||||
return mctx.name
|
||||
return mctx.mutator.name
|
||||
}
|
||||
|
||||
func (mctx *mutatorContext) CreateVariations(variationNames ...string) []Module {
|
||||
depChooser := chooseDepInherit(mctx.name, mctx.defaultVariation)
|
||||
depChooser := chooseDepInherit(mctx.mutator.name, mctx.defaultVariation)
|
||||
return mctx.createVariations(variationNames, depChooser, false)
|
||||
}
|
||||
|
||||
func (mctx *mutatorContext) createVariationsWithTransition(transition Transition, variationNames ...string) []Module {
|
||||
return mctx.createVariations(variationNames, chooseDepByTransition(mctx.name, transition), false)
|
||||
func (mctx *mutatorContext) createVariationsWithTransition(variationNames []string, outgoingTransitions [][]string) []Module {
|
||||
return mctx.createVariations(variationNames, chooseDepByIndexes(mctx.mutator.name, outgoingTransitions), false)
|
||||
}
|
||||
|
||||
func (mctx *mutatorContext) CreateLocalVariations(variationNames ...string) []Module {
|
||||
depChooser := chooseDepInherit(mctx.name, mctx.defaultVariation)
|
||||
depChooser := chooseDepInherit(mctx.mutator.name, mctx.defaultVariation)
|
||||
return mctx.createVariations(variationNames, depChooser, true)
|
||||
}
|
||||
|
||||
|
@ -1013,7 +1019,7 @@ func (mctx *mutatorContext) SetVariationProvider(module Module, provider AnyProv
|
|||
|
||||
func (mctx *mutatorContext) createVariations(variationNames []string, depChooser depChooser, local bool) []Module {
|
||||
var ret []Module
|
||||
modules, errs := mctx.context.createVariations(mctx.module, mctx.name, depChooser, variationNames, local)
|
||||
modules, errs := mctx.context.createVariations(mctx.module, mctx.mutator, depChooser, variationNames, local)
|
||||
if len(errs) > 0 {
|
||||
mctx.errs = append(mctx.errs, errs...)
|
||||
}
|
||||
|
@ -1044,7 +1050,7 @@ func (mctx *mutatorContext) AliasVariation(variationName string) {
|
|||
}
|
||||
|
||||
for _, variant := range mctx.newVariations {
|
||||
if variant.moduleOrAliasVariant().variations[mctx.name] == variationName {
|
||||
if variant.moduleOrAliasVariant().variations[mctx.mutator.name] == variationName {
|
||||
alias := &moduleAlias{
|
||||
variant: mctx.module.variant,
|
||||
target: variant.moduleOrAliasTarget(),
|
||||
|
@ -1058,13 +1064,13 @@ func (mctx *mutatorContext) AliasVariation(variationName string) {
|
|||
|
||||
var foundVariations []string
|
||||
for _, variant := range mctx.newVariations {
|
||||
foundVariations = append(foundVariations, variant.moduleOrAliasVariant().variations[mctx.name])
|
||||
foundVariations = append(foundVariations, variant.moduleOrAliasVariant().variations[mctx.mutator.name])
|
||||
}
|
||||
panic(fmt.Errorf("no %q variation in module variations %q", variationName, foundVariations))
|
||||
}
|
||||
|
||||
func (mctx *mutatorContext) CreateAliasVariation(aliasVariationName, targetVariationName string) {
|
||||
newVariant := newVariant(mctx.module, mctx.name, aliasVariationName, false)
|
||||
newVariant := newVariant(mctx.module, mctx.mutator.name, aliasVariationName, false)
|
||||
|
||||
for _, moduleOrAlias := range mctx.module.splitModules {
|
||||
if moduleOrAlias.moduleOrAliasVariant().variations.equal(newVariant.variations) {
|
||||
|
@ -1077,7 +1083,7 @@ func (mctx *mutatorContext) CreateAliasVariation(aliasVariationName, targetVaria
|
|||
}
|
||||
|
||||
for _, variant := range mctx.newVariations {
|
||||
if variant.moduleOrAliasVariant().variations[mctx.name] == targetVariationName {
|
||||
if variant.moduleOrAliasVariant().variations[mctx.mutator.name] == targetVariationName {
|
||||
// Append the alias here so that it comes after any aliases created by AliasVariation.
|
||||
mctx.module.splitModules = append(mctx.module.splitModules, &moduleAlias{
|
||||
variant: newVariant,
|
||||
|
@ -1089,18 +1095,14 @@ func (mctx *mutatorContext) CreateAliasVariation(aliasVariationName, targetVaria
|
|||
|
||||
var foundVariations []string
|
||||
for _, variant := range mctx.newVariations {
|
||||
foundVariations = append(foundVariations, variant.moduleOrAliasVariant().variations[mctx.name])
|
||||
foundVariations = append(foundVariations, variant.moduleOrAliasVariant().variations[mctx.mutator.name])
|
||||
}
|
||||
panic(fmt.Errorf("no %q variation in module variations %q", targetVariationName, foundVariations))
|
||||
}
|
||||
|
||||
func (mctx *mutatorContext) applyTransition(transition Transition) {
|
||||
mctx.context.convertDepsToVariation(mctx.module, chooseDepByTransition(mctx.name, transition))
|
||||
}
|
||||
|
||||
func (mctx *mutatorContext) SetDependencyVariation(variationName string) {
|
||||
mctx.context.convertDepsToVariation(mctx.module, chooseDepExplicit(
|
||||
mctx.name, variationName, nil))
|
||||
mctx.context.convertDepsToVariation(mctx.module, 0, chooseDepExplicit(
|
||||
mctx.mutator.name, variationName, nil))
|
||||
}
|
||||
|
||||
func (mctx *mutatorContext) SetDefaultDependencyVariation(variationName *string) {
|
||||
|
|
|
@ -16,6 +16,7 @@ package blueprint
|
|||
|
||||
import (
|
||||
"reflect"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
@ -271,7 +272,7 @@ func Test_parseNinjaOrSimpleStrings(t *testing.T) {
|
|||
|
||||
for _, tt := range testCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
inCopy := append([]string(nil), tt.in...)
|
||||
inCopy := slices.Clone(tt.in)
|
||||
|
||||
scope := newLocalScope(nil, "")
|
||||
scope.AddLocalVariable("abc", "abc")
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"slices"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
@ -233,7 +234,7 @@ func TestFs_ListDirsRecursiveFollowSymlinks(t *testing.T) {
|
|||
t.Run(test.name, func(t *testing.T) {
|
||||
got, err := fs.ListDirsRecursive(filepath.Join(dir, test.name), FollowSymlinks)
|
||||
checkErr(t, test.err, err)
|
||||
want := append([]string(nil), test.dirs...)
|
||||
want := slices.Clone(test.dirs)
|
||||
for i := range want {
|
||||
want[i] = filepath.Join(dir, want[i])
|
||||
}
|
||||
|
@ -279,7 +280,7 @@ func TestFs_ListDirsRecursiveDontFollowSymlinks(t *testing.T) {
|
|||
t.Run(test.name, func(t *testing.T) {
|
||||
got, err := fs.ListDirsRecursive(filepath.Join(dir, test.name), DontFollowSymlinks)
|
||||
checkErr(t, test.err, err)
|
||||
want := append([]string(nil), test.dirs...)
|
||||
want := slices.Clone(test.dirs)
|
||||
for i := range want {
|
||||
want[i] = filepath.Join(dir, want[i])
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
package proptools
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
"unsafe"
|
||||
)
|
||||
|
@ -33,7 +34,7 @@ func NinjaEscapeList(slice []string) []string {
|
|||
if !sliceCopied {
|
||||
// If this was the first string that was modified by escaping then make a copy of the
|
||||
// input slice to use as the output slice.
|
||||
slice = append([]string(nil), slice...)
|
||||
slice = slices.Clone(slice)
|
||||
sliceCopied = true
|
||||
}
|
||||
slice[i] = escaped
|
||||
|
@ -66,7 +67,7 @@ func ShellEscapeList(slice []string) []string {
|
|||
if !sliceCopied {
|
||||
// If this was the first string that was modified by escaping then make a copy of the
|
||||
// input slice to use as the output slice.
|
||||
slice = append([]string(nil), slice...)
|
||||
slice = slices.Clone(slice)
|
||||
sliceCopied = true
|
||||
}
|
||||
slice[i] = escaped
|
||||
|
@ -83,7 +84,7 @@ func ShellEscapeListIncludingSpaces(slice []string) []string {
|
|||
if !sliceCopied {
|
||||
// If this was the first string that was modified by escaping then make a copy of the
|
||||
// input slice to use as the output slice.
|
||||
slice = append([]string(nil), slice...)
|
||||
slice = slices.Clone(slice)
|
||||
sliceCopied = true
|
||||
}
|
||||
slice[i] = escaped
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"bytes"
|
||||
"os/exec"
|
||||
"reflect"
|
||||
"slices"
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
@ -235,7 +236,7 @@ func TestNinjaEscapeList(t *testing.T) {
|
|||
t.Run(tf.name, func(t *testing.T) {
|
||||
for _, tt := range testCases {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
inCopy := append([]string(nil), tt.in...)
|
||||
inCopy := slices.Clone(tt.in)
|
||||
|
||||
got := tf.f(tt.in)
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ package proptools
|
|||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -317,7 +318,7 @@ func extendPropertiesRecursive(dstValues []reflect.Value, srcValue reflect.Value
|
|||
// of destinations to consider. Make a copy of dstValues if necessary
|
||||
// to avoid modifying the backing array of an input parameter.
|
||||
if !dstValuesCopied {
|
||||
dstValues = append([]reflect.Value(nil), dstValues...)
|
||||
dstValues = slices.Clone(dstValues)
|
||||
dstValuesCopied = true
|
||||
}
|
||||
dstValues = append(dstValues, embeddedDstValue)
|
||||
|
|
Loading…
Reference in a new issue