Home | History | Annotate | Download | only in common
      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