Loading android/visibility.go +53 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android import ( "fmt" "regexp" "sort" "strings" "sync" Loading Loading @@ -496,13 +497,63 @@ func packageDefaultVisibility(config Config, moduleId qualifiedModuleName) compo } } type VisibilityRuleSet interface { // Widen the visibility with some extra rules. Widen(extra []string) error Strings() []string } type visibilityRuleSet struct { rules []string } var _ VisibilityRuleSet = (*visibilityRuleSet)(nil) func (v *visibilityRuleSet) Widen(extra []string) error { // Check the extra rules first just in case they are invalid. Otherwise, if // the current visibility is public then the extra rules will just be ignored. if len(extra) == 1 { singularRule := extra[0] switch singularRule { case "//visibility:public": // Public overrides everything so just discard any existing rules. v.rules = extra return nil case "//visibility:private": // Extending rule with private is an error. return fmt.Errorf("%q does not widen the visibility", singularRule) } } if len(v.rules) == 1 { switch v.rules[0] { case "//visibility:public": // No point in adding rules to something which is already public. return nil case "//visibility:private": // Adding any rules to private means it is no longer private so the // private can be discarded. v.rules = nil } } v.rules = FirstUniqueStrings(append(v.rules, extra...)) sort.Strings(v.rules) return nil } func (v *visibilityRuleSet) Strings() []string { return v.rules } // Get the effective visibility rules, i.e. the actual rules that affect the visibility of the // property irrespective of where they are defined. // // Includes visibility rules specified by package default_visibility and/or on defaults. // Short hand forms, e.g. //:__subpackages__ are replaced with their full form, e.g. // //package/containing/rule:__subpackages__. func EffectiveVisibilityRules(ctx BaseModuleContext, module Module) []string { func EffectiveVisibilityRules(ctx BaseModuleContext, module Module) VisibilityRuleSet { moduleName := ctx.OtherModuleName(module) dir := ctx.OtherModuleDir(module) qualified := qualifiedModuleName{dir, moduleName} Loading @@ -527,7 +578,7 @@ func EffectiveVisibilityRules(ctx BaseModuleContext, module Module) []string { rule = append(rule, packageRule{dir}) } return rule.Strings() return &visibilityRuleSet{rule.Strings()} } // Clear the default visibility properties so they can be replaced. Loading android/visibility_test.go +46 −0 Original line number Diff line number Diff line Loading @@ -1270,3 +1270,49 @@ func newMockParentFactory() Module { }) return m } func testVisibilityRuleSet(t *testing.T, rules, extra, expected []string) { t.Helper() set := &visibilityRuleSet{rules} err := set.Widen(extra) if err != nil { t.Error(err) return } actual := set.Strings() if !reflect.DeepEqual(actual, expected) { t.Errorf("mismatching rules after extend: expected %#v, actual %#v", expected, actual) } } func TestVisibilityRuleSet(t *testing.T) { t.Run("extend empty", func(t *testing.T) { testVisibilityRuleSet(t, nil, []string{"//foo"}, []string{"//foo"}) }) t.Run("extend", func(t *testing.T) { testVisibilityRuleSet(t, []string{"//foo"}, []string{"//bar"}, []string{"//bar", "//foo"}) }) t.Run("extend duplicate", func(t *testing.T) { testVisibilityRuleSet(t, []string{"//foo"}, []string{"//bar", "//foo"}, []string{"//bar", "//foo"}) }) t.Run("extend public", func(t *testing.T) { testVisibilityRuleSet(t, []string{"//visibility:public"}, []string{"//foo"}, []string{"//visibility:public"}) }) t.Run("extend private", func(t *testing.T) { testVisibilityRuleSet(t, []string{"//visibility:private"}, []string{"//foo"}, []string{"//foo"}) }) t.Run("extend with public", func(t *testing.T) { testVisibilityRuleSet(t, []string{"//foo"}, []string{"//visibility:public"}, []string{"//visibility:public"}) }) t.Run("extend with private", func(t *testing.T) { t.Helper() set := &visibilityRuleSet{[]string{"//foo"}} err := set.Widen([]string{"//visibility:private"}) expectedError := `"//visibility:private" does not widen the visibility` if err == nil { t.Errorf("missing error") } else if err.Error() != expectedError { t.Errorf("expected error %q found error %q", expectedError, err) } }) } sdk/sdk.go +17 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,20 @@ type sdkProperties struct { // True if this is a module_exports (or module_exports_snapshot) module type. Module_exports bool `blueprint:"mutated"` // The additional visibility to add to the prebuilt modules to allow them to // reference each other. // // This can only be used to widen the visibility of the members: // // * Specifying //visibility:public here will make all members visible and // essentially ignore their own visibility. // * Specifying //visibility:private here is an error. // * Specifying any other rule here will add it to the members visibility and // be output to the member prebuilt in the snapshot. Duplicates will be // dropped. Adding a rule to members that have //visibility:private will // cause the //visibility:private to be discarded. Prebuilt_visibility []string } // Contains information about the sdk properties that list sdk members, e.g. Loading Loading @@ -211,6 +225,9 @@ func newSdkModule(moduleExports bool) *sdk { // properties for the member type specific list properties. s.dynamicMemberTypeListProperties = s.dynamicSdkMemberTypes.createMemberListProperties() s.AddProperties(&s.properties, s.dynamicMemberTypeListProperties) // Make sure that the prebuilt visibility property is verified for errors. android.AddVisibilityProperty(s, "prebuilt_visibility", &s.properties.Prebuilt_visibility) android.InitCommonOSAndroidMultiTargetsArchModule(s, android.HostAndDeviceSupported, android.MultilibCommon) android.InitDefaultableModule(s) android.AddLoadHook(s, func(ctx android.LoadHookContext) { Loading sdk/sdk_test.go +49 −2 Original line number Diff line number Diff line Loading @@ -108,6 +108,9 @@ func TestSnapshotVisibility(t *testing.T) { // generated sdk_snapshot. ":__subpackages__", ], prebuilt_visibility: [ "//prebuilts/mysdk", ], java_header_libs: [ "myjavalib", "mypublicjavalib", Loading Loading @@ -176,6 +179,7 @@ java_import { visibility: [ "//other/foo", "//package", "//prebuilts/mysdk", ], jars: ["java/myjavalib.jar"], } Loading @@ -186,6 +190,7 @@ java_import { visibility: [ "//other/foo", "//package", "//prebuilts/mysdk", ], jars: ["java/myjavalib.jar"], } Loading @@ -210,6 +215,7 @@ java_import { visibility: [ "//other/bar", "//package", "//prebuilts/mysdk", ], jars: ["java/mydefaultedjavalib.jar"], } Loading @@ -220,6 +226,7 @@ java_import { visibility: [ "//other/bar", "//package", "//prebuilts/mysdk", ], jars: ["java/mydefaultedjavalib.jar"], } Loading @@ -227,14 +234,20 @@ java_import { java_import { name: "mysdk_myprivatejavalib@current", sdk_member_name: "myprivatejavalib", visibility: ["//package"], visibility: [ "//package", "//prebuilts/mysdk", ], jars: ["java/myprivatejavalib.jar"], } java_import { name: "myprivatejavalib", prefer: false, visibility: ["//package"], visibility: [ "//package", "//prebuilts/mysdk", ], jars: ["java/myprivatejavalib.jar"], } Loading @@ -254,6 +267,40 @@ sdk_snapshot { `)) } func TestPrebuiltVisibilityProperty_IsValidated(t *testing.T) { testSdkError(t, `prebuilt_visibility: cannot mix "//visibility:private" with any other visibility rules`, ` sdk { name: "mysdk", prebuilt_visibility: [ "//foo", "//visibility:private", ], } `) } func TestPrebuiltVisibilityProperty_AddPrivate(t *testing.T) { testSdkError(t, `prebuilt_visibility: "//visibility:private" does not widen the visibility`, ` sdk { name: "mysdk", prebuilt_visibility: [ "//visibility:private", ], java_header_libs: [ "myjavalib", ], } java_library { name: "myjavalib", // Uses package default visibility srcs: ["Test.java"], system_modules: "none", sdk_version: "none", } `) } func TestSDkInstall(t *testing.T) { sdk := ` sdk { Loading sdk/update.go +10 −2 Original line number Diff line number Diff line Loading @@ -300,7 +300,7 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) andro snapshotModule.AddProperty("name", snapshotName) // Make sure that the snapshot has the same visibility as the sdk. visibility := android.EffectiveVisibilityRules(ctx, s) visibility := android.EffectiveVisibilityRules(ctx, s).Strings() if len(visibility) != 0 { snapshotModule.AddProperty("visibility", visibility) } Loading Loading @@ -719,7 +719,15 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType } else { // Extract visibility information from a member variant. All variants have the same // visibility so it doesn't matter which one is used. visibility := android.EffectiveVisibilityRules(s.ctx, variant) visibilityRules := android.EffectiveVisibilityRules(s.ctx, variant) // Add any additional visibility rules needed for the prebuilts to reference each other. err := visibilityRules.Widen(s.sdk.properties.Prebuilt_visibility) if err != nil { s.ctx.PropertyErrorf("prebuilt_visibility", "%s", err) } visibility := visibilityRules.Strings() if len(visibility) != 0 { m.AddProperty("visibility", visibility) } Loading Loading
android/visibility.go +53 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package android import ( "fmt" "regexp" "sort" "strings" "sync" Loading Loading @@ -496,13 +497,63 @@ func packageDefaultVisibility(config Config, moduleId qualifiedModuleName) compo } } type VisibilityRuleSet interface { // Widen the visibility with some extra rules. Widen(extra []string) error Strings() []string } type visibilityRuleSet struct { rules []string } var _ VisibilityRuleSet = (*visibilityRuleSet)(nil) func (v *visibilityRuleSet) Widen(extra []string) error { // Check the extra rules first just in case they are invalid. Otherwise, if // the current visibility is public then the extra rules will just be ignored. if len(extra) == 1 { singularRule := extra[0] switch singularRule { case "//visibility:public": // Public overrides everything so just discard any existing rules. v.rules = extra return nil case "//visibility:private": // Extending rule with private is an error. return fmt.Errorf("%q does not widen the visibility", singularRule) } } if len(v.rules) == 1 { switch v.rules[0] { case "//visibility:public": // No point in adding rules to something which is already public. return nil case "//visibility:private": // Adding any rules to private means it is no longer private so the // private can be discarded. v.rules = nil } } v.rules = FirstUniqueStrings(append(v.rules, extra...)) sort.Strings(v.rules) return nil } func (v *visibilityRuleSet) Strings() []string { return v.rules } // Get the effective visibility rules, i.e. the actual rules that affect the visibility of the // property irrespective of where they are defined. // // Includes visibility rules specified by package default_visibility and/or on defaults. // Short hand forms, e.g. //:__subpackages__ are replaced with their full form, e.g. // //package/containing/rule:__subpackages__. func EffectiveVisibilityRules(ctx BaseModuleContext, module Module) []string { func EffectiveVisibilityRules(ctx BaseModuleContext, module Module) VisibilityRuleSet { moduleName := ctx.OtherModuleName(module) dir := ctx.OtherModuleDir(module) qualified := qualifiedModuleName{dir, moduleName} Loading @@ -527,7 +578,7 @@ func EffectiveVisibilityRules(ctx BaseModuleContext, module Module) []string { rule = append(rule, packageRule{dir}) } return rule.Strings() return &visibilityRuleSet{rule.Strings()} } // Clear the default visibility properties so they can be replaced. Loading
android/visibility_test.go +46 −0 Original line number Diff line number Diff line Loading @@ -1270,3 +1270,49 @@ func newMockParentFactory() Module { }) return m } func testVisibilityRuleSet(t *testing.T, rules, extra, expected []string) { t.Helper() set := &visibilityRuleSet{rules} err := set.Widen(extra) if err != nil { t.Error(err) return } actual := set.Strings() if !reflect.DeepEqual(actual, expected) { t.Errorf("mismatching rules after extend: expected %#v, actual %#v", expected, actual) } } func TestVisibilityRuleSet(t *testing.T) { t.Run("extend empty", func(t *testing.T) { testVisibilityRuleSet(t, nil, []string{"//foo"}, []string{"//foo"}) }) t.Run("extend", func(t *testing.T) { testVisibilityRuleSet(t, []string{"//foo"}, []string{"//bar"}, []string{"//bar", "//foo"}) }) t.Run("extend duplicate", func(t *testing.T) { testVisibilityRuleSet(t, []string{"//foo"}, []string{"//bar", "//foo"}, []string{"//bar", "//foo"}) }) t.Run("extend public", func(t *testing.T) { testVisibilityRuleSet(t, []string{"//visibility:public"}, []string{"//foo"}, []string{"//visibility:public"}) }) t.Run("extend private", func(t *testing.T) { testVisibilityRuleSet(t, []string{"//visibility:private"}, []string{"//foo"}, []string{"//foo"}) }) t.Run("extend with public", func(t *testing.T) { testVisibilityRuleSet(t, []string{"//foo"}, []string{"//visibility:public"}, []string{"//visibility:public"}) }) t.Run("extend with private", func(t *testing.T) { t.Helper() set := &visibilityRuleSet{[]string{"//foo"}} err := set.Widen([]string{"//visibility:private"}) expectedError := `"//visibility:private" does not widen the visibility` if err == nil { t.Errorf("missing error") } else if err.Error() != expectedError { t.Errorf("expected error %q found error %q", expectedError, err) } }) }
sdk/sdk.go +17 −0 Original line number Diff line number Diff line Loading @@ -75,6 +75,20 @@ type sdkProperties struct { // True if this is a module_exports (or module_exports_snapshot) module type. Module_exports bool `blueprint:"mutated"` // The additional visibility to add to the prebuilt modules to allow them to // reference each other. // // This can only be used to widen the visibility of the members: // // * Specifying //visibility:public here will make all members visible and // essentially ignore their own visibility. // * Specifying //visibility:private here is an error. // * Specifying any other rule here will add it to the members visibility and // be output to the member prebuilt in the snapshot. Duplicates will be // dropped. Adding a rule to members that have //visibility:private will // cause the //visibility:private to be discarded. Prebuilt_visibility []string } // Contains information about the sdk properties that list sdk members, e.g. Loading Loading @@ -211,6 +225,9 @@ func newSdkModule(moduleExports bool) *sdk { // properties for the member type specific list properties. s.dynamicMemberTypeListProperties = s.dynamicSdkMemberTypes.createMemberListProperties() s.AddProperties(&s.properties, s.dynamicMemberTypeListProperties) // Make sure that the prebuilt visibility property is verified for errors. android.AddVisibilityProperty(s, "prebuilt_visibility", &s.properties.Prebuilt_visibility) android.InitCommonOSAndroidMultiTargetsArchModule(s, android.HostAndDeviceSupported, android.MultilibCommon) android.InitDefaultableModule(s) android.AddLoadHook(s, func(ctx android.LoadHookContext) { Loading
sdk/sdk_test.go +49 −2 Original line number Diff line number Diff line Loading @@ -108,6 +108,9 @@ func TestSnapshotVisibility(t *testing.T) { // generated sdk_snapshot. ":__subpackages__", ], prebuilt_visibility: [ "//prebuilts/mysdk", ], java_header_libs: [ "myjavalib", "mypublicjavalib", Loading Loading @@ -176,6 +179,7 @@ java_import { visibility: [ "//other/foo", "//package", "//prebuilts/mysdk", ], jars: ["java/myjavalib.jar"], } Loading @@ -186,6 +190,7 @@ java_import { visibility: [ "//other/foo", "//package", "//prebuilts/mysdk", ], jars: ["java/myjavalib.jar"], } Loading @@ -210,6 +215,7 @@ java_import { visibility: [ "//other/bar", "//package", "//prebuilts/mysdk", ], jars: ["java/mydefaultedjavalib.jar"], } Loading @@ -220,6 +226,7 @@ java_import { visibility: [ "//other/bar", "//package", "//prebuilts/mysdk", ], jars: ["java/mydefaultedjavalib.jar"], } Loading @@ -227,14 +234,20 @@ java_import { java_import { name: "mysdk_myprivatejavalib@current", sdk_member_name: "myprivatejavalib", visibility: ["//package"], visibility: [ "//package", "//prebuilts/mysdk", ], jars: ["java/myprivatejavalib.jar"], } java_import { name: "myprivatejavalib", prefer: false, visibility: ["//package"], visibility: [ "//package", "//prebuilts/mysdk", ], jars: ["java/myprivatejavalib.jar"], } Loading @@ -254,6 +267,40 @@ sdk_snapshot { `)) } func TestPrebuiltVisibilityProperty_IsValidated(t *testing.T) { testSdkError(t, `prebuilt_visibility: cannot mix "//visibility:private" with any other visibility rules`, ` sdk { name: "mysdk", prebuilt_visibility: [ "//foo", "//visibility:private", ], } `) } func TestPrebuiltVisibilityProperty_AddPrivate(t *testing.T) { testSdkError(t, `prebuilt_visibility: "//visibility:private" does not widen the visibility`, ` sdk { name: "mysdk", prebuilt_visibility: [ "//visibility:private", ], java_header_libs: [ "myjavalib", ], } java_library { name: "myjavalib", // Uses package default visibility srcs: ["Test.java"], system_modules: "none", sdk_version: "none", } `) } func TestSDkInstall(t *testing.T) { sdk := ` sdk { Loading
sdk/update.go +10 −2 Original line number Diff line number Diff line Loading @@ -300,7 +300,7 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext, sdkVariants []*sdk) andro snapshotModule.AddProperty("name", snapshotName) // Make sure that the snapshot has the same visibility as the sdk. visibility := android.EffectiveVisibilityRules(ctx, s) visibility := android.EffectiveVisibilityRules(ctx, s).Strings() if len(visibility) != 0 { snapshotModule.AddProperty("visibility", visibility) } Loading Loading @@ -719,7 +719,15 @@ func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType } else { // Extract visibility information from a member variant. All variants have the same // visibility so it doesn't matter which one is used. visibility := android.EffectiveVisibilityRules(s.ctx, variant) visibilityRules := android.EffectiveVisibilityRules(s.ctx, variant) // Add any additional visibility rules needed for the prebuilts to reference each other. err := visibilityRules.Widen(s.sdk.properties.Prebuilt_visibility) if err != nil { s.ctx.PropertyErrorf("prebuilt_visibility", "%s", err) } visibility := visibilityRules.Strings() if len(visibility) != 0 { m.AddProperty("visibility", visibility) } Loading