mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-16 00:56:23 +00:00
revset: eliminate double negates
Writing double negates is silly, but it might be hidden by revset alias if we added such feature. I made fold_redundant_expression() a separate step from fold_difference() since I'll probably want to apply the cleanup step before rewriting filter expressions.
This commit is contained in:
parent
54044ea8d6
commit
0e99747728
1 changed files with 45 additions and 7 deletions
|
@ -1223,18 +1223,24 @@ fn internalize_filter_intersection(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Eliminates redundant intersection with `all()`.
|
/// Eliminates redundant nodes like `x & all()`, `~~x`.
|
||||||
fn fold_intersection_with_all(expression: &Rc<RevsetExpression>) -> Option<Rc<RevsetExpression>> {
|
///
|
||||||
transform_expression_bottom_up(expression, |expression| {
|
/// This does not rewrite 'x & none()' to 'none()' because 'x' may be an invalid
|
||||||
if let RevsetExpression::Intersection(expression1, expression2) = expression.as_ref() {
|
/// symbol.
|
||||||
|
fn fold_redundant_expression(expression: &Rc<RevsetExpression>) -> Option<Rc<RevsetExpression>> {
|
||||||
|
transform_expression_bottom_up(expression, |expression| match expression.as_ref() {
|
||||||
|
RevsetExpression::NotIn(outer) => match outer.as_ref() {
|
||||||
|
RevsetExpression::NotIn(inner) => Some(inner.clone()),
|
||||||
|
_ => None,
|
||||||
|
},
|
||||||
|
RevsetExpression::Intersection(expression1, expression2) => {
|
||||||
match (expression1.as_ref(), expression2.as_ref()) {
|
match (expression1.as_ref(), expression2.as_ref()) {
|
||||||
(_, RevsetExpression::All) => Some(expression1.clone()),
|
(_, RevsetExpression::All) => Some(expression1.clone()),
|
||||||
(RevsetExpression::All, _) => Some(expression2.clone()),
|
(RevsetExpression::All, _) => Some(expression2.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
_ => None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1257,7 +1263,7 @@ fn fold_difference(expression: &Rc<RevsetExpression>) -> Option<Rc<RevsetExpress
|
||||||
/// tree.
|
/// tree.
|
||||||
pub fn optimize(expression: Rc<RevsetExpression>) -> Rc<RevsetExpression> {
|
pub fn optimize(expression: Rc<RevsetExpression>) -> Rc<RevsetExpression> {
|
||||||
let expression = internalize_filter_intersection(&expression).unwrap_or(expression);
|
let expression = internalize_filter_intersection(&expression).unwrap_or(expression);
|
||||||
let expression = fold_intersection_with_all(&expression).unwrap_or(expression);
|
let expression = fold_redundant_expression(&expression).unwrap_or(expression);
|
||||||
fold_difference(&expression).unwrap_or(expression)
|
fold_difference(&expression).unwrap_or(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2505,6 +2511,38 @@ mod tests {
|
||||||
)
|
)
|
||||||
"###);
|
"###);
|
||||||
|
|
||||||
|
// Double/triple negates.
|
||||||
|
insta::assert_debug_snapshot!(optimize(parse("foo & ~~bar").unwrap()), @r###"
|
||||||
|
Intersection(
|
||||||
|
Symbol(
|
||||||
|
"foo",
|
||||||
|
),
|
||||||
|
Symbol(
|
||||||
|
"bar",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
"###);
|
||||||
|
insta::assert_debug_snapshot!(optimize(parse("foo & ~~~bar").unwrap()), @r###"
|
||||||
|
Difference(
|
||||||
|
Symbol(
|
||||||
|
"foo",
|
||||||
|
),
|
||||||
|
Symbol(
|
||||||
|
"bar",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
"###);
|
||||||
|
insta::assert_debug_snapshot!(optimize(parse("~(all() & ~foo) & bar").unwrap()), @r###"
|
||||||
|
Intersection(
|
||||||
|
Symbol(
|
||||||
|
"foo",
|
||||||
|
),
|
||||||
|
Symbol(
|
||||||
|
"bar",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
"###);
|
||||||
|
|
||||||
// Should be better than '(all() & ~foo) & (all() & ~bar)'.
|
// Should be better than '(all() & ~foo) & (all() & ~bar)'.
|
||||||
insta::assert_debug_snapshot!(optimize(parse("~foo & ~bar").unwrap()), @r###"
|
insta::assert_debug_snapshot!(optimize(parse("~foo & ~bar").unwrap()), @r###"
|
||||||
Difference(
|
Difference(
|
||||||
|
|
Loading…
Reference in a new issue