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:
@@ -236,6 +236,11 @@ a `default_visibility` property is specified.
|
|||||||
If no `default_visibility` property can be found then the module uses the
|
If no `default_visibility` property can be found then the module uses the
|
||||||
global default of `//visibility:legacy_public`.
|
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
|
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
|
global refactoring will be done to change this to `//visibility:private` at
|
||||||
which point all packages that do not currently specify a `default_visibility`
|
which point all packages that do not currently specify a `default_visibility`
|
||||||
|
@@ -42,9 +42,16 @@ func (d *DefaultableModuleBase) setProperties(props []interface{}) {
|
|||||||
d.defaultableProperties = props
|
d.defaultableProperties = props
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Interface that must be supported by any module to which defaults can be applied.
|
||||||
type Defaultable interface {
|
type Defaultable interface {
|
||||||
|
// Get a pointer to the struct containing the Defaults property.
|
||||||
defaults() *defaultsProperties
|
defaults() *defaultsProperties
|
||||||
|
|
||||||
|
// Set the property structures into which defaults will be added.
|
||||||
setProperties([]interface{})
|
setProperties([]interface{})
|
||||||
|
|
||||||
|
// Apply defaults from the supplied Defaults to the property structures supplied to
|
||||||
|
// setProperties(...).
|
||||||
applyDefaults(TopDownMutatorContext, []Defaults)
|
applyDefaults(TopDownMutatorContext, []Defaults)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,13 +63,25 @@ type DefaultableModule interface {
|
|||||||
var _ Defaultable = (*DefaultableModuleBase)(nil)
|
var _ Defaultable = (*DefaultableModuleBase)(nil)
|
||||||
|
|
||||||
func InitDefaultableModule(module DefaultableModule) {
|
func InitDefaultableModule(module DefaultableModule) {
|
||||||
module.(Defaultable).setProperties(module.(Module).GetProperties())
|
module.setProperties(module.(Module).GetProperties())
|
||||||
|
|
||||||
module.AddProperties(module.defaults())
|
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 {
|
type DefaultsModuleBase struct {
|
||||||
DefaultableModuleBase
|
DefaultableModuleBase
|
||||||
|
|
||||||
|
// Container for defaults of the common properties
|
||||||
|
commonProperties commonProperties
|
||||||
|
|
||||||
|
defaultsVisibilityProperties DefaultsVisibilityProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
// The common pattern for defaults modules is to register separate instances of
|
// 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.
|
// rather than disabling the defaults module itself.
|
||||||
type Defaults interface {
|
type Defaults interface {
|
||||||
Defaultable
|
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
|
isDefaults() bool
|
||||||
|
|
||||||
|
// Get the structures containing the properties for which defaults can be provided.
|
||||||
properties() []interface{}
|
properties() []interface{}
|
||||||
|
|
||||||
|
// Return the defaults common properties.
|
||||||
|
common() *commonProperties
|
||||||
|
|
||||||
|
// Return the defaults visibility properties.
|
||||||
|
defaultsVisibility() *DefaultsVisibilityProperties
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DefaultsModuleBase) isDefaults() bool {
|
func (d *DefaultsModuleBase) isDefaults() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DefaultsModule interface {
|
||||||
|
Module
|
||||||
|
Defaults
|
||||||
|
}
|
||||||
|
|
||||||
func (d *DefaultsModuleBase) properties() []interface{} {
|
func (d *DefaultsModuleBase) properties() []interface{} {
|
||||||
return d.defaultableProperties
|
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 (d *DefaultsModuleBase) GenerateAndroidBuildActions(ctx ModuleContext) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func InitDefaultsModule(module DefaultableModule) {
|
func InitDefaultsModule(module DefaultsModule) {
|
||||||
|
commonProperties := module.common()
|
||||||
|
|
||||||
module.AddProperties(
|
module.AddProperties(
|
||||||
&hostAndDeviceProperties{},
|
&hostAndDeviceProperties{},
|
||||||
&commonProperties{},
|
commonProperties,
|
||||||
&variableProperties{})
|
&variableProperties{})
|
||||||
|
|
||||||
InitArchModule(module)
|
InitArchModule(module)
|
||||||
InitDefaultableModule(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)
|
var _ Defaults = (*DefaultsModuleBase)(nil)
|
||||||
|
@@ -211,6 +211,9 @@ type Module interface {
|
|||||||
|
|
||||||
// Get information about the properties that can contain visibility rules.
|
// Get information about the properties that can contain visibility rules.
|
||||||
visibilityProperties() []visibilityProperty
|
visibilityProperties() []visibilityProperty
|
||||||
|
|
||||||
|
// Get the visibility rules that control the visibility of this module.
|
||||||
|
visibility() []string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Qualified id for a module
|
// 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
|
// If no `default_visibility` property can be found then the module uses the
|
||||||
// global default of `//visibility:legacy_public`.
|
// 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
|
// See https://android.googlesource.com/platform/build/soong/+/master/README.md#visibility for
|
||||||
// more details.
|
// more details.
|
||||||
Visibility []string
|
Visibility []string
|
||||||
@@ -503,6 +511,12 @@ func InitAndroidModule(m Module) {
|
|||||||
&base.variableProperties)
|
&base.variableProperties)
|
||||||
base.generalProperties = m.GetProperties()
|
base.generalProperties = m.GetProperties()
|
||||||
base.customizableProperties = 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) {
|
func InitAndroidArchModule(m Module, hod HostOrDeviceSupported, defaultMultilib Multilib) {
|
||||||
@@ -582,6 +596,13 @@ type ModuleBase struct {
|
|||||||
archProperties [][]interface{}
|
archProperties [][]interface{}
|
||||||
customizableProperties []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
|
noAddressSanitizer bool
|
||||||
installFiles Paths
|
installFiles Paths
|
||||||
checkbuildFiles Paths
|
checkbuildFiles Paths
|
||||||
@@ -668,10 +689,15 @@ func (m *ModuleBase) qualifiedModuleId(ctx BaseModuleContext) qualifiedModuleNam
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *ModuleBase) visibilityProperties() []visibilityProperty {
|
func (m *ModuleBase) visibilityProperties() []visibilityProperty {
|
||||||
return []visibilityProperty{
|
return m.visibilityPropertyInfo
|
||||||
newVisibilityProperty("visibility", func() []string {
|
}
|
||||||
return m.base().commonProperties.Visibility
|
|
||||||
}),
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -64,16 +64,6 @@ func (p *packageModule) qualifiedModuleId(ctx BaseModuleContext) qualifiedModule
|
|||||||
return newPackageId(ctx.ModuleDir())
|
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 {
|
func (p *packageModule) Name() string {
|
||||||
return p.properties.Name
|
return p.properties.Name
|
||||||
}
|
}
|
||||||
@@ -97,6 +87,13 @@ func PackageFactory() Module {
|
|||||||
module.properties.Name = name
|
module.properties.Name = name
|
||||||
|
|
||||||
module.AddProperties(&module.properties)
|
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
|
return module
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -67,8 +67,8 @@ type visibilityRule interface {
|
|||||||
|
|
||||||
// Describes the properties provided by a module that contain visibility rules.
|
// Describes the properties provided by a module that contain visibility rules.
|
||||||
type visibilityPropertyImpl struct {
|
type visibilityPropertyImpl struct {
|
||||||
name string
|
name string
|
||||||
stringsGetter func() []string
|
stringsProperty *[]string
|
||||||
}
|
}
|
||||||
|
|
||||||
type visibilityProperty interface {
|
type visibilityProperty interface {
|
||||||
@@ -76,10 +76,10 @@ type visibilityProperty interface {
|
|||||||
getStrings() []string
|
getStrings() []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newVisibilityProperty(name string, stringsGetter func() []string) visibilityProperty {
|
func newVisibilityProperty(name string, stringsProperty *[]string) visibilityProperty {
|
||||||
return visibilityPropertyImpl{
|
return visibilityPropertyImpl{
|
||||||
name: name,
|
name: name,
|
||||||
stringsGetter: stringsGetter,
|
stringsProperty: stringsProperty,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ func (p visibilityPropertyImpl) getName() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p visibilityPropertyImpl) getStrings() []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.
|
// 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.
|
// Checks the per-module visibility rule lists before defaults expansion.
|
||||||
func visibilityRuleChecker(ctx BottomUpMutatorContext) {
|
func visibilityRuleChecker(ctx BottomUpMutatorContext) {
|
||||||
qualified := createQualifiedModuleName(ctx)
|
qualified := createQualifiedModuleName(ctx)
|
||||||
if d, ok := ctx.Module().(Defaults); ok {
|
if m, ok := ctx.Module().(Module); 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 {
|
|
||||||
visibilityProperties := m.visibilityProperties()
|
visibilityProperties := m.visibilityProperties()
|
||||||
for _, p := range visibilityProperties {
|
for _, p := range visibilityProperties {
|
||||||
if visibility := p.getStrings(); visibility != nil {
|
if visibility := p.getStrings(); visibility != nil {
|
||||||
@@ -294,14 +285,12 @@ func visibilityRuleGatherer(ctx BottomUpMutatorContext) {
|
|||||||
qualifiedModuleId := m.qualifiedModuleId(ctx)
|
qualifiedModuleId := m.qualifiedModuleId(ctx)
|
||||||
currentPkg := qualifiedModuleId.pkg
|
currentPkg := qualifiedModuleId.pkg
|
||||||
|
|
||||||
// Parse all the properties into rules and store them.
|
// Parse the visibility rules that control access to the module and store them by id
|
||||||
visibilityProperties := m.visibilityProperties()
|
// for use when enforcing the rules.
|
||||||
for _, p := range visibilityProperties {
|
if visibility := m.visibility(); visibility != nil {
|
||||||
if visibility := p.getStrings(); visibility != nil {
|
rule := parseRules(ctx, currentPkg, m.visibility())
|
||||||
rule := parseRules(ctx, currentPkg, visibility)
|
if rule != nil {
|
||||||
if rule != nil {
|
moduleToVisibilityRuleMap(ctx).Store(qualifiedModuleId, rule)
|
||||||
moduleToVisibilityRuleMap(ctx).Store(qualifiedModuleId, rule)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -658,6 +658,40 @@ var visibilityTests = []struct {
|
|||||||
` visible to this module`,
|
` 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
|
// Package default_visibility tests
|
||||||
{
|
{
|
||||||
name: "package default_visibility property is checked",
|
name: "package default_visibility property is checked",
|
||||||
|
Reference in New Issue
Block a user