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 15 package common 16 17 import ( 18 "github.com/google/blueprint" 19 "github.com/google/blueprint/proptools" 20 ) 21 22 type defaultsProperties struct { 23 Defaults []string 24 } 25 26 type DefaultableModule struct { 27 defaultsProperties defaultsProperties 28 defaultableProperties []interface{} 29 } 30 31 func (d *DefaultableModule) defaults() *defaultsProperties { 32 return &d.defaultsProperties 33 } 34 35 func (d *DefaultableModule) setProperties(props []interface{}) { 36 d.defaultableProperties = props 37 } 38 39 type Defaultable interface { 40 defaults() *defaultsProperties 41 setProperties([]interface{}) 42 applyDefaults(AndroidTopDownMutatorContext, Defaults) 43 } 44 45 var _ Defaultable = (*DefaultableModule)(nil) 46 47 func InitDefaultableModule(module AndroidModule, d Defaultable, 48 props ...interface{}) (blueprint.Module, []interface{}) { 49 50 d.setProperties(props) 51 52 props = append(props, d.defaults()) 53 54 return module, props 55 } 56 57 type DefaultsModule struct { 58 defaultProperties []interface{} 59 } 60 61 type Defaults interface { 62 isDefaults() bool 63 setProperties([]interface{}) 64 properties() []interface{} 65 } 66 67 func (d *DefaultsModule) isDefaults() bool { 68 return true 69 } 70 71 func (d *DefaultsModule) properties() []interface{} { 72 return d.defaultProperties 73 } 74 75 func (d *DefaultsModule) setProperties(props []interface{}) { 76 d.defaultProperties = props 77 } 78 79 func InitDefaultsModule(module AndroidModule, d Defaults, props ...interface{}) (blueprint.Module, []interface{}) { 80 d.setProperties(props) 81 82 return module, props 83 } 84 85 var _ Defaults = (*DefaultsModule)(nil) 86 87 func (defaultable *DefaultableModule) applyDefaults(ctx AndroidTopDownMutatorContext, 88 defaults Defaults) { 89 90 for _, prop := range defaultable.defaultableProperties { 91 for _, def := range defaults.properties() { 92 if proptools.TypeEqual(prop, def) { 93 err := proptools.PrependProperties(prop, def, nil) 94 if err != nil { 95 if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok { 96 ctx.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error()) 97 } else { 98 panic(err) 99 } 100 } 101 } 102 } 103 } 104 } 105 106 func defaultsDepsMutator(ctx AndroidBottomUpMutatorContext) { 107 if defaultable, ok := ctx.Module().(Defaultable); ok { 108 ctx.AddDependency(ctx.Module(), defaultable.defaults().Defaults...) 109 } 110 } 111 112 func defaultsMutator(ctx AndroidTopDownMutatorContext) { 113 if defaultable, ok := ctx.Module().(Defaultable); ok { 114 for _, defaultsDep := range defaultable.defaults().Defaults { 115 ctx.VisitDirectDeps(func(m blueprint.Module) { 116 if ctx.OtherModuleName(m) == defaultsDep { 117 if defaultsModule, ok := m.(Defaults); ok { 118 defaultable.applyDefaults(ctx, defaultsModule) 119 } else { 120 ctx.PropertyErrorf("defaults", "module %s is not an defaults module", 121 ctx.OtherModuleName(m)) 122 } 123 } 124 }) 125 } 126 } 127 } 128