diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/DepthRegionTraversal.java b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/DepthRegionTraversal.java index e5026a0e7..e495d901b 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/DepthRegionTraversal.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/DepthRegionTraversal.java @@ -31,6 +31,14 @@ public class DepthRegionTraversal { traverseInternal(mth, visitor, container); } + public static @Nullable R traversePartial(MethodNode mth, IRegionPartialVisitor visitor) { + return traversePartialInternal(mth, visitor, mth.getRegion()); + } + + public static @Nullable R traversePartial(MethodNode mth, IContainer container, IRegionPartialVisitor visitor) { + return traversePartialInternal(mth, visitor, container); + } + public static void traverseIterative(MethodNode mth, IRegionIterativeVisitor visitor) { boolean repeat; int k = 0; @@ -95,6 +103,24 @@ public class DepthRegionTraversal { } } + private static @Nullable R traversePartialInternal(MethodNode mth, IRegionPartialVisitor visitor, IContainer startContainer) { + List stack = new ArrayList<>(); + stack.add(startContainer); + while (true) { + IContainer current = ListUtils.removeLast(stack); + if (current == null) { + return null; + } + R result = visitor.visit(mth, current); + if (result != null) { + return result; + } + if (current instanceof IRegion) { + addSubBlocksToStack(stack, (IRegion) current); + } + } + } + private static void addSubBlocksToStack(List stack, IRegion region) { List subBlocks = region.getSubBlocks(); // add in reverse order to keep original order during visit diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/IRegionPartialVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/IRegionPartialVisitor.java new file mode 100644 index 000000000..127b38be1 --- /dev/null +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/IRegionPartialVisitor.java @@ -0,0 +1,16 @@ +package jadx.core.dex.visitors.regions; + +import org.jetbrains.annotations.Nullable; + +import jadx.core.dex.nodes.IContainer; +import jadx.core.dex.nodes.MethodNode; + +public interface IRegionPartialVisitor { + /** + * Visit all containers in region until stopped + * + * @return non-null value to stop visiting + */ + @Nullable + R visit(MethodNode mth, IContainer container); +}