summaryrefslogtreecommitdiff
path: root/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/DecHelper.java
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/DecHelper.java')
-rw-r--r--plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/DecHelper.java218
1 files changed, 218 insertions, 0 deletions
diff --git a/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/DecHelper.java b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/DecHelper.java
new file mode 100644
index 000000000000..9c719dbc9141
--- /dev/null
+++ b/plugins/java-decompiler/engine/src/org/jetbrains/java/decompiler/modules/decompiler/DecHelper.java
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.java.decompiler.modules.decompiler;
+
+import org.jetbrains.java.decompiler.modules.decompiler.exps.Exprent;
+import org.jetbrains.java.decompiler.modules.decompiler.stats.Statement;
+
+import java.util.*;
+
+
+public class DecHelper {
+
+ public static boolean checkStatementExceptions(List<Statement> lst) {
+
+ Set<Statement> all = new HashSet<Statement>(lst);
+
+ Set<Statement> handlers = new HashSet<Statement>();
+ Set<Statement> intersection = null;
+
+ for (Statement stat : lst) {
+ Set<Statement> setNew = stat.getNeighboursSet(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_FORWARD);
+
+ if (intersection == null) {
+ intersection = setNew;
+ }
+ else {
+ HashSet<Statement> interclone = new HashSet<Statement>(intersection);
+ interclone.removeAll(setNew);
+
+ intersection.retainAll(setNew);
+
+ setNew.removeAll(intersection);
+
+ handlers.addAll(interclone);
+ handlers.addAll(setNew);
+ }
+ }
+
+ for (Statement stat : handlers) {
+ if (!all.contains(stat) || !all.containsAll(stat.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_BACKWARD))) {
+ return false;
+ }
+ }
+
+ // check for other handlers (excluding head)
+ for (int i = 1; i < lst.size(); i++) {
+ Statement stat = lst.get(i);
+ if (!stat.getPredecessorEdges(StatEdge.TYPE_EXCEPTION).isEmpty() && !handlers.contains(stat)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean isChoiceStatement(Statement head, List<Statement> lst) {
+
+ Statement post = null;
+
+ Set<Statement> setDest = head.getNeighboursSet(StatEdge.TYPE_REGULAR, Statement.DIRECTION_FORWARD);
+
+ if (setDest.contains(head)) {
+ return false;
+ }
+
+ while (true) {
+
+ lst.clear();
+
+ boolean repeat = false;
+
+ setDest.remove(post);
+
+ for (Statement stat : setDest) {
+ if (stat.getLastBasicType() != Statement.LASTBASICTYPE_GENERAL) {
+ if (post == null) {
+ post = stat;
+ repeat = true;
+ break;
+ }
+ else {
+ return false;
+ }
+ }
+
+ // preds
+ Set<Statement> setPred = stat.getNeighboursSet(StatEdge.TYPE_REGULAR, Statement.DIRECTION_BACKWARD);
+ setPred.remove(head);
+ if (setPred.contains(stat)) {
+ return false;
+ }
+
+ if (!setDest.containsAll(setPred) || setPred.size() > 1) {
+ if (post == null) {
+ post = stat;
+ repeat = true;
+ break;
+ }
+ else {
+ return false;
+ }
+ }
+ else if (setPred.size() == 1) {
+ Statement pred = setPred.iterator().next();
+ while (lst.contains(pred)) {
+ Set<Statement> setPredTemp = pred.getNeighboursSet(StatEdge.TYPE_REGULAR, Statement.DIRECTION_BACKWARD);
+ setPredTemp.remove(head);
+
+ if (!setPredTemp.isEmpty()) { // at most 1 predecessor
+ pred = setPredTemp.iterator().next();
+ if (pred == stat) {
+ return false; // loop found
+ }
+ }
+ else {
+ break;
+ }
+ }
+ }
+
+ // succs
+ List<StatEdge> lstEdges = stat.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL);
+ if (lstEdges.size() > 1) {
+ Set<Statement> setSucc = stat.getNeighboursSet(Statement.STATEDGE_DIRECT_ALL, Statement.DIRECTION_FORWARD);
+ setSucc.retainAll(setDest);
+
+ if (setSucc.size() > 0) {
+ return false;
+ }
+ else {
+ if (post == null) {
+ post = stat;
+ repeat = true;
+ break;
+ }
+ else {
+ return false;
+ }
+ }
+ }
+ else if (lstEdges.size() == 1) {
+
+ StatEdge edge = lstEdges.get(0);
+ if (edge.getType() == StatEdge.TYPE_REGULAR) {
+ Statement statd = edge.getDestination();
+ if (head == statd) {
+ return false;
+ }
+ if (!setDest.contains(statd) && post != statd) {
+ if (post != null) {
+ return false;
+ }
+ else {
+ Set<Statement> set = statd.getNeighboursSet(StatEdge.TYPE_REGULAR, Statement.DIRECTION_BACKWARD);
+ if (set.size() > 1) {
+ post = statd;
+ repeat = true;
+ break;
+ }
+ else {
+ return false;
+ }
+ }
+ }
+ }
+ }
+
+ lst.add(stat);
+ }
+
+ if (!repeat) {
+ break;
+ }
+ }
+
+ lst.add(head);
+ lst.remove(post);
+
+ lst.add(0, post);
+
+ return true;
+ }
+
+
+ public static HashSet<Statement> getUniquePredExceptions(Statement head) {
+
+ HashSet<Statement> setHandlers = new HashSet<Statement>(head.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_FORWARD));
+
+ Iterator<Statement> it = setHandlers.iterator();
+ while (it.hasNext()) {
+ if (it.next().getPredecessorEdges(StatEdge.TYPE_EXCEPTION).size() > 1) {
+ it.remove();
+ }
+ }
+ return setHandlers;
+ }
+
+ public static List<Exprent> copyExprentList(List<Exprent> lst) {
+ List<Exprent> ret = new ArrayList<Exprent>();
+ for (Exprent expr : lst) {
+ ret.add(expr.copy());
+ }
+ return ret;
+ }
+}