From 3ccab60f43eba6f4307bc9e51955a637fb5e8760 Mon Sep 17 00:00:00 2001 From: Skylot Date: Sun, 9 Mar 2014 19:13:49 +0400 Subject: [PATCH] core: remove redundant parenthesis for arithmetic operations --- .../main/java/jadx/core/codegen/InsnGen.java | 25 ++++++-------- .../core/dex/attributes/AttributeFlag.java | 1 + .../core/dex/visitors/PrepareForCodeGen.java | 34 +++++++++++++++++++ .../jadx/tests/internal/arith/TestArith2.java | 7 ++++ 4 files changed, 53 insertions(+), 14 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java index 580f5b8f1..ac4070fff 100644 --- a/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java +++ b/jadx-core/src/main/java/jadx/core/codegen/InsnGen.java @@ -720,22 +720,19 @@ public class InsnGen { } private void makeArith(ArithNode insn, CodeWriter code, EnumSet state) throws CodegenException { - ArithOp op = insn.getOp(); - if (state.contains(Flags.BODY_ONLY)) { - // wrap insn in brackets for save correct operation order + // wrap insn in brackets for save correct operation order + boolean wrap = state.contains(Flags.BODY_ONLY) + && !insn.getAttributes().contains(AttributeFlag.DONT_WRAP); + if (wrap) { code.add('('); - addArg(code, insn.getArg(0)); - code.add(' '); - code.add(op.getSymbol()); - code.add(' '); - addArg(code, insn.getArg(1)); + } + addArg(code, insn.getArg(0)); + code.add(' '); + code.add(insn.getOp().getSymbol()); + code.add(' '); + addArg(code, insn.getArg(1)); + if (wrap) { code.add(')'); - } else { - addArg(code, insn.getArg(0)); - code.add(' '); - code.add(op.getSymbol()); - code.add(' '); - addArg(code, insn.getArg(1)); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/attributes/AttributeFlag.java b/jadx-core/src/main/java/jadx/core/dex/attributes/AttributeFlag.java index 0bbc8de3d..23f17bd17 100644 --- a/jadx-core/src/main/java/jadx/core/dex/attributes/AttributeFlag.java +++ b/jadx-core/src/main/java/jadx/core/dex/attributes/AttributeFlag.java @@ -13,6 +13,7 @@ public enum AttributeFlag { RETURN, // block contains only return instruction DECLARE_VAR, + DONT_WRAP, DONT_SHRINK, DONT_GENERATE, 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 12fadd159..ba8bd1644 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 @@ -1,8 +1,11 @@ package jadx.core.dex.visitors; +import jadx.core.dex.attributes.AttributeFlag; import jadx.core.dex.instructions.ArithNode; +import jadx.core.dex.instructions.ArithOp; import jadx.core.dex.instructions.InsnType; 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.nodes.BlockNode; @@ -23,6 +26,7 @@ public class PrepareForCodeGen extends AbstractVisitor { } for (BlockNode block : blocks) { removeInstructions(block); + removeBrackets(block); modifyArith(block); } } @@ -48,6 +52,36 @@ public class PrepareForCodeGen extends AbstractVisitor { } } + private static void removeBrackets(BlockNode block) { + for (InsnNode insn : block.getInstructions()) { + checkInsn(insn); + } + } + + private static void checkInsn(InsnNode insn) { + if (insn.getType() == InsnType.ARITH) { + ArithNode arith = (ArithNode) insn; + ArithOp op = arith.getOp(); + if (op == ArithOp.ADD || op == ArithOp.SUB) { + for (int i = 0; i < 2; i++) { + InsnArg arg = arith.getArg(i); + if (arg.isInsnWrap()) { + InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn(); + wrapInsn.getAttributes().add(AttributeFlag.DONT_WRAP); + checkInsn(wrapInsn); + } + } + } + } else { + for (InsnArg arg : insn.getArguments()) { + if (arg.isInsnWrap()) { + InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn(); + checkInsn(wrapInsn); + } + } + } + } + private static void modifyArith(BlockNode block) { List list = block.getInstructions(); for (int i = 0; i < list.size(); i++) { diff --git a/jadx-core/src/test/java/jadx/tests/internal/arith/TestArith2.java b/jadx-core/src/test/java/jadx/tests/internal/arith/TestArith2.java index ec159a6ce..90ae2ae24 100644 --- a/jadx-core/src/test/java/jadx/tests/internal/arith/TestArith2.java +++ b/jadx-core/src/test/java/jadx/tests/internal/arith/TestArith2.java @@ -16,6 +16,10 @@ public class TestArith2 extends InternalJadxTest { public int test1(int a) { return (a + 2) * 3; } + + public int test2(int a, int b, int c) { + return a + b + c; + } } @Test @@ -26,5 +30,8 @@ public class TestArith2 extends InternalJadxTest { assertThat(code, containsString("return (a + 2) * 3;")); assertThat(code, not(containsString("a + 2 * 3"))); + + assertThat(code, containsString("return a + b + c;")); + assertThat(code, not(containsString("return (a + b) + c;"))); } }