Browse Source

Merge changes I99cdff4b,Ia6b5cff8,I0f438509

* changes:
  Allow an arbitrary tag to be associated with a bp property
  Rewrite code for creating versioned modules as a transformation
  Add support for transforming a module
Treehugger Robot 4 years ago
parent
commit
29fd971526
3 changed files with 159 additions and 24 deletions
  1. 6 1
      android/sdk.go
  2. 129 19
      sdk/bp.go
  3. 24 4
      sdk/update.go

+ 6 - 1
android/sdk.go

@@ -182,6 +182,8 @@ type SnapshotBuilder interface {
 	AddPrebuiltModule(member SdkMember, moduleType string) BpModule
 }
 
+type BpPropertyTag interface{}
+
 // A set of properties for use in a .bp file.
 type BpPropertySet interface {
 	// Add a property, the value can be one of the following types:
@@ -190,9 +192,12 @@ type BpPropertySet interface {
 	// * bool
 	// * BpPropertySet
 	//
-	// It is an error is multiples properties with the same name are added.
+	// It is an error if multiple properties with the same name are added.
 	AddProperty(name string, value interface{})
 
+	// Add a property with an associated tag
+	AddPropertyWithTag(name string, value interface{}, tag BpPropertyTag)
+
 	// Add a property set with the specified name and return so that additional
 	// properties can be added.
 	AddPropertySet(name string) BpPropertySet

+ 129 - 19
sdk/bp.go

@@ -22,6 +22,7 @@ import (
 
 type bpPropertySet struct {
 	properties map[string]interface{}
+	tags       map[string]android.BpPropertyTag
 	order      []string
 }
 
@@ -29,6 +30,7 @@ var _ android.BpPropertySet = (*bpPropertySet)(nil)
 
 func (s *bpPropertySet) init() {
 	s.properties = make(map[string]interface{})
+	s.tags = make(map[string]android.BpPropertyTag)
 }
 
 func (s *bpPropertySet) AddProperty(name string, value interface{}) {
@@ -40,6 +42,11 @@ func (s *bpPropertySet) AddProperty(name string, value interface{}) {
 	s.order = append(s.order, name)
 }
 
+func (s *bpPropertySet) AddPropertyWithTag(name string, value interface{}, tag android.BpPropertyTag) {
+	s.AddProperty(name, value)
+	s.tags[name] = tag
+}
+
 func (s *bpPropertySet) AddPropertySet(name string) android.BpPropertySet {
 	set := &bpPropertySet{}
 	set.init()
@@ -51,26 +58,34 @@ func (s *bpPropertySet) getValue(name string) interface{} {
 	return s.properties[name]
 }
 
-func (s *bpPropertySet) deepCopy() *bpPropertySet {
-	propertiesCopy := make(map[string]interface{})
-	for p, v := range s.properties {
-		var valueCopy interface{}
-		if ps, ok := v.(*bpPropertySet); ok {
-			valueCopy = ps.deepCopy()
-		} else if values, ok := v.([]string); ok {
-			valuesCopy := make([]string, len(values))
-			copy(valuesCopy, values)
-			valueCopy = valuesCopy
+func (s *bpPropertySet) getTag(name string) interface{} {
+	return s.tags[name]
+}
+
+func (s *bpPropertySet) transform(transformer bpPropertyTransformer) {
+	var newOrder []string
+	for _, name := range s.order {
+		value := s.properties[name]
+		tag := s.tags[name]
+		var newValue interface{}
+		var newTag android.BpPropertyTag
+		if propertySet, ok := value.(*bpPropertySet); ok {
+			newValue, newTag = transformer.transformPropertySet(name, propertySet, tag)
 		} else {
-			valueCopy = v
+			newValue, newTag = transformer.transformProperty(name, value, tag)
 		}
-		propertiesCopy[p] = valueCopy
-	}
 
-	return &bpPropertySet{
-		properties: propertiesCopy,
-		order:      append([]string(nil), s.order...),
+		if newValue == nil {
+			// Delete the property from the map and exclude it from the new order.
+			delete(s.properties, name)
+		} else {
+			// Update the property in the map and add the name to the new order list.
+			s.properties[name] = newValue
+			s.tags[name] = newTag
+			newOrder = append(newOrder, name)
+		}
 	}
+	s.order = newOrder
 }
 
 func (s *bpPropertySet) setProperty(name string, value interface{}) {
@@ -78,6 +93,7 @@ func (s *bpPropertySet) setProperty(name string, value interface{}) {
 		s.AddProperty(name, value)
 	} else {
 		s.properties[name] = value
+		s.tags[name] = nil
 	}
 }
 
@@ -111,13 +127,107 @@ type bpModule struct {
 
 var _ android.BpModule = (*bpModule)(nil)
 
+type bpPropertyTransformer interface {
+	// Transform the property set, returning the new property set/tag to insert back into the
+	// parent property set (or module if this is the top level property set).
+	//
+	// This will be called before transforming the properties in the supplied set.
+	//
+	// The name will be "" for the top level property set.
+	//
+	// Returning (nil, ...) will cause the property set to be removed.
+	transformPropertySet(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag)
+
+	// Transform a property, return the new value/tag to insert back into the property set.
+	//
+	// Returning (nil, ...) will cause the property to be removed.
+	transformProperty(name string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag)
+}
+
+// Interface for transforming bpModule objects.
+type bpTransformer interface {
+	// Transform the module, returning the result.
+	//
+	// The method can either create a new module and return that, or modify the supplied module
+	// in place and return that.
+	//
+	// After this returns the transformer is applied to the contents of the returned module.
+	transformModule(module *bpModule) *bpModule
+
+	bpPropertyTransformer
+}
+
+type identityTransformation struct{}
+
+var _ bpTransformer = (*identityTransformation)(nil)
+
+func (t identityTransformation) transformModule(module *bpModule) *bpModule {
+	return module
+}
+
+func (t identityTransformation) transformPropertySet(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+	return propertySet, tag
+}
+
+func (t identityTransformation) transformProperty(name string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) {
+	return value, tag
+}
+
 func (m *bpModule) deepCopy() *bpModule {
-	return &bpModule{
-		bpPropertySet: m.bpPropertySet.deepCopy(),
-		moduleType:    m.moduleType,
+	return m.transform(deepCopyTransformer)
+}
+
+func (m *bpModule) transform(transformer bpTransformer) *bpModule {
+	transformedModule := transformer.transformModule(m)
+	// Copy the contents of the returned property set into the module and then transform that.
+	transformedModule.bpPropertySet, _ = transformer.transformPropertySet("", transformedModule.bpPropertySet, nil)
+	transformedModule.bpPropertySet.transform(transformer)
+	return transformedModule
+}
+
+type deepCopyTransformation struct{}
+
+func (t deepCopyTransformation) transformModule(module *bpModule) *bpModule {
+	// Take a shallow copy of the module. Any mutable property values will be copied by the
+	// transformer.
+	moduleCopy := *module
+	return &moduleCopy
+}
+
+func (t deepCopyTransformation) transformPropertySet(name string, propertySet *bpPropertySet, tag android.BpPropertyTag) (*bpPropertySet, android.BpPropertyTag) {
+	// Create a shallow copy of the properties map. Any mutable property values will be copied by the
+	// transformer.
+	propertiesCopy := make(map[string]interface{})
+	for propertyName, value := range propertySet.properties {
+		propertiesCopy[propertyName] = value
+	}
+
+	// Ditto for tags map.
+	tagsCopy := make(map[string]android.BpPropertyTag)
+	for propertyName, propertyTag := range propertySet.tags {
+		tagsCopy[propertyName] = propertyTag
+	}
+
+	// Create a new property set.
+	return &bpPropertySet{
+		properties: propertiesCopy,
+		tags:       tagsCopy,
+		order:      append([]string(nil), propertySet.order...),
+	}, tag
+}
+
+func (t deepCopyTransformation) transformProperty(name string, value interface{}, tag android.BpPropertyTag) (interface{}, android.BpPropertyTag) {
+	// Copy string slice, otherwise return value.
+	if values, ok := value.([]string); ok {
+		valuesCopy := make([]string, len(values))
+		copy(valuesCopy, values)
+		return valuesCopy, tag
 	}
+	return value, tag
 }
 
+var deepCopyTransformer bpTransformer = deepCopyTransformation{}
+
 // A .bp file
 type bpFile struct {
 	modules map[string]*bpModule

+ 24 - 4
sdk/update.go

@@ -194,12 +194,16 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath {
 		member.memberType.BuildSnapshot(ctx, builder, member)
 	}
 
+	// Create a transformer that will transform an unversioned module into a versioned module.
+	unversionedToVersionedTransformer := unversionedToVersionedTransformation{builder: builder}
+
 	for _, unversioned := range builder.prebuiltOrder {
 		// Copy the unversioned module so it can be modified to make it versioned.
 		versioned := unversioned.deepCopy()
-		name := versioned.properties["name"].(string)
-		versioned.setProperty("name", builder.versionedSdkMemberName(name))
-		versioned.insertAfter("name", "sdk_member_name", name)
+
+		// Transform the unversioned module into a versioned one.
+		versioned.transform(unversionedToVersionedTransformer)
+
 		bpFile.AddModule(versioned)
 
 		// Set prefer: false - this is not strictly required as that is the default.
@@ -281,6 +285,22 @@ func (s *sdk) buildSnapshot(ctx android.ModuleContext) android.OutputPath {
 	return outputZipFile
 }
 
+type unversionedToVersionedTransformation struct {
+	identityTransformation
+	builder *snapshotBuilder
+}
+
+var _ bpTransformer = (*unversionedToVersionedTransformation)(nil)
+
+func (t unversionedToVersionedTransformation) transformModule(module *bpModule) *bpModule {
+	// Use a versioned name for the module but remember the original name for the
+	// snapshot.
+	name := module.getValue("name").(string)
+	module.setProperty("name", t.builder.versionedSdkMemberName(name))
+	module.insertAfter("name", "sdk_member_name", name)
+	return module
+}
+
 func generateBpContents(contents *generatedContents, bpFile *bpFile) {
 	contents.Printfln("// This is auto-generated. DO NOT EDIT.")
 	for _, bpModule := range bpFile.order {
@@ -294,7 +314,7 @@ func generateBpContents(contents *generatedContents, bpFile *bpFile) {
 func outputPropertySet(contents *generatedContents, set *bpPropertySet) {
 	contents.Indent()
 	for _, name := range set.order {
-		value := set.properties[name]
+		value := set.getValue(name)
 
 		reflectedValue := reflect.ValueOf(value)
 		t := reflectedValue.Type()