Loading android/module.go +48 −4 Original line number Diff line number Diff line Loading @@ -1472,6 +1472,8 @@ func (m *ModuleBase) AddJSONData(d *map[string]interface{}) { type propInfo struct { Name string Type string Value string Values []string } func (m *ModuleBase) propertiesWithValues() []propInfo { Loading Loading @@ -1511,18 +1513,60 @@ func (m *ModuleBase) propertiesWithValues() []propInfo { return } elKind := v.Type().Elem().Kind() info = append(info, propInfo{name, elKind.String() + " " + kind.String()}) info = append(info, propInfo{Name: name, Type: elKind.String() + " " + kind.String(), Values: sliceReflectionValue(v)}) default: info = append(info, propInfo{name, kind.String()}) info = append(info, propInfo{Name: name, Type: kind.String(), Value: reflectionValue(v)}) } } for _, p := range props { propsWithValues("", reflect.ValueOf(p).Elem()) } sort.Slice(info, func(i, j int) bool { return info[i].Name < info[j].Name }) return info } func reflectionValue(value reflect.Value) string { switch value.Kind() { case reflect.Bool: return fmt.Sprintf("%t", value.Bool()) case reflect.Int64: return fmt.Sprintf("%d", value.Int()) case reflect.String: return fmt.Sprintf("%s", value.String()) case reflect.Struct: if value.IsZero() { return "{}" } length := value.NumField() vals := make([]string, length, length) for i := 0; i < length; i++ { sTyp := value.Type().Field(i) if proptools.ShouldSkipProperty(sTyp) { continue } name := sTyp.Name vals[i] = fmt.Sprintf("%s: %s", name, reflectionValue(value.Field(i))) } return fmt.Sprintf("%s{%s}", value.Type(), strings.Join(vals, ", ")) case reflect.Array, reflect.Slice: vals := sliceReflectionValue(value) return fmt.Sprintf("[%s]", strings.Join(vals, ", ")) } return "" } func sliceReflectionValue(value reflect.Value) []string { length := value.Len() vals := make([]string, length, length) for i := 0; i < length; i++ { vals[i] = reflectionValue(value.Index(i)) } return vals } func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {} func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {} Loading android/module_test.go +62 −27 Original line number Diff line number Diff line Loading @@ -563,6 +563,12 @@ type PropsTestModuleEmbedded struct { Embedded_prop *string } type StructInSlice struct { G string H bool I []string } type propsTestModule struct { ModuleBase DefaultableModuleBase Loading @@ -579,6 +585,8 @@ type propsTestModule struct { E *string } F *string `blueprint:"mutated"` Slice_of_struct []StructInSlice } } Loading Loading @@ -621,7 +629,7 @@ func TestUsedProperties(t *testing.T) { } `, expectedProps: []propInfo{ propInfo{"Name", "string"}, propInfo{Name: "Name", Type: "string", Value: "foo"}, }, }, { Loading @@ -634,10 +642,10 @@ func TestUsedProperties(t *testing.T) { } `, expectedProps: []propInfo{ propInfo{"A", "string"}, propInfo{"B", "bool"}, propInfo{"D", "int64"}, propInfo{"Name", "string"}, propInfo{Name: "A", Type: "string", Value: "abc"}, propInfo{Name: "B", Type: "bool", Value: "true"}, propInfo{Name: "D", Type: "int64", Value: "123"}, propInfo{Name: "Name", Type: "string", Value: "foo"}, }, }, { Loading @@ -650,10 +658,10 @@ func TestUsedProperties(t *testing.T) { `, 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"}, propInfo{Name: "A", Type: "string", Value: ""}, propInfo{Name: "B", Type: "bool", Value: "true"}, propInfo{Name: "D", Type: "int64", Value: "123"}, propInfo{Name: "Name", Type: "string", Value: "foo"}, }, }, { Loading @@ -666,8 +674,8 @@ func TestUsedProperties(t *testing.T) { } `, expectedProps: []propInfo{ propInfo{"Nested.E", "string"}, propInfo{"Name", "string"}, propInfo{Name: "Name", Type: "string", Value: "foo"}, propInfo{Name: "Nested.E", Type: "string", Value: "abc"}, }, }, { Loading @@ -682,8 +690,8 @@ func TestUsedProperties(t *testing.T) { } `, expectedProps: []propInfo{ propInfo{"Name", "string"}, propInfo{"Arch.X86_64.A", "string"}, propInfo{Name: "Arch.X86_64.A", Type: "string", Value: "abc"}, propInfo{Name: "Name", Type: "string", Value: "foo"}, }, }, { Loading @@ -694,8 +702,34 @@ func TestUsedProperties(t *testing.T) { } `, expectedProps: []propInfo{ propInfo{"Embedded_prop", "string"}, propInfo{"Name", "string"}, propInfo{Name: "Embedded_prop", Type: "string", Value: "a"}, propInfo{Name: "Name", Type: "string", Value: "foo"}, }, }, { desc: "struct slice", bp: `test { name: "foo", slice_of_struct: [ { g: "abc", h: false, i: ["baz"], }, { g: "def", h: true, i: [], }, ] } `, expectedProps: []propInfo{ propInfo{Name: "Name", Type: "string", Value: "foo"}, propInfo{Name: "Slice_of_struct", Type: "struct slice", Values: []string{ `android.StructInSlice{G: abc, H: false, I: [baz]}`, `android.StructInSlice{G: def, H: true, I: []}`, }}, }, }, { Loading @@ -705,19 +739,20 @@ test_defaults { name: "foo_defaults", a: "a", b: true, c: ["default_c"], embedded_prop:"a", arch: { x86_64: { a: "a", a: "x86_64 a", }, }, } test { name: "foo", defaults: ["foo_defaults"], c: ["a"], c: ["c"], nested: { e: "d", e: "nested e", }, target: { linux: { Loading @@ -727,15 +762,15 @@ test { } `, 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"}, propInfo{Name: "A", Type: "string", Value: "a"}, propInfo{Name: "Arch.X86_64.A", Type: "string", Value: "x86_64 a"}, propInfo{Name: "B", Type: "bool", Value: "true"}, propInfo{Name: "C", Type: "string slice", Values: []string{"default_c", "c"}}, propInfo{Name: "Defaults", Type: "string slice", Values: []string{"foo_defaults"}}, propInfo{Name: "Embedded_prop", Type: "string", Value: "a"}, propInfo{Name: "Name", Type: "string", Value: "foo"}, propInfo{Name: "Nested.E", Type: "string", Value: "nested e"}, propInfo{Name: "Target.Linux.A", Type: "string", Value: "a"}, }, }, } Loading Loading
android/module.go +48 −4 Original line number Diff line number Diff line Loading @@ -1472,6 +1472,8 @@ func (m *ModuleBase) AddJSONData(d *map[string]interface{}) { type propInfo struct { Name string Type string Value string Values []string } func (m *ModuleBase) propertiesWithValues() []propInfo { Loading Loading @@ -1511,18 +1513,60 @@ func (m *ModuleBase) propertiesWithValues() []propInfo { return } elKind := v.Type().Elem().Kind() info = append(info, propInfo{name, elKind.String() + " " + kind.String()}) info = append(info, propInfo{Name: name, Type: elKind.String() + " " + kind.String(), Values: sliceReflectionValue(v)}) default: info = append(info, propInfo{name, kind.String()}) info = append(info, propInfo{Name: name, Type: kind.String(), Value: reflectionValue(v)}) } } for _, p := range props { propsWithValues("", reflect.ValueOf(p).Elem()) } sort.Slice(info, func(i, j int) bool { return info[i].Name < info[j].Name }) return info } func reflectionValue(value reflect.Value) string { switch value.Kind() { case reflect.Bool: return fmt.Sprintf("%t", value.Bool()) case reflect.Int64: return fmt.Sprintf("%d", value.Int()) case reflect.String: return fmt.Sprintf("%s", value.String()) case reflect.Struct: if value.IsZero() { return "{}" } length := value.NumField() vals := make([]string, length, length) for i := 0; i < length; i++ { sTyp := value.Type().Field(i) if proptools.ShouldSkipProperty(sTyp) { continue } name := sTyp.Name vals[i] = fmt.Sprintf("%s: %s", name, reflectionValue(value.Field(i))) } return fmt.Sprintf("%s{%s}", value.Type(), strings.Join(vals, ", ")) case reflect.Array, reflect.Slice: vals := sliceReflectionValue(value) return fmt.Sprintf("[%s]", strings.Join(vals, ", ")) } return "" } func sliceReflectionValue(value reflect.Value) []string { length := value.Len() vals := make([]string, length, length) for i := 0; i < length; i++ { vals[i] = reflectionValue(value.Index(i)) } return vals } func (m *ModuleBase) ComponentDepsMutator(BottomUpMutatorContext) {} func (m *ModuleBase) DepsMutator(BottomUpMutatorContext) {} Loading
android/module_test.go +62 −27 Original line number Diff line number Diff line Loading @@ -563,6 +563,12 @@ type PropsTestModuleEmbedded struct { Embedded_prop *string } type StructInSlice struct { G string H bool I []string } type propsTestModule struct { ModuleBase DefaultableModuleBase Loading @@ -579,6 +585,8 @@ type propsTestModule struct { E *string } F *string `blueprint:"mutated"` Slice_of_struct []StructInSlice } } Loading Loading @@ -621,7 +629,7 @@ func TestUsedProperties(t *testing.T) { } `, expectedProps: []propInfo{ propInfo{"Name", "string"}, propInfo{Name: "Name", Type: "string", Value: "foo"}, }, }, { Loading @@ -634,10 +642,10 @@ func TestUsedProperties(t *testing.T) { } `, expectedProps: []propInfo{ propInfo{"A", "string"}, propInfo{"B", "bool"}, propInfo{"D", "int64"}, propInfo{"Name", "string"}, propInfo{Name: "A", Type: "string", Value: "abc"}, propInfo{Name: "B", Type: "bool", Value: "true"}, propInfo{Name: "D", Type: "int64", Value: "123"}, propInfo{Name: "Name", Type: "string", Value: "foo"}, }, }, { Loading @@ -650,10 +658,10 @@ func TestUsedProperties(t *testing.T) { `, 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"}, propInfo{Name: "A", Type: "string", Value: ""}, propInfo{Name: "B", Type: "bool", Value: "true"}, propInfo{Name: "D", Type: "int64", Value: "123"}, propInfo{Name: "Name", Type: "string", Value: "foo"}, }, }, { Loading @@ -666,8 +674,8 @@ func TestUsedProperties(t *testing.T) { } `, expectedProps: []propInfo{ propInfo{"Nested.E", "string"}, propInfo{"Name", "string"}, propInfo{Name: "Name", Type: "string", Value: "foo"}, propInfo{Name: "Nested.E", Type: "string", Value: "abc"}, }, }, { Loading @@ -682,8 +690,8 @@ func TestUsedProperties(t *testing.T) { } `, expectedProps: []propInfo{ propInfo{"Name", "string"}, propInfo{"Arch.X86_64.A", "string"}, propInfo{Name: "Arch.X86_64.A", Type: "string", Value: "abc"}, propInfo{Name: "Name", Type: "string", Value: "foo"}, }, }, { Loading @@ -694,8 +702,34 @@ func TestUsedProperties(t *testing.T) { } `, expectedProps: []propInfo{ propInfo{"Embedded_prop", "string"}, propInfo{"Name", "string"}, propInfo{Name: "Embedded_prop", Type: "string", Value: "a"}, propInfo{Name: "Name", Type: "string", Value: "foo"}, }, }, { desc: "struct slice", bp: `test { name: "foo", slice_of_struct: [ { g: "abc", h: false, i: ["baz"], }, { g: "def", h: true, i: [], }, ] } `, expectedProps: []propInfo{ propInfo{Name: "Name", Type: "string", Value: "foo"}, propInfo{Name: "Slice_of_struct", Type: "struct slice", Values: []string{ `android.StructInSlice{G: abc, H: false, I: [baz]}`, `android.StructInSlice{G: def, H: true, I: []}`, }}, }, }, { Loading @@ -705,19 +739,20 @@ test_defaults { name: "foo_defaults", a: "a", b: true, c: ["default_c"], embedded_prop:"a", arch: { x86_64: { a: "a", a: "x86_64 a", }, }, } test { name: "foo", defaults: ["foo_defaults"], c: ["a"], c: ["c"], nested: { e: "d", e: "nested e", }, target: { linux: { Loading @@ -727,15 +762,15 @@ test { } `, 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"}, propInfo{Name: "A", Type: "string", Value: "a"}, propInfo{Name: "Arch.X86_64.A", Type: "string", Value: "x86_64 a"}, propInfo{Name: "B", Type: "bool", Value: "true"}, propInfo{Name: "C", Type: "string slice", Values: []string{"default_c", "c"}}, propInfo{Name: "Defaults", Type: "string slice", Values: []string{"foo_defaults"}}, propInfo{Name: "Embedded_prop", Type: "string", Value: "a"}, propInfo{Name: "Name", Type: "string", Value: "foo"}, propInfo{Name: "Nested.E", Type: "string", Value: "nested e"}, propInfo{Name: "Target.Linux.A", Type: "string", Value: "a"}, }, }, } Loading