blob: 0776405fa3bc7c0eb3ad46c9ef2df232087b3c1c [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 Cross36242852017-06-23 15:06:31 -070053func InitDefaultableModule(module Module, d Defaultable) {
Colin Crosscfad1192015-11-02 16:43:11 -080054
Colin Cross36242852017-06-23 15:06:31 -070055 d.setProperties(module.GetProperties())
Colin Crosscfad1192015-11-02 16:43:11 -080056
Colin Cross36242852017-06-23 15:06:31 -070057 module.AddProperties(d.defaults())
Colin Crosscfad1192015-11-02 16:43:11 -080058}
59
60type DefaultsModule struct {
Colin Crosse7b07132016-07-27 10:15:06 -070061 DefaultableModule
Colin Crosscfad1192015-11-02 16:43:11 -080062 defaultProperties []interface{}
63}
64
65type Defaults interface {
Colin Crosse7b07132016-07-27 10:15:06 -070066 Defaultable
Colin Crosscfad1192015-11-02 16:43:11 -080067 isDefaults() bool
Colin Crosscfad1192015-11-02 16:43:11 -080068 properties() []interface{}
69}
70
71func (d *DefaultsModule) isDefaults() bool {
72 return true
73}
74
75func (d *DefaultsModule) properties() []interface{} {
Colin Crosse7b07132016-07-27 10:15:06 -070076 return d.defaultableProperties
Colin Crosscfad1192015-11-02 16:43:11 -080077}
78
Colin Cross36242852017-06-23 15:06:31 -070079func InitDefaultsModule(module Module, d Defaults) {
80 module.AddProperties(
Colin Crossfc754582016-05-17 16:34:16 -070081 &hostAndDeviceProperties{},
82 &commonProperties{},
83 &variableProperties{})
84
Colin Cross36242852017-06-23 15:06:31 -070085 InitArchModule(module)
86 InitDefaultableModule(module, d)
Colin Crossfc754582016-05-17 16:34:16 -070087
Colin Cross36242852017-06-23 15:06:31 -070088 module.AddProperties(&module.base().nameProperties)
Colin Crossfc754582016-05-17 16:34:16 -070089
90 module.base().module = module
Colin Crosscfad1192015-11-02 16:43:11 -080091}
92
93var _ Defaults = (*DefaultsModule)(nil)
94
Colin Cross13177012016-08-09 12:00:45 -070095func (defaultable *DefaultableModule) applyDefaults(ctx TopDownMutatorContext,
96 defaultsList []Defaults) {
Colin Crosscfad1192015-11-02 16:43:11 -080097
Colin Cross13177012016-08-09 12:00:45 -070098 for _, defaults := range defaultsList {
99 for _, prop := range defaultable.defaultableProperties {
100 for _, def := range defaults.properties() {
101 if proptools.TypeEqual(prop, def) {
102 err := proptools.PrependProperties(prop, def, nil)
103 if err != nil {
104 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
105 ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
106 } else {
107 panic(err)
108 }
Colin Crosscfad1192015-11-02 16:43:11 -0800109 }
110 }
111 }
112 }
113 }
114}
115
Colin Cross635c3b02016-05-18 15:37:25 -0700116func defaultsDepsMutator(ctx BottomUpMutatorContext) {
Colin Crosscfad1192015-11-02 16:43:11 -0800117 if defaultable, ok := ctx.Module().(Defaultable); ok {
Colin Crossc99deeb2016-04-11 15:06:20 -0700118 ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults...)
Colin Crosscfad1192015-11-02 16:43:11 -0800119 }
120}
121
Colin Cross13177012016-08-09 12:00:45 -0700122func defaultsMutator(ctx TopDownMutatorContext) {
123 if defaultable, ok := ctx.Module().(Defaultable); ok && len(defaultable.defaults().Defaults) > 0 {
124 var defaultsList []Defaults
125 ctx.WalkDeps(func(module, parent blueprint.Module) bool {
126 if ctx.OtherModuleDependencyTag(module) == DefaultsDepTag {
127 if defaults, ok := module.(Defaults); ok {
128 defaultsList = append(defaultsList, defaults)
129 return len(defaults.defaults().Defaults) > 0
130 } else {
131 ctx.PropertyErrorf("defaults", "module %s is not an defaults module",
132 ctx.OtherModuleName(module))
Colin Crosscfad1192015-11-02 16:43:11 -0800133 }
Colin Cross13177012016-08-09 12:00:45 -0700134 }
135 return false
136 })
137 defaultable.applyDefaults(ctx, defaultsList)
Colin Crosscfad1192015-11-02 16:43:11 -0800138 }
139}