Commit 2c072539 authored by Skylot's avatar Skylot

fix: check variable usage before convert indexed loop to for-each variant (#483)

parent 5a940a3b
......@@ -116,7 +116,7 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor
// all checks passed
initInsn.add(AFlag.SKIP);
incrInsn.add(AFlag.SKIP);
LoopType arrForEach = checkArrayForEach(mth, initInsn, incrInsn, condition);
LoopType arrForEach = checkArrayForEach(mth, loopRegion, initInsn, incrInsn, condition);
if (arrForEach != null) {
loopRegion.setType(arrForEach);
return true;
......@@ -125,7 +125,7 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor
return true;
}
private static LoopType checkArrayForEach(MethodNode mth, InsnNode initInsn, InsnNode incrInsn,
private static LoopType checkArrayForEach(MethodNode mth, LoopRegion loopRegion, InsnNode initInsn, InsnNode incrInsn,
IfCondition condition) {
if (!(incrInsn instanceof ArithNode)) {
return null;
......@@ -186,6 +186,9 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor
if (iterVar == null) {
return null;
}
if (!usedOnlyInLoop(mth, loopRegion, iterVar)) {
return null;
}
// array for each loop confirmed
len.add(AFlag.SKIP);
......
package jadx.tests.integration.loops;
import java.io.File;
import org.junit.Test;
import jadx.core.dex.nodes.ClassNode;
import jadx.tests.api.IntegrationTest;
import static jadx.tests.api.utils.JadxMatchers.containsOne;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
public class TestIndexedLoop extends IntegrationTest {
public static class TestCls {
public File test(File[] files) {
File file = null;
if (files != null) {
int length = files.length;
if (length == 0) {
file = null;
} else {
for (int i = 0; i < length; i++) {
file = files[i];
if (file.getName().equals("f")) {
break;
}
}
}
} else {
file = null;
}
if (file != null) {
file.deleteOnExit();
}
return file;
}
public void check() {
assertThat(test(null), nullValue());
assertThat(test(new File[]{}), nullValue());
File file = new File("f");
assertThat(test(new File[]{new File("a"), file}), is(file));
}
}
@Test
public void test() {
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
assertThat(code, not(containsString("for (File file :")));
assertThat(code, containsOne("for (int i = 0; i < length; i++) {"));
}
@Test
public void testNoDebug() {
noDebugInfo();
ClassNode cls = getClassNode(TestCls.class);
String code = cls.getCode().toString();
assertThat(code, not(containsString("for (File file :")));
assertThat(code, containsOne("for (int i = 0; i < length; i++) {"));
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment