diff --git a/src/core/build_target.go b/src/core/build_target.go index 9fa9be496b..faf37952bf 100644 --- a/src/core/build_target.go +++ b/src/core/build_target.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "path/filepath" + "slices" "sort" "strings" "sync" @@ -1630,6 +1631,11 @@ func (target *BuildTarget) AddDependency(dep BuildLabel) { target.AddMaybeExportedDependency(dep, false, false, false) } +// HintDependencies allocates space for at least the given number of dependencies without reallocating. +func (target *BuildTarget) HintDependencies(n int) { + target.dependencies = slices.Grow(target.dependencies, n) +} + // AddMaybeExportedDependency adds a dependency to this target which may be exported. It deduplicates against any existing deps. func (target *BuildTarget) AddMaybeExportedDependency(dep BuildLabel, exported, source, internal bool) { if dep == target.Label { diff --git a/src/parse/asp/targets.go b/src/parse/asp/targets.go index f9ec219f2b..5c3b9b21df 100644 --- a/src/parse/asp/targets.go +++ b/src/parse/asp/targets.go @@ -263,6 +263,7 @@ func populateTarget(s *scope, t *core.BuildTarget, args []pyObject) { addMaybeNamed(s, "data", args[dataBuildRuleArgIdx], t.AddDatum, t.AddNamedDatum, false, false) addMaybeNamedOutput(s, "outs", args[outsBuildRuleArgIdx], t.AddOutput, t.AddNamedOutput, t, false) addMaybeNamedOutput(s, "optional_outs", args[optionalOutsBuildRuleArgIdx], t.AddOptionalOutput, nil, t, true) + t.HintDependencies(depLen(args[depsBuildRuleArgIdx]) + depLen(args[exportedDepsBuildRuleArgIdx]) + depLen(args[internalDepsBuildRuleArgIdx])) addDependencies(s, "deps", args[depsBuildRuleArgIdx], t, false, false) addDependencies(s, "exported_deps", args[exportedDepsBuildRuleArgIdx], t, true, false) addDependencies(s, "internal_deps", args[internalDepsBuildRuleArgIdx], t, false, true) @@ -301,6 +302,14 @@ func populateTarget(s *scope, t *core.BuildTarget, args []pyObject) { } } +// depLen returns the length of a (potential) list +func depLen(obj pyObject) int { + if l, ok := asList(obj); ok { + return len(l) + } + return 0 +} + // addEntryPoints adds entry points to a target func addEntryPoints(s *scope, arg pyObject, target *core.BuildTarget) { entryPointsPy, ok := asDict(arg)