fix: shrink code if region maker add FORCE_ASSIGN_INLINE to insn (#845)

This commit is contained in:
Skylot
2020-02-09 12:22:16 +00:00
parent 5502d93cd5
commit d0f197ea3d
3 changed files with 60 additions and 1 deletions
@@ -25,6 +25,7 @@ import jadx.core.dex.regions.SwitchRegion;
import jadx.core.dex.regions.SynchronizedRegion;
import jadx.core.dex.regions.loops.LoopRegion;
import jadx.core.dex.visitors.AbstractVisitor;
import jadx.core.dex.visitors.shrink.CodeShrinkVisitor;
import jadx.core.utils.InsnRemover;
import jadx.core.utils.RegionUtils;
import jadx.core.utils.exceptions.JadxException;
@@ -58,6 +59,8 @@ public class RegionMakerVisitor extends AbstractVisitor {
}
private static void postProcessRegions(MethodNode mth) {
processForceInlineInsns(mth);
// make try-catch regions
ProcessTryCatchRegions.process(mth);
@@ -70,6 +73,15 @@ public class RegionMakerVisitor extends AbstractVisitor {
}
}
private static void processForceInlineInsns(MethodNode mth) {
boolean needShrink = mth.getBasicBlocks().stream()
.flatMap(block -> block.getInstructions().stream())
.anyMatch(insn -> insn.contains(AFlag.FORCE_ASSIGN_INLINE));
if (needShrink) {
CodeShrinkVisitor.shrinkMethod(mth);
}
}
private static final class PostRegionVisitor extends AbstractRegionVisitor {
@Override
public void leaveRegion(MethodNode mth, IRegion region) {
@@ -9,7 +9,7 @@ import static jadx.tests.api.utils.JadxMatchers.containsOne;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
public class TestConditions19 extends IntegrationTest {
public class TestInnerAssign extends IntegrationTest {
public static class TestCls {
private String result;
@@ -0,0 +1,47 @@
package jadx.tests.integration.conditions;
import org.junit.jupiter.api.Test;
import jadx.tests.api.IntegrationTest;
import static jadx.tests.api.utils.assertj.JadxAssertions.assertThat;
public class TestInnerAssign2 extends IntegrationTest {
public static class TestCls {
private String field;
private String swapField;
@SuppressWarnings("checkstyle:InnerAssignment")
public boolean test(String str) {
String sub;
return call(str) || ((sub = this.field) != null && sub.isEmpty());
}
private boolean call(String str) {
this.field = swapField;
return str.isEmpty();
}
public boolean testWrap(String str, String fieldValue) {
this.field = null;
this.swapField = fieldValue;
return test(str);
}
public void check() {
assertThat(testWrap("", null)).isTrue();
assertThat(testWrap("a", "")).isTrue();
assertThat(testWrap("b", null)).isFalse();
assertThat(testWrap("c", "d")).isFalse();
}
}
@Test
public void test() {
assertThat(getClassNode(TestCls.class))
.code()
.containsOne("sub = this.field")
.containsOne("return call(str) || ((sub = this.field) != null && sub.isEmpty());");
}
}