Use smart casts in the AST deobfuscator

Many of the old is/as calls were left over from the original Java code.

Signed-off-by: Graham <gpe@openrs2.dev>
Graham 4 years ago
parent bde818230b
commit 880be759b7
  1. 8
      deob-ast/src/main/java/dev/openrs2/deob/ast/transform/AddSubTransformer.kt
  2. 4
      deob-ast/src/main/java/dev/openrs2/deob/ast/transform/BinaryExprOrderTransformer.kt
  3. 23
      deob-ast/src/main/java/dev/openrs2/deob/ast/transform/BitMaskTransformer.kt
  4. 11
      deob-ast/src/main/java/dev/openrs2/deob/ast/transform/ComplementTransformer.kt
  5. 83
      deob-ast/src/main/java/dev/openrs2/deob/ast/transform/EncloseTransformer.kt
  6. 9
      deob-ast/src/main/java/dev/openrs2/deob/ast/transform/ForLoopConditionTransformer.kt
  7. 52
      deob-ast/src/main/java/dev/openrs2/deob/ast/transform/GlTransformer.kt
  8. 14
      deob-ast/src/main/java/dev/openrs2/deob/ast/transform/IdentityTransformer.kt
  9. 54
      deob-ast/src/main/java/dev/openrs2/deob/ast/transform/IfElseTransformer.kt
  10. 11
      deob-ast/src/main/java/dev/openrs2/deob/ast/transform/IncrementTransformer.kt
  11. 29
      deob-ast/src/main/java/dev/openrs2/deob/ast/util/ExprUtils.kt

@ -88,14 +88,14 @@ class AddSubTransformer : Transformer() {
} }
private fun Expression.isNegative(): Boolean { private fun Expression.isNegative(): Boolean {
return when { return when (this) {
isUnaryExpr -> asUnaryExpr().operator == UnaryExpr.Operator.MINUS is UnaryExpr -> operator == UnaryExpr.Operator.MINUS
isIntegerLiteralExpr -> when (val n = asIntegerLiteralExpr().asNumber()) { is IntegerLiteralExpr -> when (val n = asNumber()) {
IntegerLiteralExpr.MAX_31_BIT_UNSIGNED_VALUE_AS_LONG -> false IntegerLiteralExpr.MAX_31_BIT_UNSIGNED_VALUE_AS_LONG -> false
is Int -> n < 0 is Int -> n < 0
else -> error("Invalid IntegerLiteralExpr type") else -> error("Invalid IntegerLiteralExpr type")
} }
isLongLiteralExpr -> when (val n = asLongLiteralExpr().asNumber()) { is LongLiteralExpr -> when (val n = asNumber()) {
LongLiteralExpr.MAX_63_BIT_UNSIGNED_VALUE_AS_BIG_INTEGER -> false LongLiteralExpr.MAX_63_BIT_UNSIGNED_VALUE_AS_BIG_INTEGER -> false
is Long -> n < 0 is Long -> n < 0
else -> error("Invalid LongLiteralExpr type") else -> error("Invalid LongLiteralExpr type")

@ -3,6 +3,8 @@ package dev.openrs2.deob.ast.transform
import com.github.javaparser.ast.CompilationUnit import com.github.javaparser.ast.CompilationUnit
import com.github.javaparser.ast.expr.BinaryExpr import com.github.javaparser.ast.expr.BinaryExpr
import com.github.javaparser.ast.expr.Expression import com.github.javaparser.ast.expr.Expression
import com.github.javaparser.ast.expr.LiteralExpr
import com.github.javaparser.ast.expr.ThisExpr
import dev.openrs2.deob.ast.Library import dev.openrs2.deob.ast.Library
import dev.openrs2.deob.ast.LibraryGroup import dev.openrs2.deob.ast.LibraryGroup
import dev.openrs2.deob.ast.util.flip import dev.openrs2.deob.ast.util.flip
@ -32,5 +34,5 @@ class BinaryExprOrderTransformer : Transformer() {
} }
private val Expression.isLiteralOrThisExpr: Boolean private val Expression.isLiteralOrThisExpr: Boolean
get() = isLiteralExpr || isThisExpr get() = this is LiteralExpr || this is ThisExpr
} }

@ -3,11 +3,11 @@ package dev.openrs2.deob.ast.transform
import com.github.javaparser.ast.CompilationUnit import com.github.javaparser.ast.CompilationUnit
import com.github.javaparser.ast.expr.BinaryExpr import com.github.javaparser.ast.expr.BinaryExpr
import com.github.javaparser.ast.expr.IntegerLiteralExpr import com.github.javaparser.ast.expr.IntegerLiteralExpr
import com.github.javaparser.ast.expr.LongLiteralExpr
import dev.openrs2.deob.ast.Library import dev.openrs2.deob.ast.Library
import dev.openrs2.deob.ast.LibraryGroup import dev.openrs2.deob.ast.LibraryGroup
import dev.openrs2.deob.ast.util.checkedAsInt import dev.openrs2.deob.ast.util.checkedAsInt
import dev.openrs2.deob.ast.util.checkedAsLong import dev.openrs2.deob.ast.util.checkedAsLong
import dev.openrs2.deob.ast.util.isIntegerOrLongLiteral
import dev.openrs2.deob.ast.util.toLongLiteralExpr import dev.openrs2.deob.ast.util.toLongLiteralExpr
import dev.openrs2.deob.ast.util.walk import dev.openrs2.deob.ast.util.walk
import javax.inject.Singleton import javax.inject.Singleton
@ -17,25 +17,25 @@ class BitMaskTransformer : Transformer() {
override fun transformUnit(group: LibraryGroup, library: Library, unit: CompilationUnit) { override fun transformUnit(group: LibraryGroup, library: Library, unit: CompilationUnit) {
unit.walk { expr: BinaryExpr -> unit.walk { expr: BinaryExpr ->
val shiftOp = expr.operator val shiftOp = expr.operator
val left = expr.left val bitwiseExpr = expr.left
val shamtExpr = expr.right val shamtExpr = expr.right
if (shiftOp !in SHIFT_OPS || !left.isBinaryExpr || !shamtExpr.isIntegerLiteralExpr) { if (shiftOp !in SHIFT_OPS || bitwiseExpr !is BinaryExpr || shamtExpr !is IntegerLiteralExpr) {
return@walk return@walk
} }
val bitwiseExpr = left.asBinaryExpr()
val bitwiseOp = bitwiseExpr.operator val bitwiseOp = bitwiseExpr.operator
val argExpr = bitwiseExpr.left val argExpr = bitwiseExpr.left
var maskExpr = bitwiseExpr.right var maskExpr = bitwiseExpr.right
if (bitwiseOp !in BITWISE_OPS || !maskExpr.isIntegerOrLongLiteral()) { if (bitwiseOp !in BITWISE_OPS) {
return@walk return@walk
} }
val shamt = shamtExpr.asIntegerLiteralExpr().checkedAsInt() val shamt = shamtExpr.checkedAsInt()
if (maskExpr.isIntegerLiteralExpr) { when (maskExpr) {
var mask = maskExpr.asIntegerLiteralExpr().checkedAsInt() is IntegerLiteralExpr -> {
var mask = maskExpr.checkedAsInt()
mask = when (shiftOp) { mask = when (shiftOp) {
BinaryExpr.Operator.SIGNED_RIGHT_SHIFT -> mask shr shamt BinaryExpr.Operator.SIGNED_RIGHT_SHIFT -> mask shr shamt
@ -44,8 +44,9 @@ class BitMaskTransformer : Transformer() {
} }
maskExpr = IntegerLiteralExpr(mask.toString()) maskExpr = IntegerLiteralExpr(mask.toString())
} else { }
var mask = maskExpr.asLongLiteralExpr().checkedAsLong() is LongLiteralExpr -> {
var mask = maskExpr.checkedAsLong()
mask = when (shiftOp) { mask = when (shiftOp) {
BinaryExpr.Operator.SIGNED_RIGHT_SHIFT -> mask shr shamt BinaryExpr.Operator.SIGNED_RIGHT_SHIFT -> mask shr shamt
@ -55,6 +56,8 @@ class BitMaskTransformer : Transformer() {
maskExpr = mask.toLongLiteralExpr() maskExpr = mask.toLongLiteralExpr()
} }
else -> return@walk
}
expr.replace(BinaryExpr(BinaryExpr(argExpr.clone(), shamtExpr.clone(), shiftOp), maskExpr, bitwiseOp)) expr.replace(BinaryExpr(BinaryExpr(argExpr.clone(), shamtExpr.clone(), shiftOp), maskExpr, bitwiseOp))
} }

@ -4,6 +4,7 @@ import com.github.javaparser.ast.CompilationUnit
import com.github.javaparser.ast.expr.BinaryExpr import com.github.javaparser.ast.expr.BinaryExpr
import com.github.javaparser.ast.expr.Expression import com.github.javaparser.ast.expr.Expression
import com.github.javaparser.ast.expr.IntegerLiteralExpr import com.github.javaparser.ast.expr.IntegerLiteralExpr
import com.github.javaparser.ast.expr.LongLiteralExpr
import com.github.javaparser.ast.expr.UnaryExpr import com.github.javaparser.ast.expr.UnaryExpr
import dev.openrs2.deob.ast.Library import dev.openrs2.deob.ast.Library
import dev.openrs2.deob.ast.LibraryGroup import dev.openrs2.deob.ast.LibraryGroup
@ -34,7 +35,7 @@ class ComplementTransformer : Transformer() {
private companion object { private companion object {
private fun Expression.isComplement(): Boolean { private fun Expression.isComplement(): Boolean {
return isUnaryExpr && asUnaryExpr().operator == UnaryExpr.Operator.BITWISE_COMPLEMENT return this is UnaryExpr && operator == UnaryExpr.Operator.BITWISE_COMPLEMENT
} }
private fun Expression.isComplementOrLiteral(): Boolean { private fun Expression.isComplementOrLiteral(): Boolean {
@ -53,10 +54,10 @@ class ComplementTransformer : Transformer() {
} }
private fun Expression.complement(): Expression { private fun Expression.complement(): Expression {
return when { return when (this) {
isUnaryExpr -> asUnaryExpr().expression is UnaryExpr -> expression
isIntegerLiteralExpr -> IntegerLiteralExpr(asIntegerLiteralExpr().checkedAsInt().inv().toString()) is IntegerLiteralExpr -> IntegerLiteralExpr(checkedAsInt().inv().toString())
isLongLiteralExpr -> asLongLiteralExpr().checkedAsLong().inv().toLongLiteralExpr() is LongLiteralExpr -> checkedAsLong().inv().toLongLiteralExpr()
else -> throw IllegalArgumentException() else -> throw IllegalArgumentException()
} }
} }

@ -1,9 +1,19 @@
package dev.openrs2.deob.ast.transform package dev.openrs2.deob.ast.transform
import com.github.javaparser.ast.CompilationUnit import com.github.javaparser.ast.CompilationUnit
import com.github.javaparser.ast.expr.ArrayAccessExpr
import com.github.javaparser.ast.expr.ArrayCreationExpr
import com.github.javaparser.ast.expr.AssignExpr
import com.github.javaparser.ast.expr.BinaryExpr import com.github.javaparser.ast.expr.BinaryExpr
import com.github.javaparser.ast.expr.CastExpr
import com.github.javaparser.ast.expr.ConditionalExpr
import com.github.javaparser.ast.expr.EnclosedExpr import com.github.javaparser.ast.expr.EnclosedExpr
import com.github.javaparser.ast.expr.Expression import com.github.javaparser.ast.expr.Expression
import com.github.javaparser.ast.expr.FieldAccessExpr
import com.github.javaparser.ast.expr.InstanceOfExpr
import com.github.javaparser.ast.expr.MethodCallExpr
import com.github.javaparser.ast.expr.ObjectCreationExpr
import com.github.javaparser.ast.expr.UnaryExpr
import dev.openrs2.deob.ast.Library import dev.openrs2.deob.ast.Library
import dev.openrs2.deob.ast.LibraryGroup import dev.openrs2.deob.ast.LibraryGroup
import dev.openrs2.deob.ast.util.walk import dev.openrs2.deob.ast.util.walk
@ -45,12 +55,12 @@ class EncloseTransformer : Transformer() {
companion object { companion object {
fun from(expr: Expression): Op? { fun from(expr: Expression): Op? {
return when { return when (expr) {
expr.isArrayAccessExpr || expr.isFieldAccessExpr -> ACCESS_PARENS is ArrayAccessExpr, is FieldAccessExpr -> ACCESS_PARENS
expr.isMethodCallExpr || expr.isEnclosedExpr -> ACCESS_PARENS is MethodCallExpr, is EnclosedExpr -> ACCESS_PARENS
expr.isUnaryExpr -> if (expr.asUnaryExpr().operator.isPostfix) POSTFIX else UNARY is UnaryExpr -> if (expr.operator.isPostfix) POSTFIX else UNARY
expr.isCastExpr || expr.isObjectCreationExpr || expr.isArrayCreationExpr -> CAST_NEW is CastExpr, is ObjectCreationExpr, is ArrayCreationExpr -> CAST_NEW
expr.isBinaryExpr -> when (expr.asBinaryExpr().operator) { is BinaryExpr -> when (expr.operator) {
BinaryExpr.Operator.MULTIPLY -> MULTIPLICATIVE BinaryExpr.Operator.MULTIPLY -> MULTIPLICATIVE
BinaryExpr.Operator.DIVIDE, BinaryExpr.Operator.REMAINDER -> MULTIPLICATIVE BinaryExpr.Operator.DIVIDE, BinaryExpr.Operator.REMAINDER -> MULTIPLICATIVE
BinaryExpr.Operator.PLUS, BinaryExpr.Operator.MINUS -> ADDITIVE BinaryExpr.Operator.PLUS, BinaryExpr.Operator.MINUS -> ADDITIVE
@ -66,9 +76,9 @@ class EncloseTransformer : Transformer() {
BinaryExpr.Operator.OR -> LOGICAL_OR BinaryExpr.Operator.OR -> LOGICAL_OR
else -> null else -> null
} }
expr.isInstanceOfExpr -> RELATIONAL is InstanceOfExpr -> RELATIONAL
expr.isConditionalExpr -> TERNARY is ConditionalExpr -> TERNARY
expr.isAssignExpr -> ASSIGNMENT is AssignExpr -> ASSIGNMENT
else -> null else -> null
} }
} }
@ -77,49 +87,34 @@ class EncloseTransformer : Transformer() {
override fun transformUnit(group: LibraryGroup, library: Library, unit: CompilationUnit) { override fun transformUnit(group: LibraryGroup, library: Library, unit: CompilationUnit) {
unit.walk { expr: Expression -> unit.walk { expr: Expression ->
when { when (expr) {
expr.isArrayAccessExpr -> { is ArrayAccessExpr -> encloseLeft(expr, expr.name)
val accessExpr = expr.asArrayAccessExpr() is FieldAccessExpr -> encloseLeft(expr, expr.scope)
encloseLeft(expr, accessExpr.name) is MethodCallExpr -> {
} expr.scope.ifPresent { scope ->
expr.isFieldAccessExpr -> {
encloseLeft(expr, expr.asFieldAccessExpr().scope)
}
expr.isMethodCallExpr -> {
expr.asMethodCallExpr().scope.ifPresent { scope ->
encloseLeft(expr, scope) encloseLeft(expr, scope)
} }
} }
expr.isUnaryExpr -> { is UnaryExpr -> encloseRight(expr, expr.expression)
val unaryExpr = expr.asUnaryExpr() is CastExpr -> encloseRight(expr, expr.expression)
encloseRight(expr, unaryExpr.expression) is ObjectCreationExpr -> {
} expr.scope.ifPresent { scope ->
expr.isCastExpr -> {
encloseRight(expr, expr.asCastExpr().expression)
}
expr.isObjectCreationExpr -> {
expr.asObjectCreationExpr().scope.ifPresent { scope ->
encloseLeft(expr, scope) encloseLeft(expr, scope)
} }
} }
expr.isBinaryExpr -> { is BinaryExpr -> {
val binaryExpr = expr.asBinaryExpr() encloseLeft(expr, expr.left)
encloseLeft(expr, binaryExpr.left) encloseRight(expr, expr.right)
encloseRight(expr, binaryExpr.right)
}
expr.isInstanceOfExpr -> {
encloseLeft(expr, expr.asInstanceOfExpr().expression)
} }
expr.isConditionalExpr -> { is InstanceOfExpr -> encloseLeft(expr, expr.expression)
val conditionalExpr = expr.asConditionalExpr() is ConditionalExpr -> {
encloseLeft(expr, conditionalExpr.condition) encloseLeft(expr, expr.condition)
encloseLeft(expr, conditionalExpr.thenExpr) encloseLeft(expr, expr.thenExpr)
encloseRight(expr, conditionalExpr.elseExpr) encloseRight(expr, expr.elseExpr)
} }
expr.isAssignExpr -> { is AssignExpr -> {
val assignExpr = expr.asAssignExpr() encloseLeft(expr, expr.target)
encloseLeft(expr, assignExpr.target) encloseRight(expr, expr.value)
encloseRight(expr, assignExpr.value)
} }
} }
} }

@ -23,13 +23,10 @@ class ForLoopConditionTransformer : Transformer() {
unit.walk { stmt: ForStmt -> unit.walk { stmt: ForStmt ->
val updatedExprs = stmt.update.mapNotNull { it.getUpdatedExpr() } val updatedExprs = stmt.update.mapNotNull { it.getUpdatedExpr() }
stmt.compare.ifPresent { compare -> stmt.compare.ifPresent { expr ->
if (!compare.isBinaryExpr) { if (expr !is BinaryExpr) {
return@ifPresent return@ifPresent
} } else if (expr.hasSideEffects()) {
val expr = compare.asBinaryExpr()
if (expr.hasSideEffects()) {
return@ifPresent return@ifPresent
} }

@ -9,13 +9,17 @@ import com.github.javaparser.ast.body.Parameter
import com.github.javaparser.ast.body.TypeDeclaration import com.github.javaparser.ast.body.TypeDeclaration
import com.github.javaparser.ast.body.VariableDeclarator import com.github.javaparser.ast.body.VariableDeclarator
import com.github.javaparser.ast.expr.BinaryExpr import com.github.javaparser.ast.expr.BinaryExpr
import com.github.javaparser.ast.expr.ConditionalExpr
import com.github.javaparser.ast.expr.Expression import com.github.javaparser.ast.expr.Expression
import com.github.javaparser.ast.expr.FieldAccessExpr import com.github.javaparser.ast.expr.FieldAccessExpr
import com.github.javaparser.ast.expr.IntegerLiteralExpr
import com.github.javaparser.ast.expr.MethodCallExpr import com.github.javaparser.ast.expr.MethodCallExpr
import com.github.javaparser.ast.expr.NameExpr import com.github.javaparser.ast.expr.NameExpr
import com.github.javaparser.ast.expr.SimpleName import com.github.javaparser.ast.expr.SimpleName
import com.github.javaparser.ast.type.PrimitiveType import com.github.javaparser.ast.type.PrimitiveType
import com.github.javaparser.resolution.types.ResolvedArrayType
import com.github.javaparser.resolution.types.ResolvedPrimitiveType import com.github.javaparser.resolution.types.ResolvedPrimitiveType
import com.github.javaparser.resolution.types.ResolvedReferenceType
import com.github.javaparser.resolution.types.ResolvedType import com.github.javaparser.resolution.types.ResolvedType
import com.github.michaelbull.logging.InlineLogger import com.github.michaelbull.logging.InlineLogger
import dev.openrs2.deob.ast.Library import dev.openrs2.deob.ast.Library
@ -65,11 +69,11 @@ class GlTransformer @Inject constructor(private val registry: GlRegistry) : Tran
} }
private fun transformFramebufferStatus(unit: CompilationUnit, expr: Expression) { private fun transformFramebufferStatus(unit: CompilationUnit, expr: Expression) {
if (!expr.isIntegerLiteralExpr) { if (expr !is IntegerLiteralExpr) {
return return
} }
val value = expr.asIntegerLiteralExpr().checkedAsInt() val value = expr.checkedAsInt()
if (value.toLong() != GL_FRAMEBUFFER_COMPLETE.value) { if (value.toLong() != GL_FRAMEBUFFER_COMPLETE.value) {
return return
} }
@ -92,8 +96,8 @@ class GlTransformer @Inject constructor(private val registry: GlRegistry) : Tran
private fun ResolvedType.isFollowedByOffset(): Boolean { private fun ResolvedType.isFollowedByOffset(): Boolean {
return when { return when {
isArray && asArrayType().componentType.isPrimitive -> true this is ResolvedArrayType && componentType.isPrimitive -> true
isReferenceType && asReferenceType().qualifiedName == "java.lang.Object" -> true this is ResolvedReferenceType && qualifiedName == "java.lang.Object" -> true
else -> false else -> false
} }
} }
@ -164,11 +168,11 @@ class GlTransformer @Inject constructor(private val registry: GlRegistry) : Tran
expr.scope.ifPresent { scope -> expr.scope.ifPresent { scope ->
val type = scope.calculateResolvedType() val type = scope.calculateResolvedType()
if (!type.isReferenceType) { if (type !is ResolvedReferenceType) {
return@ifPresent return@ifPresent
} }
val name = type.asReferenceType().qualifiedName val name = type.qualifiedName
if (name in GL_CLASSES) { if (name in GL_CLASSES) {
transformArguments(unit, expr) transformArguments(unit, expr)
} }
@ -235,26 +239,28 @@ class GlTransformer @Inject constructor(private val registry: GlRegistry) : Tran
parameter: GlParameter, parameter: GlParameter,
expr: Expression expr: Expression
) { ) {
if (expr.isBinaryExpr) { when (expr) {
val binaryExpr = expr.asBinaryExpr() is BinaryExpr -> {
transformExpr(unit, command, parameter, binaryExpr.left) transformExpr(unit, command, parameter, expr.left)
transformExpr(unit, command, parameter, binaryExpr.right) transformExpr(unit, command, parameter, expr.right)
} else if (expr.isConditionalExpr) { }
val conditionalExpr = expr.asConditionalExpr() is ConditionalExpr -> {
transformExpr(unit, command, parameter, conditionalExpr.thenExpr) transformExpr(unit, command, parameter, expr.thenExpr)
transformExpr(unit, command, parameter, conditionalExpr.elseExpr) transformExpr(unit, command, parameter, expr.elseExpr)
} else if (expr.isIntegerLiteralExpr) { }
is IntegerLiteralExpr -> {
transformIntegerLiteralExpr(unit, command, parameter, expr) transformIntegerLiteralExpr(unit, command, parameter, expr)
} }
} }
}
private fun transformIntegerLiteralExpr( private fun transformIntegerLiteralExpr(
unit: CompilationUnit, unit: CompilationUnit,
command: GlCommand, command: GlCommand,
parameter: GlParameter, parameter: GlParameter,
expr: Expression expr: IntegerLiteralExpr
) { ) {
var value = expr.asIntegerLiteralExpr().checkedAsInt() var value = expr.checkedAsInt()
val group = parameter.group ?: return val group = parameter.group ?: return
if (parameter.bitfield) { if (parameter.bitfield) {
@ -320,21 +326,21 @@ class GlTransformer @Inject constructor(private val registry: GlRegistry) : Tran
private val FIELD_METHOD_COMPARATOR = Comparator<BodyDeclaration<*>> { a, b -> private val FIELD_METHOD_COMPARATOR = Comparator<BodyDeclaration<*>> { a, b ->
when { when {
a.isFieldDeclaration && !b.isFieldDeclaration -> -1 a is FieldDeclaration && b !is FieldDeclaration -> -1
!a.isFieldDeclaration && b.isFieldDeclaration -> 1 a !is FieldDeclaration && b is FieldDeclaration -> 1
else -> 0 else -> 0
} }
} }
private fun BodyDeclaration<*>.getIntValue(): Int? { private fun BodyDeclaration<*>.getIntValue(): Int? {
if (!isFieldDeclaration) { if (this !is FieldDeclaration) {
return null return null
} }
val variable = asFieldDeclaration().variables.firstOrNull() ?: return null val variable = variables.firstOrNull() ?: return null
return variable.initializer.map { return variable.initializer.map {
if (it.isIntegerLiteralExpr) { if (it is IntegerLiteralExpr) {
it.asIntegerLiteralExpr().checkedAsInt() it.checkedAsInt()
} else { } else {
null null
} }

@ -3,6 +3,8 @@ package dev.openrs2.deob.ast.transform
import com.github.javaparser.ast.CompilationUnit import com.github.javaparser.ast.CompilationUnit
import com.github.javaparser.ast.expr.BinaryExpr import com.github.javaparser.ast.expr.BinaryExpr
import com.github.javaparser.ast.expr.Expression 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 import com.github.javaparser.ast.expr.UnaryExpr
import dev.openrs2.deob.ast.Library import dev.openrs2.deob.ast.Library
import dev.openrs2.deob.ast.LibraryGroup import dev.openrs2.deob.ast.LibraryGroup
@ -47,17 +49,17 @@ class IdentityTransformer : Transformer() {
} }
private fun Expression.isZero(): Boolean { private fun Expression.isZero(): Boolean {
return when { return when (this) {
isIntegerLiteralExpr -> asIntegerLiteralExpr().asNumber() == 0 is IntegerLiteralExpr -> asNumber() == 0
isLongLiteralExpr -> asLongLiteralExpr().asNumber() == 0L is LongLiteralExpr -> asNumber() == 0L
else -> false else -> false
} }
} }
private fun Expression.isOne(): Boolean { private fun Expression.isOne(): Boolean {
return when { return when (this) {
isIntegerLiteralExpr -> asIntegerLiteralExpr().asNumber() == 1 is IntegerLiteralExpr -> asNumber() == 1
isLongLiteralExpr -> asLongLiteralExpr().asNumber() == 1L is LongLiteralExpr -> asNumber() == 1L
else -> false else -> false
} }
} }

@ -7,6 +7,7 @@ import com.github.javaparser.ast.stmt.BlockStmt
import com.github.javaparser.ast.stmt.IfStmt import com.github.javaparser.ast.stmt.IfStmt
import com.github.javaparser.ast.stmt.ReturnStmt import com.github.javaparser.ast.stmt.ReturnStmt
import com.github.javaparser.ast.stmt.Statement import com.github.javaparser.ast.stmt.Statement
import com.github.javaparser.ast.stmt.ThrowStmt
import dev.openrs2.deob.ast.Library import dev.openrs2.deob.ast.Library
import dev.openrs2.deob.ast.LibraryGroup import dev.openrs2.deob.ast.LibraryGroup
import dev.openrs2.deob.ast.util.countNots import dev.openrs2.deob.ast.util.countNots
@ -78,7 +79,7 @@ class IfElseTransformer : Transformer() {
val notCondition = condition.not() val notCondition = condition.not()
if (notCondition.countNots() < condition.countNots()) { if (notCondition.countNots() < condition.countNots()) {
stmt.condition = notCondition stmt.condition = notCondition
if (elseStmt.isIfStmt) { if (elseStmt is IfStmt) {
val block = BlockStmt() val block = BlockStmt()
block.statements.add(elseStmt.clone()) block.statements.add(elseStmt.clone())
stmt.thenStmt = block stmt.thenStmt = block
@ -136,23 +137,19 @@ class IfElseTransformer : Transformer() {
unit.walk { stmt: IfStmt -> unit.walk { stmt: IfStmt ->
stmt.elseStmt.ifPresent { elseStmt -> stmt.elseStmt.ifPresent { elseStmt ->
// match // match
if (!elseStmt.isBlockStmt) { if (elseStmt !is BlockStmt) {
return@ifPresent return@ifPresent
} }
val blockStmt = elseStmt.asBlockStmt() val statements = elseStmt.statements
val statements = blockStmt.statements
if (statements.isEmpty()) { if (statements.isEmpty()) {
return@ifPresent return@ifPresent
} }
val head = statements[0] val ifStmt = statements[0]
if (!head.isIfStmt) { if (ifStmt !is IfStmt) {
return@ifPresent return@ifPresent
} } else if (ifStmt.elseStmt.isPresent) {
val ifStmt = head.asIfStmt()
if (ifStmt.elseStmt.isPresent) {
return@ifPresent return@ifPresent
} }
@ -164,7 +161,7 @@ class IfElseTransformer : Transformer() {
// rewrite // rewrite
val condition = ifStmt.condition.not() val condition = ifStmt.condition.not()
val tail = blockStmt.clone() val tail = elseStmt.clone()
tail.statements.removeAt(0) tail.statements.removeAt(0)
elseStmt.replace(IfStmt(condition, tail, thenStmt.clone())) elseStmt.replace(IfStmt(condition, tail, thenStmt.clone()))
@ -213,44 +210,47 @@ class IfElseTransformer : Transformer() {
} }
private fun Statement.isIf(): Boolean { private fun Statement.isIf(): Boolean {
return when { return when (this) {
isIfStmt -> true is IfStmt -> true
isBlockStmt -> { is BlockStmt -> {
val stmts = asBlockStmt().statements val stmts = statements
stmts.size == 1 && stmts[0].isIfStmt stmts.size == 1 && stmts[0] is IfStmt
} }
else -> false else -> false
} }
} }
private fun Statement.getIf(): Statement { private fun Statement.getIf(): Statement {
if (isIfStmt) { when (this) {
is IfStmt -> {
return clone() return clone()
} else if (isBlockStmt) { }
val stmts = asBlockStmt().statements is BlockStmt -> {
val stmts = statements
if (stmts.size == 1) { if (stmts.size == 1) {
val head = stmts[0] val head = stmts[0]
if (head.isIfStmt) { if (head is IfStmt) {
return head.clone() return head.clone()
} }
} }
} }
}
throw IllegalArgumentException() throw IllegalArgumentException()
} }
private fun Statement.isTailThrowOrReturn(): Boolean { private fun Statement.isTailThrowOrReturn(): Boolean {
return if (isThrowStmt || isReturnStmt) { return when (this) {
true is ThrowStmt, is ReturnStmt -> true
} else if (isBlockStmt) { is BlockStmt -> {
val stmts = asBlockStmt().statements val stmts = statements
if (stmts.isEmpty()) { if (stmts.isEmpty()) {
return false return false
} }
val tail = stmts[stmts.size - 1] val tail = stmts[stmts.size - 1]
tail.isThrowStmt || tail.isReturnStmt tail is ThrowStmt || tail is ReturnStmt
} else { }
false else -> false
} }
} }
} }

@ -13,22 +13,21 @@ import javax.inject.Singleton
class IncrementTransformer : Transformer() { class IncrementTransformer : Transformer() {
override fun transformUnit(group: LibraryGroup, library: Library, unit: CompilationUnit) { override fun transformUnit(group: LibraryGroup, library: Library, unit: CompilationUnit) {
unit.walk { stmt: ExpressionStmt -> unit.walk { stmt: ExpressionStmt ->
if (!stmt.expression.isUnaryExpr) { val expr = stmt.expression
if (expr !is UnaryExpr) {
return@walk return@walk
} }
val unaryExpr = stmt.expression.asUnaryExpr() expr.operator = expr.operator.toPostfix()
unaryExpr.operator = unaryExpr.operator.toPostfix()
} }
unit.walk { stmt: ForStmt -> unit.walk { stmt: ForStmt ->
for (expr in stmt.update) { for (expr in stmt.update) {
if (!expr.isUnaryExpr) { if (expr !is UnaryExpr) {
continue continue
} }
val unaryExpr = expr.asUnaryExpr() expr.operator = expr.operator.toPostfix()
unaryExpr.operator = unaryExpr.operator.toPostfix()
} }
} }
} }

@ -37,7 +37,7 @@ fun Long.toHexLiteralExpr(): LongLiteralExpr {
} }
fun Expression.isIntegerOrLongLiteral(): Boolean { fun Expression.isIntegerOrLongLiteral(): Boolean {
return isIntegerLiteralExpr || isLongLiteralExpr return this is IntegerLiteralExpr || this is LongLiteralExpr
} }
fun Long.toLongLiteralExpr(): LongLiteralExpr { fun Long.toLongLiteralExpr(): LongLiteralExpr {
@ -66,19 +66,15 @@ fun Expression.negate(): Expression {
} }
fun Expression.not(): Expression { fun Expression.not(): Expression {
if (isUnaryExpr) { when (this) {
val unary = asUnaryExpr() is UnaryExpr -> {
if (unary.operator == UnaryExpr.Operator.LOGICAL_COMPLEMENT) { if (operator == UnaryExpr.Operator.LOGICAL_COMPLEMENT) {
return unary.expression.clone() return expression.clone()
} }
} else if (isBinaryExpr) { }
val binary = asBinaryExpr() is BinaryExpr -> {
val left = binary.left
val right = binary.right
@Suppress("NON_EXHAUSTIVE_WHEN") @Suppress("NON_EXHAUSTIVE_WHEN")
when (binary.operator) { when (operator) {
BinaryExpr.Operator.EQUALS -> BinaryExpr.Operator.EQUALS ->
return BinaryExpr(left.clone(), right.clone(), BinaryExpr.Operator.NOT_EQUALS) return BinaryExpr(left.clone(), right.clone(), BinaryExpr.Operator.NOT_EQUALS)
BinaryExpr.Operator.NOT_EQUALS -> BinaryExpr.Operator.NOT_EQUALS ->
@ -96,18 +92,19 @@ fun Expression.not(): Expression {
BinaryExpr.Operator.OR -> BinaryExpr.Operator.OR ->
return BinaryExpr(left.not(), right.not(), BinaryExpr.Operator.AND) return BinaryExpr(left.not(), right.not(), BinaryExpr.Operator.AND)
} }
} else if (isBooleanLiteralExpr) {
return BooleanLiteralExpr(!asBooleanLiteralExpr().value)
} }
is BooleanLiteralExpr -> return BooleanLiteralExpr(!value)
}
return UnaryExpr(clone(), UnaryExpr.Operator.LOGICAL_COMPLEMENT) return UnaryExpr(clone(), UnaryExpr.Operator.LOGICAL_COMPLEMENT)
} }
fun Expression.countNots(): Int { fun Expression.countNots(): Int {
var count = 0 var count = 0
if (isUnaryExpr && asUnaryExpr().operator == UnaryExpr.Operator.LOGICAL_COMPLEMENT) { if (this is UnaryExpr && operator == UnaryExpr.Operator.LOGICAL_COMPLEMENT) {
count++ count++
} else if (isBinaryExpr && asBinaryExpr().operator == BinaryExpr.Operator.NOT_EQUALS) { } else if (this is BinaryExpr && operator == BinaryExpr.Operator.NOT_EQUALS) {
count++ count++
} }

Loading…
Cancel
Save