core: allow to skip sub-blocks for region visitor.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user