func SquashRules(src, dst *Rule, filename string) error {
	if dst.ShouldKeep() {
		return nil
	}

	for key, srcAttr := range src.attrs {
		srcValue := srcAttr.RHS
		if dstAttr, ok := dst.attrs[key]; !ok {
			dst.SetAttr(key, srcValue)
		} else if !ShouldKeep(dstAttr) {
			dstValue := dstAttr.RHS
			if squashedValue, err := squashExprs(srcValue, dstValue); err != nil {
				start, end := dstValue.Span()
				return fmt.Errorf("%s:%d.%d-%d.%d: could not squash expression", filename, start.Line, start.LineRune, end.Line, end.LineRune)
			} else {
				dst.SetAttr(key, squashedValue)
			}
		}
	}
	dst.expr.Comment().Before = append(dst.expr.Comment().Before, src.expr.Comment().Before...)
	dst.expr.Comment().Suffix = append(dst.expr.Comment().Suffix, src.expr.Comment().Suffix...)
	dst.expr.Comment().After = append(dst.expr.Comment().After, src.expr.Comment().After...)
	return nil
}
func SquashRules(src, dst *Rule, filename string) error {
	if dst.ShouldKeep() {
		return nil
	}

	for key, srcAttr := range src.attrs {
		srcValue := srcAttr.RHS
		if dstAttr, ok := dst.attrs[key]; !ok {
			dst.SetAttr(key, srcValue)
		} else if !ShouldKeep(dstAttr) {
			dstValue := dstAttr.RHS
			if squashedValue, err := squashExprs(srcValue, dstValue); err != nil {
				start, end := dstValue.Span()
				return fmt.Errorf("%s:%d.%d-%d.%d: could not squash expression", filename, start.Line, start.LineRune, end.Line, end.LineRune)
			} else {
				dst.SetAttr(key, squashedValue)
			}
		}
	}
	dst.expr.Comment().Before = append(dst.expr.Comment().Before, src.expr.Comment().Before...)
	dst.expr.Comment().Suffix = append(dst.expr.Comment().Suffix, src.expr.Comment().Suffix...)
	dst.expr.Comment().After = append(dst.expr.Comment().After, src.expr.Comment().After...)
	return nil
}
func SquashRules ( src , dst * Rule , filename string ) error { if dst . ShouldKeep ( ) { return nil } for key , srcAttr := range src . attrs { srcValue := srcAttr . RHS if dstAttr , ok := dst . attrs [ key ] ; ! ok { dst . SetAttr ( key , srcValue ) } else if ! ShouldKeep ( dstAttr ) { dstValue := dstAttr . RHS if squashedValue , err := squashExprs ( srcValue , dstValue ) ; err != nil { start , end := dstValue . Span ( ) return fmt . Errorf ( " " , filename , start . Line , start . LineRune , end . Line , end . LineRune ) } else { dst . SetAttr ( key , squashedValue ) } } } dst . expr . Comment ( ) . Before = append ( dst . expr . Comment ( ) . Before , src . expr . Comment ( ) . Before ... ) dst . expr . Comment ( ) . Suffix = append ( dst . expr . Comment ( ) . Suffix , src . expr . Comment ( ) . Suffix ... ) dst . expr . Comment ( ) . After = append ( dst . expr . Comment ( ) . After , src . expr . Comment ( ) . After ... ) return nil }
// SquashRules copies information from src into dst without discarding
// information in dst. SquashRules detects duplicate elements in lists and
// dictionaries, but it doesn't sort elements after squashing. If squashing
// fails because the expression is not understood, an error is returned,
// and neither rule is modified.
SquashRules copies information from src into dst without discarding information in dst . SquashRules detects duplicate elements in lists and dictionaries but it doesn t sort elements after squashing . If squashing fails because the expression is not understood an error is returned and neither rule is modified .