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