Move name memoization out of variables am: 6bc984abca

Original change: https://android-review.googlesource.com/c/platform/build/blueprint/+/2917001

Change-Id: I240b9a3db493a0114c53195e99721644586184da
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Colin Cross 2024-01-19 00:48:29 +00:00 committed by Automerger Merge Worker
commit c0b0a19454
7 changed files with 141 additions and 185 deletions

View file

@ -16,6 +16,7 @@ package blueprint
import (
"bytes"
"cmp"
"context"
"crypto/sha256"
"encoding/base64"
@ -29,6 +30,7 @@ import (
"reflect"
"runtime"
"runtime/pprof"
"slices"
"sort"
"strings"
"sync"
@ -100,7 +102,7 @@ type Context struct {
allowMissingDependencies bool
// set during PrepareBuildActions
pkgNames map[*packageContext]string
nameTracker *nameTracker
liveGlobals *liveTracker
globalVariables map[Variable]*ninjaString
globalPools map[Pool]*poolDef
@ -2741,7 +2743,7 @@ func jsonModuleFromModuleInfo(m *moduleInfo) *JsonModule {
return result
}
func jsonModuleWithActionsFromModuleInfo(m *moduleInfo) *JsonModule {
func jsonModuleWithActionsFromModuleInfo(m *moduleInfo, nameTracker *nameTracker) *JsonModule {
result := &JsonModule{
jsonModuleName: jsonModuleName{
Name: m.Name(),
@ -2758,17 +2760,17 @@ func jsonModuleWithActionsFromModuleInfo(m *moduleInfo) *JsonModule {
Inputs: append(append(append(
bDef.InputStrings,
bDef.ImplicitStrings...),
getNinjaStringsWithNilPkgNames(bDef.Inputs)...),
getNinjaStringsWithNilPkgNames(bDef.Implicits)...),
getNinjaStrings(bDef.Inputs, nameTracker)...),
getNinjaStrings(bDef.Implicits, nameTracker)...),
Outputs: append(append(append(
bDef.OutputStrings,
bDef.ImplicitOutputStrings...),
getNinjaStringsWithNilPkgNames(bDef.Outputs)...),
getNinjaStringsWithNilPkgNames(bDef.ImplicitOutputs)...),
getNinjaStrings(bDef.Outputs, nameTracker)...),
getNinjaStrings(bDef.ImplicitOutputs, nameTracker)...),
}
if d, ok := bDef.Variables["description"]; ok {
a.Desc = d.Value(nil)
a.Desc = d.Value(nameTracker)
}
actions = append(actions, a)
}
@ -2786,12 +2788,11 @@ func jsonModuleWithActionsFromModuleInfo(m *moduleInfo) *JsonModule {
return result
}
// Gets a list of strings from the given list of ninjaStrings by invoking ninjaString.Value with
// nil pkgNames on each of the input ninjaStrings.
func getNinjaStringsWithNilPkgNames(nStrs []*ninjaString) []string {
// Gets a list of strings from the given list of ninjaStrings by invoking ninjaString.Value on each.
func getNinjaStrings(nStrs []*ninjaString, nameTracker *nameTracker) []string {
var strs []string
for _, nstr := range nStrs {
strs = append(strs, nstr.Value(nil))
strs = append(strs, nstr.Value(nameTracker))
}
return strs
}
@ -2799,7 +2800,7 @@ func getNinjaStringsWithNilPkgNames(nStrs []*ninjaString) []string {
func (c *Context) GetWeightedOutputsFromPredicate(predicate func(*JsonModule) (bool, int)) map[string]int {
outputToWeight := make(map[string]int)
for _, m := range c.modulesSorted {
jmWithActions := jsonModuleWithActionsFromModuleInfo(m)
jmWithActions := jsonModuleWithActionsFromModuleInfo(m, c.nameTracker)
if ok, weight := predicate(jmWithActions); ok {
for _, a := range jmWithActions.Module["Actions"].([]JSONAction) {
for _, o := range a.Outputs {
@ -2831,7 +2832,7 @@ func (c *Context) PrintJSONGraphAndActions(wGraph io.Writer, wActions io.Writer)
modulesToActions := make([]*JsonModule, 0)
for _, m := range c.modulesSorted {
jm := jsonModuleFromModuleInfo(m)
jmWithActions := jsonModuleWithActionsFromModuleInfo(m)
jmWithActions := jsonModuleWithActionsFromModuleInfo(m, c.nameTracker)
for _, d := range m.directDeps {
jm.Deps = append(jm.Deps, jsonDep{
jsonModuleName: *jsonModuleNameFromModuleInfo(d.module),
@ -2918,12 +2919,12 @@ func (c *Context) PrepareBuildActions(config interface{}) (deps []string, errs [
deps = append(deps, depsPackages...)
c.memoizeFullNames(c.liveGlobals, pkgNames)
nameTracker := c.memoizeFullNames(c.liveGlobals, pkgNames)
// This will panic if it finds a problem since it's a programming error.
c.checkForVariableReferenceCycles(c.liveGlobals.variables, pkgNames)
c.checkForVariableReferenceCycles(c.liveGlobals.variables, nameTracker)
c.pkgNames = pkgNames
c.nameTracker = nameTracker
c.globalVariables = c.liveGlobals.variables
c.globalPools = c.liveGlobals.pools
c.globalRules = c.liveGlobals.rules
@ -3862,20 +3863,27 @@ func (c *Context) makeUniquePackageNames(
// memoizeFullNames stores the full name of each live global variable, rule and pool since each is
// guaranteed to be used at least twice, once in the definition and once for each usage, and many
// are used much more than once.
func (c *Context) memoizeFullNames(liveGlobals *liveTracker, pkgNames map[*packageContext]string) {
func (c *Context) memoizeFullNames(liveGlobals *liveTracker, pkgNames map[*packageContext]string) *nameTracker {
nameTracker := &nameTracker{
pkgNames: pkgNames,
variables: make(map[Variable]string),
rules: make(map[Rule]string),
pools: make(map[Pool]string),
}
for v := range liveGlobals.variables {
v.memoizeFullName(pkgNames)
nameTracker.variables[v] = v.fullName(pkgNames)
}
for r := range liveGlobals.rules {
r.memoizeFullName(pkgNames)
nameTracker.rules[r] = r.fullName(pkgNames)
}
for p := range liveGlobals.pools {
p.memoizeFullName(pkgNames)
nameTracker.pools[p] = p.fullName(pkgNames)
}
return nameTracker
}
func (c *Context) checkForVariableReferenceCycles(
variables map[Variable]*ninjaString, pkgNames map[*packageContext]string) {
variables map[Variable]*ninjaString, nameTracker *nameTracker) {
visited := make(map[Variable]bool) // variables that were already checked
checking := make(map[Variable]bool) // variables actively being checked
@ -3905,12 +3913,12 @@ func (c *Context) checkForVariableReferenceCycles(
msgs := []string{"detected variable reference cycle:"}
// Iterate backwards through the cycle list.
curName := v.fullName(pkgNames)
curValue := value.Value(pkgNames)
curName := nameTracker.Variable(v)
curValue := value.Value(nameTracker)
for i := len(cycle) - 1; i >= 0; i-- {
next := cycle[i]
nextName := next.fullName(pkgNames)
nextValue := variables[next].Value(pkgNames)
nextName := nameTracker.Variable(next)
nextValue := variables[next].Value(nameTracker)
msgs = append(msgs, fmt.Sprintf(
" %q depends on %q", curName, nextName))
@ -3958,7 +3966,7 @@ func (c *Context) AllTargets() (map[string]string, error) {
targets := map[string]string{}
var collectTargets = func(actionDefs localBuildActions) error {
for _, buildDef := range actionDefs.buildDefs {
ruleName := buildDef.Rule.fullName(c.pkgNames)
ruleName := c.nameTracker.Rule(buildDef.Rule)
for _, output := range append(buildDef.Outputs, buildDef.ImplicitOutputs...) {
outputValue, err := output.Eval(c.globalVariables)
if err != nil {
@ -4266,7 +4274,7 @@ func (c *Context) writeBuildFileHeader(nw *ninjaWriter) error {
var pkgs []pkgAssociation
maxNameLen := 0
for pkg, name := range c.pkgNames {
for pkg, name := range c.nameTracker.pkgNames {
pkgs = append(pkgs, pkgAssociation{
PkgName: name,
PkgPath: pkg.pkgPath,
@ -4319,7 +4327,7 @@ func (c *Context) writeSubninjas(nw *ninjaWriter) error {
func (c *Context) writeBuildDir(nw *ninjaWriter) error {
if c.outDir != nil {
err := nw.Assign("builddir", c.outDir.Value(c.pkgNames))
err := nw.Assign("builddir", c.outDir.Value(c.nameTracker))
if err != nil {
return err
}
@ -4332,29 +4340,6 @@ func (c *Context) writeBuildDir(nw *ninjaWriter) error {
return nil
}
type globalEntity interface {
fullName(pkgNames map[*packageContext]string) string
}
type globalEntitySorter struct {
pkgNames map[*packageContext]string
entities []globalEntity
}
func (s *globalEntitySorter) Len() int {
return len(s.entities)
}
func (s *globalEntitySorter) Less(i, j int) bool {
iName := s.entities[i].fullName(s.pkgNames)
jName := s.entities[j].fullName(s.pkgNames)
return iName < jName
}
func (s *globalEntitySorter) Swap(i, j int) {
s.entities[i], s.entities[j] = s.entities[j], s.entities[i]
}
func (c *Context) writeGlobalVariables(nw *ninjaWriter) error {
visited := make(map[Variable]bool)
@ -4373,7 +4358,7 @@ func (c *Context) writeGlobalVariables(nw *ninjaWriter) error {
}
}
err := nw.Assign(v.fullName(c.pkgNames), value.Value(c.pkgNames))
err := nw.Assign(c.nameTracker.Variable(v), value.Value(c.nameTracker))
if err != nil {
return err
}
@ -4386,15 +4371,16 @@ func (c *Context) writeGlobalVariables(nw *ninjaWriter) error {
return nil
}
globalVariables := make([]globalEntity, 0, len(c.globalVariables))
globalVariables := make([]Variable, 0, len(c.globalVariables))
for variable := range c.globalVariables {
globalVariables = append(globalVariables, variable)
}
sort.Sort(&globalEntitySorter{c.pkgNames, globalVariables})
slices.SortFunc(globalVariables, func(a, b Variable) int {
return cmp.Compare(c.nameTracker.Variable(a), c.nameTracker.Variable(b))
})
for _, entity := range globalVariables {
v := entity.(Variable)
for _, v := range globalVariables {
if !visited[v] {
err := walk(v)
if err != nil {
@ -4407,16 +4393,17 @@ func (c *Context) writeGlobalVariables(nw *ninjaWriter) error {
}
func (c *Context) writeGlobalPools(nw *ninjaWriter) error {
globalPools := make([]globalEntity, 0, len(c.globalPools))
globalPools := make([]Pool, 0, len(c.globalPools))
for pool := range c.globalPools {
globalPools = append(globalPools, pool)
}
sort.Sort(&globalEntitySorter{c.pkgNames, globalPools})
slices.SortFunc(globalPools, func(a, b Pool) int {
return cmp.Compare(c.nameTracker.Pool(a), c.nameTracker.Pool(b))
})
for _, entity := range globalPools {
pool := entity.(Pool)
name := pool.fullName(c.pkgNames)
for _, pool := range globalPools {
name := c.nameTracker.Pool(pool)
def := c.globalPools[pool]
err := def.WriteTo(nw, name)
if err != nil {
@ -4433,18 +4420,19 @@ func (c *Context) writeGlobalPools(nw *ninjaWriter) error {
}
func (c *Context) writeGlobalRules(nw *ninjaWriter) error {
globalRules := make([]globalEntity, 0, len(c.globalRules))
globalRules := make([]Rule, 0, len(c.globalRules))
for rule := range c.globalRules {
globalRules = append(globalRules, rule)
}
sort.Sort(&globalEntitySorter{c.pkgNames, globalRules})
slices.SortFunc(globalRules, func(a, b Rule) int {
return cmp.Compare(c.nameTracker.Rule(a), c.nameTracker.Rule(b))
})
for _, entity := range globalRules {
rule := entity.(Rule)
name := rule.fullName(c.pkgNames)
for _, rule := range globalRules {
name := c.nameTracker.Rule(rule)
def := c.globalRules[rule]
err := def.WriteTo(nw, name, c.pkgNames)
err := def.WriteTo(nw, name, c.nameTracker)
if err != nil {
return err
}
@ -4766,7 +4754,7 @@ func (c *Context) writeLocalBuildActions(nw *ninjaWriter,
if err != nil {
panic(err)
}
err = nw.Assign(name, value.Value(c.pkgNames))
err = nw.Assign(name, value.Value(c.nameTracker))
if err != nil {
return err
}
@ -4789,7 +4777,7 @@ func (c *Context) writeLocalBuildActions(nw *ninjaWriter,
panic(err)
}
err = def.WriteTo(nw, name, c.pkgNames)
err = def.WriteTo(nw, name, c.nameTracker)
if err != nil {
return err
}
@ -4802,7 +4790,7 @@ func (c *Context) writeLocalBuildActions(nw *ninjaWriter,
// Write the build definitions.
for _, buildDef := range defs.buildDefs {
err := buildDef.WriteTo(nw, c.pkgNames)
err := buildDef.WriteTo(nw, c.nameTracker)
if err != nil {
return err
}

View file

@ -229,8 +229,7 @@ func parseRuleParams(scope scope, params *RuleParams) (*ruleDef,
return r, nil
}
func (r *ruleDef) WriteTo(nw *ninjaWriter, name string,
pkgNames map[*packageContext]string) error {
func (r *ruleDef) WriteTo(nw *ninjaWriter, name string, nameTracker *nameTracker) error {
if r.Comment != "" {
err := nw.Comment(r.Comment)
@ -245,13 +244,13 @@ func (r *ruleDef) WriteTo(nw *ninjaWriter, name string,
}
if r.Pool != nil {
err = nw.ScopedAssign("pool", r.Pool.fullName(pkgNames))
err = nw.ScopedAssign("pool", nameTracker.Pool(r.Pool))
if err != nil {
return err
}
}
err = writeVariables(nw, r.Variables, pkgNames)
err = writeVariables(nw, r.Variables, nameTracker)
if err != nil {
return err
}
@ -415,10 +414,10 @@ func parseBuildParams(scope scope, params *BuildParams,
return b, nil
}
func (b *buildDef) WriteTo(nw *ninjaWriter, pkgNames map[*packageContext]string) error {
func (b *buildDef) WriteTo(nw *ninjaWriter, nameTracker *nameTracker) error {
var (
comment = b.Comment
rule = b.Rule.fullName(pkgNames)
rule = nameTracker.Rule(b.Rule)
outputs = b.Outputs
implicitOuts = b.ImplicitOutputs
explicitDeps = b.Inputs
@ -441,12 +440,12 @@ func (b *buildDef) WriteTo(nw *ninjaWriter, pkgNames map[*packageContext]string)
err := nw.Build(comment, rule, outputs, implicitOuts, explicitDeps, implicitDeps, orderOnlyDeps, validations,
outputStrings, implicitOutStrings, explicitDepStrings,
implicitDepStrings, orderOnlyDepStrings, validationStrings,
pkgNames)
nameTracker)
if err != nil {
return err
}
err = writeVariables(nw, b.Variables, pkgNames)
err = writeVariables(nw, b.Variables, nameTracker)
if err != nil {
return err
}
@ -458,8 +457,8 @@ func (b *buildDef) WriteTo(nw *ninjaWriter, pkgNames map[*packageContext]string)
args := make([]nameValuePair, 0, len(b.Args))
for argVar, value := range b.Args {
fullName := argVar.fullName(pkgNames)
args = append(args, nameValuePair{fullName, value.Value(pkgNames)})
fullName := nameTracker.Variable(argVar)
args = append(args, nameValuePair{fullName, value.Value(nameTracker)})
}
sort.Slice(args, func(i, j int) bool { return args[i].name < args[j].name })
@ -471,7 +470,7 @@ func (b *buildDef) WriteTo(nw *ninjaWriter, pkgNames map[*packageContext]string)
}
if !b.Optional {
err = nw.Default(pkgNames, outputs, outputStrings)
err = nw.Default(nameTracker, outputs, outputStrings)
if err != nil {
return err
}
@ -480,8 +479,7 @@ func (b *buildDef) WriteTo(nw *ninjaWriter, pkgNames map[*packageContext]string)
return nw.BlankLine()
}
func writeVariables(nw *ninjaWriter, variables map[string]*ninjaString,
pkgNames map[*packageContext]string) error {
func writeVariables(nw *ninjaWriter, variables map[string]*ninjaString, nameTracker *nameTracker) error {
var keys []string
for k := range variables {
keys = append(keys, k)
@ -489,7 +487,7 @@ func writeVariables(nw *ninjaWriter, variables map[string]*ninjaString,
sort.Strings(keys)
for _, name := range keys {
err := nw.ScopedAssign(name, variables[name].Value(pkgNames))
err := nw.ScopedAssign(name, variables[name].Value(nameTracker))
if err != nil {
return err
}

View file

@ -324,17 +324,16 @@ func parseNinjaOrSimpleStrings(scope scope, strs []string) ([]*ninjaString, []st
return ninjaStrings, simpleStrings, nil
}
func (n *ninjaString) Value(pkgNames map[*packageContext]string) string {
func (n *ninjaString) Value(nameTracker *nameTracker) string {
if n.variables == nil || len(*n.variables) == 0 {
return defaultEscaper.Replace(n.str)
}
str := &strings.Builder{}
n.ValueWithEscaper(str, pkgNames, defaultEscaper)
n.ValueWithEscaper(str, nameTracker, defaultEscaper)
return str.String()
}
func (n *ninjaString) ValueWithEscaper(w io.StringWriter, pkgNames map[*packageContext]string,
escaper *strings.Replacer) {
func (n *ninjaString) ValueWithEscaper(w io.StringWriter, nameTracker *nameTracker, escaper *strings.Replacer) {
if n.variables == nil || len(*n.variables) == 0 {
w.WriteString(escaper.Replace(n.str))
@ -348,7 +347,7 @@ func (n *ninjaString) ValueWithEscaper(w io.StringWriter, pkgNames map[*packageC
w.WriteString("$ ")
} else {
w.WriteString("${")
w.WriteString(v.variable.fullName(pkgNames))
w.WriteString(nameTracker.Variable(v.variable))
w.WriteString("}")
}
i = int(v.end)

View file

@ -164,7 +164,7 @@ func TestParseNinjaString(t *testing.T) {
output, err := parseNinjaString(scope, testCase.input)
if err == nil {
if g, w := output.Value(nil), testCase.value; g != w {
if g, w := output.Value(&nameTracker{}), testCase.value; g != w {
t.Errorf("incorrect Value output, want %q, got %q", w, g)
}
@ -191,7 +191,11 @@ func TestParseNinjaString(t *testing.T) {
}
func TestParseNinjaStringWithImportedVar(t *testing.T) {
ImpVar := &staticVariable{name_: "ImpVar", fullName_: "g.impPkg.ImpVar"}
pctx := &packageContext{}
pkgNames := map[*packageContext]string{
pctx: "impPkg",
}
ImpVar := &staticVariable{pctx: pctx, name_: "ImpVar"}
impScope := newScope(nil)
impScope.AddVariable(ImpVar)
scope := newScope(nil)
@ -211,7 +215,7 @@ func TestParseNinjaStringWithImportedVar(t *testing.T) {
t.Errorf(" got: %#v", *output.variables)
}
if g, w := output.Value(nil), "abc def ${g.impPkg.ImpVar} ghi"; g != w {
if g, w := output.Value(&nameTracker{pkgNames: pkgNames}), "abc def ${g.impPkg.ImpVar} ghi"; g != w {
t.Errorf("incorrect Value output, want %q got %q", w, g)
}
}
@ -289,7 +293,7 @@ func Test_parseNinjaOrSimpleStrings(t *testing.T) {
if gotNinjaStrings != nil {
evaluatedNinjaStrings = make([]string, 0, len(gotNinjaStrings))
for _, ns := range gotNinjaStrings {
evaluatedNinjaStrings = append(evaluatedNinjaStrings, ns.Value(nil))
evaluatedNinjaStrings = append(evaluatedNinjaStrings, ns.Value(&nameTracker{}))
}
}
@ -364,7 +368,7 @@ func BenchmarkNinjaString_Value(b *testing.B) {
b.Run(strconv.Itoa(l), func(b *testing.B) {
b.ReportAllocs()
for n := 0; n < b.N; n++ {
ns.Value(nil)
ns.Value(&nameTracker{})
}
})
}
@ -377,7 +381,7 @@ func BenchmarkNinjaString_Value(b *testing.B) {
b.Run(strconv.Itoa(l), func(b *testing.B) {
b.ReportAllocs()
for n := 0; n < b.N; n++ {
ns.Value(nil)
ns.Value(&nameTracker{})
}
})
}
@ -394,7 +398,7 @@ func BenchmarkNinjaString_Value(b *testing.B) {
b.Run(strconv.Itoa(l), func(b *testing.B) {
b.ReportAllocs()
for n := 0; n < b.N; n++ {
ns.Value(nil)
ns.Value(&nameTracker{})
}
})
}

View file

@ -117,7 +117,7 @@ func (n *ninjaWriter) Build(comment string, rule string, outputs, implicitOuts,
explicitDeps, implicitDeps, orderOnlyDeps, validations []*ninjaString,
outputStrings, implicitOutStrings, explicitDepStrings,
implicitDepStrings, orderOnlyDepStrings, validationStrings []string,
pkgNames map[*packageContext]string) error {
nameTracker *nameTracker) error {
n.justDidBlankLine = false
@ -144,7 +144,7 @@ func (n *ninjaWriter) Build(comment string, rule string, outputs, implicitOuts,
}
for _, output := range outputs {
wrapper.Space()
output.ValueWithEscaper(wrapper, pkgNames, outputEscaper)
output.ValueWithEscaper(wrapper, nameTracker, outputEscaper)
}
if len(implicitOuts) > 0 || len(implicitOutStrings) > 0 {
@ -156,7 +156,7 @@ func (n *ninjaWriter) Build(comment string, rule string, outputs, implicitOuts,
}
for _, out := range implicitOuts {
wrapper.Space()
out.ValueWithEscaper(wrapper, pkgNames, outputEscaper)
out.ValueWithEscaper(wrapper, nameTracker, outputEscaper)
}
}
@ -170,7 +170,7 @@ func (n *ninjaWriter) Build(comment string, rule string, outputs, implicitOuts,
}
for _, dep := range explicitDeps {
wrapper.Space()
dep.ValueWithEscaper(wrapper, pkgNames, inputEscaper)
dep.ValueWithEscaper(wrapper, nameTracker, inputEscaper)
}
if len(implicitDeps) > 0 || len(implicitDepStrings) > 0 {
@ -182,7 +182,7 @@ func (n *ninjaWriter) Build(comment string, rule string, outputs, implicitOuts,
}
for _, dep := range implicitDeps {
wrapper.Space()
dep.ValueWithEscaper(wrapper, pkgNames, inputEscaper)
dep.ValueWithEscaper(wrapper, nameTracker, inputEscaper)
}
}
@ -195,7 +195,7 @@ func (n *ninjaWriter) Build(comment string, rule string, outputs, implicitOuts,
}
for _, dep := range orderOnlyDeps {
wrapper.Space()
dep.ValueWithEscaper(wrapper, pkgNames, inputEscaper)
dep.ValueWithEscaper(wrapper, nameTracker, inputEscaper)
}
}
@ -208,7 +208,7 @@ func (n *ninjaWriter) Build(comment string, rule string, outputs, implicitOuts,
}
for _, dep := range validations {
wrapper.Space()
dep.ValueWithEscaper(wrapper, pkgNames, inputEscaper)
dep.ValueWithEscaper(wrapper, nameTracker, inputEscaper)
}
}
@ -261,7 +261,7 @@ func (n *ninjaWriter) ScopedAssign(name, value string) error {
return nil
}
func (n *ninjaWriter) Default(pkgNames map[*packageContext]string, targets []*ninjaString, targetStrings []string) error {
func (n *ninjaWriter) Default(nameTracker *nameTracker, targets []*ninjaString, targetStrings []string) error {
n.justDidBlankLine = false
const lineWrapLen = len(" $")
@ -280,7 +280,7 @@ func (n *ninjaWriter) Default(pkgNames map[*packageContext]string, targets []*ni
}
for _, target := range targets {
wrapper.Space()
target.ValueWithEscaper(wrapper, pkgNames, outputEscaper)
target.ValueWithEscaper(wrapper, nameTracker, outputEscaper)
}
return wrapper.Flush()

View file

@ -250,10 +250,9 @@ func (p *packageContext) ImportAs(as, pkgPath string) {
}
type staticVariable struct {
pctx *packageContext
name_ string
value_ string
fullName_ string
pctx *packageContext
name_ string
value_ string
}
// StaticVariable returns a Variable whose value does not depend on any
@ -294,16 +293,9 @@ func (v *staticVariable) name() string {
}
func (v *staticVariable) fullName(pkgNames map[*packageContext]string) string {
if v.fullName_ != "" {
return v.fullName_
}
return packageNamespacePrefix(pkgNames[v.pctx]) + v.name_
}
func (v *staticVariable) memoizeFullName(pkgNames map[*packageContext]string) {
v.fullName_ = v.fullName(pkgNames)
}
func (v *staticVariable) value(VariableFuncContext, interface{}) (*ninjaString, error) {
ninjaStr, err := parseNinjaString(v.pctx.scope, v.value_)
if err != nil {
@ -318,10 +310,9 @@ func (v *staticVariable) String() string {
}
type variableFunc struct {
pctx *packageContext
name_ string
value_ func(VariableFuncContext, interface{}) (string, error)
fullName_ string
pctx *packageContext
name_ string
value_ func(VariableFuncContext, interface{}) (string, error)
}
// VariableFuncContext is passed to VariableFunc functions.
@ -430,16 +421,9 @@ func (v *variableFunc) name() string {
}
func (v *variableFunc) fullName(pkgNames map[*packageContext]string) string {
if v.fullName_ != "" {
return v.fullName_
}
return packageNamespacePrefix(pkgNames[v.pctx]) + v.name_
}
func (v *variableFunc) memoizeFullName(pkgNames map[*packageContext]string) {
v.fullName_ = v.fullName(pkgNames)
}
func (v *variableFunc) value(ctx VariableFuncContext, config interface{}) (*ninjaString, error) {
value, err := v.value_(ctx, config)
if err != nil {
@ -500,10 +484,6 @@ func (v *argVariable) fullName(pkgNames map[*packageContext]string) string {
return v.name_
}
func (v *argVariable) memoizeFullName(pkgNames map[*packageContext]string) {
// Nothing to do, full name is known at initialization.
}
func (v *argVariable) value(ctx VariableFuncContext, config interface{}) (*ninjaString, error) {
return nil, errVariableIsArg
}
@ -513,10 +493,9 @@ func (v *argVariable) String() string {
}
type staticPool struct {
pctx *packageContext
name_ string
params PoolParams
fullName_ string
pctx *packageContext
name_ string
params PoolParams
}
// StaticPool returns a Pool whose value does not depend on any configuration
@ -558,16 +537,9 @@ func (p *staticPool) name() string {
}
func (p *staticPool) fullName(pkgNames map[*packageContext]string) string {
if p.fullName_ != "" {
return p.fullName_
}
return packageNamespacePrefix(pkgNames[p.pctx]) + p.name_
}
func (p *staticPool) memoizeFullName(pkgNames map[*packageContext]string) {
p.fullName_ = p.fullName(pkgNames)
}
func (p *staticPool) def(config interface{}) (*poolDef, error) {
def, err := parsePoolParams(p.pctx.scope, &p.params)
if err != nil {
@ -584,7 +556,6 @@ type poolFunc struct {
pctx *packageContext
name_ string
paramsFunc func(interface{}) (PoolParams, error)
fullName_ string
}
// PoolFunc returns a Pool whose value is determined by a function that takes a
@ -629,16 +600,9 @@ func (p *poolFunc) name() string {
}
func (p *poolFunc) fullName(pkgNames map[*packageContext]string) string {
if p.fullName_ != "" {
return p.fullName_
}
return packageNamespacePrefix(pkgNames[p.pctx]) + p.name_
}
func (p *poolFunc) memoizeFullName(pkgNames map[*packageContext]string) {
p.fullName_ = p.fullName(pkgNames)
}
func (p *poolFunc) def(config interface{}) (*poolDef, error) {
params, err := p.paramsFunc(config)
if err != nil {
@ -671,10 +635,6 @@ func (p *builtinPool) fullName(pkgNames map[*packageContext]string) string {
return p.name_
}
func (p *builtinPool) memoizeFullName(pkgNames map[*packageContext]string) {
// Nothing to do, full name is known at initialization.
}
func (p *builtinPool) def(config interface{}) (*poolDef, error) {
return nil, errPoolIsBuiltin
}
@ -696,7 +656,6 @@ type staticRule struct {
params RuleParams
argNames map[string]bool
scope_ *basicScope
fullName_ string
sync.Mutex // protects scope_ during lazy creation
}
@ -764,16 +723,9 @@ func (r *staticRule) name() string {
}
func (r *staticRule) fullName(pkgNames map[*packageContext]string) string {
if r.fullName_ != "" {
return r.fullName_
}
return packageNamespacePrefix(pkgNames[r.pctx]) + r.name_
}
func (r *staticRule) memoizeFullName(pkgNames map[*packageContext]string) {
r.fullName_ = r.fullName(pkgNames)
}
func (r *staticRule) def(interface{}) (*ruleDef, error) {
def, err := parseRuleParams(r.scope(), &r.params)
if err != nil {
@ -809,7 +761,6 @@ type ruleFunc struct {
paramsFunc func(interface{}) (RuleParams, error)
argNames map[string]bool
scope_ *basicScope
fullName_ string
sync.Mutex // protects scope_ during lazy creation
}
@ -878,16 +829,9 @@ func (r *ruleFunc) name() string {
}
func (r *ruleFunc) fullName(pkgNames map[*packageContext]string) string {
if r.fullName_ != "" {
return r.fullName_
}
return packageNamespacePrefix(pkgNames[r.pctx]) + r.name_
}
func (r *ruleFunc) memoizeFullName(pkgNames map[*packageContext]string) {
r.fullName_ = r.fullName(pkgNames)
}
func (r *ruleFunc) def(config interface{}) (*ruleDef, error) {
params, err := r.paramsFunc(config)
if err != nil {
@ -939,10 +883,6 @@ func (r *builtinRule) fullName(pkgNames map[*packageContext]string) string {
return r.name_
}
func (r *builtinRule) memoizeFullName(pkgNames map[*packageContext]string) {
// Nothing to do, full name is known at initialization.
}
func (r *builtinRule) def(config interface{}) (*ruleDef, error) {
return nil, errRuleIsBuiltin
}

View file

@ -28,7 +28,6 @@ type Variable interface {
packageContext() *packageContext
name() string // "foo"
fullName(pkgNames map[*packageContext]string) string // "pkg.foo" or "path.to.pkg.foo"
memoizeFullName(pkgNames map[*packageContext]string) // precompute fullName if desired
value(ctx VariableFuncContext, config interface{}) (*ninjaString, error)
String() string
}
@ -39,7 +38,6 @@ type Pool interface {
packageContext() *packageContext
name() string // "foo"
fullName(pkgNames map[*packageContext]string) string // "pkg.foo" or "path.to.pkg.foo"
memoizeFullName(pkgNames map[*packageContext]string) // precompute fullName if desired
def(config interface{}) (*poolDef, error)
String() string
}
@ -50,7 +48,6 @@ type Rule interface {
packageContext() *packageContext
name() string // "foo"
fullName(pkgNames map[*packageContext]string) string // "pkg.foo" or "path.to.pkg.foo"
memoizeFullName(pkgNames map[*packageContext]string) // precompute fullName if desired
def(config interface{}) (*ruleDef, error)
scope() *basicScope
isArg(argName string) bool
@ -369,10 +366,6 @@ func (l *localVariable) fullName(pkgNames map[*packageContext]string) string {
return l.fullName_
}
func (l *localVariable) memoizeFullName(pkgNames map[*packageContext]string) {
// Nothing to do, full name is known at initialization.
}
func (l *localVariable) value(VariableFuncContext, interface{}) (*ninjaString, error) {
return l.value_, nil
}
@ -401,10 +394,6 @@ func (l *localRule) fullName(pkgNames map[*packageContext]string) string {
return l.fullName_
}
func (l *localRule) memoizeFullName(pkgNames map[*packageContext]string) {
// Nothing to do, full name is known at initialization.
}
func (l *localRule) def(interface{}) (*ruleDef, error) {
return l.def_, nil
}
@ -420,3 +409,41 @@ func (r *localRule) isArg(argName string) bool {
func (r *localRule) String() string {
return "<local rule>:" + r.fullName_
}
type nameTracker struct {
variables map[Variable]string
rules map[Rule]string
pools map[Pool]string
pkgNames map[*packageContext]string
}
func (m *nameTracker) Variable(v Variable) string {
if m == nil {
return v.fullName(nil)
}
if name, ok := m.variables[v]; ok {
return name
}
return v.fullName(m.pkgNames)
}
func (m *nameTracker) Rule(r Rule) string {
if m == nil {
return r.fullName(nil)
}
if name, ok := m.rules[r]; ok {
return name
}
return r.fullName(m.pkgNames)
}
func (m *nameTracker) Pool(p Pool) string {
if m == nil {
return p.fullName(nil)
}
if name, ok := m.pools[p]; ok {
return name
}
return p.fullName(m.pkgNames)
}