mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-27 19:15:33 +00:00
more stringbuilders
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package com.jpexs.decompiler.flash;
|
||||
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG3Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBitsJPEG4Tag;
|
||||
@@ -46,7 +47,6 @@ import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.flash.tags.base.Container;
|
||||
import com.jpexs.decompiler.flash.tags.base.ContainerItem;
|
||||
import com.jpexs.decompiler.flash.tags.base.Exportable;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@@ -298,11 +298,11 @@ public class TagNode {
|
||||
String res;
|
||||
ASMSource asm = ((ASMSource) node.tag);
|
||||
if (isPcode) {
|
||||
res = asm.getActionSourcePrefix() + Helper.indentRows(asm.getActionSourceIndent(), asm.getASMSource(SWF.DEFAULT_VERSION, false, false, null), Graph.INDENT_STRING) + asm.getActionSourceSuffix();
|
||||
res = asm.getActionSourcePrefix() + Helper.indentRows(asm.getActionSourceIndent(), asm.getASMSource(SWF.DEFAULT_VERSION, false, false, null), HilightedTextWriter.INDENT_STRING) + asm.getActionSourceSuffix();
|
||||
} else {
|
||||
List<Action> as = asm.getActions(SWF.DEFAULT_VERSION);
|
||||
Action.setActionsAddresses(as, 0, SWF.DEFAULT_VERSION);
|
||||
res = asm.getActionSourcePrefix() + Helper.indentRows(asm.getActionSourceIndent(), Action.actionsToSource(as, SWF.DEFAULT_VERSION, ""/*FIXME*/, false), Graph.INDENT_STRING) + asm.getActionSourceSuffix();
|
||||
res = asm.getActionSourcePrefix() + Helper.indentRows(asm.getActionSourceIndent(), Action.actionsToSource(as, SWF.DEFAULT_VERSION, ""/*FIXME*/, false), HilightedTextWriter.INDENT_STRING) + asm.getActionSourceSuffix();
|
||||
}
|
||||
try (FileOutputStream fos = new FileOutputStream(f)) {
|
||||
fos.write(res.getBytes("utf-8"));
|
||||
|
||||
@@ -31,8 +31,8 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
|
||||
import com.jpexs.decompiler.flash.abc.usages.*;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -630,7 +630,7 @@ public class ABC {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (int i = 0; i < parts.length; i++) {
|
||||
for (int t = 0; t < tabs; t++) {
|
||||
ret.append(Graph.INDENT_STRING);
|
||||
ret.append(HilightedTextWriter.INDENT_STRING);
|
||||
}
|
||||
ret.append(parts[i]);
|
||||
if (i < parts.length - 1) {
|
||||
|
||||
@@ -1341,13 +1341,15 @@ public class AVM2Code implements Serializable {
|
||||
public String tabString(int len) {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (int i = 0; i < len; i++) {
|
||||
ret.append(Graph.INDENT_STRING);
|
||||
ret.append(HilightedTextWriter.INDENT_STRING);
|
||||
}
|
||||
return ret.toString();
|
||||
}
|
||||
|
||||
public String toSource(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, ConstantPool constants, MethodInfo[] method_info, MethodBody body, HashMap<Integer, String> localRegNames, Stack<GraphTargetItem> scopeStack, boolean isStaticInitializer, List<String> fullyQualifiedNames, Traits initTraits, int staticOperation, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs) {
|
||||
return toSource(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, body, false, true, localRegNames, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits, staticOperation, localRegAssigmentIps, refs);
|
||||
HilightedTextWriter writer = new HilightedTextWriter(false);
|
||||
toSource(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, body, writer, true, localRegNames, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits, staticOperation, localRegAssigmentIps, refs);
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
public int getRegisterCount() {
|
||||
@@ -1417,7 +1419,7 @@ public class AVM2Code implements Serializable {
|
||||
ignoredIns = new ArrayList<>();
|
||||
}
|
||||
|
||||
public String toSource(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, ConstantPool constants, MethodInfo[] method_info, MethodBody body, boolean hilighted, boolean replaceIndents, HashMap<Integer, String> localRegNames, Stack<GraphTargetItem> scopeStack, boolean isStaticInitializer, List<String> fullyQualifiedNames, Traits initTraits, int staticOperation, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs) {
|
||||
public HilightedTextWriter toSource(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, ConstantPool constants, MethodInfo[] method_info, MethodBody body, HilightedTextWriter writer, boolean replaceIndents, HashMap<Integer, String> localRegNames, Stack<GraphTargetItem> scopeStack, boolean isStaticInitializer, List<String> fullyQualifiedNames, Traits initTraits, int staticOperation, HashMap<Integer, Integer> localRegAssigmentIps, HashMap<Integer, List<Integer>> refs) {
|
||||
initToSource();
|
||||
List<GraphTargetItem> list;
|
||||
String s;
|
||||
@@ -1434,7 +1436,7 @@ public class AVM2Code implements Serializable {
|
||||
if (ex2 instanceof OutOfMemoryError) {
|
||||
System.gc();
|
||||
}
|
||||
return "/*\r\n * Decompilation error\r\n * Code may be obfuscated\r\n * Error type: " + ex2.getClass().getSimpleName() + "\r\n */\r\nthrow new IllegalOperationError(\"Not decompiled due to error\");\r\n";
|
||||
return writer.append("/*\r\n * Decompilation error\r\n * Code may be obfuscated\r\n * Error type: " + ex2.getClass().getSimpleName() + "\r\n */\r\nthrow new IllegalOperationError(\"Not decompiled due to error\");\r\n");
|
||||
}
|
||||
if (initTraits != null) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
@@ -1482,7 +1484,7 @@ public class AVM2Code implements Serializable {
|
||||
}
|
||||
list = newList;
|
||||
if (list.isEmpty()) {
|
||||
return "";
|
||||
return writer;
|
||||
}
|
||||
}
|
||||
//Declarations
|
||||
@@ -1532,9 +1534,9 @@ public class AVM2Code implements Serializable {
|
||||
list.remove(lastPos);
|
||||
}
|
||||
|
||||
s = Graph.graphToString(list, hilighted, replaceIndents, LocalData.create(constants, localRegNames, fullyQualifiedNames));
|
||||
Graph.graphToString(list, writer, replaceIndents, LocalData.create(constants, localRegNames, fullyQualifiedNames));
|
||||
|
||||
return s;
|
||||
return writer;
|
||||
}
|
||||
|
||||
public void removeInstruction(int pos, MethodBody body) {
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.jpexs.decompiler.flash.abc.avm2.model;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
|
||||
public class NewFunctionAVM2Item extends AVM2Item {
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.jpexs.decompiler.flash.abc.avm2.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.jpexs.decompiler.flash.abc.avm2.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@@ -20,8 +20,8 @@ import com.jpexs.decompiler.flash.abc.avm2.model.InAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.SetTypeAVM2Item;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.LoopWithType;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
@@ -71,6 +71,7 @@ public class ForEachInAVM2Item extends LoopItem implements Block {
|
||||
|
||||
@Override
|
||||
protected HilightedTextWriter appendTo(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.startLoop(loop.id, LoopWithType.LOOP_TYPE_LOOP);
|
||||
writer.append("loop" + loop.id + ":").newLine();
|
||||
writer.append("for each (");
|
||||
expression.toString(writer, localData);
|
||||
@@ -85,6 +86,7 @@ public class ForEachInAVM2Item extends LoopItem implements Block {
|
||||
writer.unindent();
|
||||
writer.append("}").newLine();
|
||||
writer.append(":loop" + loop.id);
|
||||
writer.endLoop(loop.id);
|
||||
return writer;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@ import com.jpexs.decompiler.flash.abc.avm2.model.InAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.SetTypeAVM2Item;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.LoopWithType;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
@@ -71,6 +71,7 @@ public class ForInAVM2Item extends LoopItem implements Block {
|
||||
|
||||
@Override
|
||||
protected HilightedTextWriter appendTo(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.startLoop(loop.id, LoopWithType.LOOP_TYPE_LOOP);
|
||||
writer.append("loop" + loop.id + ":").newLine();
|
||||
writer.append("for (");
|
||||
expression.toString(writer, localData);
|
||||
@@ -85,6 +86,7 @@ public class ForInAVM2Item extends LoopItem implements Block {
|
||||
writer.unindent();
|
||||
writer.append("}").newLine();
|
||||
writer.append(":loop" + loop.id);
|
||||
writer.endLoop(loop.id);
|
||||
return writer;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.types.ABCException;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.model.ContinueItem;
|
||||
import com.jpexs.decompiler.graph.model.LocalData;
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
|
||||
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
@@ -129,7 +130,13 @@ public class MethodBody implements Cloneable, Serializable {
|
||||
s += Helper.timedCall(new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
return toSource(path, isStatic, scriptIndex, classIndex, abc, trait, constants, method_info, scopeStack, isStaticInitializer, hilight, replaceIndents, fullyQualifiedNames, initTraits);
|
||||
HilightedTextWriter writer = new HilightedTextWriter(hilight);
|
||||
toSource(path, isStatic, scriptIndex, classIndex, abc, trait, constants, method_info, scopeStack, isStaticInitializer, writer, replaceIndents, fullyQualifiedNames, initTraits);
|
||||
String s = writer.toString();
|
||||
if (replaceIndents) {
|
||||
s = Graph.removeNonRefenrencedLoopLabels(s);
|
||||
}
|
||||
return s;
|
||||
}
|
||||
}, timeout, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException | ExecutionException | TimeoutException ex) {
|
||||
@@ -140,7 +147,7 @@ public class MethodBody implements Cloneable, Serializable {
|
||||
return s;
|
||||
}
|
||||
|
||||
public String toSource(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, Trait trait, ConstantPool constants, MethodInfo[] method_info, Stack<GraphTargetItem> scopeStack, boolean isStaticInitializer, boolean hilight, boolean replaceIndents, List<String> fullyQualifiedNames, Traits initTraits) {
|
||||
public HilightedTextWriter toSource(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, Trait trait, ConstantPool constants, MethodInfo[] method_info, Stack<GraphTargetItem> scopeStack, boolean isStaticInitializer, HilightedTextWriter writer, boolean replaceIndents, List<String> fullyQualifiedNames, Traits initTraits) {
|
||||
AVM2Code deobfuscated = null;
|
||||
MethodBody b = (MethodBody) Helper.deepCopy(this);
|
||||
deobfuscated = b.code;
|
||||
@@ -153,17 +160,11 @@ public class MethodBody implements Cloneable, Serializable {
|
||||
}
|
||||
}
|
||||
//deobfuscated.restoreControlFlow(constants, b);
|
||||
//try {
|
||||
String s = deobfuscated.toSource(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, b, hilight, replaceIndents, getLocalRegNames(abc), scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap<Integer, Integer>(), deobfuscated.visitCode(b));
|
||||
s = s.trim();
|
||||
if (s.equals("")) {
|
||||
s = " ";
|
||||
}
|
||||
if (hilight) {
|
||||
s = Highlighting.hilighMethod(s, this.method_info);
|
||||
}
|
||||
|
||||
return s;
|
||||
writer.startMethod(this.method_info);
|
||||
deobfuscated.toSource(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, b, writer, replaceIndents, getLocalRegNames(abc), scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap<Integer, Integer>(), deobfuscated.visitCode(b));
|
||||
writer.endMethod();
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -31,9 +31,9 @@ import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import com.jpexs.decompiler.flash.abc.types.NamespaceSet;
|
||||
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
@@ -420,12 +420,12 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
|
||||
for (String imp : imports) {
|
||||
if (!imp.startsWith(".")) {
|
||||
out.println(Graph.INDENT_STRING + "import " + imp + ";");
|
||||
out.println(HilightedTextWriter.INDENT_STRING + "import " + imp + ";");
|
||||
}
|
||||
}
|
||||
out.println();
|
||||
for (String us : uses) {
|
||||
out.println(Graph.INDENT_STRING + "use namespace " + us + ";");
|
||||
out.println(HilightedTextWriter.INDENT_STRING + "use namespace " + us + ";");
|
||||
}
|
||||
out.println();
|
||||
|
||||
@@ -434,8 +434,8 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
if (classHeader.startsWith("private ")) {
|
||||
classHeader = classHeader.substring("private ".length());
|
||||
}
|
||||
out.println(Graph.INDENT_STRING + classHeader);
|
||||
out.println(Graph.INDENT_STRING + "{");
|
||||
out.println(HilightedTextWriter.INDENT_STRING + classHeader);
|
||||
out.println(HilightedTextWriter.INDENT_STRING + "{");
|
||||
|
||||
String toPrint;
|
||||
List<String> outTraits = new LinkedList<>();
|
||||
@@ -450,7 +450,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
if (Highlighting.stripHilights(bodyStr).trim().equals("")) {
|
||||
toPrint = ABC.addTabs(bodyStr + "/*classInitializer*/", 3);
|
||||
} else {
|
||||
toPrint = Graph.INDENT_STRING + Graph.INDENT_STRING + "{\r\n" + ABC.addTabs(bodyStr, 3) + "\r\n" + Graph.INDENT_STRING + Graph.INDENT_STRING + "}";
|
||||
toPrint = HilightedTextWriter.INDENT_STRING + HilightedTextWriter.INDENT_STRING + "{\r\n" + ABC.addTabs(bodyStr, 3) + "\r\n" + HilightedTextWriter.INDENT_STRING + HilightedTextWriter.INDENT_STRING + "}";
|
||||
}
|
||||
if (highlight) {
|
||||
toPrint = Highlighting.hilighTrait(toPrint, abc.class_info[class_info].static_traits.traits.length + abc.instance_info[class_info].instance_traits.traits.length + 1);
|
||||
@@ -484,7 +484,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
} else {
|
||||
constructorParams = abc.method_info[abc.instance_info[class_info].iinit_index].getParamStr(highlight, abc.constants, null, abc, fullyQualifiedNames);
|
||||
}
|
||||
toPrint = Graph.INDENT_STRING + Graph.INDENT_STRING + modifier + "function " + abc.constants.constant_multiname[abc.instance_info[class_info].name_index].getName(abc.constants, new ArrayList<String>()/*do not want full names here*/) + "(" + constructorParams + ") {\r\n" + bodyStr + "\r\n" + Graph.INDENT_STRING + Graph.INDENT_STRING + "}";
|
||||
toPrint = HilightedTextWriter.INDENT_STRING + HilightedTextWriter.INDENT_STRING + modifier + "function " + abc.constants.constant_multiname[abc.instance_info[class_info].name_index].getName(abc.constants, new ArrayList<String>()/*do not want full names here*/) + "(" + constructorParams + ") {\r\n" + bodyStr + "\r\n" + HilightedTextWriter.INDENT_STRING + HilightedTextWriter.INDENT_STRING + "}";
|
||||
if (highlight) {
|
||||
toPrint = Highlighting.hilighTrait(toPrint, abc.class_info[class_info].static_traits.traits.length + abc.instance_info[class_info].instance_traits.traits.length);
|
||||
}
|
||||
@@ -515,7 +515,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
s = s.replace(Graph.INDENT_STRING, "");
|
||||
s = s.replace(HilightedTextWriter.INDENT_STRING, "");
|
||||
}
|
||||
bui.append(s);
|
||||
}
|
||||
@@ -523,7 +523,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
|
||||
//out.println(Helper.joinStrings(outTraits, "\r\n\r\n"));
|
||||
out.println(bui.toString());
|
||||
out.println(Graph.INDENT_STRING + "}");//class
|
||||
out.println(HilightedTextWriter.INDENT_STRING + "}");//class
|
||||
out.flush();
|
||||
//Highlighting.doHighlight = true;
|
||||
try {
|
||||
|
||||
@@ -18,9 +18,9 @@ package com.jpexs.decompiler.flash.abc.types.traits;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.util.List;
|
||||
@@ -62,7 +62,7 @@ public class TraitFunction extends Trait implements TraitWithSlot {
|
||||
if (bodyIndex != -1) {
|
||||
bodyStr = ABC.addTabs(abc.bodies[bodyIndex].toString(path + "." + abc.constants.constant_multiname[name_index].getName(abc.constants, fullyQualifiedNames), pcode, isStatic, scriptIndex, classIndex, abc, this, abc.constants, abc.method_info, new Stack<GraphTargetItem>(), false, highlight, true, fullyQualifiedNames, null), 3);
|
||||
}
|
||||
return Graph.INDENT_STRING + Graph.INDENT_STRING + header + (abc.instance_info[classIndex].isInterface() ? ";" : " {\r\n" + bodyStr + "\r\n" + Graph.INDENT_STRING + Graph.INDENT_STRING + "}");
|
||||
return HilightedTextWriter.INDENT_STRING + HilightedTextWriter.INDENT_STRING + header + (abc.instance_info[classIndex].isInterface() ? ";" : " {\r\n" + bodyStr + "\r\n" + HilightedTextWriter.INDENT_STRING + HilightedTextWriter.INDENT_STRING + "}");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@ package com.jpexs.decompiler.flash.abc.types.traits;
|
||||
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.util.List;
|
||||
@@ -67,7 +67,7 @@ public class TraitMethodGetterSetter extends Trait {
|
||||
if (bodyIndex != -1) {
|
||||
bodyStr = ABC.addTabs(abc.bodies[bodyIndex].toString(path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames), pcode, isStatic, scriptIndex, classIndex, abc, this, abc.constants, abc.method_info, new Stack<GraphTargetItem>(), false, highlight, true, fullyQualifiedNames, null), 3);
|
||||
}
|
||||
return Graph.INDENT_STRING + Graph.INDENT_STRING + header + ((classIndex != -1 && abc.instance_info[classIndex].isInterface() || bodyIndex == -1) ? ";" : " {\r\n" + bodyStr + "\r\n" + Graph.INDENT_STRING + Graph.INDENT_STRING + "}");
|
||||
return HilightedTextWriter.INDENT_STRING + HilightedTextWriter.INDENT_STRING + header + ((classIndex != -1 && abc.instance_info[classIndex].isInterface() || bodyIndex == -1) ? ";" : " {\r\n" + bodyStr + "\r\n" + HilightedTextWriter.INDENT_STRING + HilightedTextWriter.INDENT_STRING + "}");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.abc.avm2.ConstantPool;
|
||||
import com.jpexs.decompiler.flash.abc.types.Multiname;
|
||||
import com.jpexs.decompiler.flash.abc.types.Namespace;
|
||||
import com.jpexs.decompiler.flash.abc.types.ValueKind;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
@@ -106,9 +107,9 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
|
||||
return valueStr;
|
||||
}
|
||||
|
||||
public String getNameValueStr(Trait parent, boolean highlight, ABC abc, List<String> fullyQualifiedNames) {
|
||||
String valueStr = getValueStr(parent, highlight, abc, fullyQualifiedNames);
|
||||
return getNameStr(highlight, abc, fullyQualifiedNames) + (valueStr == null ? "" : " = " + valueStr) + ";";
|
||||
public String getNameValueStr(Trait parent, ABC abc, List<String> fullyQualifiedNames) {
|
||||
String valueStr = getValueStr(parent, false, abc, fullyQualifiedNames);
|
||||
return getNameStr(false, abc, fullyQualifiedNames) + (valueStr == null ? "" : " = " + valueStr) + ";";
|
||||
}
|
||||
|
||||
public boolean isNamespace() {
|
||||
@@ -145,7 +146,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
|
||||
|
||||
if (valueStr != null) {
|
||||
ret += " = ";
|
||||
int befLen = Highlighting.stripHilights(Graph.INDENT_STRING + Graph.INDENT_STRING + ret).length();
|
||||
int befLen = Highlighting.stripHilights(HilightedTextWriter.INDENT_STRING + HilightedTextWriter.INDENT_STRING + ret).length();
|
||||
String[] valueStrParts = valueStr.split("\r\n");
|
||||
boolean first = true;
|
||||
for (int i = 0; i < valueStrParts.length; i++) {
|
||||
@@ -154,14 +155,14 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
|
||||
}
|
||||
if (Highlighting.stripHilights(valueStrParts[i]).equals(Graph.INDENTOPEN)) {
|
||||
if (!first) {
|
||||
befLen += Graph.INDENT_STRING.length();
|
||||
befLen += HilightedTextWriter.INDENT_STRING.length();
|
||||
}
|
||||
ret += valueStrParts[i].replace(Graph.INDENTOPEN, ""); //there can be highlights!
|
||||
continue;
|
||||
}
|
||||
if (Highlighting.stripHilights(valueStrParts[i]).equals(Graph.INDENTCLOSE)) {
|
||||
if (!first) {
|
||||
befLen -= Graph.INDENT_STRING.length();
|
||||
befLen -= HilightedTextWriter.INDENT_STRING.length();
|
||||
}
|
||||
ret += valueStrParts[i].replace(Graph.INDENTCLOSE, ""); //there can be highlights!
|
||||
continue;
|
||||
@@ -176,7 +177,7 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
ret = Graph.INDENT_STRING + Graph.INDENT_STRING + Highlighting.trim(ret) + ";";
|
||||
ret = HilightedTextWriter.INDENT_STRING + HilightedTextWriter.INDENT_STRING + Highlighting.trim(ret) + ";";
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ import com.jpexs.decompiler.flash.action.swf4.*;
|
||||
import com.jpexs.decompiler.flash.action.swf5.*;
|
||||
import com.jpexs.decompiler.flash.action.swf7.ActionDefineFunction2;
|
||||
import com.jpexs.decompiler.flash.ecma.Null;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
@@ -726,8 +727,10 @@ public class Action implements GraphSourceItem {
|
||||
int staticOperation = Graph.SOP_USE_STATIC; //(Boolean) Configuration.getConfig("autoDeobfuscate", true) ? Graph.SOP_SKIP_STATIC : Graph.SOP_USE_STATIC;
|
||||
|
||||
List<GraphTargetItem> tree = actionsToTree(new HashMap<Integer, String>(), new HashMap<String, GraphTargetItem>(), new HashMap<String, GraphTargetItem>(), actions, version, staticOperation, path);
|
||||
|
||||
return Graph.graphToString(tree, highlight, true, new LocalData());
|
||||
HilightedTextWriter writer = new HilightedTextWriter(highlight);
|
||||
Graph.graphToString(tree, writer, true, new LocalData());
|
||||
String s = Graph.removeNonRefenrencedLoopLabels(writer.toString());
|
||||
return s;
|
||||
}
|
||||
}, timeout, TimeUnit.SECONDS);
|
||||
} catch (TimeoutException ex) {
|
||||
|
||||
@@ -99,7 +99,7 @@ public class FunctionActionItem extends ActionItem {
|
||||
writer.append(")").newLine();
|
||||
writer.append("{").newLine();
|
||||
writer.indent();
|
||||
writer.appendNoHilight(Graph.graphToString(actions, writer.getIsHighlighted(), false, localData));
|
||||
Graph.graphToString(actions, writer, false, localData);
|
||||
writer.unindent();
|
||||
return writer.append("}");
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.jpexs.decompiler.flash.action.swf4.RegisterNumber;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.collections.MyEntry;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
@@ -85,11 +84,11 @@ public class ClassActionItem extends ActionItem implements Block {
|
||||
}
|
||||
Set<String> allMembers = new HashSet<>();
|
||||
for (GraphTargetItem it : allUsages) {
|
||||
allMembers.add(it.toStringNoQuotes(false, null));
|
||||
allMembers.add(it.toStringNoQuotes(LocalData.empty));
|
||||
}
|
||||
uninitializedVars.addAll(allMembers);
|
||||
for (MyEntry<GraphTargetItem, GraphTargetItem> v : vars) {
|
||||
String s = v.key.toStringNoQuotes(false, null);
|
||||
String s = v.key.toStringNoQuotes(LocalData.empty);
|
||||
if (uninitializedVars.contains(s)) {
|
||||
uninitializedVars.remove(s);
|
||||
}
|
||||
|
||||
@@ -31,8 +31,8 @@ import com.jpexs.decompiler.flash.action.swf5.ActionStoreRegister;
|
||||
import com.jpexs.decompiler.flash.action.swf6.ActionEnumerate2;
|
||||
import com.jpexs.decompiler.flash.ecma.Null;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.LoopWithType;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
@@ -65,6 +65,7 @@ public class ForInActionItem extends LoopActionItem implements Block {
|
||||
|
||||
@Override
|
||||
protected HilightedTextWriter appendTo(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.startLoop(loop.id, LoopWithType.LOOP_TYPE_LOOP);
|
||||
writer.append("loop" + loop.id + ":").newLine();
|
||||
writer.append("for(");
|
||||
if ((variableName instanceof DirectValueActionItem) && (((DirectValueActionItem) variableName).value instanceof RegisterNumber)) {
|
||||
@@ -81,7 +82,9 @@ public class ForInActionItem extends LoopActionItem implements Block {
|
||||
}
|
||||
writer.unindent();
|
||||
writer.append("}").newLine();
|
||||
return writer.append(":loop" + loop.id);
|
||||
writer.append(":loop" + loop.id);
|
||||
writer.endLoop(loop.id);
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -51,7 +51,7 @@ public class IfFrameLoadedActionItem extends ActionItem implements Block {
|
||||
writer.append(")").newLine();
|
||||
writer.append("{").newLine();
|
||||
writer.indent();
|
||||
writer.appendNoHilight(Graph.graphToString(actions, writer.getIsHighlighted(), false, localData));
|
||||
Graph.graphToString(actions, writer, false, localData);
|
||||
writer.unindent();
|
||||
return writer.append("}");
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.action.model.ActionItem;
|
||||
import com.jpexs.decompiler.flash.action.swf3.ActionSetTarget;
|
||||
import com.jpexs.decompiler.flash.action.swf4.ActionSetTarget2;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItemPos;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
|
||||
@@ -25,7 +25,6 @@ import com.jpexs.decompiler.flash.action.swf4.ActionJump;
|
||||
import com.jpexs.decompiler.flash.action.swf7.ActionTry;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
@@ -151,7 +150,7 @@ public class TryActionItem extends ActionItem implements Block {
|
||||
String catchName = null;
|
||||
if (catchExceptions != null) {
|
||||
if (!catchExceptions.isEmpty()) {
|
||||
catchName = catchExceptions.get(0).toStringNoQuotes(false, LocalData.create(new ConstantPool(asGenerator.getConstantPool())));
|
||||
catchName = catchExceptions.get(0).toStringNoQuotes(LocalData.create(new ConstantPool(asGenerator.getConstantPool())));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.action.model.ActionItem;
|
||||
import com.jpexs.decompiler.flash.action.swf5.ActionWith;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
|
||||
@@ -410,12 +410,12 @@ public class ActionScriptParser {
|
||||
if (nameStr instanceof GetMemberActionItem) {
|
||||
GetMemberActionItem mem = (GetMemberActionItem) nameStr;
|
||||
if (mem.memberName instanceof DirectValueActionItem) {
|
||||
classNameStr = ((DirectValueActionItem) mem.memberName).toStringNoQuotes(false, LocalData.create(new ConstantPool(constantPool)));
|
||||
classNameStr = ((DirectValueActionItem) mem.memberName).toStringNoQuotes(LocalData.create(new ConstantPool(constantPool)));
|
||||
}
|
||||
} else if (nameStr instanceof GetVariableActionItem) {
|
||||
GetVariableActionItem var = (GetVariableActionItem) nameStr;
|
||||
if (var.name instanceof DirectValueActionItem) {
|
||||
classNameStr = ((DirectValueActionItem) var.name).toStringNoQuotes(false, LocalData.create(new ConstantPool(constantPool)));
|
||||
classNameStr = ((DirectValueActionItem) var.name).toStringNoQuotes(LocalData.create(new ConstantPool(constantPool)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ public class ActionGetVariable extends Action {
|
||||
@Override
|
||||
public void translate(Stack<GraphTargetItem> stack, List<GraphTargetItem> output, java.util.HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem name = stack.pop();
|
||||
GraphTargetItem computedVal = variables.get(name.toStringNoQuotes(false, LocalData.create(null)));
|
||||
GraphTargetItem computedVal = variables.get(name.toStringNoQuotes(LocalData.empty));
|
||||
if (name instanceof DirectValueActionItem && ((DirectValueActionItem) name).value.equals("/:$version")) {
|
||||
stack.push(new GetVersionActionItem(this));
|
||||
} else if (!(name instanceof DirectValueActionItem) && !(name instanceof GetVariableActionItem)) {
|
||||
|
||||
@@ -50,7 +50,7 @@ public class ActionSetVariable extends Action implements StoreTypeAction {
|
||||
public void translate(Stack<GraphTargetItem> stack, List<GraphTargetItem> output, java.util.HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem value = stack.pop().getThroughDuplicate();
|
||||
GraphTargetItem name = stack.pop();
|
||||
variables.put(name.toStringNoQuotes(false, LocalData.create(null)), value);
|
||||
variables.put(name.toStringNoQuotes(LocalData.empty), value);
|
||||
if (value instanceof IncrementActionItem) {
|
||||
GraphTargetItem obj = ((IncrementActionItem) value).object;
|
||||
if (!stack.isEmpty()) {
|
||||
@@ -126,6 +126,6 @@ public class ActionSetVariable extends Action implements StoreTypeAction {
|
||||
if (stack.size() < 2) {
|
||||
return null;
|
||||
}
|
||||
return stack.get(stack.size() - 2).toStringNoQuotes(false, LocalData.create(cpool));
|
||||
return stack.get(stack.size() - 2).toStringNoQuotes(LocalData.create(cpool));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class ActionCallFunction extends Action {
|
||||
args.add(stack.pop());
|
||||
}
|
||||
CallFunctionActionItem cft = new CallFunctionActionItem(this, functionName, args);
|
||||
cft.calculatedFunction = functions.get(functionName.toStringNoQuotes(false, LocalData.create(null)));
|
||||
cft.calculatedFunction = functions.get(functionName.toStringNoQuotes(LocalData.empty));
|
||||
stack.push(cft);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ public class ActionDefineLocal extends Action {
|
||||
public void translate(Stack<GraphTargetItem> stack, List<GraphTargetItem> output, java.util.HashMap<Integer, String> regNames, HashMap<String, GraphTargetItem> variables, HashMap<String, GraphTargetItem> functions, int staticOperation, String path) {
|
||||
GraphTargetItem value = stack.pop();
|
||||
GraphTargetItem name = stack.pop();
|
||||
variables.put(name.toStringNoQuotes(false, LocalData.create(null)), value);
|
||||
variables.put(name.toStringNoQuotes(LocalData.empty), value);
|
||||
output.add(new DefineLocalActionItem(this, name, value));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,10 +34,10 @@ import com.jpexs.decompiler.flash.gui.Main;
|
||||
import com.jpexs.decompiler.flash.gui.TagTreeModel;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.gui.abc.LineMarkedEditorPane;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ASMSource;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.helpers.Cache;
|
||||
import com.jpexs.helpers.Helper;
|
||||
@@ -327,7 +327,7 @@ public class ActionPanel extends JPanel implements ActionListener {
|
||||
lastDecompiled = sc.text;
|
||||
lastASM = asm;
|
||||
stripped = lastDecompiled;
|
||||
decompiledEditor.setText(asm.getActionSourcePrefix() + Helper.indentRows(asm.getActionSourceIndent(), lastDecompiled, Graph.INDENT_STRING) + asm.getActionSourceSuffix());
|
||||
decompiledEditor.setText(asm.getActionSourcePrefix() + Helper.indentRows(asm.getActionSourceIndent(), lastDecompiled, HilightedTextWriter.INDENT_STRING) + asm.getActionSourceSuffix());
|
||||
}
|
||||
setEditMode(false);
|
||||
setDecompiledEditMode(false);
|
||||
@@ -608,7 +608,7 @@ public class ActionPanel extends JPanel implements ActionListener {
|
||||
decompiledEditor.getCaret().setVisible(true);
|
||||
decLabel.setIcon(View.getIcon("editing16"));
|
||||
} else {
|
||||
String newText = pref + Helper.indentRows(lastASM.getActionSourceIndent(), lastDecompiled, Graph.INDENT_STRING) + lastASM.getActionSourceSuffix();
|
||||
String newText = pref + Helper.indentRows(lastASM.getActionSourceIndent(), lastDecompiled, HilightedTextWriter.INDENT_STRING) + lastASM.getActionSourceSuffix();
|
||||
decompiledEditor.setText(newText);
|
||||
if (lastLine > -1) {
|
||||
decompiledEditor.gotoLine(lastLine + prefLines + 1);
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
package com.jpexs.decompiler.flash.helpers;
|
||||
|
||||
import com.jpexs.decompiler.flash.helpers.hilight.Highlighting;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
@@ -28,13 +28,14 @@ import java.util.Stack;
|
||||
*/
|
||||
public class HilightedTextWriter {
|
||||
|
||||
public static final String INDENT_STRING = " ";
|
||||
private StringBuilder sb = new StringBuilder();
|
||||
private boolean hilight;
|
||||
private boolean newLine = true;
|
||||
private int indent = 0;
|
||||
private Stack<GraphSourceItemPosition> offsets = new Stack<>();
|
||||
private Stack<LoopWithType> loopStack = new Stack<>();
|
||||
|
||||
public HilightedTextWriter() {
|
||||
}
|
||||
|
||||
public HilightedTextWriter(boolean hilight) {
|
||||
this.hilight = hilight;
|
||||
}
|
||||
@@ -43,15 +44,75 @@ public class HilightedTextWriter {
|
||||
return hilight;
|
||||
}
|
||||
|
||||
public void addOffset(GraphSourceItem src, int pos) {
|
||||
public HilightedTextWriter startOffset(GraphSourceItem src, int pos) {
|
||||
GraphSourceItemPosition itemPos = new GraphSourceItemPosition();
|
||||
itemPos.graphSourceItem = src;
|
||||
itemPos.position = pos;
|
||||
offsets.add(itemPos);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void removeOffset() {
|
||||
public HilightedTextWriter endOffset() {
|
||||
offsets.pop();
|
||||
return this;
|
||||
}
|
||||
|
||||
public HilightedTextWriter startMethod(long index) {
|
||||
if (hilight) {
|
||||
appendNoHilight(Highlighting.HLOPEN);
|
||||
appendNoHilight(Helper.escapeString("type=method;index=" + index));
|
||||
appendNoHilight(Highlighting.HLEND);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public HilightedTextWriter endMethod() {
|
||||
if (hilight) {
|
||||
appendNoHilight(Highlighting.HLCLOSE);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public HilightedTextWriter startLoop(long loopId, int loopType) {
|
||||
LoopWithType loop = new LoopWithType();
|
||||
loop.loopId = loopId;
|
||||
loop.type = loopType;
|
||||
loopStack.add(loop);
|
||||
return this;
|
||||
}
|
||||
|
||||
public HilightedTextWriter endLoop(long loopId) {
|
||||
LoopWithType loopIdInStack = loopStack.pop();
|
||||
if (loopId != loopIdInStack.loopId) {
|
||||
throw new Error("LoopId mismatch");
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getLoop() {
|
||||
if (loopStack.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
return loopStack.peek().loopId;
|
||||
}
|
||||
|
||||
public long getNonSwitchLoop() {
|
||||
if (loopStack.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int pos = loopStack.size() - 1;
|
||||
LoopWithType loop;
|
||||
do {
|
||||
loop = loopStack.get(pos);
|
||||
pos--;
|
||||
} while ((pos >= 0) && (loop.type == LoopWithType.LOOP_TYPE_SWITCH));
|
||||
|
||||
if (loop.type == LoopWithType.LOOP_TYPE_SWITCH) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return loop.loopId;
|
||||
}
|
||||
|
||||
public HilightedTextWriter append(String str) {
|
||||
@@ -59,30 +120,31 @@ public class HilightedTextWriter {
|
||||
GraphSourceItem src = itemPos.graphSourceItem;
|
||||
int pos = itemPos.position;
|
||||
if (src != null && hilight) {
|
||||
sb.append(Highlighting.hilighOffset(str, src.getOffset() + pos + 1));
|
||||
appendToSb(Highlighting.hilighOffset(str, src.getOffset() + pos + 1));
|
||||
} else {
|
||||
sb.append(str);
|
||||
appendToSb(str);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public HilightedTextWriter appendNoHilight(String str) {
|
||||
sb.append(str);
|
||||
appendToSb(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
public HilightedTextWriter indent() {
|
||||
append(Graph.INDENTOPEN).newLine();
|
||||
indent++;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HilightedTextWriter unindent() {
|
||||
append(Graph.INDENTCLOSE).newLine();
|
||||
indent--;
|
||||
return this;
|
||||
}
|
||||
|
||||
public HilightedTextWriter newLine() {
|
||||
sb.append("\r\n");
|
||||
newLine = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -101,4 +163,18 @@ public class HilightedTextWriter {
|
||||
public String toString() {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void appendToSb(String str) {
|
||||
if (newLine) {
|
||||
newLine = false;
|
||||
appendIndent();
|
||||
}
|
||||
sb.append(str);
|
||||
}
|
||||
|
||||
private void appendIndent() {
|
||||
for (int i = 0; i < indent; i++) {
|
||||
appendNoHilight(INDENT_STRING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2010-2013 JPEXS
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.helpers;
|
||||
|
||||
/**
|
||||
* Provides methods for highlighting positions of instructions in the text.
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class LoopWithType {
|
||||
|
||||
public static int LOOP_TYPE_LOOP = 0;
|
||||
public static int LOOP_TYPE_SWITCH = 1;
|
||||
|
||||
public long loopId;
|
||||
public int type;
|
||||
|
||||
}
|
||||
@@ -160,9 +160,9 @@ public class Highlighting implements Serializable {
|
||||
public Highlighting(int startPos, int len, long offset) {
|
||||
this(startPos, len, "");
|
||||
}
|
||||
private static final String HLOPEN = "<ffdec:\"";
|
||||
private static final String HLEND = "\">";
|
||||
private static final String HLCLOSE = "</ffdec>";
|
||||
public static final String HLOPEN = "<ffdec:\"";
|
||||
public static final String HLEND = "\">";
|
||||
public static final String HLCLOSE = "</ffdec>";
|
||||
|
||||
public static String hilight(String text, String data) {
|
||||
return HLOPEN + Helper.escapeString(data) + HLEND + text + HLCLOSE;
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.RunnableIOEx;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.action.Action;
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.tags.CSMTextSettingsTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineButton2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineButtonCxformTag;
|
||||
@@ -89,7 +90,6 @@ import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
|
||||
import com.jpexs.decompiler.flash.types.sound.MP3FRAME;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.helpers.Helper;
|
||||
import java.awt.Font;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
@@ -1113,7 +1113,7 @@ public class XFLConverter {
|
||||
|
||||
private static String convertActionScript(ASMSource as) {
|
||||
String decompiledAS = Action.actionsToSource(as.getActions(SWF.DEFAULT_VERSION), SWF.DEFAULT_VERSION, as.toString(), false);
|
||||
return as.getActionSourcePrefix() + Helper.indentRows(as.getActionSourceIndent(), decompiledAS, Graph.INDENT_STRING) + as.getActionSourceSuffix();
|
||||
return as.getActionSourcePrefix() + Helper.indentRows(as.getActionSourceIndent(), decompiledAS, HilightedTextWriter.INDENT_STRING) + as.getActionSourceSuffix();
|
||||
}
|
||||
|
||||
private static long getTimestamp() {
|
||||
|
||||
@@ -2139,15 +2139,6 @@ public class Graph {
|
||||
* String used to unindent line when converting to string
|
||||
*/
|
||||
public static final String INDENTCLOSE = "INDENTCLOSE";
|
||||
public static final String INDENT_STRING = " ";
|
||||
|
||||
private static String tabString(int len) {
|
||||
String ret = "";
|
||||
for (int i = 0; i < len; i++) {
|
||||
ret += INDENT_STRING;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts list of TreeItems to string
|
||||
@@ -2156,50 +2147,19 @@ public class Graph {
|
||||
* @param localData
|
||||
* @return String
|
||||
*/
|
||||
public static String graphToString(List<GraphTargetItem> tree, boolean highlight, boolean replaceIndents, LocalData localData) {
|
||||
HilightedTextWriter writer = new HilightedTextWriter(highlight);
|
||||
public static HilightedTextWriter graphToString(List<GraphTargetItem> tree, HilightedTextWriter writer, boolean replaceIndents, LocalData localData) {
|
||||
for (GraphTargetItem ti : tree) {
|
||||
if (!ti.isEmpty()) {
|
||||
ti.toStringSemicoloned(writer, localData).newLine();
|
||||
}
|
||||
}
|
||||
String[] parts = writer.toString().split("\r\n");
|
||||
StringBuilder ret = new StringBuilder();
|
||||
return writer;
|
||||
}
|
||||
|
||||
public static String removeNonRefenrencedLoopLabels(String source) {
|
||||
String[] parts = source.split("\r\n");
|
||||
String labelPattern = "loop(switch)?[0-9]*:";
|
||||
try {
|
||||
Stack<String> loopStack = new Stack<>();
|
||||
for (int p = 0; p < parts.length; p++) {
|
||||
String stripped = Highlighting.stripHilights(parts[p]);
|
||||
if (stripped.matches(labelPattern)) {
|
||||
loopStack.add(stripped.substring(0, stripped.length() - 1));
|
||||
}
|
||||
if (stripped.startsWith("break ")) {
|
||||
if (stripped.equals("break " + loopStack.peek().replace("switch", "") + ";")) {
|
||||
parts[p] = parts[p].replace(" " + loopStack.peek().replace("switch", ""), "");
|
||||
}
|
||||
}
|
||||
if (stripped.startsWith("continue ")) {
|
||||
if (loopStack.size() > 0) {
|
||||
int pos = loopStack.size() - 1;
|
||||
String loopname = "";
|
||||
do {
|
||||
loopname = loopStack.get(pos);
|
||||
pos--;
|
||||
} while ((pos >= 0) && (loopname.startsWith("loopswitch")));
|
||||
if (stripped.equals("continue " + loopname + ";")) {
|
||||
parts[p] = parts[p].replace(" " + loopname, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (stripped.startsWith(":")) {
|
||||
loopStack.pop();
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
|
||||
int level = 0;
|
||||
StringBuilder ret = new StringBuilder();
|
||||
for (int p = 0; p < parts.length; p++) {
|
||||
String strippedP = Highlighting.stripHilights(parts[p]).trim();
|
||||
if (strippedP.matches(labelPattern)) {//endsWith(":") && (!strippedP.startsWith("case ")) && (!strippedP.equals("default:"))) {
|
||||
@@ -2226,20 +2186,8 @@ public class Graph {
|
||||
if (strippedP.startsWith(":")) {
|
||||
continue;
|
||||
}
|
||||
strippedP = Highlighting.stripHilights(parts[p]).trim();
|
||||
|
||||
if (replaceIndents) {
|
||||
if (strippedP.equals(INDENTOPEN)) {
|
||||
level++;
|
||||
continue;
|
||||
}
|
||||
if (strippedP.equals(INDENTCLOSE)) {
|
||||
level--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
ret.append(tabString(level));
|
||||
ret.append(parts[p].trim());
|
||||
ret.append(parts[p]);
|
||||
ret.append("\r\n");
|
||||
}
|
||||
return ret.toString();
|
||||
|
||||
@@ -84,12 +84,12 @@ public abstract class GraphTargetItem implements Serializable {
|
||||
}
|
||||
|
||||
public HilightedTextWriter toStringSemicoloned(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.addOffset(src, pos);
|
||||
writer.startOffset(src, pos);
|
||||
appendTo(writer, localData);
|
||||
if (needsSemicolon()) {
|
||||
writer.append(";");
|
||||
}
|
||||
writer.removeOffset();
|
||||
writer.endOffset();
|
||||
return writer;
|
||||
}
|
||||
|
||||
@@ -103,9 +103,9 @@ public abstract class GraphTargetItem implements Serializable {
|
||||
}
|
||||
|
||||
public HilightedTextWriter toString(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.addOffset(src, pos);
|
||||
writer.startOffset(src, pos);
|
||||
appendTo(writer, localData);
|
||||
writer.removeOffset();
|
||||
writer.endOffset();
|
||||
return writer;
|
||||
}
|
||||
|
||||
@@ -144,16 +144,16 @@ public abstract class GraphTargetItem implements Serializable {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String toStringNoQuotes(boolean highlight, LocalData localData) {
|
||||
HilightedTextWriter writer = new HilightedTextWriter(highlight);
|
||||
public String toStringNoQuotes(LocalData localData) {
|
||||
HilightedTextWriter writer = new HilightedTextWriter(false);
|
||||
toStringNoQuotes(writer, localData);
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
public HilightedTextWriter toStringNoQuotes(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.addOffset(src, pos);
|
||||
writer.startOffset(src, pos);
|
||||
appendToNoQuotes(writer, localData);
|
||||
writer.removeOffset();
|
||||
writer.endOffset();
|
||||
return writer;
|
||||
}
|
||||
|
||||
@@ -174,12 +174,12 @@ public abstract class GraphTargetItem implements Serializable {
|
||||
}
|
||||
|
||||
public HilightedTextWriter toStringNL(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.addOffset(src, pos);
|
||||
writer.startOffset(src, pos);
|
||||
appendTo(writer, localData);
|
||||
if (needsNewLine()) {
|
||||
writer.newLine();
|
||||
}
|
||||
writer.removeOffset();
|
||||
writer.endOffset();
|
||||
return writer;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public class BlockItem extends GraphTargetItem {
|
||||
protected HilightedTextWriter appendTo(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.append("{").newLine();
|
||||
writer.indent();
|
||||
writer.appendNoHilight(Graph.graphToString(commands, writer.getIsHighlighted(), false, localData));
|
||||
Graph.graphToString(commands, writer, false, localData);
|
||||
writer.newLine();
|
||||
writer.unindent();
|
||||
return writer.append("}");
|
||||
|
||||
@@ -21,8 +21,11 @@ public class BreakItem extends GraphTargetItem {
|
||||
|
||||
@Override
|
||||
protected HilightedTextWriter appendTo(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.append("break ");
|
||||
return writer.append("loop" + loopId);
|
||||
writer.append("break");
|
||||
if (loopId != writer.getLoop()) {
|
||||
writer.append(" loop" + loopId);
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,8 +21,11 @@ public class ContinueItem extends GraphTargetItem {
|
||||
|
||||
@Override
|
||||
protected HilightedTextWriter appendTo(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.append("continue ");
|
||||
return writer.append("loop" + loopId);
|
||||
writer.append("continue");
|
||||
if (loopId != writer.getNonSwitchLoop()) {
|
||||
writer.append(" loop" + loopId);
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
package com.jpexs.decompiler.graph.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.LoopWithType;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
@@ -51,6 +51,7 @@ public class DoWhileItem extends LoopItem implements Block {
|
||||
|
||||
@Override
|
||||
protected HilightedTextWriter appendTo(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.startLoop(loop.id, LoopWithType.LOOP_TYPE_LOOP);
|
||||
writer.append("loop" + loop.id + ":").newLine();
|
||||
writer.append("do").newLine();
|
||||
writer.append("{").newLine();
|
||||
@@ -75,7 +76,9 @@ public class DoWhileItem extends LoopItem implements Block {
|
||||
}
|
||||
|
||||
writer.append(");").newLine();
|
||||
return writer.append(":loop" + loop.id);
|
||||
writer.append(":loop" + loop.id);
|
||||
writer.endLoop(loop.id);
|
||||
return writer;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
package com.jpexs.decompiler.graph.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.LoopWithType;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
@@ -52,6 +52,7 @@ public class ForItem extends LoopItem implements Block {
|
||||
|
||||
@Override
|
||||
protected HilightedTextWriter appendTo(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.startLoop(loop.id, LoopWithType.LOOP_TYPE_LOOP);
|
||||
writer.append("loop" + loop.id + ":").newLine();
|
||||
writer.append("for(");
|
||||
int p = 0;
|
||||
@@ -93,6 +94,7 @@ public class ForItem extends LoopItem implements Block {
|
||||
writer.unindent();
|
||||
writer.append("}").newLine();
|
||||
writer.append(":loop" + loop.id).newLine();
|
||||
writer.endLoop(loop.id);
|
||||
return writer;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.jpexs.decompiler.graph.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.SourceGenerator;
|
||||
|
||||
@@ -26,6 +26,7 @@ import java.util.List;
|
||||
*/
|
||||
public class LocalData {
|
||||
|
||||
public static LocalData empty = new LocalData();
|
||||
public ConstantPool constants;
|
||||
public com.jpexs.decompiler.flash.abc.avm2.ConstantPool constantsAvm2;
|
||||
public HashMap<Integer, String> localRegNames;
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
package com.jpexs.decompiler.graph.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.LoopWithType;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
@@ -53,6 +53,7 @@ public class SwitchItem extends LoopItem implements Block {
|
||||
|
||||
@Override
|
||||
protected HilightedTextWriter appendTo(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.startLoop(loop.id, LoopWithType.LOOP_TYPE_SWITCH);
|
||||
writer.append("loopswitch" + loop.id + ":").newLine();
|
||||
writer.append("switch(");
|
||||
switchedObject.toString(writer, localData);
|
||||
@@ -91,6 +92,7 @@ public class SwitchItem extends LoopItem implements Block {
|
||||
writer.unindent();
|
||||
writer.append("}").newLine();
|
||||
writer.append(":loop" + loop.id);
|
||||
writer.endLoop(loop.id);
|
||||
return writer;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
package com.jpexs.decompiler.graph.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.LoopWithType;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
@@ -39,6 +39,7 @@ public class UniversalLoopItem extends LoopItem implements Block {
|
||||
|
||||
@Override
|
||||
protected HilightedTextWriter appendTo(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.startLoop(loop.id, LoopWithType.LOOP_TYPE_LOOP);
|
||||
writer.append("loop" + loop.id + ":").newLine();
|
||||
writer.append("while(true)").newLine();
|
||||
writer.append("{").newLine();
|
||||
@@ -51,6 +52,7 @@ public class UniversalLoopItem extends LoopItem implements Block {
|
||||
writer.unindent();
|
||||
writer.append("}").newLine();
|
||||
writer.append(":loop" + loop.id);
|
||||
writer.endLoop(loop.id);
|
||||
return writer;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
package com.jpexs.decompiler.graph.model;
|
||||
|
||||
import com.jpexs.decompiler.flash.helpers.HilightedTextWriter;
|
||||
import com.jpexs.decompiler.flash.helpers.LoopWithType;
|
||||
import com.jpexs.decompiler.graph.Block;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphSourceItem;
|
||||
import com.jpexs.decompiler.graph.GraphTargetItem;
|
||||
import com.jpexs.decompiler.graph.Loop;
|
||||
@@ -46,6 +46,7 @@ public class WhileItem extends LoopItem implements Block {
|
||||
|
||||
@Override
|
||||
protected HilightedTextWriter appendTo(HilightedTextWriter writer, LocalData localData) {
|
||||
writer.startLoop(loop.id, LoopWithType.LOOP_TYPE_LOOP);
|
||||
writer.append("loop" + loop.id + ":").newLine();
|
||||
writer.append("while(");
|
||||
for (int i = 0; i < expression.size(); i++) {
|
||||
@@ -68,6 +69,7 @@ public class WhileItem extends LoopItem implements Block {
|
||||
writer.unindent();
|
||||
writer.append("}").newLine();
|
||||
writer.append(":loop" + loop.id);
|
||||
writer.endLoop(loop.id);
|
||||
return writer;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user