forked from openrs2/openrs2
parent
bf55b0d901
commit
556923559c
@ -0,0 +1,58 @@ |
||||
package dev.openrs2.deob.ast.transform; |
||||
|
||||
import com.github.javaparser.ast.CompilationUnit; |
||||
import com.github.javaparser.ast.NodeList; |
||||
import com.github.javaparser.ast.stmt.IfStmt; |
||||
import com.github.javaparser.ast.stmt.Statement; |
||||
import dev.openrs2.deob.ast.visitor.NegateExprVisitor; |
||||
|
||||
public final class IfElseTransformer extends Transformer { |
||||
private static boolean isIf(Statement stmt) { |
||||
if (stmt.isIfStmt()) { |
||||
return true; |
||||
} else if (stmt.isBlockStmt()) { |
||||
NodeList<Statement> stmts = stmt.asBlockStmt().getStatements(); |
||||
return stmts.size() == 1 && stmts.get(0).isIfStmt(); |
||||
} else { |
||||
return false; |
||||
} |
||||
} |
||||
|
||||
private static Statement getIf(Statement stmt) { |
||||
if (stmt.isIfStmt()) { |
||||
return stmt; |
||||
} else if (stmt.isBlockStmt()) { |
||||
NodeList<Statement> stmts = stmt.asBlockStmt().getStatements(); |
||||
if (stmts.size() == 1) { |
||||
Statement head = stmts.get(0); |
||||
if (head.isIfStmt()) { |
||||
return head; |
||||
} |
||||
} |
||||
} |
||||
|
||||
throw new IllegalArgumentException(); |
||||
} |
||||
|
||||
@Override |
||||
public void transform(CompilationUnit unit) { |
||||
unit.findAll(IfStmt.class).forEach(stmt -> { |
||||
stmt.getElseStmt().ifPresent(elseStmt -> { |
||||
var thenStmt = stmt.getThenStmt(); |
||||
if (isIf(thenStmt) && !isIf(elseStmt)) { |
||||
stmt.setCondition(stmt.getCondition().accept(new NegateExprVisitor(), null)); |
||||
stmt.setThenStmt(elseStmt); |
||||
stmt.setElseStmt(thenStmt); |
||||
} |
||||
}); |
||||
}); |
||||
|
||||
unit.findAll(IfStmt.class).forEach(stmt -> { |
||||
stmt.getElseStmt().ifPresent(elseStmt -> { |
||||
if (isIf(elseStmt)) { |
||||
stmt.setElseStmt(getIf(elseStmt)); |
||||
} |
||||
}); |
||||
}); |
||||
} |
||||
} |
@ -0,0 +1,72 @@ |
||||
package dev.openrs2.deob.ast.visitor; |
||||
|
||||
import com.github.javaparser.ast.Node; |
||||
import com.github.javaparser.ast.NodeList; |
||||
import com.github.javaparser.ast.expr.BinaryExpr; |
||||
import com.github.javaparser.ast.expr.BooleanLiteralExpr; |
||||
import com.github.javaparser.ast.expr.EnclosedExpr; |
||||
import com.github.javaparser.ast.expr.Expression; |
||||
import com.github.javaparser.ast.expr.UnaryExpr; |
||||
import com.github.javaparser.ast.visitor.GenericVisitorWithDefaults; |
||||
|
||||
// TODO(gpe): need to be careful about operator precedence/EnclosedExpr
|
||||
public final class NegateExprVisitor extends GenericVisitorWithDefaults<Expression, Void> { |
||||
@Override |
||||
public Expression defaultAction(Node n, Void arg) { |
||||
if (!(n instanceof Expression)) { |
||||
throw new IllegalArgumentException(); |
||||
} |
||||
return new UnaryExpr((Expression) n, UnaryExpr.Operator.LOGICAL_COMPLEMENT); |
||||
} |
||||
|
||||
@Override |
||||
public Expression defaultAction(NodeList n, Void arg) { |
||||
throw new IllegalArgumentException(); |
||||
} |
||||
|
||||
@Override |
||||
public Expression visit(BinaryExpr n, Void arg) { |
||||
var left = n.getLeft(); |
||||
var right = n.getRight(); |
||||
switch (n.getOperator()) { |
||||
case EQUALS: |
||||
return new BinaryExpr(left, right, BinaryExpr.Operator.NOT_EQUALS); |
||||
case NOT_EQUALS: |
||||
return new BinaryExpr(left, right, BinaryExpr.Operator.EQUALS); |
||||
case GREATER: |
||||
return new BinaryExpr(left, right, BinaryExpr.Operator.LESS_EQUALS); |
||||
case GREATER_EQUALS: |
||||
return new BinaryExpr(left, right, BinaryExpr.Operator.LESS); |
||||
case LESS: |
||||
return new BinaryExpr(left, right, BinaryExpr.Operator.GREATER_EQUALS); |
||||
case LESS_EQUALS: |
||||
return new BinaryExpr(left, right, BinaryExpr.Operator.GREATER); |
||||
case AND: |
||||
return new BinaryExpr(left.accept(this, arg), right.accept(this, arg), BinaryExpr.Operator.OR); |
||||
case OR: |
||||
return new BinaryExpr(left.accept(this, arg), right.accept(this, arg), BinaryExpr.Operator.AND); |
||||
default: |
||||
return defaultAction(n, arg); |
||||
} |
||||
} |
||||
|
||||
@Override |
||||
public Expression visit(BooleanLiteralExpr n, Void arg) { |
||||
return new BooleanLiteralExpr(!n.getValue()); |
||||
} |
||||
|
||||
@Override |
||||
public Expression visit(EnclosedExpr n, Void arg) { |
||||
return n.getInner().accept(this, arg); |
||||
} |
||||
|
||||
@Override |
||||
public Expression visit(UnaryExpr n, Void arg) { |
||||
switch (n.getOperator()) { |
||||
case LOGICAL_COMPLEMENT: |
||||
return n.getExpression(); |
||||
default: |
||||
return defaultAction(n, arg); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue