Improve structuring of if/else chains ending in a throw or return

pull/48/head
Graham 5 years ago
parent 261cc87125
commit 5e46c058cd
  1. 76
      deob-ast/src/main/java/dev/openrs2/deob/ast/transform/IfElseTransformer.java

@ -36,6 +36,22 @@ public final class IfElseTransformer extends Transformer {
throw new IllegalArgumentException();
}
private static boolean isTailThrowOrReturn(Statement stmt) {
if (stmt.isThrowStmt() || stmt.isReturnStmt()) {
return true;
} else if (stmt.isBlockStmt()) {
var stmts = stmt.asBlockStmt().getStatements();
if (stmts.isEmpty()) {
return false;
}
var tail = stmts.get(stmts.size() - 1);
return tail.isThrowStmt() || tail.isReturnStmt();
} else {
return false;
}
}
@Override
public void transform(CompilationUnit unit) {
NodeUtils.walk(unit, Node.TreeTraversal.POSTORDER, IfStmt.class, stmt -> {
@ -78,5 +94,65 @@ public final class IfElseTransformer extends Transformer {
}
});
});
/*
* Rewrite:
*
* ...
* } else {
* if (x != 123) {
* ...
* throw ...;
* }
* ...
* }
*
* to:
*
* ...
* } else if (x == 123) {
* ...
* } else {
* ...
* throw ...;
* }
*/
NodeUtils.walk(unit, Node.TreeTraversal.POSTORDER, IfStmt.class, stmt -> {
stmt.getElseStmt().ifPresent(elseStmt -> {
/* match */
if (!elseStmt.isBlockStmt()) {
return;
}
var blockStmt = elseStmt.asBlockStmt();
var statements = blockStmt.getStatements();
if (statements.isEmpty()) {
return;
}
var head = statements.get(0);
if (!head.isIfStmt()) {
return;
}
var ifStmt = head.asIfStmt();
if (ifStmt.getElseStmt().isPresent()) {
return;
}
var thenStmt = ifStmt.getThenStmt();
if (!isTailThrowOrReturn(thenStmt)) {
return;
}
/* rewrite */
var condition = ExprUtils.not(ifStmt.getCondition());
var tail = blockStmt.clone();
tail.getStatements().remove(0);
elseStmt.replace(new IfStmt(condition, tail, thenStmt.clone()));
});
});
}
}

Loading…
Cancel
Save