diff --git a/context.go b/context.go index 811df15..c8bc1f9 100644 --- a/context.go +++ b/context.go @@ -82,7 +82,7 @@ type Context struct { 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) setNinjaBuildDir(value *ninjaString) { } 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) makeUniquePackageNames( } 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 @@ func (c *Context) writeBuildDir(nw *ninjaWriter) error { } 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 @@ type ModuleContext interface { 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 @@ func (m *moduleContext) ModuleSubDir() string { 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 @@ func (m *moduleContext) Variable(pctx *PackageContext, name, value string) { 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 @@ func (m *moduleContext) Rule(pctx *PackageContext, name string, 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 parseRuleParams(scope scope, params *RuleParams) (*ruleDef, } 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 @@ func parseBuildParams(scope scope, params *BuildParams) (*buildDef, 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 @@ func (b *buildDef) WriteTo(nw *ninjaWriter, pkgNames map[*PackageContext]string) 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 @@ func parseNinjaStrings(scope scope, strs []string) ([]*ninjaString, 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 @@ import ( // 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 @@ func NewPackageContext(pkgPath string) *PackageContext { i := strings.LastIndex(pkgPath, "/") shortName := pkgPath[i+1:] - p := &PackageContext{ + p := &packageContext{ fullName: pkgName, shortName: shortName, pkgPath: pkgPath, @@ -198,7 +220,7 @@ func pkgPathToName(pkgPath string) string { // 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 @@ func (p *PackageContext) Import(pkgPath string) { // 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 @@ func (p *PackageContext) ImportAs(as, pkgPath string) { } type staticVariable struct { - pctx *PackageContext + pctx *packageContext name_ string value_ string } @@ -247,7 +269,7 @@ type staticVariable struct { // 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 @@ func (p *PackageContext) StaticVariable(name, value string) Variable { return v } -func (v *staticVariable) packageContext() *PackageContext { +func (v *staticVariable) packageContext() *packageContext { return v.pctx } @@ -271,7 +293,7 @@ func (v *staticVariable) name() string { 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 @@ func (v *staticVariable) String() string { } type variableFunc struct { - pctx *PackageContext + pctx *packageContext name_ string value_ func(interface{}) (string, error) } @@ -305,7 +327,7 @@ type variableFunc struct { // 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 @@ func (p *PackageContext) VariableFunc(name string, // 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 @@ func (p *PackageContext) VariableConfigMethod(name string, return v } -func (v *variableFunc) packageContext() *PackageContext { +func (v *variableFunc) packageContext() *packageContext { return v.pctx } @@ -371,7 +393,7 @@ func (v *variableFunc) name() string { 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 @@ type argVariable struct { name_ string } -func (v *argVariable) packageContext() *PackageContext { +func (v *argVariable) packageContext() *packageContext { panic("this should not be called") } @@ -431,7 +453,7 @@ func (v *argVariable) name() string { 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 @@ func (v *argVariable) String() string { } type staticPool struct { - pctx *PackageContext + pctx *packageContext name_ string params PoolParams } @@ -458,7 +480,7 @@ type staticPool struct { // 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 @@ func (p *PackageContext) StaticPool(name string, params PoolParams) Pool { return pool } -func (p *staticPool) packageContext() *PackageContext { +func (p *staticPool) packageContext() *packageContext { return p.pctx } @@ -483,7 +505,7 @@ func (p *staticPool) name() string { 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 @@ func (p *staticPool) String() string { } type poolFunc struct { - pctx *PackageContext + pctx *packageContext name_ string paramsFunc func(interface{}) (PoolParams, error) } @@ -515,7 +537,7 @@ type poolFunc struct { // 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 @@ func (p *PackageContext) PoolFunc(name string, f func(interface{}) (PoolParams, return pool } -func (p *poolFunc) packageContext() *PackageContext { +func (p *poolFunc) packageContext() *packageContext { return p.pctx } @@ -542,7 +564,7 @@ func (p *poolFunc) name() string { 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 @@ type builtinPool struct { name_ string } -func (p *builtinPool) packageContext() *PackageContext { +func (p *builtinPool) packageContext() *packageContext { return nil } @@ -574,7 +596,7 @@ func (p *builtinPool) name() string { 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 @@ func (p *builtinPool) String() string { } type staticRule struct { - pctx *PackageContext + pctx *packageContext name_ string params RuleParams argNames map[string]bool @@ -613,7 +635,7 @@ type staticRule struct { // 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 @@ func (p *PackageContext) StaticRule(name string, params RuleParams, return r } -func (r *staticRule) packageContext() *PackageContext { +func (r *staticRule) packageContext() *packageContext { return r.pctx } @@ -658,7 +680,7 @@ func (r *staticRule) name() string { 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 @@ func (r *staticRule) String() string { } type ruleFunc struct { - pctx *PackageContext + pctx *packageContext name_ string paramsFunc func(interface{}) (RuleParams, error) argNames map[string]bool @@ -719,7 +741,7 @@ type ruleFunc struct { // 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 @@ func (p *PackageContext) RuleFunc(name string, f func(interface{}) (RuleParams, return rule } -func (r *ruleFunc) packageContext() *PackageContext { +func (r *ruleFunc) packageContext() *packageContext { return r.pctx } @@ -764,7 +786,7 @@ func (r *ruleFunc) name() string { 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 @@ type builtinRule struct { sync.Mutex // protects scope_ during lazy creation } -func (r *builtinRule) packageContext() *PackageContext { +func (r *builtinRule) packageContext() *packageContext { return nil } @@ -815,7 +837,7 @@ func (r *builtinRule) name() string { 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 @@ import ( // 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 @@ type Variable interface { // 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 @@ type Pool interface { // 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 @@ func newLocalScope(parent *basicScope, namePrefix string) *localScope { // 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 @@ type localVariable struct { value_ *ninjaString } -func (l *localVariable) packageContext() *PackageContext { +func (l *localVariable) packageContext() *packageContext { return nil } @@ -362,7 +362,7 @@ func (l *localVariable) name() string { 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 @@ type localRule struct { scope_ *basicScope } -func (l *localRule) packageContext() *PackageContext { +func (l *localRule) packageContext() *packageContext { return nil } @@ -390,7 +390,7 @@ func (l *localRule) name() string { 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 @@ type SingletonContext interface { 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 @@ func (s *singletonContext) Errorf(format string, args ...interface{}) { 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 @@ func (s *singletonContext) Variable(pctx *PackageContext, name, value string) { 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 @@ func (s *singletonContext) Rule(pctx *PackageContext, name string, 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 @@ func (s *singletonContext) RequireNinjaVersion(major, minor, micro int) { 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)