Merge changes I7b9462d3,Icadd470a,I1d459da1,I01d8f518

* changes:
  Add defaults_visibility support
  Refactor visibility to support visibility on defaults modules
  Add DefaultsModule interface
  Improve documentation of defaults mechanism
This commit is contained in:
Paul Duffin 2019-07-26 08:35:15 +00:00 committed by Gerrit Code Review
commit 4b03cb46a5
6 changed files with 155 additions and 43 deletions

View file

@ -236,6 +236,11 @@ a `default_visibility` property is specified.
If no `default_visibility` property can be found then the module uses the
global default of `//visibility:legacy_public`.
The `visibility` property has no effect on a defaults module although it does
apply to any non-defaults module that uses it. To set the visibility of a
defaults module, use the `defaults_visibility` property on the defaults module;
not to be confused with the `default_visibility` property on the package module.
Once the build has been completely switched over to soong it is possible that a
global refactoring will be done to change this to `//visibility:private` at
which point all packages that do not currently specify a `default_visibility`

View file

@ -42,9 +42,16 @@ func (d *DefaultableModuleBase) setProperties(props []interface{}) {
d.defaultableProperties = props
}
// Interface that must be supported by any module to which defaults can be applied.
type Defaultable interface {
// Get a pointer to the struct containing the Defaults property.
defaults() *defaultsProperties
// Set the property structures into which defaults will be added.
setProperties([]interface{})
// Apply defaults from the supplied Defaults to the property structures supplied to
// setProperties(...).
applyDefaults(TopDownMutatorContext, []Defaults)
}
@ -56,13 +63,25 @@ type DefaultableModule interface {
var _ Defaultable = (*DefaultableModuleBase)(nil)
func InitDefaultableModule(module DefaultableModule) {
module.(Defaultable).setProperties(module.(Module).GetProperties())
module.setProperties(module.(Module).GetProperties())
module.AddProperties(module.defaults())
}
// The Defaults_visibility property.
type DefaultsVisibilityProperties struct {
// Controls the visibility of the defaults module itself.
Defaults_visibility []string
}
type DefaultsModuleBase struct {
DefaultableModuleBase
// Container for defaults of the common properties
commonProperties commonProperties
defaultsVisibilityProperties DefaultsVisibilityProperties
}
// The common pattern for defaults modules is to register separate instances of
@ -87,33 +106,75 @@ type DefaultsModuleBase struct {
// rather than disabling the defaults module itself.
type Defaults interface {
Defaultable
// Although this function is unused it is actually needed to ensure that only modules that embed
// DefaultsModuleBase will type-assert to the Defaults interface.
isDefaults() bool
// Get the structures containing the properties for which defaults can be provided.
properties() []interface{}
// Return the defaults common properties.
common() *commonProperties
// Return the defaults visibility properties.
defaultsVisibility() *DefaultsVisibilityProperties
}
func (d *DefaultsModuleBase) isDefaults() bool {
return true
}
type DefaultsModule interface {
Module
Defaults
}
func (d *DefaultsModuleBase) properties() []interface{} {
return d.defaultableProperties
}
func (d *DefaultsModuleBase) common() *commonProperties {
return &d.commonProperties
}
func (d *DefaultsModuleBase) defaultsVisibility() *DefaultsVisibilityProperties {
return &d.defaultsVisibilityProperties
}
func (d *DefaultsModuleBase) GenerateAndroidBuildActions(ctx ModuleContext) {
}
func InitDefaultsModule(module DefaultableModule) {
func InitDefaultsModule(module DefaultsModule) {
commonProperties := module.common()
module.AddProperties(
&hostAndDeviceProperties{},
&commonProperties{},
commonProperties,
&variableProperties{})
InitArchModule(module)
InitDefaultableModule(module)
module.AddProperties(&module.base().nameProperties)
// Add properties that will not have defaults applied to them.
base := module.base()
defaultsVisibility := module.defaultsVisibility()
module.AddProperties(&base.nameProperties, defaultsVisibility)
module.base().module = module
// The defaults_visibility property controls the visibility of a defaults module.
base.primaryVisibilityProperty =
newVisibilityProperty("defaults_visibility", &defaultsVisibility.Defaults_visibility)
// Unlike non-defaults modules the visibility property is not stored in m.base().commonProperties.
// Instead it is stored in a separate instance of commonProperties created above so use that.
// The visibility property needs to be checked (but not parsed) by the visibility module during
// its checking phase and parsing phase.
base.visibilityPropertyInfo = []visibilityProperty{
base.primaryVisibilityProperty,
newVisibilityProperty("visibility", &commonProperties.Visibility),
}
base.module = module
}
var _ Defaults = (*DefaultsModuleBase)(nil)

View file

@ -211,6 +211,9 @@ type Module interface {
// Get information about the properties that can contain visibility rules.
visibilityProperties() []visibilityProperty
// Get the visibility rules that control the visibility of this module.
visibility() []string
}
// Qualified id for a module
@ -302,6 +305,11 @@ type commonProperties struct {
// If no `default_visibility` property can be found then the module uses the
// global default of `//visibility:legacy_public`.
//
// The `visibility` property has no effect on a defaults module although it does
// apply to any non-defaults module that uses it. To set the visibility of a
// defaults module, use the `defaults_visibility` property on the defaults module;
// not to be confused with the `default_visibility` property on the package module.
//
// See https://android.googlesource.com/platform/build/soong/+/master/README.md#visibility for
// more details.
Visibility []string
@ -503,6 +511,12 @@ func InitAndroidModule(m Module) {
&base.variableProperties)
base.generalProperties = m.GetProperties()
base.customizableProperties = m.GetProperties()
// The default_visibility property needs to be checked and parsed by the visibility module during
// its checking and parsing phases.
base.primaryVisibilityProperty =
newVisibilityProperty("visibility", &base.commonProperties.Visibility)
base.visibilityPropertyInfo = []visibilityProperty{base.primaryVisibilityProperty}
}
func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
@ -582,6 +596,13 @@ type ModuleBase struct {
archProperties [][]interface{}
customizableProperties []interface{}
// Information about all the properties on the module that contains visibility rules that need
// checking.
visibilityPropertyInfo []visibilityProperty
// The primary visibility property, may be nil, that controls access to the module.
primaryVisibilityProperty visibilityProperty
noAddressSanitizer bool
installFiles Paths
checkbuildFiles Paths
@ -668,10 +689,15 @@ func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleNam
}
func (m *ModuleBase) visibilityProperties() []visibilityProperty {
return []visibilityProperty{
newVisibilityProperty("visibility", func() []string {
return m.base().commonProperties.Visibility
}),
return m.visibilityPropertyInfo
}
func (m *ModuleBase) visibility() []string {
// The soong_namespace module does not initialize the primaryVisibilityProperty.
if m.primaryVisibilityProperty != nil {
return m.primaryVisibilityProperty.getStrings()
} else {
return nil
}
}

View file

@ -64,16 +64,6 @@ func (p *packageModule) qualifiedModuleId(ctx BaseModuleContext) qualifiedModule
return newPackageId(ctx.ModuleDir())
}
// Override to ensure that the default_visibility rules are checked by the visibility module during
// its checking phase.
func (p *packageModule) visibilityProperties() []visibilityProperty {
return []visibilityProperty{
newVisibilityProperty("default_visibility", func() []string {
return p.properties.Default_visibility
}),
}
}
func (p *packageModule) Name() string {
return p.properties.Name
}
@ -97,6 +87,13 @@ func PackageFactory() Module {
module.properties.Name = name
module.AddProperties(&module.properties)
// The default_visibility property needs to be checked and parsed by the visibility module during
// its checking and parsing phases.
module.primaryVisibilityProperty =
newVisibilityProperty("default_visibility", &module.properties.Default_visibility)
module.visibilityPropertyInfo = []visibilityProperty{module.primaryVisibilityProperty}
return module
}

View file

@ -67,8 +67,8 @@ type visibilityRule interface {
// Describes the properties provided by a module that contain visibility rules.
type visibilityPropertyImpl struct {
name string
stringsGetter func() []string
name string
stringsProperty *[]string
}
type visibilityProperty interface {
@ -76,10 +76,10 @@ type visibilityProperty interface {
getStrings() []string
}
func newVisibilityProperty(name string, stringsGetter func() []string) visibilityProperty {
func newVisibilityProperty(name string, stringsProperty *[]string) visibilityProperty {
return visibilityPropertyImpl{
name: name,
stringsGetter: stringsGetter,
name: name,
stringsProperty: stringsProperty,
}
}
@ -88,7 +88,7 @@ func (p visibilityPropertyImpl) getName() string {
}
func (p visibilityPropertyImpl) getStrings() []string {
return p.stringsGetter()
return *p.stringsProperty
}
// A compositeRule is a visibility rule composed from a list of atomic visibility rules.
@ -211,16 +211,7 @@ func registerVisibilityRuleEnforcer(ctx RegisterMutatorsContext) {
// Checks the per-module visibility rule lists before defaults expansion.
func visibilityRuleChecker(ctx BottomUpMutatorContext) {
qualified := createQualifiedModuleName(ctx)
if d, ok := ctx.Module().(Defaults); ok {
// Defaults modules don't store the payload properties in m.base().
for _, props := range d.properties() {
if cp, ok := props.(*commonProperties); ok {
if visibility := cp.Visibility; visibility != nil {
checkRules(ctx, qualified.pkg, "visibility", visibility)
}
}
}
} else if m, ok := ctx.Module().(Module); ok {
if m, ok := ctx.Module().(Module); ok {
visibilityProperties := m.visibilityProperties()
for _, p := range visibilityProperties {
if visibility := p.getStrings(); visibility != nil {
@ -294,14 +285,12 @@ func visibilityRuleGatherer(ctx BottomUpMutatorContext) {
qualifiedModuleId := m.qualifiedModuleId(ctx)
currentPkg := qualifiedModuleId.pkg
// Parse all the properties into rules and store them.
visibilityProperties := m.visibilityProperties()
for _, p := range visibilityProperties {
if visibility := p.getStrings(); visibility != nil {
rule := parseRules(ctx, currentPkg, visibility)
if rule != nil {
moduleToVisibilityRuleMap(ctx).Store(qualifiedModuleId, rule)
}
// Parse the visibility rules that control access to the module and store them by id
// for use when enforcing the rules.
if visibility := m.visibility(); visibility != nil {
rule := parseRules(ctx, currentPkg, m.visibility())
if rule != nil {
moduleToVisibilityRuleMap(ctx).Store(qualifiedModuleId, rule)
}
}
}

View file

@ -658,6 +658,40 @@ var visibilityTests = []struct {
` visible to this module`,
},
},
// Defaults module's defaults_visibility tests
{
name: "defaults_visibility invalid",
fs: map[string][]byte{
"top/Blueprints": []byte(`
mock_defaults {
name: "top_defaults",
defaults_visibility: ["//visibility:invalid"],
}`),
},
expectedErrors: []string{
`defaults_visibility: unrecognized visibility rule "//visibility:invalid"`,
},
},
{
name: "defaults_visibility overrides package default",
fs: map[string][]byte{
"top/Blueprints": []byte(`
package {
default_visibility: ["//visibility:private"],
}
mock_defaults {
name: "top_defaults",
defaults_visibility: ["//visibility:public"],
}`),
"outsider/Blueprints": []byte(`
mock_library {
name: "liboutsider",
defaults: ["top_defaults"],
}`),
},
},
// Package default_visibility tests
{
name: "package default_visibility property is checked",