diff --git a/jadx-core/src/main/java/jadx/core/codegen/ConditionGen.java b/jadx-core/src/main/java/jadx/core/codegen/ConditionGen.java index ec0f30d9e88bf87ff91172041c279c5fda5131c0..f13f72152674d844249f29e3f57c0fb746ec8818 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/ConditionGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/ConditionGen.java @@ -4,6 +4,7 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.Queue; +import jadx.core.dex.attributes.AFlag; import jadx.core.dex.instructions.ArithNode; import jadx.core.dex.instructions.IfOp; import jadx.core.dex.instructions.InsnType; @@ -155,7 +156,7 @@ public class ConditionGen extends InsnGen { } private boolean isWrapNeeded(IfCondition condition) { - if (condition.isCompare()) { + if (condition.isCompare() || condition.contains(AFlag.DONT_WRAP)) { return false; } return condition.getMode() != Mode.NOT; diff --git a/jadx-core/src/main/java/jadx/core/dex/regions/conditions/IfCondition.java b/jadx-core/src/main/java/jadx/core/dex/regions/conditions/IfCondition.java index 8d58aad333ace333ab2063cf6839f28d49f99f91..ff859114e47abdaca1c3cda66fbd14585b51164e 100644 --- a/jadx-core/src/main/java/jadx/core/dex/regions/conditions/IfCondition.java +++ b/jadx-core/src/main/java/jadx/core/dex/regions/conditions/IfCondition.java @@ -8,6 +8,9 @@ import java.util.LinkedList; import java.util.List; import java.util.Objects; +import jadx.core.dex.attributes.AFlag; +import jadx.core.dex.attributes.AttributeStorage; +import jadx.core.dex.attributes.EmptyAttrStorage; import jadx.core.dex.instructions.ArithNode; import jadx.core.dex.instructions.ArithOp; import jadx.core.dex.instructions.IfNode; @@ -31,6 +34,10 @@ public final class IfCondition { OR } + private static final AttributeStorage EMPTY_ATTR_STORAGE = new EmptyAttrStorage(); + + private AttributeStorage storage = EMPTY_ATTR_STORAGE; + private final Mode mode; private final List args; private final Compare compare; @@ -262,6 +269,23 @@ public final class IfCondition { return list; } + public void add(AFlag flag) { + initStorage().add(flag); + } + + public boolean contains(AFlag flag) { + return storage.contains(flag); + } + + private AttributeStorage initStorage() { + AttributeStorage store = storage; + if (store == EMPTY_ATTR_STORAGE) { + store = new AttributeStorage(); + storage = store; + } + return store; + } + @Override public String toString() { switch (mode) { diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java b/jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java index 02b7b9d9fc1cc27f2f67ac87fd4d903ee7edda21..bf8e2ce9ac64eaa720046e868a71bc89a7d687c5 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/PrepareForCodeGen.java @@ -11,9 +11,12 @@ import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.InsnWrapArg; import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.instructions.mods.ConstructorInsn; +import jadx.core.dex.instructions.mods.TernaryInsn; import jadx.core.dex.nodes.BlockNode; import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.MethodNode; +import jadx.core.dex.regions.conditions.IfCondition; +import jadx.core.dex.regions.conditions.IfCondition.Mode; import jadx.core.dex.visitors.regions.variables.ProcessVariables; import jadx.core.dex.visitors.shrink.CodeShrinkVisitor; import jadx.core.utils.exceptions.JadxException; @@ -104,7 +107,7 @@ public class PrepareForCodeGen extends AbstractVisitor { } /** - * Remove parenthesis for wrapped insn in arith '+' or '-' + * Remove parenthesis for wrapped insn in arith '+' or '-' * ('(a + b) +c' => 'a + b + c') */ private static void removeParenthesis(InsnNode insn) { @@ -124,6 +127,9 @@ public class PrepareForCodeGen extends AbstractVisitor { } } } else { + if (insn.getType() == InsnType.TERNARY) { + removeParenthesis(((TernaryInsn) insn).getCondition()); + } for (InsnArg arg : insn.getArguments()) { if (arg.isInsnWrap()) { InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn(); @@ -133,6 +139,15 @@ public class PrepareForCodeGen extends AbstractVisitor { } } + private static void removeParenthesis(IfCondition cond) { + Mode mode = cond.getMode(); + for (IfCondition c : cond.getArgs()) { + if (c.getMode() == mode) { + c.add(AFlag.DONT_WRAP); + } + } + } + /** * Replace arithmetic operation with short form * ('a = a + 2' => 'a += 2') diff --git a/jadx-core/src/test/java/jadx/tests/integration/conditions/TestConditions16.java b/jadx-core/src/test/java/jadx/tests/integration/conditions/TestConditions16.java index daf98be022ed288a9df40844bacb7f180b31a841..8bea89d55583d261517475dcfc0ef303926fa51d 100644 --- a/jadx-core/src/test/java/jadx/tests/integration/conditions/TestConditions16.java +++ b/jadx-core/src/test/java/jadx/tests/integration/conditions/TestConditions16.java @@ -2,7 +2,6 @@ package jadx.tests.integration.conditions; import org.junit.jupiter.api.Test; -import jadx.NotYetImplemented; import jadx.core.dex.nodes.ClassNode; import jadx.tests.api.IntegrationTest; @@ -27,19 +26,10 @@ public class TestConditions16 extends IntegrationTest { } @Test - @NotYetImplemented public void test() { ClassNode cls = getClassNode(TestCls.class); String code = cls.getCode().toString(); assertThat(code, containsOne("return a < 0 || (b % 2 != 0 && a > 28) || b < 0;")); } - - @Test - public void test2() { - ClassNode cls = getClassNode(TestCls.class); - String code = cls.getCode().toString(); - - assertThat(code, containsOne("return a < 0 || ((b % 2 != 0 && a > 28) || b < 0);")); - } }