mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-22 05:45:43 +00:00
Fixed: #270 AS decompilation - comma in ternar
This commit is contained in:
@@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file.
|
||||
- [#1572] SVG Export - clipping must not use groups
|
||||
- [#270] AS decompilation - switch in loop
|
||||
- [#270] AS decompilation - loop followed by try
|
||||
- [#270] AS decompilation - comma in ternar
|
||||
|
||||
## [14.2.0] - 2021-03-12
|
||||
### Added
|
||||
|
||||
@@ -1825,6 +1825,15 @@ public class Graph {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected boolean canBeCommaised(List<GraphTargetItem> list) {
|
||||
for (GraphTargetItem item : list) {
|
||||
if (item instanceof Block) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected List<GraphTargetItem> printGraph(List<GotoItem> foundGotos, Map<GraphPart, List<GraphTargetItem>> partCodes, Map<GraphPart, Integer> partCodePos, Set<GraphPart> visited, BaseLocalData localData, TranslateStack stack, Set<GraphPart> allParts, GraphPart parent, GraphPart part, List<GraphPart> stopPart, List<StopPartKind> stopPartKind, List<Loop> loops, List<ThrowState> throwStates, List<GraphTargetItem> ret, int staticOperation, String path, int recursionLevel) throws InterruptedException {
|
||||
if (Thread.currentThread().isInterrupted()) {
|
||||
throw new InterruptedException();
|
||||
@@ -2133,6 +2142,14 @@ public class Graph {
|
||||
caseCommaCommands.put(cpos, commaCommands);
|
||||
commaCommands = new ArrayList<>();
|
||||
it = to.onFalse;
|
||||
if (it instanceof CommaExpressionItem) {
|
||||
commaCommands = new ArrayList<>();
|
||||
CommaExpressionItem ce = (CommaExpressionItem) it;
|
||||
for (int f = 0; f < ce.commands.size() - 1; f++) {
|
||||
commaCommands.add(ce.commands.get(f));
|
||||
}
|
||||
it = ce.commands.get(ce.commands.size() - 1);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@@ -2307,8 +2324,25 @@ public class Graph {
|
||||
List<GraphTargetItem> filteredOnTrue = onTrue;
|
||||
List<GraphTargetItem> filteredOnFalse = onFalse;
|
||||
|
||||
if (!isEmpty(filteredOnTrue) && !isEmpty(filteredOnFalse) && filteredOnTrue.size() == 1 && filteredOnFalse.size() == 1 && (filteredOnTrue.get(0) instanceof PushItem) && (filteredOnFalse.get(0) instanceof PushItem)) {
|
||||
stack.push(new TernarOpItem(null, localData.lineStartInstruction, expr.invert(null), ((PushItem) filteredOnTrue.get(0)).value, ((PushItem) filteredOnFalse.get(0)).value));
|
||||
if (!isEmpty(filteredOnTrue) && !isEmpty(filteredOnFalse)
|
||||
&& (filteredOnTrue.get(filteredOnTrue.size() - 1) instanceof PushItem)
|
||||
&& (filteredOnFalse.get(filteredOnFalse.size() - 1) instanceof PushItem)
|
||||
&& canBeCommaised(filteredOnTrue) && canBeCommaised(filteredOnFalse)) {
|
||||
GraphTargetItem ternarOnTrue;
|
||||
if (filteredOnTrue.size() > 1) {
|
||||
filteredOnTrue.set(filteredOnTrue.size() - 1, filteredOnTrue.get(filteredOnTrue.size() - 1).value); // replace Pushitem with its value
|
||||
ternarOnTrue = new CommaExpressionItem(null, null, filteredOnTrue);
|
||||
} else {
|
||||
ternarOnTrue = filteredOnTrue.get(0).value;
|
||||
}
|
||||
GraphTargetItem ternarOnFalse;
|
||||
if (filteredOnFalse.size() > 1) {
|
||||
filteredOnFalse.set(filteredOnFalse.size() - 1, filteredOnFalse.get(filteredOnFalse.size() - 1).value); // replace Pushitem with its value
|
||||
ternarOnFalse = new CommaExpressionItem(null, null, filteredOnFalse);
|
||||
} else {
|
||||
ternarOnFalse = filteredOnFalse.get(0).value;
|
||||
}
|
||||
stack.push(new TernarOpItem(null, localData.lineStartInstruction, expr.invert(null), ternarOnTrue, ternarOnFalse));
|
||||
} else {
|
||||
boolean isIf = true;
|
||||
//If the ontrue is empty, switch ontrue and onfalse
|
||||
|
||||
@@ -35,7 +35,7 @@ public class CommaExpressionItem extends GraphTargetItem {
|
||||
public List<GraphTargetItem> commands;
|
||||
|
||||
public CommaExpressionItem(GraphSourceItem src, GraphSourceItem lineStartIns, List<GraphTargetItem> commands) {
|
||||
super(src, lineStartIns, PRECEDENCE_PRIMARY);
|
||||
super(src, lineStartIns, PRECEDENCE_COMMA);
|
||||
this.commands = commands;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,31 +53,31 @@ public class TernarOpItem extends GraphTargetItem {
|
||||
|
||||
@Override
|
||||
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
|
||||
if (expression.getPrecedence() >= precedence){
|
||||
if (expression.getPrecedence() >= precedence) {
|
||||
writer.append("(");
|
||||
}
|
||||
expression.toString(writer, localData);
|
||||
if (expression.getPrecedence() >= precedence){
|
||||
if (expression.getPrecedence() >= precedence) {
|
||||
writer.append(")");
|
||||
}
|
||||
writer.append(" ? ");
|
||||
|
||||
if (onTrue instanceof TernarOpItem){ //ternar in ternar better in parenthesis
|
||||
|
||||
if (onTrue.getPrecedence() >= precedence && onTrue.getPrecedence() != GraphTargetItem.NOPRECEDENCE) { // >= ternar in ternar better in parenthesis
|
||||
writer.append("(");
|
||||
}
|
||||
onTrue.toString(writer, localData);
|
||||
if (onTrue instanceof TernarOpItem){
|
||||
if (onTrue.getPrecedence() >= precedence && onTrue.getPrecedence() != GraphTargetItem.NOPRECEDENCE) {
|
||||
writer.append(")");
|
||||
}
|
||||
}
|
||||
writer.append(" : ");
|
||||
if (onFalse instanceof TernarOpItem){
|
||||
writer.append("(");
|
||||
if (onFalse.getPrecedence() >= precedence && onFalse.getPrecedence() != GraphTargetItem.NOPRECEDENCE) {
|
||||
writer.append("(");
|
||||
}
|
||||
onFalse.toString(writer, localData);
|
||||
if (onFalse instanceof TernarOpItem){
|
||||
writer.append(")");
|
||||
if (onFalse.getPrecedence() >= precedence && onFalse.getPrecedence() != GraphTargetItem.NOPRECEDENCE) {
|
||||
writer.append(")");
|
||||
}
|
||||
|
||||
|
||||
return writer;
|
||||
}
|
||||
|
||||
|
||||
@@ -1978,7 +1978,7 @@ public class ActionScript2Test extends ActionScript2TestBase {
|
||||
+ "{\r\n"
|
||||
+ "trace(_loc1_);\r\n"
|
||||
+ "}\r\n"
|
||||
+ "_loc3_.r1 = _loc2_ + 1 + \". \" + (!_loc4_ ? _loc3_.r2 = v1[_loc2_][0] : \"unk\");\r\n"
|
||||
+ "_loc3_.r1 = _loc2_ + 1 + \". \" + (!_loc4_ ? (_loc3_.r2 = v1[_loc2_][0]) : \"unk\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"chainedAfterForInTest\");\r\n"
|
||||
+ "var v1 = {};\r\n"
|
||||
|
||||
@@ -75,6 +75,14 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComma() {
|
||||
decompileMethod("classic_air", "testComma", "var a:int = 5;\r\n"
|
||||
+ "var b:int = 0;\r\n"
|
||||
+ "trace(a > 4 ? (b = 5, a) : 35);\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComplexExpressions() {
|
||||
decompileMethod("classic_air", "testComplexExpressions", "var i:int = 0;\r\n"
|
||||
@@ -560,6 +568,25 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForInIf() {
|
||||
decompileMethod("classic_air", "testForInIf", "var arr:Array = [\"a\",\"b\",\"c\"];\r\n"
|
||||
+ "var b:int = 5;\r\n"
|
||||
+ "for(var a in arr)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "if(b == 5)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "if(b <= 7)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "return;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"b>7\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"forend\");\r\n"
|
||||
+ "}\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForInReturn() {
|
||||
decompileMethod("classic_air", "testForInReturn", "var dic:Dictionary = null;\r\n"
|
||||
@@ -574,6 +601,27 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForInSwitch() {
|
||||
decompileMethod("classic_air", "testForInSwitch", "var arr:Array = [\"a\",\"b\",\"c\"];\r\n"
|
||||
+ "for(var a in arr)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "switch(a)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "case \"a\":\r\n"
|
||||
+ "trace(\"val a\");\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "case \"b\":\r\n"
|
||||
+ "trace(\"val b\");\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "case \"c\":\r\n"
|
||||
+ "trace(\"val c\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"final\");\r\n"
|
||||
+ "}\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForXml() {
|
||||
decompileMethod("classic_air", "testForXml", "var i:int = 0;\r\n"
|
||||
@@ -846,6 +894,31 @@ public class ActionScript3ClassicAirDecompileTest extends ActionScript3Decompile
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIfTry() {
|
||||
decompileMethod("classic_air", "testIfTry", "var c:int = 0;\r\n"
|
||||
+ "var i:int = 0;\r\n"
|
||||
+ "var b:Boolean = true;\r\n"
|
||||
+ "if(b)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "c = 5;\r\n"
|
||||
+ "for(i = 0; i < c; )\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"xx\");\r\n"
|
||||
+ "i++;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "}\r\n"
|
||||
+ "try\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in try\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "catch(e:Error)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in catch\");\r\n"
|
||||
+ "}\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIgnoreAndOr() {
|
||||
decompileMethod("classic_air", "testIgnoreAndOr", "var k:int = Math.random();\r\n"
|
||||
|
||||
@@ -75,6 +75,14 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComma() {
|
||||
decompileMethod("classic", "testComma", "var a:int = 5;\r\n"
|
||||
+ "var b:int = 0;\r\n"
|
||||
+ "trace(a > 4 ? (b = 5, a) : 35);\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComplexExpressions() {
|
||||
decompileMethod("classic", "testComplexExpressions", "var i:int = 0;\r\n"
|
||||
@@ -554,6 +562,26 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForInIf() {
|
||||
decompileMethod("classic", "testForInIf", "var a:* = null;\r\n"
|
||||
+ "var arr:Array = [\"a\",\"b\",\"c\"];\r\n"
|
||||
+ "var b:int = 5;\r\n"
|
||||
+ "for(a in arr)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "if(b == 5)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "if(b <= 7)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "return;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"b>7\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"forend\");\r\n"
|
||||
+ "}\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForInReturn() {
|
||||
decompileMethod("classic", "testForInReturn", "var dic:Dictionary = null;\r\n"
|
||||
@@ -568,6 +596,29 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForInSwitch() {
|
||||
decompileMethod("classic", "testForInSwitch", "var a:* = null;\r\n"
|
||||
+ "var arr:Array = [\"a\",\"b\",\"c\"];\r\n"
|
||||
+ "for(a in arr)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "switch(a)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "case \"a\":\r\n"
|
||||
+ "trace(\"val a\");\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "case \"b\":\r\n"
|
||||
+ "trace(\"val b\");\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "case \"c\":\r\n"
|
||||
+ "trace(\"val c\");\r\n"
|
||||
+ "break;\r\n"
|
||||
+ "}\r\n"
|
||||
+ "trace(\"final\");\r\n"
|
||||
+ "}\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testForXml() {
|
||||
decompileMethod("classic", "testForXml", "var c:int = 0;\r\n"
|
||||
@@ -837,6 +888,30 @@ public class ActionScript3ClassicDecompileTest extends ActionScript3DecompileTes
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIfTry() {
|
||||
decompileMethod("classic", "testIfTry", "var c:int = 0;\r\n"
|
||||
+ "var i:int = 0;\r\n"
|
||||
+ "var b:Boolean = true;\r\n"
|
||||
+ "if(b)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "c = 5;\r\n"
|
||||
+ "for(i = 0; i < c; i++)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"xx\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "}\r\n"
|
||||
+ "try\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in try\");\r\n"
|
||||
+ "}\r\n"
|
||||
+ "catch(e:Error)\r\n"
|
||||
+ "{\r\n"
|
||||
+ "trace(\"in catch\");\r\n"
|
||||
+ "}\r\n",
|
||||
false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIgnoreAndOr() {
|
||||
decompileMethod("classic", "testIgnoreAndOr", "var k:int = Math.random();\r\n"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -21,6 +21,7 @@ package
|
||||
TestChainedAssignments;
|
||||
TestComplexExpressions;
|
||||
TestContinueLevels;
|
||||
TestComma;
|
||||
TestCompoundAssignments;
|
||||
TestDecl2;
|
||||
TestDeclarations;
|
||||
|
||||
13
libsrc/ffdec_lib/testdata/as3_new/src/tests/TestComma.as
vendored
Normal file
13
libsrc/ffdec_lib/testdata/as3_new/src/tests/TestComma.as
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
package tests
|
||||
{
|
||||
|
||||
public class TestComma
|
||||
{
|
||||
public function run():*
|
||||
{
|
||||
var a:int = 5;
|
||||
var b:int = 0;
|
||||
trace(a > 4 ? (b = 5, a) : 35);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user