Loading android/module.go +59 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import ( "os" "path" "path/filepath" "reflect" "regexp" "strings" "text/scanner" Loading Loading @@ -1326,7 +1327,64 @@ func (m *ModuleBase) GetUnconvertedBp2buildDeps() []string { } func (m *ModuleBase) AddJSONData(d *map[string]interface{}) { (*d)["Android"] = map[string]interface{}{} (*d)["Android"] = map[string]interface{}{ // Properties set in Blueprint or in blueprint of a defaults modules "SetProperties": m.propertiesWithValues(), } } type propInfo struct { Name string Type string } func (m *ModuleBase) propertiesWithValues() []propInfo { var info []propInfo props := m.GetProperties() var propsWithValues func(name string, v reflect.Value) propsWithValues = func(name string, v reflect.Value) { kind := v.Kind() switch kind { case reflect.Ptr, reflect.Interface: if v.IsNil() { return } propsWithValues(name, v.Elem()) case reflect.Struct: if v.IsZero() { return } for i := 0; i < v.NumField(); i++ { namePrefix := name sTyp := v.Type().Field(i) if proptools.ShouldSkipProperty(sTyp) { continue } if name != "" && !strings.HasSuffix(namePrefix, ".") { namePrefix += "." } if !proptools.IsEmbedded(sTyp) { namePrefix += sTyp.Name } sVal := v.Field(i) propsWithValues(namePrefix, sVal) } case reflect.Array, reflect.Slice: if v.IsNil() { return } elKind := v.Type().Elem().Kind() info = append(info, propInfo{name, elKind.String() + " " + kind.String()}) default: info = append(info, propInfo{name, kind.String()}) } } for _, p := range props { propsWithValues("", reflect.ValueOf(p).Elem()) } return info } func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {} Loading android/module_test.go +201 −0 Original line number Diff line number Diff line Loading @@ -615,3 +615,204 @@ func parseMkRules(t *testing.T, config Config, nodes []mkparser.Node) []installM return rules } type PropsTestModuleEmbedded struct { Embedded_prop *string } type propsTestModule struct { ModuleBase DefaultableModuleBase props struct { A string `android:"arch_variant"` B *bool C []string } otherProps struct { PropsTestModuleEmbedded D *int64 Nested struct { E *string } F *string `blueprint:"mutated"` } } func propsTestModuleFactory() Module { module := &propsTestModule{} module.AddProperties(&module.props, &module.otherProps) InitAndroidArchModule(module, HostAndDeviceSupported, MultilibBoth) InitDefaultableModule(module) return module } type propsTestModuleDefaults struct { ModuleBase DefaultsModuleBase } func propsTestModuleDefaultsFactory() Module { defaults := &propsTestModuleDefaults{} module := propsTestModule{} defaults.AddProperties(&module.props, &module.otherProps) InitDefaultsModule(defaults) return defaults } func (p *propsTestModule) GenerateAndroidBuildActions(ctx ModuleContext) { str := "abc" p.otherProps.F = &str } func TestUsedProperties(t *testing.T) { testCases := []struct { desc string bp string expectedProps []propInfo }{ { desc: "only name", bp: `test { name: "foo", } `, expectedProps: []propInfo{ propInfo{"Name", "string"}, }, }, { desc: "some props", bp: `test { name: "foo", a: "abc", b: true, d: 123, } `, expectedProps: []propInfo{ propInfo{"A", "string"}, propInfo{"B", "bool"}, propInfo{"D", "int64"}, propInfo{"Name", "string"}, }, }, { desc: "unused non-pointer prop", bp: `test { name: "foo", b: true, d: 123, } `, expectedProps: []propInfo{ // for non-pointer cannot distinguish between unused and intentionally set to empty propInfo{"A", "string"}, propInfo{"B", "bool"}, propInfo{"D", "int64"}, propInfo{"Name", "string"}, }, }, { desc: "nested props", bp: `test { name: "foo", nested: { e: "abc", } } `, expectedProps: []propInfo{ propInfo{"Nested.E", "string"}, propInfo{"Name", "string"}, }, }, { desc: "arch props", bp: `test { name: "foo", arch: { x86_64: { a: "abc", }, } } `, expectedProps: []propInfo{ propInfo{"Name", "string"}, propInfo{"Arch.X86_64.A", "string"}, }, }, { desc: "embedded props", bp: `test { name: "foo", embedded_prop: "a", } `, expectedProps: []propInfo{ propInfo{"Embedded_prop", "string"}, propInfo{"Name", "string"}, }, }, { desc: "defaults", bp: ` test_defaults { name: "foo_defaults", a: "a", b: true, embedded_prop:"a", arch: { x86_64: { a: "a", }, }, } test { name: "foo", defaults: ["foo_defaults"], c: ["a"], nested: { e: "d", }, target: { linux: { a: "a", }, }, } `, expectedProps: []propInfo{ propInfo{"A", "string"}, propInfo{"B", "bool"}, propInfo{"C", "string slice"}, propInfo{"Embedded_prop", "string"}, propInfo{"Nested.E", "string"}, propInfo{"Name", "string"}, propInfo{"Arch.X86_64.A", "string"}, propInfo{"Target.Linux.A", "string"}, propInfo{"Defaults", "string slice"}, }, }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { result := GroupFixturePreparers( PrepareForTestWithAllowMissingDependencies, PrepareForTestWithDefaults, FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterModuleType("test", propsTestModuleFactory) ctx.RegisterModuleType("test_defaults", propsTestModuleDefaultsFactory) }), FixtureWithRootAndroidBp(tc.bp), ).RunTest(t) foo := result.ModuleForTests("foo", "").Module().base() AssertDeepEquals(t, "foo ", tc.expectedProps, foo.propertiesWithValues()) }) } } java/droidstubs_test.go +7 −10 Original line number Diff line number Diff line Loading @@ -244,17 +244,14 @@ func TestAddJSONData(t *testing.T) { } jsonData := map[string]interface{}{} prebuiltStubsSources.AddJSONData(&jsonData) if fmt.Sprint(jsonData) != fmt.Sprint( map[string]interface{}{ "Android": map[string]interface{}{}, "Actions": []map[string]interface{}{ expectedOut := []map[string]interface{}{ map[string]interface{}{ "Inputs": []string{}, "Outputs": []string{}, }, }, }) { t.Errorf("The JSON data map isn't as expected %s.", jsonData) } if !reflect.DeepEqual(jsonData["Actions"], expectedOut) { t.Errorf("The JSON action data %#v isn't as expected %#v.", jsonData["Actions"], expectedOut) } } Loading Loading
android/module.go +59 −1 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ import ( "os" "path" "path/filepath" "reflect" "regexp" "strings" "text/scanner" Loading Loading @@ -1326,7 +1327,64 @@ func (m *ModuleBase) GetUnconvertedBp2buildDeps() []string { } func (m *ModuleBase) AddJSONData(d *map[string]interface{}) { (*d)["Android"] = map[string]interface{}{} (*d)["Android"] = map[string]interface{}{ // Properties set in Blueprint or in blueprint of a defaults modules "SetProperties": m.propertiesWithValues(), } } type propInfo struct { Name string Type string } func (m *ModuleBase) propertiesWithValues() []propInfo { var info []propInfo props := m.GetProperties() var propsWithValues func(name string, v reflect.Value) propsWithValues = func(name string, v reflect.Value) { kind := v.Kind() switch kind { case reflect.Ptr, reflect.Interface: if v.IsNil() { return } propsWithValues(name, v.Elem()) case reflect.Struct: if v.IsZero() { return } for i := 0; i < v.NumField(); i++ { namePrefix := name sTyp := v.Type().Field(i) if proptools.ShouldSkipProperty(sTyp) { continue } if name != "" && !strings.HasSuffix(namePrefix, ".") { namePrefix += "." } if !proptools.IsEmbedded(sTyp) { namePrefix += sTyp.Name } sVal := v.Field(i) propsWithValues(namePrefix, sVal) } case reflect.Array, reflect.Slice: if v.IsNil() { return } elKind := v.Type().Elem().Kind() info = append(info, propInfo{name, elKind.String() + " " + kind.String()}) default: info = append(info, propInfo{name, kind.String()}) } } for _, p := range props { propsWithValues("", reflect.ValueOf(p).Elem()) } return info } func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {} Loading
android/module_test.go +201 −0 Original line number Diff line number Diff line Loading @@ -615,3 +615,204 @@ func parseMkRules(t *testing.T, config Config, nodes []mkparser.Node) []installM return rules } type PropsTestModuleEmbedded struct { Embedded_prop *string } type propsTestModule struct { ModuleBase DefaultableModuleBase props struct { A string `android:"arch_variant"` B *bool C []string } otherProps struct { PropsTestModuleEmbedded D *int64 Nested struct { E *string } F *string `blueprint:"mutated"` } } func propsTestModuleFactory() Module { module := &propsTestModule{} module.AddProperties(&module.props, &module.otherProps) InitAndroidArchModule(module, HostAndDeviceSupported, MultilibBoth) InitDefaultableModule(module) return module } type propsTestModuleDefaults struct { ModuleBase DefaultsModuleBase } func propsTestModuleDefaultsFactory() Module { defaults := &propsTestModuleDefaults{} module := propsTestModule{} defaults.AddProperties(&module.props, &module.otherProps) InitDefaultsModule(defaults) return defaults } func (p *propsTestModule) GenerateAndroidBuildActions(ctx ModuleContext) { str := "abc" p.otherProps.F = &str } func TestUsedProperties(t *testing.T) { testCases := []struct { desc string bp string expectedProps []propInfo }{ { desc: "only name", bp: `test { name: "foo", } `, expectedProps: []propInfo{ propInfo{"Name", "string"}, }, }, { desc: "some props", bp: `test { name: "foo", a: "abc", b: true, d: 123, } `, expectedProps: []propInfo{ propInfo{"A", "string"}, propInfo{"B", "bool"}, propInfo{"D", "int64"}, propInfo{"Name", "string"}, }, }, { desc: "unused non-pointer prop", bp: `test { name: "foo", b: true, d: 123, } `, expectedProps: []propInfo{ // for non-pointer cannot distinguish between unused and intentionally set to empty propInfo{"A", "string"}, propInfo{"B", "bool"}, propInfo{"D", "int64"}, propInfo{"Name", "string"}, }, }, { desc: "nested props", bp: `test { name: "foo", nested: { e: "abc", } } `, expectedProps: []propInfo{ propInfo{"Nested.E", "string"}, propInfo{"Name", "string"}, }, }, { desc: "arch props", bp: `test { name: "foo", arch: { x86_64: { a: "abc", }, } } `, expectedProps: []propInfo{ propInfo{"Name", "string"}, propInfo{"Arch.X86_64.A", "string"}, }, }, { desc: "embedded props", bp: `test { name: "foo", embedded_prop: "a", } `, expectedProps: []propInfo{ propInfo{"Embedded_prop", "string"}, propInfo{"Name", "string"}, }, }, { desc: "defaults", bp: ` test_defaults { name: "foo_defaults", a: "a", b: true, embedded_prop:"a", arch: { x86_64: { a: "a", }, }, } test { name: "foo", defaults: ["foo_defaults"], c: ["a"], nested: { e: "d", }, target: { linux: { a: "a", }, }, } `, expectedProps: []propInfo{ propInfo{"A", "string"}, propInfo{"B", "bool"}, propInfo{"C", "string slice"}, propInfo{"Embedded_prop", "string"}, propInfo{"Nested.E", "string"}, propInfo{"Name", "string"}, propInfo{"Arch.X86_64.A", "string"}, propInfo{"Target.Linux.A", "string"}, propInfo{"Defaults", "string slice"}, }, }, } for _, tc := range testCases { t.Run(tc.desc, func(t *testing.T) { result := GroupFixturePreparers( PrepareForTestWithAllowMissingDependencies, PrepareForTestWithDefaults, FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterModuleType("test", propsTestModuleFactory) ctx.RegisterModuleType("test_defaults", propsTestModuleDefaultsFactory) }), FixtureWithRootAndroidBp(tc.bp), ).RunTest(t) foo := result.ModuleForTests("foo", "").Module().base() AssertDeepEquals(t, "foo ", tc.expectedProps, foo.propertiesWithValues()) }) } }
java/droidstubs_test.go +7 −10 Original line number Diff line number Diff line Loading @@ -244,17 +244,14 @@ func TestAddJSONData(t *testing.T) { } jsonData := map[string]interface{}{} prebuiltStubsSources.AddJSONData(&jsonData) if fmt.Sprint(jsonData) != fmt.Sprint( map[string]interface{}{ "Android": map[string]interface{}{}, "Actions": []map[string]interface{}{ expectedOut := []map[string]interface{}{ map[string]interface{}{ "Inputs": []string{}, "Outputs": []string{}, }, }, }) { t.Errorf("The JSON data map isn't as expected %s.", jsonData) } if !reflect.DeepEqual(jsonData["Actions"], expectedOut) { t.Errorf("The JSON action data %#v isn't as expected %#v.", jsonData["Actions"], expectedOut) } } Loading