org.jetbrains.java.decompiler.modules.decompiler.DecHelper Maven / Gradle / Ivy
/*
* 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 lst) {
Set all = new HashSet(lst);
Set handlers = new HashSet();
Set intersection = null;
for (Statement stat : lst) {
Set setNew = stat.getNeighboursSet(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_FORWARD);
if (intersection == null) {
intersection = setNew;
}
else {
HashSet interclone = new HashSet(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 lst) {
Statement post = null;
Set 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 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 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 lstEdges = stat.getSuccessorEdges(Statement.STATEDGE_DIRECT_ALL);
if (lstEdges.size() > 1) {
Set 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 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 getUniquePredExceptions(Statement head) {
HashSet setHandlers = new HashSet(head.getNeighbours(StatEdge.TYPE_EXCEPTION, Statement.DIRECTION_FORWARD));
Iterator it = setHandlers.iterator();
while (it.hasNext()) {
if (it.next().getPredecessorEdges(StatEdge.TYPE_EXCEPTION).size() > 1) {
it.remove();
}
}
return setHandlers;
}
public static List copyExprentList(List lst) {
List ret = new ArrayList();
for (Exprent expr : lst) {
ret.add(expr.copy());
}
return ret;
}
}