| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 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 |  | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 15 | package android | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 16 |  | 
| Colin Cross | 795c377 | 2017-03-16 16:50:10 -0700 | [diff] [blame] | 17 | import ( | 
| Colin Cross | 795c377 | 2017-03-16 16:50:10 -0700 | [diff] [blame] | 18 | 	"github.com/google/blueprint" | 
| Colin Cross | 519917d | 2017-11-02 16:35:56 -0700 | [diff] [blame] | 19 | 	"github.com/google/blueprint/proptools" | 
| Colin Cross | 795c377 | 2017-03-16 16:50:10 -0700 | [diff] [blame] | 20 | ) | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 21 |  | 
| Jeff Gaston | af3cc2d | 2017-09-27 17:01:44 -0700 | [diff] [blame] | 22 | // Phases: | 
 | 23 | //   run Pre-arch mutators | 
 | 24 | //   run archMutator | 
 | 25 | //   run Pre-deps mutators | 
 | 26 | //   run depsMutator | 
 | 27 | //   run PostDeps mutators | 
 | 28 | //   continue on to GenerateAndroidBuildActions | 
| Colin Cross | 1e676be | 2016-10-12 14:38:15 -0700 | [diff] [blame] | 29 |  | 
| Colin Cross | 795c377 | 2017-03-16 16:50:10 -0700 | [diff] [blame] | 30 | func registerMutatorsToContext(ctx *blueprint.Context, mutators []*mutator) { | 
 | 31 | 	for _, t := range mutators { | 
 | 32 | 		var handle blueprint.MutatorHandle | 
 | 33 | 		if t.bottomUpMutator != nil { | 
 | 34 | 			handle = ctx.RegisterBottomUpMutator(t.name, t.bottomUpMutator) | 
 | 35 | 		} else if t.topDownMutator != nil { | 
 | 36 | 			handle = ctx.RegisterTopDownMutator(t.name, t.topDownMutator) | 
 | 37 | 		} | 
 | 38 | 		if t.parallel { | 
 | 39 | 			handle.Parallel() | 
| Colin Cross | 1e676be | 2016-10-12 14:38:15 -0700 | [diff] [blame] | 40 | 		} | 
 | 41 | 	} | 
| Colin Cross | 1e676be | 2016-10-12 14:38:15 -0700 | [diff] [blame] | 42 | } | 
 | 43 |  | 
| Colin Cross | cec8171 | 2017-07-13 14:43:27 -0700 | [diff] [blame] | 44 | func registerMutators(ctx *blueprint.Context, preArch, preDeps, postDeps []RegisterMutatorFunc) { | 
 | 45 | 	mctx := ®isterMutatorsContext{} | 
| Nan Zhang | db0b9a3 | 2017-02-27 10:12:13 -0800 | [diff] [blame] | 46 |  | 
 | 47 | 	register := func(funcs []RegisterMutatorFunc) { | 
 | 48 | 		for _, f := range funcs { | 
| Colin Cross | cec8171 | 2017-07-13 14:43:27 -0700 | [diff] [blame] | 49 | 			f(mctx) | 
| Nan Zhang | db0b9a3 | 2017-02-27 10:12:13 -0800 | [diff] [blame] | 50 | 		} | 
 | 51 | 	} | 
 | 52 |  | 
| Colin Cross | cec8171 | 2017-07-13 14:43:27 -0700 | [diff] [blame] | 53 | 	register(preArch) | 
| Nan Zhang | db0b9a3 | 2017-02-27 10:12:13 -0800 | [diff] [blame] | 54 |  | 
| Colin Cross | cec8171 | 2017-07-13 14:43:27 -0700 | [diff] [blame] | 55 | 	register(preDeps) | 
 | 56 |  | 
 | 57 | 	mctx.BottomUp("deps", depsMutator).Parallel() | 
 | 58 |  | 
 | 59 | 	register(postDeps) | 
 | 60 |  | 
 | 61 | 	registerMutatorsToContext(ctx, mctx.mutators) | 
| Colin Cross | 795c377 | 2017-03-16 16:50:10 -0700 | [diff] [blame] | 62 | } | 
 | 63 |  | 
 | 64 | type registerMutatorsContext struct { | 
 | 65 | 	mutators []*mutator | 
 | 66 | } | 
| Colin Cross | 1e676be | 2016-10-12 14:38:15 -0700 | [diff] [blame] | 67 |  | 
 | 68 | type RegisterMutatorsContext interface { | 
 | 69 | 	TopDown(name string, m AndroidTopDownMutator) MutatorHandle | 
 | 70 | 	BottomUp(name string, m AndroidBottomUpMutator) MutatorHandle | 
 | 71 | } | 
 | 72 |  | 
 | 73 | type RegisterMutatorFunc func(RegisterMutatorsContext) | 
 | 74 |  | 
| Colin Cross | cec8171 | 2017-07-13 14:43:27 -0700 | [diff] [blame] | 75 | var preArch = []RegisterMutatorFunc{ | 
 | 76 | 	func(ctx RegisterMutatorsContext) { | 
 | 77 | 		ctx.TopDown("load_hooks", loadHookMutator).Parallel() | 
 | 78 | 	}, | 
| Dan Willemsen | 6e72ef7 | 2018-01-26 18:27:02 -0800 | [diff] [blame] | 79 | 	RegisterNamespaceMutator, | 
| Colin Cross | 5ea9bcc | 2017-07-27 15:41:32 -0700 | [diff] [blame] | 80 | 	RegisterPrebuiltsPreArchMutators, | 
| Colin Cross | 89536d4 | 2017-07-07 14:35:50 -0700 | [diff] [blame] | 81 | 	RegisterDefaultsPreArchMutators, | 
| Colin Cross | cec8171 | 2017-07-13 14:43:27 -0700 | [diff] [blame] | 82 | } | 
 | 83 |  | 
| Colin Cross | ae4c618 | 2017-09-15 17:33:55 -0700 | [diff] [blame] | 84 | func registerArchMutator(ctx RegisterMutatorsContext) { | 
 | 85 | 	ctx.BottomUp("arch", archMutator).Parallel() | 
 | 86 | 	ctx.TopDown("arch_hooks", archHookMutator).Parallel() | 
 | 87 | } | 
 | 88 |  | 
| Colin Cross | cec8171 | 2017-07-13 14:43:27 -0700 | [diff] [blame] | 89 | var preDeps = []RegisterMutatorFunc{ | 
| Colin Cross | ae4c618 | 2017-09-15 17:33:55 -0700 | [diff] [blame] | 90 | 	registerArchMutator, | 
| Colin Cross | cec8171 | 2017-07-13 14:43:27 -0700 | [diff] [blame] | 91 | } | 
 | 92 |  | 
 | 93 | var postDeps = []RegisterMutatorFunc{ | 
| Colin Cross | 5ea9bcc | 2017-07-27 15:41:32 -0700 | [diff] [blame] | 94 | 	RegisterPrebuiltsPostDepsMutators, | 
| Steven Moreland | 65b3fd9 | 2017-12-06 14:18:35 -0800 | [diff] [blame] | 95 | 	registerNeverallowMutator, | 
| Colin Cross | cec8171 | 2017-07-13 14:43:27 -0700 | [diff] [blame] | 96 | } | 
| Colin Cross | 1e676be | 2016-10-12 14:38:15 -0700 | [diff] [blame] | 97 |  | 
 | 98 | func PreArchMutators(f RegisterMutatorFunc) { | 
 | 99 | 	preArch = append(preArch, f) | 
 | 100 | } | 
 | 101 |  | 
 | 102 | func PreDepsMutators(f RegisterMutatorFunc) { | 
 | 103 | 	preDeps = append(preDeps, f) | 
 | 104 | } | 
 | 105 |  | 
 | 106 | func PostDepsMutators(f RegisterMutatorFunc) { | 
 | 107 | 	postDeps = append(postDeps, f) | 
 | 108 | } | 
 | 109 |  | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 110 | type AndroidTopDownMutator func(TopDownMutatorContext) | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 111 |  | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 112 | type TopDownMutatorContext interface { | 
| Colin Cross | aabf679 | 2017-11-29 00:27:14 -0800 | [diff] [blame] | 113 | 	BaseModuleContext | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 114 | 	androidBaseContext | 
| Colin Cross | 3f68a13 | 2017-10-23 17:10:29 -0700 | [diff] [blame] | 115 |  | 
 | 116 | 	OtherModuleExists(name string) bool | 
 | 117 | 	Rename(name string) | 
| Colin Cross | 519917d | 2017-11-02 16:35:56 -0700 | [diff] [blame] | 118 | 	Module() Module | 
| Colin Cross | 3f68a13 | 2017-10-23 17:10:29 -0700 | [diff] [blame] | 119 |  | 
 | 120 | 	OtherModuleName(m blueprint.Module) string | 
 | 121 | 	OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{}) | 
 | 122 | 	OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag | 
 | 123 |  | 
 | 124 | 	CreateModule(blueprint.ModuleFactory, ...interface{}) | 
 | 125 |  | 
 | 126 | 	GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module | 
 | 127 | 	GetDirectDep(name string) (blueprint.Module, blueprint.DependencyTag) | 
 | 128 |  | 
| Colin Cross | d11fcda | 2017-10-23 17:59:01 -0700 | [diff] [blame] | 129 | 	VisitDirectDeps(visit func(Module)) | 
| Colin Cross | ee6143c | 2017-12-30 17:54:27 -0800 | [diff] [blame] | 130 | 	VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) | 
| Colin Cross | d11fcda | 2017-10-23 17:59:01 -0700 | [diff] [blame] | 131 | 	VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) | 
 | 132 | 	VisitDepsDepthFirst(visit func(Module)) | 
 | 133 | 	VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) | 
 | 134 | 	WalkDeps(visit func(Module, Module) bool) | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 135 | } | 
 | 136 |  | 
 | 137 | type androidTopDownMutatorContext struct { | 
 | 138 | 	blueprint.TopDownMutatorContext | 
 | 139 | 	androidBaseContextImpl | 
 | 140 | } | 
 | 141 |  | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 142 | type AndroidBottomUpMutator func(BottomUpMutatorContext) | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 143 |  | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 144 | type BottomUpMutatorContext interface { | 
| Colin Cross | aabf679 | 2017-11-29 00:27:14 -0800 | [diff] [blame] | 145 | 	BaseModuleContext | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 146 | 	androidBaseContext | 
| Colin Cross | aabf679 | 2017-11-29 00:27:14 -0800 | [diff] [blame] | 147 |  | 
 | 148 | 	OtherModuleExists(name string) bool | 
 | 149 | 	Rename(name string) | 
 | 150 | 	Module() blueprint.Module | 
 | 151 |  | 
 | 152 | 	AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) | 
 | 153 | 	AddReverseDependency(module blueprint.Module, tag blueprint.DependencyTag, name string) | 
 | 154 | 	CreateVariations(...string) []blueprint.Module | 
 | 155 | 	CreateLocalVariations(...string) []blueprint.Module | 
 | 156 | 	SetDependencyVariation(string) | 
 | 157 | 	AddVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) | 
 | 158 | 	AddFarVariationDependencies([]blueprint.Variation, blueprint.DependencyTag, ...string) | 
 | 159 | 	AddInterVariantDependency(tag blueprint.DependencyTag, from, to blueprint.Module) | 
 | 160 | 	ReplaceDependencies(string) | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 161 | } | 
 | 162 |  | 
 | 163 | type androidBottomUpMutatorContext struct { | 
 | 164 | 	blueprint.BottomUpMutatorContext | 
 | 165 | 	androidBaseContextImpl | 
 | 166 | } | 
 | 167 |  | 
| Colin Cross | 795c377 | 2017-03-16 16:50:10 -0700 | [diff] [blame] | 168 | func (x *registerMutatorsContext) BottomUp(name string, m AndroidBottomUpMutator) MutatorHandle { | 
| Colin Cross | 798bfce | 2016-10-12 14:28:16 -0700 | [diff] [blame] | 169 | 	f := func(ctx blueprint.BottomUpMutatorContext) { | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 170 | 		if a, ok := ctx.Module().(Module); ok { | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 171 | 			actx := &androidBottomUpMutatorContext{ | 
 | 172 | 				BottomUpMutatorContext: ctx, | 
 | 173 | 				androidBaseContextImpl: a.base().androidBaseContextFactory(ctx), | 
 | 174 | 			} | 
| Colin Cross | 798bfce | 2016-10-12 14:28:16 -0700 | [diff] [blame] | 175 | 			m(actx) | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 176 | 		} | 
| Colin Cross | 798bfce | 2016-10-12 14:28:16 -0700 | [diff] [blame] | 177 | 	} | 
 | 178 | 	mutator := &mutator{name: name, bottomUpMutator: f} | 
| Colin Cross | 795c377 | 2017-03-16 16:50:10 -0700 | [diff] [blame] | 179 | 	x.mutators = append(x.mutators, mutator) | 
| Colin Cross | 798bfce | 2016-10-12 14:28:16 -0700 | [diff] [blame] | 180 | 	return mutator | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 181 | } | 
 | 182 |  | 
| Colin Cross | 795c377 | 2017-03-16 16:50:10 -0700 | [diff] [blame] | 183 | func (x *registerMutatorsContext) TopDown(name string, m AndroidTopDownMutator) MutatorHandle { | 
| Colin Cross | 798bfce | 2016-10-12 14:28:16 -0700 | [diff] [blame] | 184 | 	f := func(ctx blueprint.TopDownMutatorContext) { | 
| Colin Cross | 635c3b0 | 2016-05-18 15:37:25 -0700 | [diff] [blame] | 185 | 		if a, ok := ctx.Module().(Module); ok { | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 186 | 			actx := &androidTopDownMutatorContext{ | 
 | 187 | 				TopDownMutatorContext:  ctx, | 
 | 188 | 				androidBaseContextImpl: a.base().androidBaseContextFactory(ctx), | 
 | 189 | 			} | 
| Colin Cross | 798bfce | 2016-10-12 14:28:16 -0700 | [diff] [blame] | 190 | 			m(actx) | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 191 | 		} | 
| Colin Cross | 798bfce | 2016-10-12 14:28:16 -0700 | [diff] [blame] | 192 | 	} | 
 | 193 | 	mutator := &mutator{name: name, topDownMutator: f} | 
| Colin Cross | 795c377 | 2017-03-16 16:50:10 -0700 | [diff] [blame] | 194 | 	x.mutators = append(x.mutators, mutator) | 
| Colin Cross | 798bfce | 2016-10-12 14:28:16 -0700 | [diff] [blame] | 195 | 	return mutator | 
 | 196 | } | 
 | 197 |  | 
 | 198 | type MutatorHandle interface { | 
 | 199 | 	Parallel() MutatorHandle | 
 | 200 | } | 
 | 201 |  | 
 | 202 | func (mutator *mutator) Parallel() MutatorHandle { | 
 | 203 | 	mutator.parallel = true | 
 | 204 | 	return mutator | 
| Colin Cross | 6362e27 | 2015-10-29 15:25:03 -0700 | [diff] [blame] | 205 | } | 
| Colin Cross | 1e676be | 2016-10-12 14:38:15 -0700 | [diff] [blame] | 206 |  | 
 | 207 | func depsMutator(ctx BottomUpMutatorContext) { | 
 | 208 | 	if m, ok := ctx.Module().(Module); ok { | 
 | 209 | 		m.DepsMutator(ctx) | 
 | 210 | 	} | 
 | 211 | } | 
| Colin Cross | d11fcda | 2017-10-23 17:59:01 -0700 | [diff] [blame] | 212 |  | 
| Colin Cross | aabf679 | 2017-11-29 00:27:14 -0800 | [diff] [blame] | 213 | func (a *androidTopDownMutatorContext) Config() Config { | 
 | 214 | 	return a.config | 
 | 215 | } | 
 | 216 |  | 
 | 217 | func (a *androidBottomUpMutatorContext) Config() Config { | 
 | 218 | 	return a.config | 
 | 219 | } | 
 | 220 |  | 
| Colin Cross | 519917d | 2017-11-02 16:35:56 -0700 | [diff] [blame] | 221 | func (a *androidTopDownMutatorContext) Module() Module { | 
 | 222 | 	module, _ := a.TopDownMutatorContext.Module().(Module) | 
 | 223 | 	return module | 
 | 224 | } | 
 | 225 |  | 
| Colin Cross | d11fcda | 2017-10-23 17:59:01 -0700 | [diff] [blame] | 226 | func (a *androidTopDownMutatorContext) VisitDirectDeps(visit func(Module)) { | 
 | 227 | 	a.TopDownMutatorContext.VisitDirectDeps(func(module blueprint.Module) { | 
 | 228 | 		if aModule, _ := module.(Module); aModule != nil { | 
 | 229 | 			visit(aModule) | 
 | 230 | 		} | 
 | 231 | 	}) | 
 | 232 | } | 
 | 233 |  | 
| Colin Cross | ee6143c | 2017-12-30 17:54:27 -0800 | [diff] [blame] | 234 | func (a *androidTopDownMutatorContext) VisitDirectDepsWithTag(tag blueprint.DependencyTag, visit func(Module)) { | 
 | 235 | 	a.TopDownMutatorContext.VisitDirectDeps(func(module blueprint.Module) { | 
 | 236 | 		if aModule, _ := module.(Module); aModule != nil { | 
 | 237 | 			if a.TopDownMutatorContext.OtherModuleDependencyTag(aModule) == tag { | 
 | 238 | 				visit(aModule) | 
 | 239 | 			} | 
 | 240 | 		} | 
 | 241 | 	}) | 
 | 242 | } | 
 | 243 |  | 
| Colin Cross | d11fcda | 2017-10-23 17:59:01 -0700 | [diff] [blame] | 244 | func (a *androidTopDownMutatorContext) VisitDirectDepsIf(pred func(Module) bool, visit func(Module)) { | 
 | 245 | 	a.TopDownMutatorContext.VisitDirectDepsIf( | 
 | 246 | 		// pred | 
 | 247 | 		func(module blueprint.Module) bool { | 
 | 248 | 			if aModule, _ := module.(Module); aModule != nil { | 
 | 249 | 				return pred(aModule) | 
 | 250 | 			} else { | 
 | 251 | 				return false | 
 | 252 | 			} | 
 | 253 | 		}, | 
 | 254 | 		// visit | 
 | 255 | 		func(module blueprint.Module) { | 
 | 256 | 			visit(module.(Module)) | 
 | 257 | 		}) | 
 | 258 | } | 
 | 259 |  | 
 | 260 | func (a *androidTopDownMutatorContext) VisitDepsDepthFirst(visit func(Module)) { | 
 | 261 | 	a.TopDownMutatorContext.VisitDepsDepthFirst(func(module blueprint.Module) { | 
 | 262 | 		if aModule, _ := module.(Module); aModule != nil { | 
 | 263 | 			visit(aModule) | 
 | 264 | 		} | 
 | 265 | 	}) | 
 | 266 | } | 
 | 267 |  | 
 | 268 | func (a *androidTopDownMutatorContext) VisitDepsDepthFirstIf(pred func(Module) bool, visit func(Module)) { | 
 | 269 | 	a.TopDownMutatorContext.VisitDepsDepthFirstIf( | 
 | 270 | 		// pred | 
 | 271 | 		func(module blueprint.Module) bool { | 
 | 272 | 			if aModule, _ := module.(Module); aModule != nil { | 
 | 273 | 				return pred(aModule) | 
 | 274 | 			} else { | 
 | 275 | 				return false | 
 | 276 | 			} | 
 | 277 | 		}, | 
 | 278 | 		// visit | 
 | 279 | 		func(module blueprint.Module) { | 
 | 280 | 			visit(module.(Module)) | 
 | 281 | 		}) | 
 | 282 | } | 
 | 283 |  | 
 | 284 | func (a *androidTopDownMutatorContext) WalkDeps(visit func(Module, Module) bool) { | 
 | 285 | 	a.TopDownMutatorContext.WalkDeps(func(child, parent blueprint.Module) bool { | 
 | 286 | 		childAndroidModule, _ := child.(Module) | 
 | 287 | 		parentAndroidModule, _ := parent.(Module) | 
 | 288 | 		if childAndroidModule != nil && parentAndroidModule != nil { | 
 | 289 | 			return visit(childAndroidModule, parentAndroidModule) | 
 | 290 | 		} else { | 
 | 291 | 			return false | 
 | 292 | 		} | 
 | 293 | 	}) | 
 | 294 | } | 
| Colin Cross | 519917d | 2017-11-02 16:35:56 -0700 | [diff] [blame] | 295 |  | 
 | 296 | func (a *androidTopDownMutatorContext) AppendProperties(props ...interface{}) { | 
 | 297 | 	for _, p := range props { | 
 | 298 | 		err := proptools.AppendMatchingProperties(a.Module().base().customizableProperties, | 
 | 299 | 			p, nil) | 
 | 300 | 		if err != nil { | 
 | 301 | 			if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok { | 
 | 302 | 				a.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error()) | 
 | 303 | 			} else { | 
 | 304 | 				panic(err) | 
 | 305 | 			} | 
 | 306 | 		} | 
 | 307 | 	} | 
 | 308 | } | 
 | 309 |  | 
 | 310 | func (a *androidTopDownMutatorContext) PrependProperties(props ...interface{}) { | 
 | 311 | 	for _, p := range props { | 
 | 312 | 		err := proptools.PrependMatchingProperties(a.Module().base().customizableProperties, | 
 | 313 | 			p, nil) | 
 | 314 | 		if err != nil { | 
 | 315 | 			if propertyErr, ok := err.(*proptools.ExtendPropertyError); ok { | 
 | 316 | 				a.PropertyErrorf(propertyErr.Property, "%s", propertyErr.Err.Error()) | 
 | 317 | 			} else { | 
 | 318 | 				panic(err) | 
 | 319 | 			} | 
 | 320 | 		} | 
 | 321 | 	} | 
 | 322 | } |