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:
Colin Cross 2024-04-02 17:45:32 +00:00 committed by Automerger Merge Worker
commit a295d7b965
9 changed files with 153 additions and 114 deletions

View file

@ -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()
}

View file

@ -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

View file

@ -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 {

View file

@ -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) {

View file

@ -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")

View file

@ -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])
}

View file

@ -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

View file

@ -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)

View file

@ -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)