Simplify visibility rules that include //visibility:public am: 44885e29d6

Change-Id: Ia189b5486bc51b3b6a399f1cde66a2030c70c557
This commit is contained in:
Automerger Merge Worker
2020-02-20 14:46:10 +00:00
3 changed files with 46 additions and 14 deletions

View File

@@ -186,8 +186,8 @@ func (r privateRule) String() string {
var visibilityRuleMap = NewOnceKey("visibilityRuleMap") var visibilityRuleMap = NewOnceKey("visibilityRuleMap")
// The map from qualifiedModuleName to visibilityRule. // The map from qualifiedModuleName to visibilityRule.
func moduleToVisibilityRuleMap(ctx BaseModuleContext) *sync.Map { func moduleToVisibilityRuleMap(config Config) *sync.Map {
return ctx.Config().Once(visibilityRuleMap, func() interface{} { return config.Once(visibilityRuleMap, func() interface{} {
return &sync.Map{} return &sync.Map{}
}).(*sync.Map) }).(*sync.Map)
} }
@@ -304,7 +304,7 @@ func visibilityRuleGatherer(ctx BottomUpMutatorContext) {
if visibility := m.visibility(); visibility != nil { if visibility := m.visibility(); visibility != nil {
rule := parseRules(ctx, currentPkg, m.visibility()) rule := parseRules(ctx, currentPkg, m.visibility())
if rule != nil { if rule != nil {
moduleToVisibilityRuleMap(ctx).Store(qualifiedModuleId, rule) moduleToVisibilityRuleMap(ctx.Config()).Store(qualifiedModuleId, rule)
} }
} }
} }
@@ -312,6 +312,7 @@ func visibilityRuleGatherer(ctx BottomUpMutatorContext) {
func parseRules(ctx BaseModuleContext, currentPkg string, visibility []string) compositeRule { func parseRules(ctx BaseModuleContext, currentPkg string, visibility []string) compositeRule {
rules := make(compositeRule, 0, len(visibility)) rules := make(compositeRule, 0, len(visibility))
hasPrivateRule := false hasPrivateRule := false
hasPublicRule := false
hasNonPrivateRule := false hasNonPrivateRule := false
for _, v := range visibility { for _, v := range visibility {
ok, pkg, name := splitRule(v, currentPkg) ok, pkg, name := splitRule(v, currentPkg)
@@ -328,6 +329,7 @@ func parseRules(ctx BaseModuleContext, currentPkg string, visibility []string) c
isPrivateRule = true isPrivateRule = true
case "public": case "public":
r = publicRule{} r = publicRule{}
hasPublicRule = true
} }
} else { } else {
switch name { switch name {
@@ -355,6 +357,11 @@ func parseRules(ctx BaseModuleContext, currentPkg string, visibility []string) c
return compositeRule{privateRule{}} return compositeRule{privateRule{}}
} }
if hasPublicRule {
// Public overrides all other rules so just return it.
return compositeRule{publicRule{}}
}
return rules return rules
} }
@@ -415,21 +422,21 @@ func visibilityRuleEnforcer(ctx TopDownMutatorContext) {
return return
} }
rule := effectiveVisibilityRules(ctx, depQualified) rule := effectiveVisibilityRules(ctx.Config(), depQualified)
if rule != nil && !rule.matches(qualified) { if rule != nil && !rule.matches(qualified) {
ctx.ModuleErrorf("depends on %s which is not visible to this module", depQualified) ctx.ModuleErrorf("depends on %s which is not visible to this module", depQualified)
} }
}) })
} }
func effectiveVisibilityRules(ctx BaseModuleContext, qualified qualifiedModuleName) compositeRule { func effectiveVisibilityRules(config Config, qualified qualifiedModuleName) compositeRule {
moduleToVisibilityRule := moduleToVisibilityRuleMap(ctx) moduleToVisibilityRule := moduleToVisibilityRuleMap(config)
value, ok := moduleToVisibilityRule.Load(qualified) value, ok := moduleToVisibilityRule.Load(qualified)
var rule compositeRule var rule compositeRule
if ok { if ok {
rule = value.(compositeRule) rule = value.(compositeRule)
} else { } else {
rule = packageDefaultVisibility(ctx, qualified) rule = packageDefaultVisibility(config, qualified)
} }
return rule return rule
} }
@@ -441,8 +448,8 @@ func createQualifiedModuleName(ctx BaseModuleContext) qualifiedModuleName {
return qualified return qualified
} }
func packageDefaultVisibility(ctx BaseModuleContext, moduleId qualifiedModuleName) compositeRule { func packageDefaultVisibility(config Config, moduleId qualifiedModuleName) compositeRule {
moduleToVisibilityRule := moduleToVisibilityRuleMap(ctx) moduleToVisibilityRule := moduleToVisibilityRuleMap(config)
packageQualifiedId := moduleId.getContainingPackageId() packageQualifiedId := moduleId.getContainingPackageId()
for { for {
value, ok := moduleToVisibilityRule.Load(packageQualifiedId) value, ok := moduleToVisibilityRule.Load(packageQualifiedId)
@@ -469,7 +476,7 @@ func EffectiveVisibilityRules(ctx BaseModuleContext, module Module) []string {
dir := ctx.OtherModuleDir(module) dir := ctx.OtherModuleDir(module)
qualified := qualifiedModuleName{dir, moduleName} qualified := qualifiedModuleName{dir, moduleName}
rule := effectiveVisibilityRules(ctx, qualified) rule := effectiveVisibilityRules(ctx.Config(), qualified)
return rule.Strings() return rule.Strings()
} }

View File

@@ -1,15 +1,17 @@
package android package android
import ( import (
"reflect"
"testing" "testing"
"github.com/google/blueprint" "github.com/google/blueprint"
) )
var visibilityTests = []struct { var visibilityTests = []struct {
name string name string
fs map[string][]byte fs map[string][]byte
expectedErrors []string expectedErrors []string
effectiveVisibility map[qualifiedModuleName][]string
}{ }{
{ {
name: "invalid visibility: empty list", name: "invalid visibility: empty list",
@@ -493,6 +495,9 @@ var visibilityTests = []struct {
deps: ["libexample"], deps: ["libexample"],
}`), }`),
}, },
effectiveVisibility: map[qualifiedModuleName][]string{
qualifiedModuleName{pkg: "top", name: "libexample"}: {"//visibility:public"},
},
}, },
{ {
name: "//visibility:public mixed with other from different defaults 1", name: "//visibility:public mixed with other from different defaults 1",
@@ -903,13 +908,27 @@ var visibilityTests = []struct {
func TestVisibility(t *testing.T) { func TestVisibility(t *testing.T) {
for _, test := range visibilityTests { for _, test := range visibilityTests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
_, errs := testVisibility(buildDir, test.fs) ctx, errs := testVisibility(buildDir, test.fs)
CheckErrorsAgainstExpectations(t, errs, test.expectedErrors) CheckErrorsAgainstExpectations(t, errs, test.expectedErrors)
if test.effectiveVisibility != nil {
checkEffectiveVisibility(t, ctx, test.effectiveVisibility)
}
}) })
} }
} }
func checkEffectiveVisibility(t *testing.T, ctx *TestContext, effectiveVisibility map[qualifiedModuleName][]string) {
for moduleName, expectedRules := range effectiveVisibility {
rule := effectiveVisibilityRules(ctx.config, moduleName)
stringRules := rule.Strings()
if !reflect.DeepEqual(expectedRules, stringRules) {
t.Errorf("effective rules mismatch: expected %q, found %q", expectedRules, stringRules)
}
}
}
func testVisibility(buildDir string, fs map[string][]byte) (*TestContext, []error) { func testVisibility(buildDir string, fs map[string][]byte) (*TestContext, []error) {
// Create a new config per test as visibility information is stored in the config. // Create a new config per test as visibility information is stored in the config.

View File

@@ -111,8 +111,14 @@ func TestSnapshotVisibility(t *testing.T) {
sdk_version: "none", sdk_version: "none",
} }
java_defaults {
name: "java-defaults",
visibility: ["//other/bar"],
}
java_library { java_library {
name: "mypublicjavalib", name: "mypublicjavalib",
defaults: ["java-defaults"],
visibility: ["//visibility:public"], visibility: ["//visibility:public"],
srcs: ["Test.java"], srcs: ["Test.java"],
system_modules: "none", system_modules: "none",