diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java index 28b76e9..0be7d59 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/SimplifyExprentsHelper.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2015 JetBrains s.r.o. + * Copyright 2000-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -854,6 +854,11 @@ public class SimplifyExprentsHelper { return false; } + // avoid flattening to 'iff' if any of the branches is an 'iff' already + if (isIff(ifex.getValue()) || isIff(elseex.getValue())) { + return false; + } + List data = new ArrayList<>(); data.addAll(stif.getFirst().getExprents()); @@ -880,6 +885,10 @@ public class SimplifyExprentsHelper { return false; } + private static boolean isIff(Exprent exp) { + return exp.type == Exprent.EXPRENT_FUNCTION && ((FunctionExprent) exp).getFuncType() == FunctionExprent.FUNCTION_IIF; + } + static { class14Builder.parse( "statement type:if iftype:if exprsize:-1\n" + diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 2388d8d..1c2779c 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -93,6 +93,7 @@ public class SingleClassesTest { @Test public void testExtendingSubclass() { doTest("pkg/TestExtendingSubclass"); } @Test public void testSyntheticAccess() { doTest("pkg/TestSyntheticAccess"); } @Test public void testIllegalVarName() { doTest("pkg/TestIllegalVarName"); } + @Test public void testIffSimplification() { doTest("pkg/TestIffSimplification"); } @Test public void testKotlinConstructor() { doTest("pkg/TestKotlinConstructorKt"); } @Test public void testAsserts() { doTest("pkg/TestAsserts"); } @Test public void testLocalsNames() { doTest("pkg/TestLocalsNames"); } diff --git a/testData/classes/pkg/TestIffSimplification.class b/testData/classes/pkg/TestIffSimplification.class new file mode 100644 index 0000000..6dcb9b1 Binary files /dev/null and b/testData/classes/pkg/TestIffSimplification.class differ diff --git a/testData/results/TestIffSimplification.dec b/testData/results/TestIffSimplification.dec new file mode 100644 index 0000000..26940dc --- /dev/null +++ b/testData/results/TestIffSimplification.dec @@ -0,0 +1,107 @@ +package pkg; + +public class TestIffSimplification { + public int simpleIff(boolean status, int[] values) { + return status?values[0]:values[1];// 7 + } + + public int simpleIf(boolean status, int[] values) { + return status?values[0]:values[1];// 11 12 15 + } + + public int nestedIf(boolean status, boolean condition, int[] values) { + if(status) {// 20 + return condition?values[2]:values[0];// 21 22 25 + } else { + return values[1];// 29 + } + } + + public int compareTo(int mc1, int mc2, byte csg1, byte csg2, double score1, double score2, int doc1, int doc2) { + if(mc1 != mc2) {// 34 + return mc1 < mc2?1:-1;// 35 + } else if(csg1 != csg2) {// 38 + return csg1 < csg2?1:-1;// 39 + } else if(Math.abs(score1 - score2) < 1.0E-6D) {// 42 + return doc1 < doc2?-1:1;// 43 + } else { + return score1 < score2?1:-1;// 46 + } + } +} + +class 'pkg/TestIffSimplification' { + method 'simpleIff (Z[I)I' { + 1 4 + 5 4 + 6 4 + b 4 + c 4 + d 4 + } + + method 'simpleIf (Z[I)I' { + 1 8 + 5 8 + 6 8 + 9 8 + a 8 + } + + method 'nestedIf (ZZ[I)I' { + 1 12 + 5 13 + 9 13 + a 13 + d 13 + e 13 + 11 15 + 12 15 + 13 15 + } + + method 'compareTo (IIBBDDII)I' { + 2 20 + 7 21 + a 21 + e 21 + f 21 + 13 22 + 19 23 + 1c 23 + 20 23 + 21 23 + 26 24 + 27 24 + 2a 24 + 2d 24 + 2e 24 + 35 25 + 38 25 + 3c 25 + 3d 25 + 42 27 + 43 27 + 46 27 + 4a 27 + 4b 27 + } +} + +Lines mapping: +7 <-> 5 +11 <-> 9 +12 <-> 9 +15 <-> 9 +20 <-> 13 +21 <-> 14 +22 <-> 14 +25 <-> 14 +29 <-> 16 +34 <-> 21 +35 <-> 22 +38 <-> 23 +39 <-> 24 +42 <-> 25 +43 <-> 26 +46 <-> 28 diff --git a/testData/src/pkg/TestIffSimplification.java b/testData/src/pkg/TestIffSimplification.java new file mode 100644 index 0000000..5b87363 --- /dev/null +++ b/testData/src/pkg/TestIffSimplification.java @@ -0,0 +1,48 @@ +package pkg; + +import java.lang.Math; + +public class TestIffSimplification { + public int simpleIff(boolean status, int[] values) { + return status ? values[0] : values[1]; + } + + public int simpleIf(boolean status, int[] values) { + if (status) { + return values[0]; + } + else { + return values[1]; + } + } + + public int nestedIf(boolean status, boolean condition, int[] values) { + if (status) { + if (condition) { + return values[2]; + } + else { + return values[0]; + } + } + else { + return values[1]; + } + } + + public int compareTo(int mc1, int mc2, byte csg1, byte csg2, double score1, double score2, int doc1, int doc2) { + if (mc1 != mc2) { + return mc1 < mc2 ? 1 : -1; + } + + if (csg1 != csg2) { + return csg1 < csg2 ? 1 : -1; + } + + if (Math.abs(score1 - score2) < 1e-6) { + return doc1 < doc2 ? -1 : 1; + } + + return score1 < score2 ? 1 : -1; + } +} \ No newline at end of file