forked from openrs2/openrs2
parent
578927d2f7
commit
7d959ed135
@ -0,0 +1,183 @@ |
|||||||
|
package dev.openrs2.deob.ast.transform; |
||||||
|
|
||||||
|
import java.util.Optional; |
||||||
|
|
||||||
|
import com.github.javaparser.ast.CompilationUnit; |
||||||
|
import com.github.javaparser.ast.expr.EnclosedExpr; |
||||||
|
import com.github.javaparser.ast.expr.Expression; |
||||||
|
|
||||||
|
public final class EncloseTransformer extends Transformer { |
||||||
|
private enum Associativity { |
||||||
|
LEFT, |
||||||
|
RIGHT, |
||||||
|
NONE |
||||||
|
} |
||||||
|
|
||||||
|
private enum Op { |
||||||
|
ACCESS_PARENS(Associativity.LEFT), |
||||||
|
POSTFIX(Associativity.NONE), |
||||||
|
UNARY(Associativity.RIGHT), |
||||||
|
CAST_NEW(Associativity.RIGHT), |
||||||
|
MULTIPLICATIVE(Associativity.LEFT), |
||||||
|
ADDITIVE(Associativity.LEFT), |
||||||
|
SHIFT(Associativity.LEFT), |
||||||
|
RELATIONAL(Associativity.LEFT), |
||||||
|
EQUALITY(Associativity.NONE), |
||||||
|
BITWISE_AND(Associativity.LEFT), |
||||||
|
BITWISE_XOR(Associativity.LEFT), |
||||||
|
BITWISE_OR(Associativity.LEFT), |
||||||
|
LOGICAL_AND(Associativity.LEFT), |
||||||
|
LOGICAL_OR(Associativity.LEFT), |
||||||
|
TERNARY(Associativity.RIGHT), |
||||||
|
ASSIGNMENT(Associativity.RIGHT); |
||||||
|
|
||||||
|
public static Optional<Op> from(Expression expr) { |
||||||
|
if (expr.isArrayAccessExpr() || expr.isFieldAccessExpr() || expr.isMethodCallExpr() || expr.isEnclosedExpr()) { |
||||||
|
return Optional.of(ACCESS_PARENS); |
||||||
|
} else if (expr.isUnaryExpr()) { |
||||||
|
return Optional.of(expr.asUnaryExpr().getOperator().isPostfix() ? POSTFIX : UNARY); |
||||||
|
} else if (expr.isCastExpr() || expr.isObjectCreationExpr() || expr.isArrayCreationExpr()) { |
||||||
|
return Optional.of(CAST_NEW); |
||||||
|
} else if (expr.isBinaryExpr()) { |
||||||
|
switch (expr.asBinaryExpr().getOperator()) { |
||||||
|
case MULTIPLY: |
||||||
|
case DIVIDE: |
||||||
|
case REMAINDER: |
||||||
|
return Optional.of(MULTIPLICATIVE); |
||||||
|
case PLUS: |
||||||
|
case MINUS: |
||||||
|
return Optional.of(ADDITIVE); |
||||||
|
case LEFT_SHIFT: |
||||||
|
case SIGNED_RIGHT_SHIFT: |
||||||
|
case UNSIGNED_RIGHT_SHIFT: |
||||||
|
return Optional.of(SHIFT); |
||||||
|
case LESS: |
||||||
|
case LESS_EQUALS: |
||||||
|
case GREATER: |
||||||
|
case GREATER_EQUALS: |
||||||
|
return Optional.of(RELATIONAL); |
||||||
|
case EQUALS: |
||||||
|
case NOT_EQUALS: |
||||||
|
return Optional.of(EQUALITY); |
||||||
|
case BINARY_AND: |
||||||
|
return Optional.of(BITWISE_AND); |
||||||
|
case XOR: |
||||||
|
return Optional.of(BITWISE_XOR); |
||||||
|
case BINARY_OR: |
||||||
|
return Optional.of(BITWISE_OR); |
||||||
|
case AND: |
||||||
|
return Optional.of(LOGICAL_AND); |
||||||
|
case OR: |
||||||
|
return Optional.of(LOGICAL_OR); |
||||||
|
} |
||||||
|
} else if (expr.isInstanceOfExpr()) { |
||||||
|
return Optional.of(RELATIONAL); |
||||||
|
} else if (expr.isConditionalExpr()) { |
||||||
|
return Optional.of(TERNARY); |
||||||
|
} else if (expr.isAssignExpr()) { |
||||||
|
return Optional.of(ASSIGNMENT); |
||||||
|
} |
||||||
|
return Optional.empty(); |
||||||
|
} |
||||||
|
|
||||||
|
private final Associativity associativity; |
||||||
|
|
||||||
|
Op(Associativity associativity) { |
||||||
|
this.associativity = associativity; |
||||||
|
} |
||||||
|
|
||||||
|
public Associativity getAssociativity() { |
||||||
|
return associativity; |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isPrecedenceLess(Op other) { |
||||||
|
return ordinal() > other.ordinal(); |
||||||
|
} |
||||||
|
|
||||||
|
public boolean isPrecedenceLessEqual(Op other) { |
||||||
|
return ordinal() >= other.ordinal(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static void encloseLeft(Expression parent, Expression child) { |
||||||
|
var parentOp = Op.from(parent).orElseThrow(IllegalArgumentException::new); |
||||||
|
Op.from(child).ifPresent(childOp -> { |
||||||
|
switch (parentOp.getAssociativity()) { |
||||||
|
case LEFT: |
||||||
|
if (childOp.isPrecedenceLess(parentOp)) { |
||||||
|
parent.replace(child, new EnclosedExpr(child.clone())); |
||||||
|
} |
||||||
|
break; |
||||||
|
case NONE: |
||||||
|
case RIGHT: |
||||||
|
if (childOp.isPrecedenceLessEqual(parentOp)) { |
||||||
|
parent.replace(child, new EnclosedExpr(child.clone())); |
||||||
|
} |
||||||
|
break; |
||||||
|
default: |
||||||
|
throw new IllegalArgumentException(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private static void encloseRight(Expression parent, Expression child) { |
||||||
|
var parentOp = Op.from(parent).orElseThrow(IllegalArgumentException::new); |
||||||
|
Op.from(child).ifPresent(childOp -> { |
||||||
|
switch (parentOp.getAssociativity()) { |
||||||
|
case NONE: |
||||||
|
case LEFT: |
||||||
|
if (childOp.isPrecedenceLessEqual(parentOp)) { |
||||||
|
parent.replace(child, new EnclosedExpr(child.clone())); |
||||||
|
} |
||||||
|
break; |
||||||
|
case RIGHT: |
||||||
|
if (childOp.isPrecedenceLess(parentOp)) { |
||||||
|
parent.replace(child, new EnclosedExpr(child.clone())); |
||||||
|
} |
||||||
|
break; |
||||||
|
default: |
||||||
|
throw new IllegalArgumentException(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void transform(CompilationUnit unit) { |
||||||
|
unit.findAll(Expression.class).forEach(expr -> { |
||||||
|
if (expr.isArrayAccessExpr()) { |
||||||
|
var accessExpr = expr.asArrayAccessExpr(); |
||||||
|
encloseLeft(expr, accessExpr.getName()); |
||||||
|
} else if (expr.isFieldAccessExpr()) { |
||||||
|
encloseLeft(expr, expr.asFieldAccessExpr().getScope()); |
||||||
|
} else if (expr.isMethodCallExpr()) { |
||||||
|
expr.asMethodCallExpr().getScope().ifPresent(scope -> { |
||||||
|
encloseLeft(expr, scope); |
||||||
|
}); |
||||||
|
} else if (expr.isUnaryExpr()) { |
||||||
|
var unaryExpr = expr.asUnaryExpr(); |
||||||
|
encloseRight(expr, unaryExpr.getExpression()); |
||||||
|
} else if (expr.isCastExpr()) { |
||||||
|
encloseRight(expr, expr.asCastExpr().getExpression()); |
||||||
|
} else if (expr.isObjectCreationExpr()) { |
||||||
|
expr.asObjectCreationExpr().getScope().ifPresent(scope -> { |
||||||
|
encloseLeft(expr, scope); |
||||||
|
}); |
||||||
|
} else if (expr.isBinaryExpr()) { |
||||||
|
var binaryExpr = expr.asBinaryExpr(); |
||||||
|
encloseLeft(expr, binaryExpr.getLeft()); |
||||||
|
encloseRight(expr, binaryExpr.getRight()); |
||||||
|
} else if (expr.isInstanceOfExpr()) { |
||||||
|
encloseLeft(expr, expr.asInstanceOfExpr().getExpression()); |
||||||
|
} else if (expr.isConditionalExpr()) { |
||||||
|
var conditionalExpr = expr.asConditionalExpr(); |
||||||
|
encloseLeft(expr, conditionalExpr.getCondition()); |
||||||
|
encloseLeft(expr, conditionalExpr.getThenExpr()); |
||||||
|
encloseRight(expr, conditionalExpr.getElseExpr()); |
||||||
|
} else if (expr.isAssignExpr()) { |
||||||
|
var assignExpr = expr.asAssignExpr(); |
||||||
|
encloseLeft(expr, assignExpr.getTarget()); |
||||||
|
encloseRight(expr, assignExpr.getValue()); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,13 @@ |
|||||||
|
package dev.openrs2.deob.ast.transform; |
||||||
|
|
||||||
|
import com.github.javaparser.ast.CompilationUnit; |
||||||
|
import com.github.javaparser.ast.expr.EnclosedExpr; |
||||||
|
|
||||||
|
public final class UnencloseTransformer extends Transformer { |
||||||
|
@Override |
||||||
|
public void transform(CompilationUnit unit) { |
||||||
|
unit.findAll(EnclosedExpr.class).forEach(expr -> { |
||||||
|
expr.replace(expr.getInner().clone()); |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue