blob: df1409e8d7e673481aaf1fae0811c4b9bb266518 [file] [log] [blame]
Colin Crosscfad1192015-11-02 16:43:11 -08001// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
Colin Cross635c3b02016-05-18 15:37:25 -070015package android
Colin Crosscfad1192015-11-02 16:43:11 -080016
17import (
18 "github.com/google/blueprint"
19 "github.com/google/blueprint/proptools"
20)
21
Colin Crossc99deeb2016-04-11 15:06:20 -070022type defaultsDependencyTag struct {
23 blueprint.BaseDependencyTag
24}
25
26var DefaultsDepTag defaultsDependencyTag
27
Colin Crosscfad1192015-11-02 16:43:11 -080028type defaultsProperties struct {
29 Defaults []string
30}
31
32type DefaultableModule struct {
33 defaultsProperties defaultsProperties
34 defaultableProperties []interface{}
35}
36
37func (d *DefaultableModule) defaults() *defaultsProperties {
38 return &d.defaultsProperties
39}
40
41func (d *DefaultableModule) setProperties(props []interface{}) {
42 d.defaultableProperties = props
43}
44
45type Defaultable interface {
46 defaults() *defaultsProperties
47 setProperties([]interface{})
Colin Cross13177012016-08-09 12:00:45 -070048 applyDefaults(TopDownMutatorContext, []Defaults)
Colin Crosscfad1192015-11-02 16:43:11 -080049}
50
51var _ Defaultable = (*DefaultableModule)(nil)
52
Colin Cross635c3b02016-05-18 15:37:25 -070053func InitDefaultableModule(module Module, d Defaultable,
Colin Crosscfad1192015-11-02 16:43:11 -080054 props ...interface{}) (blueprint.Module, []interface{}) {
55
56 d.setProperties(props)
57
58 props = append(props, d.defaults())
59
60 return module, props
61}
62
63type DefaultsModule struct {
Colin Crosse7b07132016-07-27 10:15:06 -070064 DefaultableModule
Colin Crosscfad1192015-11-02 16:43:11 -080065 defaultProperties []interface{}
66}
67
68type Defaults interface {
Colin Crosse7b07132016-07-27 10:15:06 -070069 Defaultable
Colin Crosscfad1192015-11-02 16:43:11 -080070 isDefaults() bool
Colin Crosscfad1192015-11-02 16:43:11 -080071 properties() []interface{}
72}
73
74func (d *DefaultsModule) isDefaults() bool {
75 return true
76}
77
78func (d *DefaultsModule) properties() []interface{} {
Colin Crosse7b07132016-07-27 10:15:06 -070079 return d.defaultableProperties
Colin Crosscfad1192015-11-02 16:43:11 -080080}
81
Colin Cross635c3b02016-05-18 15:37:25 -070082func InitDefaultsModule(module Module, d Defaults, props ...interface{}) (blueprint.Module, []interface{}) {
Colin Crossfc754582016-05-17 16:34:16 -070083 props = append(props,
84 &hostAndDeviceProperties{},
85 &commonProperties{},
86 &variableProperties{})
87
88 _, props = InitArchModule(module, props...)
89
90 _, props = InitDefaultableModule(module, d, props...)
91
92 props = append(props, &module.base().nameProperties)
93
94 module.base().module = module
95
96 return module, props
Colin Crosscfad1192015-11-02 16:43:11 -080097}
98
99var _ Defaults = (*DefaultsModule)(nil)
100
Colin Cross13177012016-08-09 12:00:45 -0700101func (defaultable *DefaultableModule) applyDefaults(ctx TopDownMutatorContext,
102 defaultsList []Defaults) {
Colin Crosscfad1192015-11-02 16:43:11 -0800103
Colin Cross13177012016-08-09 12:00:45 -0700104 for _, defaults := range defaultsList {
105 for _, prop := range defaultable.defaultableProperties {
106 for _, def := range defaults.properties() {
107 if proptools.TypeEqual(prop, def) {
108 err := proptools.PrependProperties(prop, def, nil)
109 if err != nil {
110 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
111 ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
112 } else {
113 panic(err)
114 }
Colin Crosscfad1192015-11-02 16:43:11 -0800115 }
116 }
117 }
118 }
119 }
120}
121
Colin Cross635c3b02016-05-18 15:37:25 -0700122func defaultsDepsMutator(ctx BottomUpMutatorContext) {
Colin Crosscfad1192015-11-02 16:43:11 -0800123 if defaultable, ok := ctx.Module().(Defaultable); ok {
Colin Crossc99deeb2016-04-11 15:06:20 -0700124 ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults...)
Colin Crosscfad1192015-11-02 16:43:11 -0800125 }
126}
127
Colin Cross13177012016-08-09 12:00:45 -0700128func defaultsMutator(ctx TopDownMutatorContext) {
129 if defaultable, ok := ctx.Module().(Defaultable); ok && len(defaultable.defaults().Defaults) > 0 {
130 var defaultsList []Defaults
131 ctx.WalkDeps(func(module, parent blueprint.Module) bool {
132 if ctx.OtherModuleDependencyTag(module) == DefaultsDepTag {
133 if defaults, ok := module.(Defaults); ok {
134 defaultsList = append(defaultsList, defaults)
135 return len(defaults.defaults().Defaults) > 0
136 } else {
137 ctx.PropertyErrorf("defaults", "module %s is not an defaults module",
138 ctx.OtherModuleName(module))
Colin Crosscfad1192015-11-02 16:43:11 -0800139 }
Colin Cross13177012016-08-09 12:00:45 -0700140 }
141 return false
142 })
143 defaultable.applyDefaults(ctx, defaultsList)
Colin Crosscfad1192015-11-02 16:43:11 -0800144 }
145}