Default clause position in switch fixed

This commit is contained in:
Jindra Petřík
2016-01-17 21:59:20 +01:00
parent 33e433fa26
commit 4994c4a70c
10 changed files with 279 additions and 185 deletions
@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.model.AndItem;
import com.jpexs.decompiler.graph.model.BreakItem;
import com.jpexs.decompiler.graph.model.ContinueItem;
import com.jpexs.decompiler.graph.model.DefaultItem;
import com.jpexs.decompiler.graph.model.DoWhileItem;
import com.jpexs.decompiler.graph.model.DuplicateItem;
import com.jpexs.decompiler.graph.model.ExitItem;
@@ -1725,7 +1726,6 @@ public class Graph {
List<GraphTargetItem> caseValues = new ArrayList<>();
List<List<GraphTargetItem>> caseCommands = new ArrayList<>();
List<GraphTargetItem> defaultCommands = new ArrayList<>();
List<Integer> valueMappings = new ArrayList<>();
Loop swLoop = new Loop(loops.size(), null, next);
swLoop.phase = 1;
@@ -1800,15 +1800,17 @@ public class Graph {
first = true;
pos = 0;
//This is tied to AS3 switch implementation which has nextparts switched from index 1. TODO: Make more universal
GraphPart defaultPart = hasExpr ? part.nextParts.get(1 + defaultBranch) : part.nextParts.get(0);
//int defaultNum = hasExpr ? 1 + defaultBranch : 0;
for (int i = 1; i < part.nextParts.size(); i++) {
if (part.nextParts.get(i) != defaultPart) {
if (caseExpressions.containsKey(pos)) {
caseValues.add(caseExpressions.get(pos));
} else {
caseValues.add(new IntegerValueItem(null, localData.lineStartInstruction, pos));
}
if (caseExpressions.containsKey(pos)) {
caseValues.add(caseExpressions.get(pos));
} else if (part.nextParts.get(i) == defaultPart) {
caseValues.add(new DefaultItem());
} else {
caseValues.add(new IntegerValueItem(null, localData.lineStartInstruction, pos));
}
pos++;
}
@@ -1816,13 +1818,14 @@ public class Graph {
first = true;
pos = 0;
List<GraphTargetItem> nextCommands = new ArrayList<>();
for (GraphPart p : part.nextParts) {
for (int i = 1; i < part.nextParts.size(); i++) {
GraphPart p = part.nextParts.get(i);
/*if (pos == ignoredBranch) {
pos++;
continue;
}*/
if (p != defaultPart) {
//if (p != defaultPart)
{
if (vis.contains(p)) {
valueMappings.add(caseCommands.size() - 1);
continue;
@@ -1844,37 +1847,60 @@ public class Graph {
}
}
if (next != p) {
if (p == defaultPart && !defaultCommands.isEmpty()) {
//ignore
} else {
//if (p == defaultPart && !defaultCommands.isEmpty()) {
//ignore
//} else
{
TranslateStack s2 = (TranslateStack) stack.clone();
s2.clear();
nextCommands = printGraph(partCodes, partCodePos, visited, prepareBranchLocalData(localData), s2, allParts, part, p, stopPart2, loops, null, staticOperation, path, recursionLevel + 1);
makeAllCommands(nextCommands, s2);
if (p == defaultPart) {
defaultCommands = nextCommands;
} else {
caseCommands.add(nextCommands);
}
caseCommands.add(nextCommands);
vis.add(p);
}
} else if (p == defaultPart) {
defaultCommands = nextCommands;
} else {
caseCommands.add(nextCommands);
}
first = false;
pos++;
}
//remove last break from default clause
if (!defaultCommands.isEmpty() && (defaultCommands.get(defaultCommands.size() - 1) instanceof BreakItem)) {
BreakItem bi = (BreakItem) defaultCommands.get(defaultCommands.size() - 1);
if (bi.loopId == swLoop.id) {
defaultCommands.remove(defaultCommands.size() - 1);
//If the lastone is default empty and alone, remove it
if (!caseCommands.isEmpty()) {
List<GraphTargetItem> lastc = caseCommands.get(caseCommands.size() - 1);
if (!lastc.isEmpty() && (lastc.get(lastc.size() - 1) instanceof BreakItem)) {
BreakItem bi = (BreakItem) lastc.get(lastc.size() - 1);
if (bi.loopId == swLoop.id) {
lastc.remove(lastc.size() - 1);
}
}
if (lastc.isEmpty()) {
int cnt = 0;
if (caseValues.get(caseValues.size() - 1) instanceof DefaultItem) {
for (int i = valueMappings.size() - 1; i >= 0; i--) {
if (valueMappings.get(i) == caseCommands.size() - 1) {
cnt++;
}
}
if (cnt == 1) {
caseValues.remove(caseValues.size() - 1);
valueMappings.remove(valueMappings.size() - 1);
caseCommands.remove(lastc);
}
}
}
}
SwitchItem sw = new SwitchItem(null, localData.lineStartInstruction, swLoop, switchedItem, caseValues, caseCommands, defaultCommands, valueMappings);
//remove last break from last section
if (!caseCommands.isEmpty()) {
List<GraphTargetItem> lastc = caseCommands.get(caseCommands.size() - 1);
if (!lastc.isEmpty() && (lastc.get(lastc.size() - 1) instanceof BreakItem)) {
BreakItem bi = (BreakItem) lastc.get(lastc.size() - 1);
if (bi.loopId == swLoop.id) {
lastc.remove(lastc.size() - 1);
}
}
}
SwitchItem sw = new SwitchItem(null, localData.lineStartInstruction, swLoop, switchedItem, caseValues, caseCommands, valueMappings);
currentRet.add(sw);
swLoop.phase = 2;
if (next != null) {
@@ -0,0 +1,24 @@
package com.jpexs.decompiler.graph.model;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.TypeItem;
public class DefaultItem extends GraphTargetItem {
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
return writer.append("default");
}
@Override
public boolean hasReturnValue() {
return true;
}
@Override
public GraphTargetItem returnType() {
return TypeItem.UNBOUNDED;
}
}
@@ -42,8 +42,6 @@ public class SwitchItem extends LoopItem implements Block {
public List<List<GraphTargetItem>> caseCommands;
public List<GraphTargetItem> defaultCommands;
public List<Integer> valuesMapping;
private boolean labelUsed;
@@ -52,18 +50,14 @@ public class SwitchItem extends LoopItem implements Block {
public List<List<GraphTargetItem>> getSubs() {
List<List<GraphTargetItem>> ret = new ArrayList<>();
ret.addAll(caseCommands);
if (defaultCommands != null) {
ret.add(defaultCommands);
}
return ret;
}
public SwitchItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, Loop loop, GraphTargetItem switchedObject, List<GraphTargetItem> caseValues, List<List<GraphTargetItem>> caseCommands, List<GraphTargetItem> defaultCommands, List<Integer> valuesMapping) {
public SwitchItem(GraphSourceItem instruction, GraphSourceItem lineStartIns, Loop loop, GraphTargetItem switchedObject, List<GraphTargetItem> caseValues, List<List<GraphTargetItem>> caseCommands, List<Integer> valuesMapping) {
super(instruction, lineStartIns, loop);
this.switchedObject = switchedObject;
this.caseValues = caseValues;
this.caseCommands = caseCommands;
this.defaultCommands = defaultCommands;
this.valuesMapping = valuesMapping;
}
@@ -90,7 +84,9 @@ public class SwitchItem extends LoopItem implements Block {
for (int i = 0; i < caseCommands.size(); i++) {
for (int k = 0; k < valuesMapping.size(); k++) {
if (valuesMapping.get(k) == i) {
writer.append("case ");
if (!(caseValues.get(k) instanceof DefaultItem)) {
writer.append("case ");
}
caseValues.get(k).toString(writer, localData);
writer.append(":").newLine();
}
@@ -103,19 +99,6 @@ public class SwitchItem extends LoopItem implements Block {
}
writer.unindent();
}
if (defaultCommands != null) {
if (defaultCommands.size() > 0) {
writer.append("default");
writer.append(":").newLine();
writer.indent();
for (int j = 0; j < defaultCommands.size(); j++) {
if (!defaultCommands.get(j).isEmpty()) {
defaultCommands.get(j).toStringSemicoloned(writer, localData).newLine();
}
}
writer.unindent();
}
}
writer.endBlock();
if (writer instanceof NulWriter) {
LoopWithType loopOjb = ((NulWriter) writer).endLoop(loop.id);
@@ -138,16 +121,6 @@ public class SwitchItem extends LoopItem implements Block {
}
}
}
if (defaultCommands != null) {
for (GraphTargetItem ti : defaultCommands) {
if (ti instanceof ContinueItem) {
ret.add((ContinueItem) ti);
}
if (ti instanceof Block) {
ret.addAll(((Block) ti).getContinues());
}
}
}
return ret;
}