new for loop continues detection

This commit is contained in:
Jindra Petřík
2021-01-29 07:32:21 +01:00
parent f8f7d00981
commit bfe0fce888
14 changed files with 250 additions and 128 deletions

View File

@@ -28,10 +28,18 @@ import java.util.Map;
import java.util.Set;
/**
*
* Detects "precontinues" in Graph. A precontinue is target of continue
* statement in a for loop. For loop in this case has single backedge.
* Precontinue is predeccessor of loops backedge. Precontinue can have branches
* in it (and in some special cases like xml .() operator a while too). This
* class tries to simplify graph up to the level that precontinue is a single
* node.
*
* @author JPEXS
*/
public class GraphPrecontinueDetector {
public void detectPrecontinues(List<GraphPart> heads, Set<GraphPart> allParts, List<Loop> loops) {
boolean isSomethingTodo = false;
for (Loop el : loops) {
@@ -106,7 +114,12 @@ public class GraphPrecontinueDetector {
//printGraph(headNodes);
}
private void printGraph(List<Node> headNodes) {
/**
* Converts node graph to graphviz for easily display.
*
* @param headNodes
*/
public void printGraph(List<Node> headNodes) {
Set<Node> allNodes = new LinkedHashSet<>();
for (Node headNode : headNodes) {
populateNodes(headNode, allNodes);
@@ -196,7 +209,7 @@ public class GraphPrecontinueDetector {
whileNode.graphPart = node.graphPart;
whileNode.body = bodyNode;
whileNode.body.removeFromGraph();
whileNode.prev = new NonNullList<>(node.prev);
whileNode.prev = new ArrayList<>(node.prev);
node.replacePrevs(whileNode);
node.replaceNexts(whileNode);
whileNode.next.add(breakNode);
@@ -204,7 +217,8 @@ public class GraphPrecontinueDetector {
numWhile.setVal(numWhile.getVal() + 1);
}
for (Node n : result.next) {
List<Node> nexts = new ArrayList<>(result.next);
for (Node n : nexts) {
handleWhile(n, visited, numWhile);
}
return result;
@@ -231,8 +245,8 @@ public class GraphPrecontinueDetector {
JoinedNode joinedNode = new JoinedNode();
joinedNode.graphPart = node.graphPart;
joinedNode.nodes = nodeList;
joinedNode.next = new NonNullList<>(currentNode.next);
joinedNode.prev = new NonNullList<>(node.prev);
joinedNode.next = new ArrayList<>(currentNode.next);
joinedNode.prev = new ArrayList<>(node.prev);
node.replacePrevs(joinedNode);
currentNode.replaceNexts(joinedNode);
for (Node n : nodeList) {
@@ -243,7 +257,8 @@ public class GraphPrecontinueDetector {
numJoined.setVal(numJoined.getVal() + 1);
}
for (Node n : result.next) {
List<Node> nexts = new ArrayList<>(result.next);
for (Node n : nexts) {
joinNodes(n, visited, numJoined);
}
@@ -270,7 +285,7 @@ public class GraphPrecontinueDetector {
ifNode.onTrue.removeFromGraph();
ifNode.onFalse = null;
ifNode.graphPart = node.graphPart;
ifNode.prev = new NonNullList<>(node.prev);
ifNode.prev = new ArrayList<>(node.prev);
node.replacePrevs(ifNode);
Node after = node.next.get(1);
node.removeFromGraph();
@@ -300,7 +315,7 @@ public class GraphPrecontinueDetector {
ifNode.onFalse.parentNode = ifNode;
ifNode.onFalse.removeFromGraph();
ifNode.graphPart = node.graphPart;
ifNode.prev = new NonNullList<>(node.prev);
ifNode.prev = new ArrayList<>(node.prev);
node.replacePrevs(ifNode);
Node after = node.next.get(0);
node.removeFromGraph();
@@ -331,7 +346,7 @@ public class GraphPrecontinueDetector {
ifNode.onFalse.parentNode = ifNode;
ifNode.onFalse.removeFromGraph();
ifNode.graphPart = node.graphPart;
ifNode.prev = new NonNullList<>(node.prev);
ifNode.prev = new ArrayList<>(node.prev);
node.replacePrevs(ifNode);
Node after = node.next.get(0).next.get(0);
node.removeFromGraph();

View File

@@ -1,3 +1,19 @@
/*
* Copyright (C) 2010-2018 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.graph.precontinues;
/**

View File

@@ -1,3 +1,19 @@
/*
* Copyright (C) 2010-2018 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.graph.precontinues;
import java.util.ArrayList;

View File

@@ -26,8 +26,8 @@ import java.util.List;
* @author JPEXS
*/
public class Node {
public List<Node> next = new NonNullList<>();
public List<Node> prev = new NonNullList<Node>();
public List<Node> next = new ArrayList<>();
public List<Node> prev = new ArrayList<Node>();
public GraphPart graphPart;
private static int CURRENT_ID = 0;
private int id;

View File

@@ -1,39 +0,0 @@
package com.jpexs.decompiler.graph.precontinues;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
*
* @author JPEXS
*/
class NonNullList<T> extends ArrayList<T> {
public NonNullList(Collection<? extends T> col) {
super(col);
}
public NonNullList() {
}
@Override
public boolean add(T item) {
if (item == null) {
throw new NullPointerException("The collection does not support null values");
} else {
return super.add(item);
}
}
@Override
public boolean addAll(Collection<? extends T> items) {
if (items.contains(null)) {
throw new NullPointerException("The collection does not support null values");
} else {
return super.addAll(items);
}
}
}