mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-07 02:58:43 +00:00
Support for comma operator in switch case statements
This commit is contained in:
@@ -6,6 +6,8 @@ All notable changes to this project will be documented in this file.
|
||||
- Using new FFDec icon on Mac
|
||||
- AS3: get/set slot for global scope
|
||||
- AS3: Incorrect handling of strict equals operator in if vs switch resulting in §§pop
|
||||
- Better goto detection/for continue
|
||||
- Support for comma operator in switch case statements
|
||||
|
||||
### Changed
|
||||
- AS3 test methods separated to classes
|
||||
|
||||
@@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
|
||||
import com.jpexs.decompiler.graph.model.AndItem;
|
||||
import com.jpexs.decompiler.graph.model.BranchStackResistant;
|
||||
import com.jpexs.decompiler.graph.model.BreakItem;
|
||||
import com.jpexs.decompiler.graph.model.CommaExpressionItem;
|
||||
import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
import com.jpexs.decompiler.graph.model.DefaultItem;
|
||||
import com.jpexs.decompiler.graph.model.DoWhileItem;
|
||||
@@ -100,7 +101,6 @@ public class Graph {
|
||||
return new LinkedHashMap<>();
|
||||
}
|
||||
|
||||
|
||||
protected List<GraphTargetItem> filter(List<GraphTargetItem> list) {
|
||||
return new ArrayList<>(list);
|
||||
}
|
||||
@@ -747,7 +747,6 @@ public class Graph {
|
||||
|
||||
//GraphPartDecision decision = prefix.isEmpty() ? null : prefix.get(prefix.size() - 1);
|
||||
//int removedCount = decisionToRemovedCount.containsKey(decision) ? decisionToRemovedCount.get(decision) : 0;
|
||||
|
||||
for (int i = 0; i < comparedPaths.size(); i++) {
|
||||
for (int j = prefix.size(); j < comparedPaths.get(i).size(); j++) {
|
||||
GraphPart partToClose = comparedPaths.get(i).get(j).part;
|
||||
@@ -877,7 +876,6 @@ public class Graph {
|
||||
}
|
||||
return null;
|
||||
}*/
|
||||
|
||||
protected boolean isPartEmpty(GraphPart part) {
|
||||
return false;
|
||||
}
|
||||
@@ -2346,8 +2344,12 @@ public class Graph {
|
||||
if (part.nextParts.size() > 2) {
|
||||
GraphPart next = getMostCommonPart(localData, part.nextParts, loops, new ArrayList<>());
|
||||
List<GraphPart> vis = new ArrayList<>();
|
||||
GraphTargetItem switchedItem = stack.pop();
|
||||
GraphTargetItem originalSwitchedItem = stack.pop();
|
||||
makeAllCommands(currentRet, stack);
|
||||
GraphTargetItem switchedItem = originalSwitchedItem;
|
||||
if ((switchedItem instanceof PopItem) && !currentRet.isEmpty() && (currentRet.get(currentRet.size() - 1) instanceof IfItem)) {
|
||||
switchedItem = currentRet.get(currentRet.size() - 1);
|
||||
}
|
||||
|
||||
List<GraphTargetItem> caseValues = new ArrayList<>();
|
||||
List<List<GraphTargetItem>> caseCommands = new ArrayList<>();
|
||||
@@ -2365,26 +2367,68 @@ public class Graph {
|
||||
GraphTargetItem it = switchedItem;
|
||||
int defaultBranch = 0;
|
||||
boolean hasExpr = false;
|
||||
List<GraphTargetItem> commaCommands = new ArrayList<>();
|
||||
Map<Integer, List<GraphTargetItem>> caseCommaCommands = new HashMap<>();
|
||||
|
||||
while (it instanceof TernarOpItem) {
|
||||
TernarOpItem to = (TernarOpItem) it;
|
||||
if (to.expression instanceof EqualsTypeItem) {
|
||||
if (to.onTrue instanceof IntegerValueTypeItem) {
|
||||
int cpos = ((IntegerValueTypeItem) to.onTrue).intValue();
|
||||
caseExpressionLeftSides.put(cpos, ((EqualsTypeItem) to.expression).getLeftSide());
|
||||
caseExpressionRightSides.put(cpos, ((EqualsTypeItem) to.expression).getRightSide());
|
||||
it = to.onFalse;
|
||||
while ((it instanceof TernarOpItem) || (it instanceof IfItem)) {
|
||||
|
||||
if (it instanceof IfItem) {
|
||||
IfItem ii = (IfItem) it;
|
||||
if (ii.expression instanceof EqualsTypeItem) {
|
||||
if (!ii.onFalse.isEmpty() && !ii.onTrue.isEmpty()
|
||||
&& ii.onTrue.get(ii.onTrue.size() - 1) instanceof PushItem
|
||||
&& ii.onTrue.get(ii.onTrue.size() - 1).value instanceof IntegerValueTypeItem) {
|
||||
int cpos = ((IntegerValueTypeItem) ii.onTrue.get(ii.onTrue.size() - 1).value).intValue();
|
||||
caseCommaCommands.put(cpos, commaCommands);
|
||||
caseExpressionLeftSides.put(cpos, ((EqualsTypeItem) ii.expression).getLeftSide());
|
||||
caseExpressionRightSides.put(cpos, ((EqualsTypeItem) ii.expression).getRightSide());
|
||||
commaCommands = new ArrayList<>();
|
||||
for (int f = 0; f < ii.onFalse.size() - 1; f++) {
|
||||
commaCommands.add(ii.onFalse.get(f));
|
||||
}
|
||||
it = ii.onFalse.get(ii.onFalse.size() - 1);
|
||||
if (it instanceof PushItem) {
|
||||
it = it.value;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (ii.expression instanceof FalseItem && !ii.onFalse.isEmpty()) {
|
||||
it = ii.onFalse.get(ii.onFalse.size() - 1);
|
||||
} else if (ii.expression instanceof TrueItem && !ii.onTrue.isEmpty()) {
|
||||
it = ii.onTrue.get(ii.onTrue.size() - 1);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (it instanceof TernarOpItem) {
|
||||
TernarOpItem to = (TernarOpItem) it;
|
||||
if (to.expression instanceof EqualsTypeItem) {
|
||||
if (to.onTrue instanceof IntegerValueTypeItem) {
|
||||
int cpos = ((IntegerValueTypeItem) to.onTrue).intValue();
|
||||
caseExpressionLeftSides.put(cpos, ((EqualsTypeItem) to.expression).getLeftSide());
|
||||
caseExpressionRightSides.put(cpos, ((EqualsTypeItem) to.expression).getRightSide());
|
||||
caseCommaCommands.put(cpos, commaCommands);
|
||||
commaCommands = new ArrayList<>();
|
||||
it = to.onFalse;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (to.expression instanceof FalseItem) {
|
||||
it = to.onFalse;
|
||||
} else if (to.expression instanceof TrueItem) {
|
||||
it = to.onTrue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else if (to.expression instanceof FalseItem) {
|
||||
it = to.onFalse;
|
||||
} else if (to.expression instanceof TrueItem) {
|
||||
it = to.onTrue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (switchedItem != originalSwitchedItem && !caseExpressionRightSides.isEmpty()) {
|
||||
currentRet.remove(currentRet.size() - 1);
|
||||
} else {
|
||||
switchedItem = originalSwitchedItem;
|
||||
}
|
||||
|
||||
//int ignoredBranch = -1;
|
||||
if (it instanceof IntegerValueTypeItem) {
|
||||
defaultBranch = ((IntegerValueTypeItem) it).intValue();
|
||||
@@ -2432,7 +2476,13 @@ public class Graph {
|
||||
|
||||
for (int i = 1; i < part.nextParts.size(); i++) {
|
||||
if (caseExpressions.containsKey(pos)) {
|
||||
caseValues.add(caseExpressions.get(pos));
|
||||
GraphTargetItem expr = caseExpressions.get(pos);
|
||||
if (caseCommaCommands.get(pos).size() > 0) {
|
||||
List<GraphTargetItem> exprCommaCommands = new ArrayList<>(caseCommaCommands.get(pos));
|
||||
exprCommaCommands.add(expr);
|
||||
expr = new CommaExpressionItem(null, expr.lineStartItem, exprCommaCommands);
|
||||
}
|
||||
caseValues.add(expr);
|
||||
} else if (part.nextParts.get(i) == defaultPart) {
|
||||
caseValues.add(new DefaultItem());
|
||||
} else {
|
||||
|
||||
@@ -1162,6 +1162,22 @@ public class ActionScript3Test extends ActionScriptTestBase {
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwitchComma() {
|
||||
decompileMethod("testSwitchComma", "var a:String = \"A\";\r\n"
|
||||
+ "switch(a)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "case \"A\":\r\n"
|
||||
+ "trace(\"is A\");\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "case \"B\":\r\n"
|
||||
+ "trace(\"is B\");\r\n"
|
||||
+ "case TestSwitchComma.X, \"C\":\r\n"
|
||||
+ "trace(\"is C\");\r\n"
|
||||
+ "}\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSwitchDefault() {
|
||||
decompileMethod("testSwitchDefault", "var a:* = 5;\r\n"
|
||||
|
||||
Binary file not shown.
@@ -69,8 +69,9 @@ package
|
||||
TestRest;
|
||||
TestStrictEquals;
|
||||
TestStringConcat;
|
||||
TestStrings;
|
||||
TestStrings;
|
||||
TestSwitch;
|
||||
TestSwitchComma;
|
||||
TestSwitchDefault;
|
||||
TestTernarOperator;
|
||||
TestTry;
|
||||
|
||||
27
libsrc/ffdec_lib/testdata/flashdevelop/src/tests/TestSwitchComma.as
vendored
Normal file
27
libsrc/ffdec_lib/testdata/flashdevelop/src/tests/TestSwitchComma.as
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
package tests
|
||||
{
|
||||
public class TestSwitchComma
|
||||
{
|
||||
private static const X:int = 7;
|
||||
|
||||
public function run():*
|
||||
{
|
||||
var b:int = 5;
|
||||
|
||||
var a:String = "A";
|
||||
switch (a)
|
||||
{
|
||||
case "A":
|
||||
trace("is A");
|
||||
break;
|
||||
case "B":
|
||||
trace("is B");
|
||||
case TestSwitchComma.X,"C":
|
||||
trace("is C");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user