• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// 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
15package android
16
17import (
18	"github.com/google/blueprint"
19	"github.com/google/blueprint/proptools"
20)
21
22type defaultsDependencyTag struct {
23	blueprint.BaseDependencyTag
24}
25
26var DefaultsDepTag defaultsDependencyTag
27
28type defaultsProperties struct {
29	Defaults []string
30}
31
32type DefaultableModuleBase struct {
33	defaultsProperties    defaultsProperties
34	defaultableProperties []interface{}
35}
36
37func (d *DefaultableModuleBase) defaults() *defaultsProperties {
38	return &d.defaultsProperties
39}
40
41func (d *DefaultableModuleBase) setProperties(props []interface{}) {
42	d.defaultableProperties = props
43}
44
45type Defaultable interface {
46	defaults() *defaultsProperties
47	setProperties([]interface{})
48	applyDefaults(TopDownMutatorContext, []Defaults)
49}
50
51type DefaultableModule interface {
52	Module
53	Defaultable
54}
55
56var _ Defaultable = (*DefaultableModuleBase)(nil)
57
58func InitDefaultableModule(module DefaultableModule) {
59	module.(Defaultable).setProperties(module.(Module).GetProperties())
60
61	module.AddProperties(module.defaults())
62}
63
64type DefaultsModuleBase struct {
65	DefaultableModuleBase
66	defaultProperties []interface{}
67}
68
69type Defaults interface {
70	Defaultable
71	isDefaults() bool
72	properties() []interface{}
73}
74
75func (d *DefaultsModuleBase) isDefaults() bool {
76	return true
77}
78
79func (d *DefaultsModuleBase) properties() []interface{} {
80	return d.defaultableProperties
81}
82
83func InitDefaultsModule(module DefaultableModule) {
84	module.AddProperties(
85		&hostAndDeviceProperties{},
86		&commonProperties{},
87		&variableProperties{})
88
89	InitArchModule(module)
90	InitDefaultableModule(module)
91
92	module.AddProperties(&module.base().nameProperties)
93
94	module.base().module = module
95}
96
97var _ Defaults = (*DefaultsModuleBase)(nil)
98
99func (defaultable *DefaultableModuleBase) applyDefaults(ctx TopDownMutatorContext,
100	defaultsList []Defaults) {
101
102	for _, defaults := range defaultsList {
103		for _, prop := range defaultable.defaultableProperties {
104			for _, def := range defaults.properties() {
105				if proptools.TypeEqual(prop, def) {
106					err := proptools.PrependProperties(prop, def, nil)
107					if err != nil {
108						if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok {
109							ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error())
110						} else {
111							panic(err)
112						}
113					}
114				}
115			}
116		}
117	}
118}
119
120func RegisterDefaultsPreArchMutators(ctx RegisterMutatorsContext) {
121	ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
122	ctx.TopDown("defaults", defaultsMutator).Parallel()
123}
124
125func defaultsDepsMutator(ctx BottomUpMutatorContext) {
126	if defaultable, ok := ctx.Module().(Defaultable); ok {
127		ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults...)
128	}
129}
130
131func defaultsMutator(ctx TopDownMutatorContext) {
132	if defaultable, ok := ctx.Module().(Defaultable); ok && len(defaultable.defaults().Defaults) > 0 {
133		var defaultsList []Defaults
134		seen := make(map[Defaults]bool)
135
136		ctx.WalkDeps(func(module, parent Module) bool {
137			if ctx.OtherModuleDependencyTag(module) == DefaultsDepTag {
138				if defaults, ok := module.(Defaults); ok {
139					if !seen[defaults] {
140						seen[defaults] = true
141						defaultsList = append(defaultsList, defaults)
142						return len(defaults.defaults().Defaults) > 0
143					}
144				} else {
145					ctx.PropertyErrorf("defaults", "module %s is not an defaults module",
146						ctx.OtherModuleName(module))
147				}
148			}
149			return false
150		})
151		defaultable.applyDefaults(ctx, defaultsList)
152	}
153}
154