forked from openrs2/openrs2
parent
53160e422d
commit
9f09a81db1
@ -1,185 +0,0 @@ |
|||||||
package dev.openrs2.deob.ast.transform; |
|
||||||
|
|
||||||
import java.util.Optional; |
|
||||||
|
|
||||||
import com.github.javaparser.ast.CompilationUnit; |
|
||||||
import com.github.javaparser.ast.Node; |
|
||||||
import com.github.javaparser.ast.expr.EnclosedExpr; |
|
||||||
import com.github.javaparser.ast.expr.Expression; |
|
||||||
import dev.openrs2.deob.ast.util.NodeUtils; |
|
||||||
|
|
||||||
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) { |
|
||||||
NodeUtils.walk(unit, Node.TreeTraversal.POSTORDER, Expression.class, 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,162 @@ |
|||||||
|
package dev.openrs2.deob.ast.transform |
||||||
|
|
||||||
|
import com.github.javaparser.ast.CompilationUnit |
||||||
|
import com.github.javaparser.ast.Node |
||||||
|
import com.github.javaparser.ast.expr.BinaryExpr |
||||||
|
import com.github.javaparser.ast.expr.EnclosedExpr |
||||||
|
import com.github.javaparser.ast.expr.Expression |
||||||
|
import dev.openrs2.deob.ast.util.NodeUtils |
||||||
|
|
||||||
|
class EncloseTransformer : Transformer() { |
||||||
|
private enum class Associativity { |
||||||
|
LEFT, |
||||||
|
RIGHT, |
||||||
|
NONE |
||||||
|
} |
||||||
|
|
||||||
|
private enum class Op(val associativity: Associativity) { |
||||||
|
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); |
||||||
|
|
||||||
|
fun isPrecedenceLess(other: Op): Boolean { |
||||||
|
return ordinal > other.ordinal |
||||||
|
} |
||||||
|
|
||||||
|
fun isPrecedenceLessEqual(other: Op): Boolean { |
||||||
|
return ordinal >= other.ordinal |
||||||
|
} |
||||||
|
|
||||||
|
companion object { |
||||||
|
fun from(expr: Expression): Op? { |
||||||
|
return when { |
||||||
|
expr.isArrayAccessExpr || expr.isFieldAccessExpr -> ACCESS_PARENS |
||||||
|
expr.isMethodCallExpr || expr.isEnclosedExpr -> ACCESS_PARENS |
||||||
|
expr.isUnaryExpr -> if (expr.asUnaryExpr().operator.isPostfix) POSTFIX else UNARY |
||||||
|
expr.isCastExpr || expr.isObjectCreationExpr || expr.isArrayCreationExpr -> CAST_NEW |
||||||
|
expr.isBinaryExpr -> when (expr.asBinaryExpr().operator) { |
||||||
|
BinaryExpr.Operator.MULTIPLY -> MULTIPLICATIVE |
||||||
|
BinaryExpr.Operator.DIVIDE, BinaryExpr.Operator.REMAINDER -> MULTIPLICATIVE |
||||||
|
BinaryExpr.Operator.PLUS, BinaryExpr.Operator.MINUS -> ADDITIVE |
||||||
|
BinaryExpr.Operator.LEFT_SHIFT -> SHIFT |
||||||
|
BinaryExpr.Operator.SIGNED_RIGHT_SHIFT, BinaryExpr.Operator.UNSIGNED_RIGHT_SHIFT -> SHIFT |
||||||
|
BinaryExpr.Operator.LESS, BinaryExpr.Operator.LESS_EQUALS -> RELATIONAL |
||||||
|
BinaryExpr.Operator.GREATER, BinaryExpr.Operator.GREATER_EQUALS -> RELATIONAL |
||||||
|
BinaryExpr.Operator.EQUALS, BinaryExpr.Operator.NOT_EQUALS -> EQUALITY |
||||||
|
BinaryExpr.Operator.BINARY_AND -> BITWISE_AND |
||||||
|
BinaryExpr.Operator.XOR -> BITWISE_XOR |
||||||
|
BinaryExpr.Operator.BINARY_OR -> BITWISE_OR |
||||||
|
BinaryExpr.Operator.AND -> LOGICAL_AND |
||||||
|
BinaryExpr.Operator.OR -> LOGICAL_OR |
||||||
|
else -> null |
||||||
|
} |
||||||
|
expr.isInstanceOfExpr -> RELATIONAL |
||||||
|
expr.isConditionalExpr -> TERNARY |
||||||
|
expr.isAssignExpr -> ASSIGNMENT |
||||||
|
else -> null |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
override fun transform(unit: CompilationUnit) { |
||||||
|
NodeUtils.walk(unit, Node.TreeTraversal.POSTORDER, Expression::class.java) { expr -> |
||||||
|
when { |
||||||
|
expr.isArrayAccessExpr -> { |
||||||
|
val accessExpr = expr.asArrayAccessExpr() |
||||||
|
encloseLeft(expr, accessExpr.name) |
||||||
|
} |
||||||
|
expr.isFieldAccessExpr -> { |
||||||
|
encloseLeft(expr, expr.asFieldAccessExpr().scope) |
||||||
|
} |
||||||
|
expr.isMethodCallExpr -> { |
||||||
|
expr.asMethodCallExpr().scope.ifPresent { scope -> |
||||||
|
encloseLeft(expr, scope) |
||||||
|
} |
||||||
|
} |
||||||
|
expr.isUnaryExpr -> { |
||||||
|
val unaryExpr = expr.asUnaryExpr() |
||||||
|
encloseRight(expr, unaryExpr.expression) |
||||||
|
} |
||||||
|
expr.isCastExpr -> { |
||||||
|
encloseRight(expr, expr.asCastExpr().expression) |
||||||
|
} |
||||||
|
expr.isObjectCreationExpr -> { |
||||||
|
expr.asObjectCreationExpr().scope.ifPresent { scope -> |
||||||
|
encloseLeft(expr, scope) |
||||||
|
} |
||||||
|
} |
||||||
|
expr.isBinaryExpr -> { |
||||||
|
val binaryExpr = expr.asBinaryExpr() |
||||||
|
encloseLeft(expr, binaryExpr.left) |
||||||
|
encloseRight(expr, binaryExpr.right) |
||||||
|
} |
||||||
|
expr.isInstanceOfExpr -> { |
||||||
|
encloseLeft(expr, expr.asInstanceOfExpr().expression) |
||||||
|
} |
||||||
|
expr.isConditionalExpr -> { |
||||||
|
val conditionalExpr = expr.asConditionalExpr() |
||||||
|
encloseLeft(expr, conditionalExpr.condition) |
||||||
|
encloseLeft(expr, conditionalExpr.thenExpr) |
||||||
|
encloseRight(expr, conditionalExpr.elseExpr) |
||||||
|
} |
||||||
|
expr.isAssignExpr -> { |
||||||
|
val assignExpr = expr.asAssignExpr() |
||||||
|
encloseLeft(expr, assignExpr.target) |
||||||
|
encloseRight(expr, assignExpr.value) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
companion object { |
||||||
|
private fun encloseLeft(parent: Expression, child: Expression) { |
||||||
|
val parentOp = Op.from(parent) ?: throw IllegalArgumentException() |
||||||
|
val childOp = Op.from(child) ?: return |
||||||
|
|
||||||
|
when (parentOp.associativity) { |
||||||
|
Associativity.LEFT -> { |
||||||
|
if (childOp.isPrecedenceLess(parentOp)) { |
||||||
|
parent.replace(child, EnclosedExpr(child.clone())) |
||||||
|
} |
||||||
|
} |
||||||
|
Associativity.NONE, Associativity.RIGHT -> { |
||||||
|
if (childOp.isPrecedenceLessEqual(parentOp)) { |
||||||
|
parent.replace(child, EnclosedExpr(child.clone())) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private fun encloseRight(parent: Expression, child: Expression) { |
||||||
|
val parentOp = Op.from(parent) ?: throw IllegalArgumentException() |
||||||
|
val childOp = Op.from(child) ?: return |
||||||
|
|
||||||
|
when (parentOp.associativity) { |
||||||
|
Associativity.NONE, Associativity.LEFT -> { |
||||||
|
if (childOp.isPrecedenceLessEqual(parentOp)) { |
||||||
|
parent.replace(child, EnclosedExpr(child.clone())) |
||||||
|
} |
||||||
|
} |
||||||
|
Associativity.RIGHT -> { |
||||||
|
if (childOp.isPrecedenceLess(parentOp)) { |
||||||
|
parent.replace(child, EnclosedExpr(child.clone())) |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue