core: allow to skip sub-blocks for region visitor.

This commit is contained in:
Skylot
2015-06-26 21:26:08 +03:00
parent 1d84c00161
commit 71f249113d
8 changed files with 23 additions and 13 deletions
@@ -7,7 +7,8 @@ import jadx.core.dex.nodes.MethodNode;
public abstract class AbstractRegionVisitor implements IRegionVisitor {
@Override
public void enterRegion(MethodNode mth, IRegion region) {
public boolean enterRegion(MethodNode mth, IRegion region) {
return true;
}
@Override
@@ -64,13 +64,14 @@ public class CheckRegions extends AbstractVisitor {
// check loop conditions
DepthRegionTraversal.traverse(mth, new AbstractRegionVisitor() {
@Override
public void enterRegion(MethodNode mth, IRegion region) {
public boolean enterRegion(MethodNode mth, IRegion region) {
if (region instanceof LoopRegion) {
BlockNode loopHeader = ((LoopRegion) region).getHeader();
if (loopHeader != null && loopHeader.getInstructions().size() != 1) {
ErrorsCounter.methodError(mth, "Incorrect condition in loop: " + loopHeader);
}
}
return true;
}
});
}
@@ -23,9 +23,9 @@ public class CleanRegions {
}
IRegionVisitor removeEmptyBlocks = new AbstractRegionVisitor() {
@Override
public void enterRegion(MethodNode mth, IRegion region) {
public boolean enterRegion(MethodNode mth, IRegion region) {
if (!(region instanceof Region)) {
return;
return true;
}
for (Iterator<IContainer> it = region.getSubBlocks().iterator(); it.hasNext(); ) {
@@ -42,6 +42,7 @@ public class CleanRegions {
}
}
return true;
}
};
DepthRegionTraversal.traverse(mth, removeEmptyBlocks);
@@ -53,9 +53,10 @@ public class DepthRegionTraversal {
visitor.processBlock(mth, (IBlock) container);
} else if (container instanceof IRegion) {
IRegion region = (IRegion) container;
visitor.enterRegion(mth, region);
for (IContainer subCont : region.getSubBlocks()) {
traverseInternal(mth, visitor, subCont);
if (visitor.enterRegion(mth, region)) {
for (IContainer subCont : region.getSubBlocks()) {
traverseInternal(mth, visitor, subCont);
}
}
visitor.leaveRegion(mth, region);
}
@@ -8,7 +8,10 @@ public interface IRegionVisitor {
void processBlock(MethodNode mth, IBlock container);
void enterRegion(MethodNode mth, IRegion region);
/**
* @return true for traverse sub-blocks, false otherwise.
*/
boolean enterRegion(MethodNode mth, IRegion region);
void leaveRegion(MethodNode mth, IRegion region);
@@ -38,10 +38,11 @@ public class IfRegionVisitor extends AbstractVisitor implements IRegionVisitor,
}
@Override
public void enterRegion(MethodNode mth, IRegion region) {
public boolean enterRegion(MethodNode mth, IRegion region) {
if (region instanceof IfRegion) {
processIfRegion(mth, (IfRegion) region);
}
return true;
}
@Override
@@ -47,10 +47,11 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor
}
@Override
public void enterRegion(MethodNode mth, IRegion region) {
public boolean enterRegion(MethodNode mth, IRegion region) {
if (region instanceof LoopRegion) {
processLoopRegion(mth, (LoopRegion) region);
}
return true;
}
private static void processLoopRegion(MethodNode mth, LoopRegion loopRegion) {
@@ -12,12 +12,13 @@ public abstract class TracedRegionVisitor implements IRegionVisitor {
protected final Deque<IRegion> regionStack = new ArrayDeque<IRegion>();
@Override
public final void enterRegion(MethodNode mth, IRegion region) {
public boolean enterRegion(MethodNode mth, IRegion region) {
regionStack.push(region);
return true;
}
@Override
public final void processBlock(MethodNode mth, IBlock container) {
public void processBlock(MethodNode mth, IBlock container) {
IRegion curRegion = regionStack.peek();
processBlockTraced(mth, container, curRegion);
}
@@ -25,7 +26,7 @@ public abstract class TracedRegionVisitor implements IRegionVisitor {
public abstract void processBlockTraced(MethodNode mth, IBlock container, IRegion currentRegion);
@Override
public final void leaveRegion(MethodNode mth, IRegion region) {
public void leaveRegion(MethodNode mth, IRegion region) {
regionStack.pop();
}
}