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 DefaultableModuleBase struct {
     33 	defaultsProperties    defaultsProperties
     34 	defaultableProperties []interface{}
     35 }
     36 
     37 func (d *DefaultableModuleBase) defaults() *defaultsProperties {
     38 	return &d.defaultsProperties
     39 }
     40 
     41 func (d *DefaultableModuleBase) 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 type DefaultableModule interface {
     52 	Module
     53 	Defaultable
     54 }
     55 
     56 var _ Defaultable = (*DefaultableModuleBase)(nil)
     57 
     58 func InitDefaultableModule(module DefaultableModule) {
     59 	module.(Defaultable).setProperties(module.(Module).GetProperties())
     60 
     61 	module.AddProperties(module.defaults())
     62 }
     63 
     64 type DefaultsModuleBase struct {
     65 	DefaultableModuleBase
     66 	defaultProperties []interface{}
     67 }
     68 
     69 type Defaults interface {
     70 	Defaultable
     71 	isDefaults() bool
     72 	properties() []interface{}
     73 }
     74 
     75 func (d *DefaultsModuleBase) isDefaults() bool {
     76 	return true
     77 }
     78 
     79 func (d *DefaultsModuleBase) properties() []interface{} {
     80 	return d.defaultableProperties
     81 }
     82 
     83 func 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 
     97 var _ Defaults = (*DefaultsModuleBase)(nil)
     98 
     99 func (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 
    120 func RegisterDefaultsPreArchMutators(ctx RegisterMutatorsContext) {
    121 	ctx.BottomUp("defaults_deps", defaultsDepsMutator).Parallel()
    122 	ctx.TopDown("defaults", defaultsMutator).Parallel()
    123 }
    124 
    125 func defaultsDepsMutator(ctx BottomUpMutatorContext) {
    126 	if defaultable, ok := ctx.Module().(Defaultable); ok {
    127 		ctx.AddDependency(ctx.Module(), DefaultsDepTag, defaultable.defaults().Defaults...)
    128 	}
    129 }
    130 
    131 func 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