diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go index adb0a7bb9..a60863036 100644 --- a/bpfix/bpfix/bpfix.go +++ b/bpfix/bpfix/bpfix.go @@ -136,6 +136,10 @@ var fixSteps = []FixStep{ Name: "removeScudoProperty", Fix: runPatchListMod(removeObsoleteProperty("sanitize.scudo")), }, + { + Name: "formatFlagProperties", + Fix: runPatchListMod(formatFlagProperties), + }, } func NewFixRequest() FixRequest { @@ -1343,3 +1347,69 @@ func inList(s string, list []string) bool { } return false } + +func formatFlagProperty(mod *parser.Module, field string, buf []byte, patchlist *parser.PatchList) error { + // the comment or empty lines in the value of the field are skipped + listValue, ok := getLiteralListProperty(mod, field) + if !ok { + // if do not find + return nil + } + for i := 0; i < len(listValue.Values); i++ { + curValue, ok := listValue.Values[i].(*parser.String) + if !ok { + return fmt.Errorf("Expecting string for %s.%s fields", mod.Type, field) + } + if !strings.HasPrefix(curValue.Value, "-") { + return fmt.Errorf("Expecting the string `%s` starting with '-'", curValue.Value) + } + if i+1 < len(listValue.Values) { + nextValue, ok := listValue.Values[i+1].(*parser.String) + if !ok { + return fmt.Errorf("Expecting string for %s.%s fields", mod.Type, field) + } + if !strings.HasPrefix(nextValue.Value, "-") { + // delete the line + err := patchlist.Add(curValue.Pos().Offset, curValue.End().Offset+2, "") + if err != nil { + return err + } + // replace the line + value := "\"" + curValue.Value + " " + nextValue.Value + "\"," + err = patchlist.Add(nextValue.Pos().Offset, nextValue.End().Offset+1, value) + if err != nil { + return err + } + // combined two lines to one + i++ + } + } + } + return nil +} + +func formatFlagProperties(mod *parser.Module, buf []byte, patchlist *parser.PatchList) error { + relevantFields := []string{ + // cc flags + "asflags", + "cflags", + "clang_asflags", + "clang_cflags", + "conlyflags", + "cppflags", + "ldflags", + "tidy_flags", + // java flags + "aaptflags", + "dxflags", + "javacflags", + "kotlincflags", + } + for _, field := range relevantFields { + err := formatFlagProperty(mod, field, buf, patchlist) + if err != nil { + return err + } + } + return nil +} diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go index b994e2547..d8772c10d 100644 --- a/bpfix/bpfix/bpfix_test.go +++ b/bpfix/bpfix/bpfix_test.go @@ -1336,3 +1336,275 @@ func TestRewriteTestModuleTypes(t *testing.T) { }) } } + +func TestFormatFlagProperty(t *testing.T) { + tests := []struct { + name string + in string + out string + }{ + { + name: "group options and values for apptflags, dxflags, javacflags, and kotlincflags", + in: ` + android_test { + name: "foo", + aaptflags: [ + // comment1_1 + "--flag1", + // comment1_2 + "1", + // comment2_1 + // comment2_2 + "--flag2", + // comment3_1 + // comment3_2 + // comment3_3 + "--flag3", + // comment3_4 + // comment3_5 + // comment3_6 + "3", + // other comment1_1 + // other comment1_2 + ], + dxflags: [ + "--flag1", + // comment1_1 + "1", + // comment2_1 + "--flag2", + // comment3_1 + "--flag3", + // comment3_2 + "3", + ], + javacflags: [ + "--flag1", + + "1", + "--flag2", + "--flag3", + "3", + ], + kotlincflags: [ + + "--flag1", + "1", + + "--flag2", + "--flag3", + "3", + + ], + } + `, + out: ` + android_test { + name: "foo", + aaptflags: [ + // comment1_1 + // comment1_2 + "--flag1 1", + // comment2_1 + // comment2_2 + "--flag2", + // comment3_1 + // comment3_2 + // comment3_3 + // comment3_4 + // comment3_5 + // comment3_6 + "--flag3 3", + // other comment1_1 + // other comment1_2 + ], + dxflags: [ + // comment1_1 + "--flag1 1", + // comment2_1 + "--flag2", + // comment3_1 + // comment3_2 + "--flag3 3", + ], + javacflags: [ + + "--flag1 1", + "--flag2", + "--flag3 3", + ], + kotlincflags: [ + + "--flag1 1", + + "--flag2", + "--flag3 3", + + ], + } + `, + }, + { + name: "group options and values for asflags, cflags, clang_asflags, clang_cflags, conlyflags, cppflags, ldflags, and tidy_flags", + in: ` + cc_test { + name: "foo", + asflags: [ + // comment1_1 + "--flag1", + "1", + // comment2_1 + // comment2_2 + "--flag2", + // comment2_3 + "2", + // comment3_1 + // comment3_2 + "--flag3", + // comment3_3 + // comment3_4 + // comment3_4 + "3", + // comment4_1 + // comment4_2 + // comment4_3 + "--flag4", + ], + cflags: [ + "--flag1", + "1", + "--flag2", + "2", + "--flag3", + "3", + "--flag4", + ], + clang_asflags: [ + "--flag1", + "1", + "--flag2", + "2", + "--flag3", + "3", + "--flag4", + ], + clang_cflags: [ + "--flag1", + "1", + "--flag2", + "2", + "--flag3", + "3", + "--flag4", + ], + conlyflags: [ + "--flag1", + "1", + "--flag2", + "2", + "--flag3", + "3", + "--flag4", + ], + cppflags: [ + "--flag1", + "1", + "--flag2", + "2", + "--flag3", + "3", + "--flag4", + ], + ldflags: [ + "--flag1", + "1", + "--flag2", + "2", + "--flag3", + "3", + "--flag4", + ], + tidy_flags: [ + "--flag1", + "1", + "--flag2", + "2", + "--flag3", + "3", + "--flag4", + ], + } + `, + out: ` + cc_test { + name: "foo", + asflags: [ + // comment1_1 + "--flag1 1", + // comment2_1 + // comment2_2 + // comment2_3 + "--flag2 2", + // comment3_1 + // comment3_2 + // comment3_3 + // comment3_4 + // comment3_4 + "--flag3 3", + // comment4_1 + // comment4_2 + // comment4_3 + "--flag4", + ], + cflags: [ + "--flag1 1", + "--flag2 2", + "--flag3 3", + "--flag4", + ], + clang_asflags: [ + "--flag1 1", + "--flag2 2", + "--flag3 3", + "--flag4", + ], + clang_cflags: [ + "--flag1 1", + "--flag2 2", + "--flag3 3", + "--flag4", + ], + conlyflags: [ + "--flag1 1", + "--flag2 2", + "--flag3 3", + "--flag4", + ], + cppflags: [ + "--flag1 1", + "--flag2 2", + "--flag3 3", + "--flag4", + ], + ldflags: [ + "--flag1 1", + "--flag2 2", + "--flag3 3", + "--flag4", + ], + tidy_flags: [ + "--flag1 1", + "--flag2 2", + "--flag3 3", + "--flag4", + ], + } + `, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + runPass(t, test.in, test.out, runPatchListMod(formatFlagProperties)) + }) + } +}