use of jadx.core.dex.regions.conditions.IfRegion in project jadx by skylot.
the class RegionMaker method processIf.
private BlockNode processIf(IRegion currentRegion, BlockNode block, IfNode ifnode, RegionStack stack) {
if (block.contains(AFlag.ADDED_TO_REGION)) {
// block already included in other 'if' region
return ifnode.getThenBlock();
}
IfInfo currentIf = makeIfInfo(mth, block);
if (currentIf == null) {
return null;
}
IfInfo mergedIf = mergeNestedIfNodes(currentIf);
if (mergedIf != null) {
currentIf = mergedIf;
} else {
// invert simple condition (compiler often do it)
currentIf = IfInfo.invert(currentIf);
}
IfInfo modifiedIf = IfMakerHelper.restructureIf(mth, block, currentIf);
if (modifiedIf != null) {
currentIf = modifiedIf;
} else {
if (currentIf.getMergedBlocks().size() <= 1) {
return null;
}
currentIf = makeIfInfo(mth, block);
currentIf = IfMakerHelper.restructureIf(mth, block, currentIf);
if (currentIf == null) {
// all attempts failed
return null;
}
}
confirmMerge(currentIf);
IfRegion ifRegion = new IfRegion(currentRegion);
ifRegion.updateCondition(currentIf);
currentRegion.getSubBlocks().add(ifRegion);
BlockNode outBlock = currentIf.getOutBlock();
stack.push(ifRegion);
stack.addExit(outBlock);
ifRegion.setThenRegion(makeRegion(currentIf.getThenBlock(), stack));
BlockNode elseBlock = currentIf.getElseBlock();
if (elseBlock == null || stack.containsExit(elseBlock)) {
ifRegion.setElseRegion(null);
} else {
ifRegion.setElseRegion(makeRegion(elseBlock, stack));
}
// TODO: make more common algorithm
if (ifRegion.getElseRegion() == null && outBlock != null) {
List<EdgeInsnAttr> edgeInsnAttrs = outBlock.getAll(AType.EDGE_INSN);
if (!edgeInsnAttrs.isEmpty()) {
Region elseRegion = new Region(ifRegion);
for (EdgeInsnAttr edgeInsnAttr : edgeInsnAttrs) {
if (edgeInsnAttr.getEnd().equals(outBlock)) {
addEdgeInsn(currentIf, elseRegion, edgeInsnAttr);
}
}
ifRegion.setElseRegion(elseRegion);
}
}
stack.pop();
return outBlock;
}
use of jadx.core.dex.regions.conditions.IfRegion 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.regions.conditions.IfRegion in project jadx by skylot.
the class RegionGen method connectElseIf.
/**
* Connect if-else-if block
*/
private boolean connectElseIf(ICodeWriter code, IContainer els) throws CodegenException {
if (els.contains(AFlag.ELSE_IF_CHAIN) && els instanceof Region) {
List<IContainer> subBlocks = ((Region) els).getSubBlocks();
if (subBlocks.size() == 1) {
IContainer elseBlock = subBlocks.get(0);
if (elseBlock instanceof IfRegion) {
declareVars(code, elseBlock);
makeIf((IfRegion) elseBlock, code, false);
return true;
}
}
}
return false;
}
use of jadx.core.dex.regions.conditions.IfRegion in project jadx by skylot.
the class IfRegionVisitor method markElseIfChains.
/**
* Mark if-else-if chains
*/
private static void markElseIfChains(IfRegion ifRegion) {
if (hasSimpleReturnBlock(ifRegion.getThenRegion())) {
return;
}
IContainer elsRegion = ifRegion.getElseRegion();
if (elsRegion instanceof Region) {
List<IContainer> subBlocks = ((Region) elsRegion).getSubBlocks();
if (subBlocks.size() == 1 && subBlocks.get(0) instanceof IfRegion) {
subBlocks.get(0).add(AFlag.ELSE_IF_CHAIN);
elsRegion.add(AFlag.ELSE_IF_CHAIN);
}
}
}
Aggregations