diff --git a/deob-ast/src/main/java/dev/openrs2/deob/ast/transform/IfElseTransformer.java b/deob-ast/src/main/java/dev/openrs2/deob/ast/transform/IfElseTransformer.java index 4c6734023e..6a02d1bb3c 100644 --- a/deob-ast/src/main/java/dev/openrs2/deob/ast/transform/IfElseTransformer.java +++ b/deob-ast/src/main/java/dev/openrs2/deob/ast/transform/IfElseTransformer.java @@ -54,11 +54,11 @@ public final class IfElseTransformer extends Transformer { } /* - * Prefer if (a) over if (!a). We don't swap != as it makes - * checking bitwise flags look worse. + * Prefer fewer NOTs in the if condition. */ - if (ExprUtils.isNot(condition)) { - stmt.setCondition(ExprUtils.not(condition)); + var notCondition = ExprUtils.not(condition); + if (ExprUtils.countNots(notCondition) < ExprUtils.countNots(condition)) { + stmt.setCondition(notCondition); stmt.setThenStmt(elseStmt.clone()); stmt.setElseStmt(thenStmt.clone()); } diff --git a/deob-ast/src/main/java/dev/openrs2/deob/ast/util/ExprUtils.java b/deob-ast/src/main/java/dev/openrs2/deob/ast/util/ExprUtils.java index c346bde5c0..10650924be 100644 --- a/deob-ast/src/main/java/dev/openrs2/deob/ast/util/ExprUtils.java +++ b/deob-ast/src/main/java/dev/openrs2/deob/ast/util/ExprUtils.java @@ -71,6 +71,22 @@ public final class ExprUtils { return new UnaryExpr(expr.clone(), UnaryExpr.Operator.LOGICAL_COMPLEMENT); } + public static int countNots(Expression expr) { + int count = 0; + + if (expr.isUnaryExpr() && expr.asUnaryExpr().getOperator() == UnaryExpr.Operator.LOGICAL_COMPLEMENT) { + count++; + } else if (expr.isBinaryExpr() && expr.asBinaryExpr().getOperator() == BinaryExpr.Operator.NOT_EQUALS) { + count++; + } + + for (Expression child : expr.getChildNodesByType(Expression.class)) { + count += countNots(child); + } + + return count; + } + public static boolean hasSideEffects(Expression expr) { if (expr.isLiteralExpr() || expr.isNameExpr() | expr.isFieldAccessExpr()) { return false;