Commit 71f24911 authored by Skylot's avatar Skylot

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

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