Add hook to be called after defaults have been applied
Previously, the only way for a module type to create modules (other
than defining its own mutator) was to register a LoadHook. However,
that is called before defaults are applied so any properties used in
that hook cannot take advantage of defaults, e.g. java_sdk_library
cannot use defaults to set its sdk_version property and have that
affect its child modules.
This change adds a new SetDefaultableHook() to DefaultableModule to
register a hook that is called after any defaults have been applied.
Also adds some tests to ensure that errors in the visibility property
introduced in a DefaultableHook are reported in the gather phase of
visibility processing.
A follow up change will switch java_sdk_library to use that instead
of the AddLoadHook() mechanism.
Bug: 155295806
Test: m checkapi
Change-Id: I13df3115f9e225f7324b6725eaeb16a78cc2538a
diff --git a/android/visibility_test.go b/android/visibility_test.go
index 8dd6a8f..4cf41a6 100644
--- a/android/visibility_test.go
+++ b/android/visibility_test.go
@@ -903,6 +903,69 @@
}`),
},
},
+ {
+ name: "ensure visibility properties are checked for correctness",
+ fs: map[string][]byte{
+ "top/Blueprints": []byte(`
+ mock_parent {
+ name: "parent",
+ visibility: ["//top/nested"],
+ child: {
+ name: "libchild",
+ visibility: ["top/other"],
+ },
+ }`),
+ },
+ expectedErrors: []string{
+ `module "parent": child.visibility: invalid visibility pattern "top/other"`,
+ },
+ },
+ {
+ name: "invalid visibility added to child detected during gather phase",
+ fs: map[string][]byte{
+ "top/Blueprints": []byte(`
+ mock_parent {
+ name: "parent",
+ visibility: ["//top/nested"],
+ child: {
+ name: "libchild",
+ invalid_visibility: ["top/other"],
+ },
+ }`),
+ },
+ expectedErrors: []string{
+ // That this error is reported against the child not the parent shows it was
+ // not being detected in the parent which is correct as invalid_visibility is
+ // purposely not added to the list of visibility properties to check, and was
+ // in fact detected in the child in the gather phase. Contrast this error message
+ // with the preceding one.
+ `module "libchild" \(created by module "parent"\): visibility: invalid visibility pattern "top/other"`,
+ },
+ },
+ {
+ name: "automatic visibility inheritance enabled",
+ fs: map[string][]byte{
+ "top/Blueprints": []byte(`
+ mock_parent {
+ name: "parent",
+ visibility: ["//top/nested"],
+ child: {
+ name: "libchild",
+ visibility: ["//top/other"],
+ },
+ }`),
+ "top/nested/Blueprints": []byte(`
+ mock_library {
+ name: "libnested",
+ deps: ["libchild"],
+ }`),
+ "top/other/Blueprints": []byte(`
+ mock_library {
+ name: "libother",
+ deps: ["libchild"],
+ }`),
+ },
+ },
}
func TestVisibility(t *testing.T) {
@@ -936,6 +999,7 @@
ctx := NewTestArchContext()
ctx.RegisterModuleType("mock_library", newMockLibraryModule)
+ ctx.RegisterModuleType("mock_parent", newMockParentFactory)
ctx.RegisterModuleType("mock_defaults", defaultsFactory)
// Order of the following method calls is significant.
@@ -996,3 +1060,42 @@
InitDefaultsModule(m)
return m
}
+
+type mockParentProperties struct {
+ Child struct {
+ Name *string
+
+ // Visibility to pass to the child module.
+ Visibility []string
+
+ // Purposely not validated visibility to pass to the child.
+ Invalid_visibility []string
+ }
+}
+
+type mockParent struct {
+ ModuleBase
+ DefaultableModuleBase
+ properties mockParentProperties
+}
+
+func (p *mockParent) GenerateAndroidBuildActions(ModuleContext) {
+}
+
+func newMockParentFactory() Module {
+ m := &mockParent{}
+ m.AddProperties(&m.properties)
+ InitAndroidArchModule(m, HostAndDeviceSupported, MultilibCommon)
+ InitDefaultableModule(m)
+ AddVisibilityProperty(m, "child.visibility", &m.properties.Child.Visibility)
+
+ m.SetDefaultableHook(func(ctx DefaultableHookContext) {
+ visibility := m.properties.Child.Visibility
+ visibility = append(visibility, m.properties.Child.Invalid_visibility...)
+ ctx.CreateModule(newMockLibraryModule, &struct {
+ Name *string
+ Visibility []string
+ }{m.properties.Child.Name, visibility})
+ })
+ return m
+}