Home | History | Annotate | Download | only in android
      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 android
     16 
     17 import (
     18 	"github.com/google/blueprint"
     19 	"github.com/google/blueprint/proptools"
     20 )
     21 
     22 type defaultsDependencyTag struct {
     23 	blueprint.BaseDependencyTag
     24 }
     25 
     26 var DefaultsDepTag defaultsDependencyTag
     27 
     28 type defaultsProperties struct {
     29 	Defaults []string
     30 }
     31 
     32 type DefaultableModule struct {
     33 	defaultsProperties    defaultsProperties
     34 	defaultableProperties []interface{}
     35 }
     36 
     37 func (d *DefaultableModule) defaults() *defaultsProperties {
     38 	return &d.defaultsProperties
     39 }
     40 
     41 func (d *DefaultableModule) setProperties(props []interface{}) {
     42 	d.defaultableProperties = props
     43 }
     44 
     45 type Defaultable interface {
     46 	defaults() *defaultsProperties
     47 	setProperties([]interface{})
     48 	applyDefaults(TopDownMutatorContext, []Defaults)
     49 }
     50 
     51 var _ Defaultable = (*DefaultableModule)(nil)
     52 
     53 func InitDefaultableModule(module Module, d Defaultable,
     54 	props ...interface{}) (blueprint.Module, []interface{}) {
     55 
     56 	d.setProperties(props)
     57 
     58 	props = append(props, d.defaults())
     59 
     60 	return module, props
     61 }
     62 
     63 type DefaultsModule struct {
     64 	DefaultableModule
     65 	defaultProperties []interface{}
     66 }
     67 
     68 type Defaults interface {
     69 	Defaultable
     70 	isDefaults() bool
     71 	properties() []interface{}
     72 }
     73 
     74 func (d *DefaultsModule) isDefaults() bool {
     75 	return true
     76 }
     77 
     78 func (d *DefaultsModule) properties() []interface{} {
     79 	return d.defaultableProperties
     80 }
     81 
     82 func InitDefaultsModule(module Module, d Defaults, props ...interface{}) (blueprint.Module, []interface{}) {
     83 	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
     97 }
     98 
     99 var _ Defaults = (*DefaultsModule)(nil)
    100 
    101 func (defaultable *DefaultableModule) applyDefaults(ctx TopDownMutatorContext,
    102 	defaultsList []Defaults) {
    103 
    104 	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 						}
    115 					}
    116 				}
    117 			}
    118 		}
    119 	}
    120 }
    121 
    122 func defaultsDepsMutator(ctx BottomUpMutatorContext) {
    123 	if defaultable, ok := ctx.Module().(Defaultable); ok {
    124 		ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults...)
    125 	}
    126 }
    127 
    128 func 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))
    139 				}
    140 			}
    141 			return false
    142 		})
    143 		defaultable.applyDefaults(ctx, defaultsList)
    144 	}
    145 }
    146