Allow wrapping of PackageContext
Turn PackageContext into an interface so that build systems can wrap it
to add more custom helpers.
This does introduce an API change, though it should be fairly simple.
NewPackageContext used to provide an opaque *PackageContext struct, now it
provides a PackageContext interface.
Change-Id: I383c64a303d857ef5e0dec86ad77f791ba4c9639
diff --git a/context.go b/context.go
index 811df15..c8bc1f9 100644
--- a/context.go
+++ b/context.go
@@ -82,7 +82,7 @@
ignoreUnknownModuleTypes bool
// set during PrepareBuildActions
- pkgNames map[*PackageContext]string
+ pkgNames map[*packageContext]string
globalVariables map[Variable]*ninjaString
globalPools map[Pool]*poolDef
globalRules map[Rule]*ruleDef
@@ -1919,13 +1919,13 @@
}
func (c *Context) makeUniquePackageNames(
- liveGlobals *liveTracker) map[*PackageContext]string {
+ liveGlobals *liveTracker) map[*packageContext]string {
- pkgs := make(map[string]*PackageContext)
- pkgNames := make(map[*PackageContext]string)
- longPkgNames := make(map[*PackageContext]bool)
+ pkgs := make(map[string]*packageContext)
+ pkgNames := make(map[*packageContext]string)
+ longPkgNames := make(map[*packageContext]bool)
- processPackage := func(pctx *PackageContext) {
+ processPackage := func(pctx *packageContext) {
if pctx == nil {
// This is a built-in rule and has no package.
return
@@ -1972,7 +1972,7 @@
}
func (c *Context) checkForVariableReferenceCycles(
- variables map[Variable]*ninjaString, pkgNames map[*PackageContext]string) {
+ variables map[Variable]*ninjaString, pkgNames map[*packageContext]string) {
visited := make(map[Variable]bool) // variables that were already checked
checking := make(map[Variable]bool) // variables actively being checked
@@ -2313,11 +2313,11 @@
}
type globalEntity interface {
- fullName(pkgNames map[*PackageContext]string) string
+ fullName(pkgNames map[*packageContext]string) string
}
type globalEntitySorter struct {
- pkgNames map[*PackageContext]string
+ pkgNames map[*packageContext]string
entities []globalEntity
}
diff --git a/module_ctx.go b/module_ctx.go
index ce3cb8a..bb33d37 100644
--- a/module_ctx.go
+++ b/module_ctx.go
@@ -137,9 +137,9 @@
ModuleSubDir() string
- Variable(pctx *PackageContext, name, value string)
- Rule(pctx *PackageContext, name string, params RuleParams, argNames ...string) Rule
- Build(pctx *PackageContext, params BuildParams)
+ Variable(pctx PackageContext, name, value string)
+ Rule(pctx PackageContext, name string, params RuleParams, argNames ...string) Rule
+ Build(pctx PackageContext, params BuildParams)
AddNinjaFileDeps(deps ...string)
@@ -267,7 +267,7 @@
return m.module.variantName
}
-func (m *moduleContext) Variable(pctx *PackageContext, name, value string) {
+func (m *moduleContext) Variable(pctx PackageContext, name, value string) {
m.scope.ReparentTo(pctx)
v, err := m.scope.AddLocalVariable(name, value)
@@ -278,7 +278,7 @@
m.actionDefs.variables = append(m.actionDefs.variables, v)
}
-func (m *moduleContext) Rule(pctx *PackageContext, name string,
+func (m *moduleContext) Rule(pctx PackageContext, name string,
params RuleParams, argNames ...string) Rule {
m.scope.ReparentTo(pctx)
@@ -293,7 +293,7 @@
return r
}
-func (m *moduleContext) Build(pctx *PackageContext, params BuildParams) {
+func (m *moduleContext) Build(pctx PackageContext, params BuildParams) {
m.scope.ReparentTo(pctx)
def, err := parseBuildParams(m.scope, ¶ms)
diff --git a/ninja_defs.go b/ninja_defs.go
index 05b8f2f..e7a2929 100644
--- a/ninja_defs.go
+++ b/ninja_defs.go
@@ -207,7 +207,7 @@
}
func (r *ruleDef) WriteTo(nw *ninjaWriter, name string,
- pkgNames map[*PackageContext]string) error {
+ pkgNames map[*packageContext]string) error {
if r.Comment != "" {
err := nw.Comment(r.Comment)
@@ -327,7 +327,7 @@
return b, nil
}
-func (b *buildDef) WriteTo(nw *ninjaWriter, pkgNames map[*PackageContext]string) error {
+func (b *buildDef) WriteTo(nw *ninjaWriter, pkgNames map[*packageContext]string) error {
var (
comment = b.Comment
rule = b.Rule.fullName(pkgNames)
@@ -372,7 +372,7 @@
return nw.BlankLine()
}
-func valueList(list []*ninjaString, pkgNames map[*PackageContext]string,
+func valueList(list []*ninjaString, pkgNames map[*packageContext]string,
escaper *strings.Replacer) []string {
result := make([]string, len(list))
diff --git a/ninja_strings.go b/ninja_strings.go
index 3492da2..5bdddea 100644
--- a/ninja_strings.go
+++ b/ninja_strings.go
@@ -258,11 +258,11 @@
return result, nil
}
-func (n *ninjaString) Value(pkgNames map[*PackageContext]string) string {
+func (n *ninjaString) Value(pkgNames map[*packageContext]string) string {
return n.ValueWithEscaper(pkgNames, defaultEscaper)
}
-func (n *ninjaString) ValueWithEscaper(pkgNames map[*PackageContext]string,
+func (n *ninjaString) ValueWithEscaper(pkgNames map[*packageContext]string,
escaper *strings.Replacer) string {
str := escaper.Replace(n.strings[0])
diff --git a/package_ctx.go b/package_ctx.go
index 0d3f0ae..5b93c20 100644
--- a/package_ctx.go
+++ b/package_ctx.go
@@ -53,20 +53,42 @@
// Outputs: []string{"$myPrivateVar"},
// })
// }
-type PackageContext struct {
+type PackageContext interface {
+ Import(pkgPath string)
+ ImportAs(as, pkgPath string)
+
+ StaticVariable(name, value string) Variable
+ VariableFunc(name string, f func(config interface{}) (string, error)) Variable
+ VariableConfigMethod(name string, method interface{}) Variable
+
+ StaticPool(name string, params PoolParams) Pool
+ PoolFunc(name string, f func(interface{}) (PoolParams, error)) Pool
+
+ StaticRule(name string, params RuleParams, argNames ...string) Rule
+ RuleFunc(name string, f func(interface{}) (RuleParams, error), argNames ...string) Rule
+
+ getScope() *basicScope
+}
+
+type packageContext struct {
fullName string
shortName string
pkgPath string
scope *basicScope
}
+var _ PackageContext = &packageContext{}
-var packageContexts = map[string]*PackageContext{}
+func (p *packageContext) getScope() *basicScope {
+ return p.scope
+}
+
+var packageContexts = map[string]*packageContext{}
// NewPackageContext creates a PackageContext object for a given package. The
// pkgPath argument should always be set to the full path used to import the
// package. This function may only be called from a Go package's init()
// function or as part of a package-scoped variable initialization.
-func NewPackageContext(pkgPath string) *PackageContext {
+func NewPackageContext(pkgPath string) PackageContext {
checkCalledFromInit()
if _, present := packageContexts[pkgPath]; present {
@@ -82,7 +104,7 @@
i := strings.LastIndex(pkgPath, "/")
shortName := pkgPath[i+1:]
- p := &PackageContext{
+ p := &packageContext{
fullName: pkgName,
shortName: shortName,
pkgPath: pkgPath,
@@ -198,7 +220,7 @@
// from Go's import declaration, which derives the local name from the package
// clause in the imported package. By convention these names are made to match,
// but this is not required.
-func (p *PackageContext) Import(pkgPath string) {
+func (p *packageContext) Import(pkgPath string) {
checkCalledFromInit()
importPkg, ok := packageContexts[pkgPath]
if !ok {
@@ -214,7 +236,7 @@
// ImportAs provides the same functionality as Import, but it allows the local
// name that will be used to refer to the package to be specified explicitly.
// It may only be called from a Go package's init() function.
-func (p *PackageContext) ImportAs(as, pkgPath string) {
+func (p *packageContext) ImportAs(as, pkgPath string) {
checkCalledFromInit()
importPkg, ok := packageContexts[pkgPath]
if !ok {
@@ -233,7 +255,7 @@
}
type staticVariable struct {
- pctx *PackageContext
+ pctx *packageContext
name_ string
value_ string
}
@@ -247,7 +269,7 @@
// represents a Ninja variable that will be output. The name argument should
// exactly match the Go variable name, and the value string may reference other
// Ninja variables that are visible within the calling Go package.
-func (p *PackageContext) StaticVariable(name, value string) Variable {
+func (p *packageContext) StaticVariable(name, value string) Variable {
checkCalledFromInit()
err := validateNinjaName(name)
if err != nil {
@@ -263,7 +285,7 @@
return v
}
-func (v *staticVariable) packageContext() *PackageContext {
+func (v *staticVariable) packageContext() *packageContext {
return v.pctx
}
@@ -271,7 +293,7 @@
return v.name_
}
-func (v *staticVariable) fullName(pkgNames map[*PackageContext]string) string {
+func (v *staticVariable) fullName(pkgNames map[*packageContext]string) string {
return packageNamespacePrefix(pkgNames[v.pctx]) + v.name_
}
@@ -289,7 +311,7 @@
}
type variableFunc struct {
- pctx *PackageContext
+ pctx *packageContext
name_ string
value_ func(interface{}) (string, error)
}
@@ -305,7 +327,7 @@
// exactly match the Go variable name, and the value string returned by f may
// reference other Ninja variables that are visible within the calling Go
// package.
-func (p *PackageContext) VariableFunc(name string,
+func (p *packageContext) VariableFunc(name string,
f func(config interface{}) (string, error)) Variable {
checkCalledFromInit()
@@ -335,7 +357,7 @@
// exactly match the Go variable name, and the value string returned by method
// may reference other Ninja variables that are visible within the calling Go
// package.
-func (p *PackageContext) VariableConfigMethod(name string,
+func (p *packageContext) VariableConfigMethod(name string,
method interface{}) Variable {
checkCalledFromInit()
@@ -363,7 +385,7 @@
return v
}
-func (v *variableFunc) packageContext() *PackageContext {
+func (v *variableFunc) packageContext() *packageContext {
return v.pctx
}
@@ -371,7 +393,7 @@
return v.name_
}
-func (v *variableFunc) fullName(pkgNames map[*PackageContext]string) string {
+func (v *variableFunc) fullName(pkgNames map[*packageContext]string) string {
return packageNamespacePrefix(pkgNames[v.pctx]) + v.name_
}
@@ -423,7 +445,7 @@
name_ string
}
-func (v *argVariable) packageContext() *PackageContext {
+func (v *argVariable) packageContext() *packageContext {
panic("this should not be called")
}
@@ -431,7 +453,7 @@
return v.name_
}
-func (v *argVariable) fullName(pkgNames map[*PackageContext]string) string {
+func (v *argVariable) fullName(pkgNames map[*packageContext]string) string {
return v.name_
}
@@ -444,7 +466,7 @@
}
type staticPool struct {
- pctx *PackageContext
+ pctx *packageContext
name_ string
params PoolParams
}
@@ -458,7 +480,7 @@
// represents a Ninja pool that will be output. The name argument should
// exactly match the Go variable name, and the params fields may reference other
// Ninja variables that are visible within the calling Go package.
-func (p *PackageContext) StaticPool(name string, params PoolParams) Pool {
+func (p *packageContext) StaticPool(name string, params PoolParams) Pool {
checkCalledFromInit()
err := validateNinjaName(name)
@@ -475,7 +497,7 @@
return pool
}
-func (p *staticPool) packageContext() *PackageContext {
+func (p *staticPool) packageContext() *packageContext {
return p.pctx
}
@@ -483,7 +505,7 @@
return p.name_
}
-func (p *staticPool) fullName(pkgNames map[*PackageContext]string) string {
+func (p *staticPool) fullName(pkgNames map[*packageContext]string) string {
return packageNamespacePrefix(pkgNames[p.pctx]) + p.name_
}
@@ -500,7 +522,7 @@
}
type poolFunc struct {
- pctx *PackageContext
+ pctx *packageContext
name_ string
paramsFunc func(interface{}) (PoolParams, error)
}
@@ -515,7 +537,7 @@
// exactly match the Go variable name, and the string fields of the PoolParams
// returned by f may reference other Ninja variables that are visible within the
// calling Go package.
-func (p *PackageContext) PoolFunc(name string, f func(interface{}) (PoolParams,
+func (p *packageContext) PoolFunc(name string, f func(interface{}) (PoolParams,
error)) Pool {
checkCalledFromInit()
@@ -534,7 +556,7 @@
return pool
}
-func (p *poolFunc) packageContext() *PackageContext {
+func (p *poolFunc) packageContext() *packageContext {
return p.pctx
}
@@ -542,7 +564,7 @@
return p.name_
}
-func (p *poolFunc) fullName(pkgNames map[*PackageContext]string) string {
+func (p *poolFunc) fullName(pkgNames map[*packageContext]string) string {
return packageNamespacePrefix(pkgNames[p.pctx]) + p.name_
}
@@ -566,7 +588,7 @@
name_ string
}
-func (p *builtinPool) packageContext() *PackageContext {
+func (p *builtinPool) packageContext() *packageContext {
return nil
}
@@ -574,7 +596,7 @@
return p.name_
}
-func (p *builtinPool) fullName(pkgNames map[*PackageContext]string) string {
+func (p *builtinPool) fullName(pkgNames map[*packageContext]string) string {
return p.name_
}
@@ -587,7 +609,7 @@
}
type staticRule struct {
- pctx *PackageContext
+ pctx *packageContext
name_ string
params RuleParams
argNames map[string]bool
@@ -613,7 +635,7 @@
// results in the package-scoped variable's value being used for build
// statements that do not override the argument. For argument names that do not
// shadow package-scoped variables the default value is an empty string.
-func (p *PackageContext) StaticRule(name string, params RuleParams,
+func (p *packageContext) StaticRule(name string, params RuleParams,
argNames ...string) Rule {
checkCalledFromInit()
@@ -650,7 +672,7 @@
return r
}
-func (r *staticRule) packageContext() *PackageContext {
+func (r *staticRule) packageContext() *packageContext {
return r.pctx
}
@@ -658,7 +680,7 @@
return r.name_
}
-func (r *staticRule) fullName(pkgNames map[*PackageContext]string) string {
+func (r *staticRule) fullName(pkgNames map[*packageContext]string) string {
return packageNamespacePrefix(pkgNames[r.pctx]) + r.name_
}
@@ -692,7 +714,7 @@
}
type ruleFunc struct {
- pctx *PackageContext
+ pctx *packageContext
name_ string
paramsFunc func(interface{}) (RuleParams, error)
argNames map[string]bool
@@ -719,7 +741,7 @@
// scoped variable results in the package-scoped variable's value being used for
// build statements that do not override the argument. For argument names that
// do not shadow package-scoped variables the default value is an empty string.
-func (p *PackageContext) RuleFunc(name string, f func(interface{}) (RuleParams,
+func (p *packageContext) RuleFunc(name string, f func(interface{}) (RuleParams,
error), argNames ...string) Rule {
checkCalledFromInit()
@@ -756,7 +778,7 @@
return rule
}
-func (r *ruleFunc) packageContext() *PackageContext {
+func (r *ruleFunc) packageContext() *packageContext {
return r.pctx
}
@@ -764,7 +786,7 @@
return r.name_
}
-func (r *ruleFunc) fullName(pkgNames map[*PackageContext]string) string {
+func (r *ruleFunc) fullName(pkgNames map[*packageContext]string) string {
return packageNamespacePrefix(pkgNames[r.pctx]) + r.name_
}
@@ -807,7 +829,7 @@
sync.Mutex // protects scope_ during lazy creation
}
-func (r *builtinRule) packageContext() *PackageContext {
+func (r *builtinRule) packageContext() *packageContext {
return nil
}
@@ -815,7 +837,7 @@
return r.name_
}
-func (r *builtinRule) fullName(pkgNames map[*PackageContext]string) string {
+func (r *builtinRule) fullName(pkgNames map[*packageContext]string) string {
return r.name_
}
diff --git a/scope.go b/scope.go
index ef4eb2c..84db0cf 100644
--- a/scope.go
+++ b/scope.go
@@ -25,9 +25,9 @@
// to the output .ninja file. A variable may contain references to other global
// Ninja variables, but circular variable references are not allowed.
type Variable interface {
- packageContext() *PackageContext
+ packageContext() *packageContext
name() string // "foo"
- fullName(pkgNames map[*PackageContext]string) string // "pkg.foo" or "path.to.pkg.foo"
+ fullName(pkgNames map[*packageContext]string) string // "pkg.foo" or "path.to.pkg.foo"
value(config interface{}) (*ninjaString, error)
String() string
}
@@ -35,9 +35,9 @@
// A Pool represents a Ninja pool that will be written to the output .ninja
// file.
type Pool interface {
- packageContext() *PackageContext
+ packageContext() *packageContext
name() string // "foo"
- fullName(pkgNames map[*PackageContext]string) string // "pkg.foo" or "path.to.pkg.foo"
+ fullName(pkgNames map[*packageContext]string) string // "pkg.foo" or "path.to.pkg.foo"
def(config interface{}) (*poolDef, error)
String() string
}
@@ -45,9 +45,9 @@
// A Rule represents a Ninja build rule that will be written to the output
// .ninja file.
type Rule interface {
- packageContext() *PackageContext
+ packageContext() *packageContext
name() string // "foo"
- fullName(pkgNames map[*PackageContext]string) string // "pkg.foo" or "path.to.pkg.foo"
+ fullName(pkgNames map[*packageContext]string) string // "pkg.foo" or "path.to.pkg.foo"
def(config interface{}) (*ruleDef, error)
scope() *basicScope
isArg(argName string) bool
@@ -260,8 +260,8 @@
// package context. This allows a ModuleContext and SingletonContext to call
// a function defined in a different Go package and have that function retain
// access to all of the package-scoped variables of its own package.
-func (s *localScope) ReparentTo(pctx *PackageContext) {
- s.scope.parent = pctx.scope
+func (s *localScope) ReparentTo(pctx PackageContext) {
+ s.scope.parent = pctx.getScope()
}
func (s *localScope) LookupVariable(name string) (Variable, error) {
@@ -354,7 +354,7 @@
value_ *ninjaString
}
-func (l *localVariable) packageContext() *PackageContext {
+func (l *localVariable) packageContext() *packageContext {
return nil
}
@@ -362,7 +362,7 @@
return l.name_
}
-func (l *localVariable) fullName(pkgNames map[*PackageContext]string) string {
+func (l *localVariable) fullName(pkgNames map[*packageContext]string) string {
return l.namePrefix + l.name_
}
@@ -382,7 +382,7 @@
scope_ *basicScope
}
-func (l *localRule) packageContext() *PackageContext {
+func (l *localRule) packageContext() *packageContext {
return nil
}
@@ -390,7 +390,7 @@
return l.name_
}
-func (l *localRule) fullName(pkgNames map[*PackageContext]string) string {
+func (l *localRule) fullName(pkgNames map[*packageContext]string) string {
return l.namePrefix + l.name_
}
diff --git a/singleton_ctx.go b/singleton_ctx.go
index ee96fc6..2ba0199 100644
--- a/singleton_ctx.go
+++ b/singleton_ctx.go
@@ -32,15 +32,15 @@
ModuleErrorf(module Module, format string, args ...interface{})
Errorf(format string, args ...interface{})
- Variable(pctx *PackageContext, name, value string)
- Rule(pctx *PackageContext, name string, params RuleParams, argNames ...string) Rule
- Build(pctx *PackageContext, params BuildParams)
+ Variable(pctx PackageContext, name, value string)
+ Rule(pctx PackageContext, name string, params RuleParams, argNames ...string) Rule
+ Build(pctx PackageContext, params BuildParams)
RequireNinjaVersion(major, minor, micro int)
// SetNinjaBuildDir sets the value of the top-level "builddir" Ninja variable
// that controls where Ninja stores its build log files. This value can be
// set at most one time for a single build, later calls are ignored.
- SetNinjaBuildDir(pctx *PackageContext, value string)
+ SetNinjaBuildDir(pctx PackageContext, value string)
VisitAllModules(visit func(Module))
VisitAllModulesIf(pred func(Module) bool, visit func(Module))
@@ -96,7 +96,7 @@
s.errs = append(s.errs, fmt.Errorf(format, args...))
}
-func (s *singletonContext) Variable(pctx *PackageContext, name, value string) {
+func (s *singletonContext) Variable(pctx PackageContext, name, value string) {
s.scope.ReparentTo(pctx)
v, err := s.scope.AddLocalVariable(name, value)
@@ -107,7 +107,7 @@
s.actionDefs.variables = append(s.actionDefs.variables, v)
}
-func (s *singletonContext) Rule(pctx *PackageContext, name string,
+func (s *singletonContext) Rule(pctx PackageContext, name string,
params RuleParams, argNames ...string) Rule {
s.scope.ReparentTo(pctx)
@@ -122,7 +122,7 @@
return r
}
-func (s *singletonContext) Build(pctx *PackageContext, params BuildParams) {
+func (s *singletonContext) Build(pctx PackageContext, params BuildParams) {
s.scope.ReparentTo(pctx)
def, err := parseBuildParams(s.scope, ¶ms)
@@ -137,7 +137,7 @@
s.context.requireNinjaVersion(major, minor, micro)
}
-func (s *singletonContext) SetNinjaBuildDir(pctx *PackageContext, value string) {
+func (s *singletonContext) SetNinjaBuildDir(pctx PackageContext, value string) {
s.scope.ReparentTo(pctx)
ninjaValue, err := parseNinjaString(s.scope, value)