blob: 549d079db38793a5214fe4cf6132955e22a832cc [file] [log] [blame]
Jamie Gennis1bc967e2014-05-27 16:34:41 -07001package blueprint
2
3import (
4 "fmt"
5 "path/filepath"
6)
7
8type Singleton interface {
9 GenerateBuildActions(SingletonContext)
10}
11
12type SingletonContext interface {
13 Config() Config
14
15 ModuleName(module Module) string
16 ModuleDir(module Module) string
17 BlueprintFile(module Module) string
18
19 ModuleErrorf(module Module, format string, args ...interface{})
20 Errorf(format string, args ...interface{})
21
22 Variable(name, value string)
23 Rule(name string, params RuleParams) Rule
24 Build(params BuildParams)
25 RequireNinjaVersion(major, minor, micro int)
26
27 // SetBuildDir sets the value of the top-level "builddir" Ninja variable
28 // that controls where Ninja stores its build log files. This value can be
29 // set at most one time for a single build. Setting it multiple times (even
30 // across different singletons) will result in a panic.
31 SetBuildDir(value string)
32
33 VisitAllModules(visit func(Module))
34 VisitAllModulesIf(pred func(Module) bool, visit func(Module))
35}
36
37var _ SingletonContext = (*singletonContext)(nil)
38
39type singletonContext struct {
40 context *Context
41 config Config
42 scope *localScope
43
44 errs []error
45
46 actionDefs localBuildActions
47}
48
49func (s *singletonContext) Config() Config {
50 return s.config
51}
52
53func (s *singletonContext) ModuleName(module Module) string {
54 info := s.context.moduleInfo[module]
55 return info.properties.Name
56}
57
58func (s *singletonContext) ModuleDir(module Module) string {
59 info := s.context.moduleInfo[module]
60 return filepath.Dir(info.relBlueprintFile)
61}
62
63func (s *singletonContext) BlueprintFile(module Module) string {
64 info := s.context.moduleInfo[module]
65 return info.relBlueprintFile
66}
67
68func (s *singletonContext) ModuleErrorf(module Module, format string,
69 args ...interface{}) {
70
71 info := s.context.moduleInfo[module]
72 s.errs = append(s.errs, &Error{
73 Err: fmt.Errorf(format, args...),
74 Pos: info.pos,
75 })
76}
77
78func (s *singletonContext) Errorf(format string, args ...interface{}) {
79 // TODO: Make this not result in the error being printed as "internal error"
80 s.errs = append(s.errs, fmt.Errorf(format, args...))
81}
82
83func (s *singletonContext) Variable(name, value string) {
84 v, err := s.scope.AddLocalVariable(name, value)
85 if err != nil {
86 panic(err)
87 }
88
89 s.actionDefs.variables = append(s.actionDefs.variables, v)
90}
91
92func (s *singletonContext) Rule(name string, params RuleParams) Rule {
93 // TODO: Verify that params.Pool is accessible in this module's scope.
94
95 r, err := s.scope.AddLocalRule(name, &params)
96 if err != nil {
97 panic(err)
98 }
99
100 s.actionDefs.rules = append(s.actionDefs.rules, r)
101
102 return r
103}
104
105func (s *singletonContext) Build(params BuildParams) {
106 // TODO: Verify that params.Rule is accessible in this module's scope.
107
108 def, err := parseBuildParams(s.scope, &params)
109 if err != nil {
110 panic(err)
111 }
112
113 s.actionDefs.buildDefs = append(s.actionDefs.buildDefs, def)
114}
115
116func (s *singletonContext) RequireNinjaVersion(major, minor, micro int) {
117 s.context.requireNinjaVersion(major, minor, micro)
118}
119
120func (s *singletonContext) SetBuildDir(value string) {
121 ninjaValue, err := parseNinjaString(s.scope, value)
122 if err != nil {
123 panic(err)
124 }
125
126 s.context.setBuildDir(ninjaValue)
127}
128
129func (s *singletonContext) VisitAllModules(visit func(Module)) {
130 s.context.visitAllModules(visit)
131}
132
133func (s *singletonContext) VisitAllModulesIf(pred func(Module) bool,
134 visit func(Module)) {
135
136 s.context.visitAllModulesIf(pred, visit)
137}