use of jadx.core.dex.nodes.IRegion in project jadx by skylot.
the class CheckRegions method visit.
@Override
public void visit(MethodNode mth) throws JadxException {
if (mth.isNoCode() || mth.getRegion() == null || mth.getBasicBlocks().isEmpty() || mth.contains(AType.JADX_ERROR)) {
return;
}
// check if all blocks included in regions
Set<BlockNode> blocksInRegions = new HashSet<>();
DepthRegionTraversal.traverse(mth, new AbstractRegionVisitor() {
@Override
public void processBlock(MethodNode mth, IBlock container) {
if (!(container instanceof BlockNode)) {
return;
}
BlockNode block = (BlockNode) container;
if (blocksInRegions.add(block)) {
return;
}
if (LOG.isDebugEnabled() && !block.contains(AFlag.RETURN) && !block.contains(AFlag.REMOVE) && !block.contains(AFlag.SYNTHETIC) && !block.getInstructions().isEmpty()) {
LOG.debug("Duplicated block: {} - {}", mth, block);
}
}
});
if (mth.getBasicBlocks().size() != blocksInRegions.size()) {
for (BlockNode block : mth.getBasicBlocks()) {
if (!blocksInRegions.contains(block) && !block.getInstructions().isEmpty() && !block.contains(AFlag.ADDED_TO_REGION) && !block.contains(AFlag.DONT_GENERATE) && !block.contains(AFlag.REMOVE)) {
String blockCode = getBlockInsnStr(mth, block).replace("*/", "*\\/");
mth.addWarn("Code restructure failed: missing block: " + block + ", code lost:" + blockCode);
}
}
}
DepthRegionTraversal.traverse(mth, new AbstractRegionVisitor() {
@Override
public boolean enterRegion(MethodNode mth, IRegion region) {
if (region instanceof LoopRegion) {
// check loop conditions
BlockNode loopHeader = ((LoopRegion) region).getHeader();
if (loopHeader != null && loopHeader.getInstructions().size() != 1) {
mth.addWarn("Incorrect condition in loop: " + loopHeader);
}
}
return true;
}
});
}
use of jadx.core.dex.nodes.IRegion in project jadx by skylot.
the class IfRegionVisitor method removeRedundantElseBlock.
private static boolean removeRedundantElseBlock(MethodNode mth, IfRegion ifRegion) {
if (ifRegion.getElseRegion() == null || ifRegion.contains(AFlag.ELSE_IF_CHAIN) || ifRegion.getElseRegion().contains(AFlag.ELSE_IF_CHAIN)) {
return false;
}
if (!RegionUtils.hasExitBlock(ifRegion.getThenRegion())) {
return false;
}
// see #jadx.tests.integration.conditions.TestConditions9
if (mth.isVoidReturn() && insnsCount(ifRegion.getThenRegion()) == 2 && insnsCount(ifRegion.getElseRegion()) == 2) {
return false;
}
IRegion parent = ifRegion.getParent();
Region newRegion = new Region(parent);
if (parent.replaceSubBlock(ifRegion, newRegion)) {
newRegion.add(ifRegion);
newRegion.add(ifRegion.getElseRegion());
ifRegion.setElseRegion(null);
return true;
}
return false;
}
use of jadx.core.dex.nodes.IRegion in project jadx by skylot.
the class TracedRegionVisitor method processBlock.
@Override
public void processBlock(MethodNode mth, IBlock container) {
IRegion curRegion = regionStack.peek();
processBlockTraced(mth, container, curRegion);
}
use of jadx.core.dex.nodes.IRegion in project jadx by skylot.
the class ProcessVariables method isAllUseAfter.
/**
* Check if all {@code usePlaces} are after {@code checkPlace}
*/
private static boolean isAllUseAfter(UsePlace checkPlace, List<UsePlace> usePlaces) {
IRegion region = checkPlace.getRegion();
IBlock block = checkPlace.getBlock();
Set<UsePlace> toCheck = new HashSet<>(usePlaces);
boolean blockFound = false;
for (IContainer subBlock : region.getSubBlocks()) {
if (!blockFound && subBlock == block) {
blockFound = true;
}
if (blockFound) {
toCheck.removeIf(usePlace -> isContainerContainsUsePlace(subBlock, usePlace));
if (toCheck.isEmpty()) {
return true;
}
}
}
return false;
}
use of jadx.core.dex.nodes.IRegion in project jadx by skylot.
the class CleanRegions method process.
public static void process(MethodNode mth) {
if (mth.isNoCode() || mth.getBasicBlocks().isEmpty()) {
return;
}
IRegionVisitor removeEmptyBlocks = new AbstractRegionVisitor() {
@Override
public boolean enterRegion(MethodNode mth, IRegion region) {
if (!(region instanceof Region)) {
return true;
}
for (Iterator<IContainer> it = region.getSubBlocks().iterator(); it.hasNext(); ) {
IContainer container = it.next();
if (container instanceof BlockNode) {
BlockNode block = (BlockNode) container;
if (block.getInstructions().isEmpty()) {
try {
it.remove();
} catch (UnsupportedOperationException e) {
LOG.warn("Can't remove block: {} from: {}, mth: {}", block, region, mth);
}
}
}
}
return true;
}
};
DepthRegionTraversal.traverse(mth, removeEmptyBlocks);
}
Aggregations