Open-source multiplayer game server compatible with the RuneScape client
https://www.openrs2.org/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
3.6 KiB
108 lines
3.6 KiB
package dev.openrs2.deob.ast.util;
|
|
|
|
import com.github.javaparser.ast.expr.BinaryExpr;
|
|
import com.github.javaparser.ast.expr.BooleanLiteralExpr;
|
|
import com.github.javaparser.ast.expr.Expression;
|
|
import com.github.javaparser.ast.expr.IntegerLiteralExpr;
|
|
import com.github.javaparser.ast.expr.LongLiteralExpr;
|
|
import com.github.javaparser.ast.expr.UnaryExpr;
|
|
|
|
public final class ExprUtils {
|
|
public static boolean isIntegerOrLongLiteral(Expression expr) {
|
|
return expr.isIntegerLiteralExpr() || expr.isLongLiteralExpr();
|
|
}
|
|
|
|
public static LongLiteralExpr createLong(long value) {
|
|
return new LongLiteralExpr(Long.toString(value).concat("L"));
|
|
}
|
|
|
|
public static boolean isNot(Expression expr) {
|
|
return expr.isUnaryExpr() && expr.asUnaryExpr().getOperator() == UnaryExpr.Operator.LOGICAL_COMPLEMENT;
|
|
}
|
|
|
|
public static Expression negate(Expression expr) {
|
|
if (expr.isUnaryExpr() && expr.asUnaryExpr().getOperator() == UnaryExpr.Operator.MINUS) {
|
|
return expr.asUnaryExpr().getExpression().clone();
|
|
} else if (expr.isIntegerLiteralExpr()) {
|
|
return new IntegerLiteralExpr(-expr.asIntegerLiteralExpr().asInt());
|
|
} else if (expr.isLongLiteralExpr()) {
|
|
return createLong(-expr.asLongLiteralExpr().asLong());
|
|
} else {
|
|
throw new IllegalArgumentException();
|
|
}
|
|
}
|
|
|
|
public static Expression not(Expression expr) {
|
|
if (expr.isUnaryExpr()) {
|
|
var unary = expr.asUnaryExpr();
|
|
if (unary.getOperator() == UnaryExpr.Operator.LOGICAL_COMPLEMENT) {
|
|
return unary.getExpression().clone();
|
|
}
|
|
} else if (expr.isBinaryExpr()) {
|
|
var binary = expr.asBinaryExpr();
|
|
|
|
var left = binary.getLeft();
|
|
var right = binary.getRight();
|
|
|
|
switch (binary.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(not(left), not(right), BinaryExpr.Operator.OR);
|
|
case OR:
|
|
return new BinaryExpr(not(left), not(right), BinaryExpr.Operator.AND);
|
|
}
|
|
} else if (expr.isBooleanLiteralExpr()) {
|
|
return new BooleanLiteralExpr(!expr.asBooleanLiteralExpr().getValue());
|
|
}
|
|
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.findAll(Expression.class)) {
|
|
if (child != expr) {
|
|
count += countNots(child);
|
|
}
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
public static boolean hasSideEffects(Expression expr) {
|
|
if (expr.isLiteralExpr() || expr.isNameExpr() | expr.isFieldAccessExpr()) {
|
|
return false;
|
|
} else if (expr.isUnaryExpr()) {
|
|
return hasSideEffects(expr.asUnaryExpr().getExpression());
|
|
} else if (expr.isBinaryExpr()) {
|
|
var binary = expr.asBinaryExpr();
|
|
return hasSideEffects(binary.getLeft()) || hasSideEffects(binary.getRight());
|
|
} else if (expr.isArrayAccessExpr()) {
|
|
var access = expr.asArrayAccessExpr();
|
|
return hasSideEffects(access.getName()) || hasSideEffects(access.getIndex());
|
|
}
|
|
// TODO(gpe): more cases
|
|
return true;
|
|
}
|
|
|
|
private ExprUtils() {
|
|
/* empty */
|
|
}
|
|
}
|
|
|