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:
commit
4b03cb46a5
6 changed files with 155 additions and 43 deletions
|
@ -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`
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
Loading…
Reference in a new issue