blob: b63ed5e4bebf4f1d75223128571630f2915c5d68 [file] [log] [blame]
Jamie Gennis1bc967e2014-05-27 16:34:41 -07001package blueprint
2
3import (
4 "fmt"
5 "path/filepath"
Jamie Gennis6a40c192014-07-02 16:40:31 -07006 "text/scanner"
Jamie Gennis1bc967e2014-05-27 16:34:41 -07007)
8
9type Module interface {
10 GenerateBuildActions(ModuleContext)
11}
12
13type ModuleContext interface {
14 ModuleName() string
Jamie Gennisd4c53d82014-06-22 17:02:55 -070015 OtherModuleName(m Module) string
Jamie Gennis1bc967e2014-05-27 16:34:41 -070016 ModuleDir() string
Jamie Gennis6eb4d242014-06-11 18:31:16 -070017 Config() interface{}
Jamie Gennis1bc967e2014-05-27 16:34:41 -070018
Jamie Gennis6a40c192014-07-02 16:40:31 -070019 Errorf(pos scanner.Position, fmt string, args ...interface{})
Jamie Gennis1bc967e2014-05-27 16:34:41 -070020 ModuleErrorf(fmt string, args ...interface{})
21 PropertyErrorf(property, fmt string, args ...interface{})
Jamie Gennisd4c53d82014-06-22 17:02:55 -070022 OtherModuleErrorf(m Module, fmt string, args ...interface{})
Jamie Gennis6a40c192014-07-02 16:40:31 -070023 Failed() bool
Jamie Gennis1bc967e2014-05-27 16:34:41 -070024
25 Variable(name, value string)
Jamie Genniscbc6f862014-06-05 20:00:22 -070026 Rule(name string, params RuleParams, argNames ...string) Rule
Jamie Gennis1bc967e2014-05-27 16:34:41 -070027 Build(params BuildParams)
28
29 VisitDepsDepthFirst(visit func(Module))
30 VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module))
Mathias Agopian5b8477d2014-06-25 17:21:54 -070031
32 AddNinjaFileDeps(deps ...string)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070033}
34
35var _ ModuleContext = (*moduleContext)(nil)
36
37type moduleContext struct {
38 context *Context
Jamie Gennis6eb4d242014-06-11 18:31:16 -070039 config interface{}
Jamie Gennis1bc967e2014-05-27 16:34:41 -070040 module Module
41 scope *localScope
42 info *moduleInfo
43
Mathias Agopian5b8477d2014-06-25 17:21:54 -070044 ninjaFileDeps []string
45 errs []error
Jamie Gennis1bc967e2014-05-27 16:34:41 -070046
47 actionDefs localBuildActions
48}
49
50func (m *moduleContext) ModuleName() string {
51 return m.info.properties.Name
52}
53
Jamie Gennisd4c53d82014-06-22 17:02:55 -070054func (m *moduleContext) OtherModuleName(module Module) string {
55 info := m.context.moduleInfo[module]
56 return info.properties.Name
57}
58
Jamie Gennis1bc967e2014-05-27 16:34:41 -070059func (m *moduleContext) ModuleDir() string {
Jamie Gennisec701282014-06-12 20:06:31 -070060 return filepath.Dir(m.info.relBlueprintsFile)
Jamie Gennis1bc967e2014-05-27 16:34:41 -070061}
62
Jamie Gennis6eb4d242014-06-11 18:31:16 -070063func (m *moduleContext) Config() interface{} {
Jamie Gennis1bc967e2014-05-27 16:34:41 -070064 return m.config
65}
66
Jamie Gennis6a40c192014-07-02 16:40:31 -070067func (m *moduleContext) Errorf(pos scanner.Position, format string,
68 args ...interface{}) {
69
70 m.errs = append(m.errs, &Error{
71 Err: fmt.Errorf(format, args...),
72 Pos: pos,
73 })
74}
75
Jamie Gennis1bc967e2014-05-27 16:34:41 -070076func (m *moduleContext) ModuleErrorf(format string, args ...interface{}) {
77 m.errs = append(m.errs, &Error{
78 Err: fmt.Errorf(format, args...),
79 Pos: m.info.pos,
80 })
81}
82
83func (m *moduleContext) PropertyErrorf(property, format string,
84 args ...interface{}) {
85
86 pos, ok := m.info.propertyPos[property]
87 if !ok {
88 panic(fmt.Errorf("property %q was not set for this module", property))
89 }
90
91 m.errs = append(m.errs, &Error{
92 Err: fmt.Errorf(format, args...),
93 Pos: pos,
94 })
95}
96
Jamie Gennisd4c53d82014-06-22 17:02:55 -070097func (m *moduleContext) OtherModuleErrorf(module Module, format string,
98 args ...interface{}) {
99
100 info := m.context.moduleInfo[module]
101 m.errs = append(m.errs, &Error{
102 Err: fmt.Errorf(format, args...),
103 Pos: info.pos,
104 })
105}
106
Jamie Gennis6a40c192014-07-02 16:40:31 -0700107func (m *moduleContext) Failed() bool {
108 return len(m.errs) > 0
109}
110
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700111func (m *moduleContext) Variable(name, value string) {
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700112 const skip = 2
113 m.scope.ReparentToCallerPackage(skip)
114
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700115 v, err := m.scope.AddLocalVariable(name, value)
116 if err != nil {
117 panic(err)
118 }
119
120 m.actionDefs.variables = append(m.actionDefs.variables, v)
121}
122
Jamie Genniscbc6f862014-06-05 20:00:22 -0700123func (m *moduleContext) Rule(name string, params RuleParams,
124 argNames ...string) Rule {
125
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700126 const skip = 2
127 m.scope.ReparentToCallerPackage(skip)
128
Jamie Genniscbc6f862014-06-05 20:00:22 -0700129 r, err := m.scope.AddLocalRule(name, &params, argNames...)
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700130 if err != nil {
131 panic(err)
132 }
133
134 m.actionDefs.rules = append(m.actionDefs.rules, r)
135
136 return r
137}
138
139func (m *moduleContext) Build(params BuildParams) {
Jamie Gennis0ed63ef2014-06-30 18:07:17 -0700140 const skip = 2
141 m.scope.ReparentToCallerPackage(skip)
142
Jamie Gennis1bc967e2014-05-27 16:34:41 -0700143 def, err := parseBuildParams(m.scope, &params)
144 if err != nil {
145 panic(err)
146 }
147
148 m.actionDefs.buildDefs = append(m.actionDefs.buildDefs, def)
149}
150
151func (m *moduleContext) VisitDepsDepthFirst(visit func(Module)) {
152 m.context.visitDepsDepthFirst(m.module, visit)
153}
154
155func (m *moduleContext) VisitDepsDepthFirstIf(pred func(Module) bool,
156 visit func(Module)) {
157
158 m.context.visitDepsDepthFirstIf(m.module, pred, visit)
159}
Mathias Agopian5b8477d2014-06-25 17:21:54 -0700160
161func (m *moduleContext) AddNinjaFileDeps(deps ...string) {
162 m.ninjaFileDeps = append(m.ninjaFileDeps, deps...)
163}