in rule/merge.go [372:437]
func squashDict(x, y *bzl.DictExpr) (*bzl.DictExpr, error) {
if x == nil {
return y, nil
}
if y == nil {
return x, nil
}
cases := make(map[string]*bzl.KeyValueExpr)
addCase := func(e bzl.Expr) error {
kv := e.(*bzl.KeyValueExpr)
key, ok := kv.Key.(*bzl.StringExpr)
if !ok {
return errors.New("could not squash non-string dict key")
}
if _, ok := kv.Value.(*bzl.ListExpr); !ok {
return errors.New("could not squash non-list dict value")
}
if c, ok := cases[key.Value]; ok {
if sq, err := squashList(kv.Value.(*bzl.ListExpr), c.Value.(*bzl.ListExpr)); err != nil {
return err
} else {
c.Value = sq
}
} else {
kvCopy := *kv
cases[key.Value] = &kvCopy
}
return nil
}
for _, e := range x.List {
if err := addCase(e); err != nil {
return nil, err
}
}
for _, e := range y.List {
if err := addCase(e); err != nil {
return nil, err
}
}
keys := make([]string, 0, len(cases))
haveDefault := false
for k := range cases {
if k == "//conditions:default" {
haveDefault = true
continue
}
keys = append(keys, k)
}
sort.Strings(keys)
if haveDefault {
keys = append(keys, "//conditions:default") // must be last
}
squashed := *x
squashed.Comments.Before = append(x.Comments.Before, y.Comments.Before...)
squashed.Comments.Suffix = append(x.Comments.Suffix, y.Comments.Suffix...)
squashed.Comments.After = append(x.Comments.After, y.Comments.After...)
squashed.List = make([]*bzl.KeyValueExpr, 0, len(cases))
for _, k := range keys {
squashed.List = append(squashed.List, cases[k])
}
return &squashed, nil
}