fix: limit ternary wrap to one level (#2844)

This commit is contained in:
Skylot
2026-04-09 20:45:43 +01:00
parent 1e908f7af3
commit f95c5e8f39
3 changed files with 78 additions and 6 deletions
@@ -31,13 +31,18 @@ public class TernaryMod extends AbstractRegionVisitor implements IRegionIterativ
private static final TernaryMod INSTANCE = new TernaryMod(); private static final TernaryMod INSTANCE = new TernaryMod();
public static void process(MethodNode mth) { public static void process(MethodNode mth) {
// first: convert all found ternary nodes in one iteration boolean changed = false;
// convert all found ternary nodes in one iteration
DepthRegionTraversal.traverse(mth, INSTANCE); DepthRegionTraversal.traverse(mth, INSTANCE);
if (mth.contains(AFlag.REQUEST_CODE_SHRINK)) { if (mth.contains(AFlag.REQUEST_CODE_SHRINK)) {
CodeShrinkVisitor.shrinkMethod(mth); CodeShrinkVisitor.shrinkMethod(mth);
changed = true;
}
if (changed && mth.isConstructor()) {
// aggressive mode to help code inline before super call in constructor
// iterative runs with shrink after each change
DepthRegionTraversal.traverseIterative(mth, INSTANCE);
} }
// second: iterative runs with shrink after each change
DepthRegionTraversal.traverseIterative(mth, INSTANCE);
} }
@Override @Override
@@ -3,7 +3,8 @@ package jadx.tests.integration.conditions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import jadx.tests.api.IntegrationTest; import jadx.tests.api.IntegrationTest;
import jadx.tests.api.utils.assertj.JadxAssertions;
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
public class TestConditions14 extends IntegrationTest { public class TestConditions14 extends IntegrationTest {
@@ -22,9 +23,15 @@ public class TestConditions14 extends IntegrationTest {
@Test @Test
public void test() { public void test() {
JadxAssertions.assertThat(getClassNode(TestCls.class)) assertThat(getClassNode(TestCls.class))
.code() .code()
.containsOne("boolean r = a == null ? b != null : !a.equals(b);") .containsLines(2,
"boolean r;",
"if (a == null) {",
indent() + "r = b != null;",
"} else {",
indent() + "r = !a.equals(b);",
"}")
.containsOne("if (r) {") .containsOne("if (r) {")
.containsOne("System.out.println(\"r=\" + r);"); .containsOne("System.out.println(\"r=\" + r);");
} }
@@ -0,0 +1,60 @@
package jadx.tests.integration.conditions;
import jadx.tests.api.IntegrationTest;
import jadx.tests.api.extensions.profiles.TestProfile;
import jadx.tests.api.extensions.profiles.TestWithProfiles;
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
public class TestConditions22 extends IntegrationTest {
public static class TestCls {
public static int test(int i, int j) {
int k;
if (i == 1) {
if (j == 2) {
k = 3;
} else {
k = 0;
}
} else if (i == 2) {
if (j == 3) {
k = 4;
} else {
k = 0;
}
} else if (i == 3) {
if (j == 4) {
k = 5;
} else {
k = 0;
}
} else {
k = 0;
}
System.out.println("k = " + k);
return k;
}
public void check() {
assertThat(test(1, 2)).isEqualTo(3);
assertThat(test(1, 1)).isEqualTo(0);
assertThat(test(2, 3)).isEqualTo(4);
assertThat(test(2, 2)).isEqualTo(0);
assertThat(test(3, 4)).isEqualTo(5);
assertThat(test(3, 3)).isEqualTo(0);
assertThat(test(4, 4)).isEqualTo(0);
}
}
@TestWithProfiles(TestProfile.JAVA17)
public void testJava() {
noDebugInfo();
assertThat(getClassNode(TestCls.class))
.code()
.containsOne(indent(2) + "if (")
.containsOne(indent(2) + "} else if (")
.containsOne(indent(2) + "} else {");
}
}