diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java index 31ce6a1ed..01f32861f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java @@ -770,11 +770,11 @@ public class ABC { return null; } List staticTraits = class_info.get(classIndex).static_traits.traits; - if (traitId < staticTraits.size()) { + if (traitId >= 0 && traitId < staticTraits.size()) { return staticTraits.get(traitId); } else { List instanceTraits = instance_info.get(classIndex).instance_traits.traits; - if (traitId < staticTraits.size() + instanceTraits.size()) { + if (traitId >= 0 && traitId < staticTraits.size() + instanceTraits.size()) { traitId -= staticTraits.size(); return instanceTraits.get(traitId); } else { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java index e2d4063bd..d8387c175 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java @@ -20,6 +20,9 @@ import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.abc.types.Multiname; import com.jpexs.decompiler.flash.abc.types.Namespace; import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.TraitClass; +import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; +import com.jpexs.decompiler.flash.abc.types.traits.Traits; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.exporters.settings.ScriptExportSettings; @@ -28,6 +31,7 @@ import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.helpers.NulWriter; import com.jpexs.decompiler.flash.treeitems.AS3ClassTreeItem; import com.jpexs.decompiler.graph.DottedChain; +import com.jpexs.decompiler.graph.ScopeStack; import com.jpexs.helpers.CancellableWorker; import com.jpexs.helpers.Helper; import com.jpexs.helpers.Path; @@ -64,6 +68,7 @@ public class ScriptPack extends AS3ClassTreeItem { private final ClassPath path; public boolean isSimple = false; + public boolean scriptInitializerIsEmpty = false; @Override public SWF getSwf() { @@ -133,6 +138,34 @@ public class ScriptPack extends AS3ClassTreeItem { return packageName.equals("") ? scriptName : packageName + "." + scriptName; }*/ public void convert(final NulWriter writer, final List traits, final ScriptExportMode exportMode, final boolean parallel) throws InterruptedException { + + int script_init = abc.script_info.get(scriptIndex).init_index; + int bodyIndex = abc.findBodyIndex(script_init); + if (bodyIndex != -1) { + List ts = new ArrayList<>(); + //initialize all classes traits + for (Trait t : traits) { + if (t instanceof TraitClass) { + ts.add(abc.class_info.get(((TraitClass) t).class_info).static_traits); + + for (Trait trait : abc.class_info.get(((TraitClass) t).class_info).static_traits.traits) { + if (trait instanceof TraitSlotConst) { + ((TraitSlotConst) trait).assignedValue = null; + } + } + for (Trait trait : abc.instance_info.get(((TraitClass) t).class_info).instance_traits.traits) { + if (trait instanceof TraitSlotConst) { + ((TraitSlotConst) trait).assignedValue = null; + } + } + } + } + + writer.mark(); + abc.bodies.get(bodyIndex).convert(path +/*packageName +*/ "/.scriptinitializer", exportMode, true, script_init, scriptIndex, -1, abc, null, abc.constants, abc.method_info, new ScopeStack(), GraphTextWriter.TRAIT_SCRIPT_INITIALIZER, writer, new ArrayList(), ts, true); + scriptInitializerIsEmpty = !writer.getMark(); + + } for (int t : traitIndices) { Trait trait = traits.get(t); Multiname name = trait.getName(abc); @@ -147,6 +180,31 @@ public class ScriptPack extends AS3ClassTreeItem { private void appendTo(GraphTextWriter writer, List traits, ScriptExportMode exportMode, boolean parallel) throws InterruptedException { boolean first = true; + //script initializer + int script_init = abc.script_info.get(scriptIndex).init_index; + int bodyIndex = abc.findBodyIndex(script_init); + if (bodyIndex != -1 && Configuration.enableScriptInitializerDisplay.get()) { + //Note: There must be trait/method highlight even if the initializer is empty to TraitList in GUI to work correctly + //TODO: handle this better in GUI(?) + writer.startTrait(GraphTextWriter.TRAIT_SCRIPT_INITIALIZER); + writer.startMethod(script_init); + if (!scriptInitializerIsEmpty) { + writer.startBlock(); + abc.bodies.get(bodyIndex).toString(path +/*packageName +*/ "/.scriptinitializer", exportMode, abc, null, abc.constants, abc.method_info, writer, new ArrayList()); + writer.endBlock(); + } else { + writer.append(" "); + } + writer.endMethod(); + writer.endTrait(); + if (!scriptInitializerIsEmpty) { + writer.newLine(); + } + first = false; + } else { + //"/*classInitializer*/"; + } + for (int t : traitIndices) { if (!first) { writer.newLine(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 0b769c353..593d0ada2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -1879,7 +1879,7 @@ public class AVM2Code implements Cloneable { }*/ } - public List toGraphTargetItems(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, AVM2ConstantPool constants, List method_info, MethodBody body, HashMap localRegNames, ScopeStack scopeStack, boolean isStaticInitializer, List fullyQualifiedNames, Traits initTraits, int staticOperation, HashMap localRegAssigmentIps, HashMap> refs) throws InterruptedException { + public List toGraphTargetItems(String path, int methodIndex, boolean isStatic, int scriptIndex, int classIndex, ABC abc, AVM2ConstantPool constants, List method_info, MethodBody body, HashMap localRegNames, ScopeStack scopeStack, int initializerType, List fullyQualifiedNames, List initTraits, int staticOperation, HashMap localRegAssigmentIps, HashMap> refs) throws InterruptedException { initToSource(); List list; HashMap localRegs = new HashMap<>(); @@ -1893,6 +1893,7 @@ public class AVM2Code implements Cloneable { list = AVM2Graph.translateViaGraph(path, this, abc, body, isStatic, scriptIndex, classIndex, localRegs, scopeStack, localRegNames, fullyQualifiedNames, staticOperation, localRegAssigmentIps, refs); if (initTraits != null) { + loopi: for (int i = 0; i < list.size(); i++) { GraphTargetItem ti = list.get(i); if ((ti instanceof InitPropertyAVM2Item) || (ti instanceof SetPropertyAVM2Item)) { @@ -1907,20 +1908,23 @@ public class AVM2Code implements Cloneable { value = ((SetPropertyAVM2Item) ti).value; } Multiname m = abc.constants.getMultiname(multinameIndex); - for (Trait t : initTraits.traits) { - Multiname tm = abc.constants.getMultiname(t.name_index); - - if (tm != null && tm.equals(m)) { - if ((t instanceof TraitSlotConst)) { - if (((TraitSlotConst) t).isConst() || isStaticInitializer) { - if ((((TraitSlotConst) t).assignedValue) == null) { - ((TraitSlotConst) t).assignedValue = value; - list.remove(i); - i--; - continue; + for (Traits ts : initTraits) { + for (Trait t : ts.traits) { + Multiname tm = abc.constants.getMultiname(t.name_index); + if (tm != null && tm.equals(m)) { + if ((t instanceof TraitSlotConst)) { + if (((TraitSlotConst) t).isConst() || initializerType == GraphTextWriter.TRAIT_CLASS_INITIALIZER || initializerType == GraphTextWriter.TRAIT_SCRIPT_INITIALIZER) { + if ((((TraitSlotConst) t).assignedValue) == null) { + ((TraitSlotConst) t).assignedValue = value; + ((TraitSlotConst) t).assignmentInitializer = initializerType; + ((TraitSlotConst) t).assignmentMethod = methodIndex; + list.remove(i); + i--; + continue loopi; + } } + break; } - break; } } } @@ -1930,7 +1934,7 @@ public class AVM2Code implements Cloneable { } } } - if (isStaticInitializer) { + if (initializerType == GraphTextWriter.TRAIT_CLASS_INITIALIZER || initializerType == GraphTextWriter.TRAIT_SCRIPT_INITIALIZER) { List newList = new ArrayList<>(); for (GraphTargetItem ti : list) { if (!(ti instanceof ReturnVoidAVM2Item)) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java index 0d557a5c1..3a8cd6edd 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java @@ -86,7 +86,7 @@ public class NewFunctionAVM2Item extends AVM2Item { writer.startBlock(); if (body != null) { if (writer instanceof NulWriter) { - body.convert(path + "/inner", ScriptExportMode.AS, isStatic, scriptIndex, classIndex, abc, null, constants, methodInfo, new ScopeStack(), false, (NulWriter) writer, fullyQualifiedNames, null, false); + body.convert(path + "/inner", ScriptExportMode.AS, isStatic, methodIndex, scriptIndex, classIndex, abc, null, constants, methodInfo, new ScopeStack(), 0, (NulWriter) writer, fullyQualifiedNames, null, false); } else { body.toString(path + "/inner", ScriptExportMode.AS, abc, null, constants, methodInfo, writer, fullyQualifiedNames); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java index 21f43885d..753850321 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/MethodBody.java @@ -276,7 +276,7 @@ public final class MethodBody implements Cloneable { return ret; } - public void convert(final String path, ScriptExportMode exportMode, final boolean isStatic, final int scriptIndex, final int classIndex, final ABC abc, final Trait trait, final AVM2ConstantPool constants, final List method_info, final ScopeStack scopeStack, final boolean isStaticInitializer, final NulWriter writer, final List fullyQualifiedNames, final Traits initTraits, boolean firstLevel) throws InterruptedException { + public void convert(final String path, ScriptExportMode exportMode, final boolean isStatic, final int methodIndex, final int scriptIndex, final int classIndex, final ABC abc, final Trait trait, final AVM2ConstantPool constants, final List method_info, final ScopeStack scopeStack, final int initializerType, final NulWriter writer, final List fullyQualifiedNames, final List initTraits, boolean firstLevel) throws InterruptedException { if (debugMode) { System.err.println("Decompiling " + path); } @@ -294,11 +294,11 @@ public final class MethodBody implements Cloneable { @Override public Void call() throws InterruptedException { try (Statistics s1 = new Statistics("MethodBody.convert")) { - MethodBody converted = convertMethodBody(path, isStatic, scriptIndex, classIndex, abc, trait, constants, method_info, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits); + MethodBody converted = convertMethodBody(path, isStatic, scriptIndex, classIndex, abc, trait, constants, method_info, scopeStack, initializerType != GraphTextWriter.TRAIT_INSTANCE_INITIALIZER, fullyQualifiedNames, initTraits); HashMap localRegNames = getLocalRegNames(abc); List convertedItems1; try (Statistics s = new Statistics("AVM2Code.toGraphTargetItems")) { - convertedItems1 = converted.getCode().toGraphTargetItems(path, isStatic, scriptIndex, classIndex, abc, constants, method_info, converted, localRegNames, scopeStack, isStaticInitializer, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap<>(), converted.getCode().visitCode(converted)); + convertedItems1 = converted.getCode().toGraphTargetItems(path, methodIndex, isStatic, scriptIndex, classIndex, abc, constants, method_info, converted, localRegNames, scopeStack, initializerType, fullyQualifiedNames, initTraits, Graph.SOP_USE_STATIC, new HashMap<>(), converted.getCode().visitCode(converted)); } try (Statistics s = new Statistics("Graph.graphToString")) { Graph.graphToString(convertedItems1, writer, LocalData.create(constants, localRegNames, fullyQualifiedNames)); @@ -365,7 +365,7 @@ public final class MethodBody implements Cloneable { return writer; } - public MethodBody convertMethodBody(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, Trait trait, AVM2ConstantPool constants, List method_info, ScopeStack scopeStack, boolean isStaticInitializer, List fullyQualifiedNames, Traits initTraits) throws InterruptedException { + public MethodBody convertMethodBody(String path, boolean isStatic, int scriptIndex, int classIndex, ABC abc, Trait trait, AVM2ConstantPool constants, List method_info, ScopeStack scopeStack, boolean isStaticInitializer, List fullyQualifiedNames, List initTraits) throws InterruptedException { MethodBody body = clone(); AVM2Code code = body.getCode(); code.markMappedOffsets(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java index b0c95baaf..d2e5c3785 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java @@ -468,7 +468,7 @@ public class TraitClass extends Trait implements TraitWithSlot { if (bodyIndex != -1) { //Note: There must be trait/method highlight even if the initializer is empty to TraitList in GUI to work correctly //TODO: handle this better in GUI(?) - writer.startTrait(classInfo.static_traits.traits.size() + instanceInfo.instance_traits.traits.size() + 1); + writer.startTrait(GraphTextWriter.TRAIT_CLASS_INITIALIZER); writer.startMethod(classInfo.cinit_index); if (!classInitializerIsEmpty) { writer.startBlock(); @@ -507,7 +507,7 @@ public class TraitClass extends Trait implements TraitWithSlot { } writer.newLine(); - writer.startTrait(classInfo.static_traits.traits.size() + instanceInfo.instance_traits.traits.size()); + writer.startTrait(GraphTextWriter.TRAIT_INSTANCE_INITIALIZER); writer.startMethod(instanceInfo.iinit_index); writer.appendNoHilight(modifier); writer.appendNoHilight("function "); @@ -547,30 +547,23 @@ public class TraitClass extends Trait implements TraitWithSlot { String instanceInfoName = instanceInfo.getName(abc.constants).getName(abc.constants, fullyQualifiedNames, false); ClassInfo classInfo = abc.class_info.get(class_info); - for (Trait trait : classInfo.static_traits.traits) { - if (trait instanceof TraitSlotConst) { - ((TraitSlotConst) trait).assignedValue = null; - } - } - - for (Trait trait : instanceInfo.instance_traits.traits) { - if (trait instanceof TraitSlotConst) { - ((TraitSlotConst) trait).assignedValue = null; - } - } - + //class initializer int bodyIndex = abc.findBodyIndex(classInfo.cinit_index); if (bodyIndex != -1) { writer.mark(); - abc.bodies.get(bodyIndex).convert(path +/*packageName +*/ "/" + instanceInfoName + ".staticinitializer", exportMode, true, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new ScopeStack(), true, writer, fullyQualifiedNames, classInfo.static_traits, true); + List ts = new ArrayList<>(); + ts.add(classInfo.static_traits); + abc.bodies.get(bodyIndex).convert(path +/*packageName +*/ "/" + instanceInfoName + ".staticinitializer", exportMode, true, classInfo.cinit_index, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new ScopeStack(), GraphTextWriter.TRAIT_CLASS_INITIALIZER, writer, fullyQualifiedNames, ts, true); classInitializerIsEmpty = !writer.getMark(); } - //constructor + //constructor - instance initializer if (!instanceInfo.isInterface()) { bodyIndex = abc.findBodyIndex(instanceInfo.iinit_index); if (bodyIndex != -1) { - abc.bodies.get(bodyIndex).convert(path +/*packageName +*/ "/" + instanceInfoName + ".initializer", exportMode, false, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new ScopeStack(), false, writer, fullyQualifiedNames, instanceInfo.instance_traits, true); + List ts = new ArrayList<>(); + ts.add(instanceInfo.instance_traits); + abc.bodies.get(bodyIndex).convert(path +/*packageName +*/ "/" + instanceInfoName + ".initializer", exportMode, false, instanceInfo.iinit_index, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new ScopeStack(), GraphTextWriter.TRAIT_INSTANCE_INITIALIZER, writer, fullyQualifiedNames, ts, true); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java index 36d9ef724..473eaf595 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitFunction.java @@ -97,7 +97,7 @@ public class TraitFunction extends Trait implements TraitWithSlot { if (!abc.instance_info.get(classIndex).isInterface()) { int bodyIndex = abc.findBodyIndex(method_info); if (bodyIndex != -1) { - abc.bodies.get(bodyIndex).convert(path + "." + abc.constants.getMultiname(name_index).getName(abc.constants, fullyQualifiedNames, false), exportMode, isStatic, scriptIndex, classIndex, abc, this, abc.constants, abc.method_info, new ScopeStack(), false, writer, fullyQualifiedNames, null, true); + abc.bodies.get(bodyIndex).convert(path + "." + abc.constants.getMultiname(name_index).getName(abc.constants, fullyQualifiedNames, false), exportMode, isStatic, method_info, scriptIndex, classIndex, abc, this, abc.constants, abc.method_info, new ScopeStack(), 0, writer, fullyQualifiedNames, null, true); } } writer.endMethod(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java index bc01a059e..2c10edf5f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitMethodGetterSetter.java @@ -81,7 +81,7 @@ public class TraitMethodGetterSetter extends Trait { int bodyIndex = abc.findBodyIndex(method_info); if (!(classIndex != -1 && abc.instance_info.get(classIndex).isInterface() || bodyIndex == -1)) { if (bodyIndex != -1) { - abc.bodies.get(bodyIndex).convert(path, exportMode, isStatic, scriptIndex, classIndex, abc, this, abc.constants, abc.method_info, new ScopeStack(), false, writer, fullyQualifiedNames, null, true); + abc.bodies.get(bodyIndex).convert(path, exportMode, isStatic, method_info, scriptIndex, classIndex, abc, this, abc.constants, abc.method_info, new ScopeStack(), 0, writer, fullyQualifiedNames, null, true); } } writer.endMethod(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java index 6607b683b..d49bd2f5a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java @@ -47,6 +47,9 @@ public class TraitSlotConst extends Trait implements TraitWithSlot { @Internal public GraphTargetItem assignedValue; + public int assignmentInitializer = 0; + public int assignmentMethod = 0; + @Override public void delete(ABC abc, boolean d) { abc.constants.constant_multiname.get(name_index).deleted = d; @@ -101,19 +104,15 @@ public class TraitSlotConst extends Trait implements TraitWithSlot { public void getValueStr(Trait parent, GraphTextWriter writer, ABC abc, List fullyQualifiedNames) throws InterruptedException { if (assignedValue != null) { - if (parent instanceof TraitClass) { - TraitClass tc = (TraitClass) parent; - int traitInitId = abc.class_info.get(tc.class_info).static_traits.traits.size() - + abc.instance_info.get(tc.class_info).instance_traits.traits.size() + 1; - int initMethod = abc.class_info.get(tc.class_info).cinit_index; - writer.startTrait(traitInitId); - writer.startMethod(initMethod); - if (Configuration.showMethodBodyId.get()) { - writer.appendNoHilight("// method body id: "); - writer.appendNoHilight(abc.findBodyIndex(initMethod)); - writer.newLine(); - } + + writer.startTrait(assignmentInitializer); + writer.startMethod(assignmentMethod); + if (Configuration.showMethodBodyId.get()) { + writer.appendNoHilight("// method body id: "); + writer.appendNoHilight(abc.findBodyIndex(assignmentMethod)); + writer.newLine(); } + assignedValue.toString(writer, LocalData.create(abc.constants, new HashMap<>(), fullyQualifiedNames)); if (parent instanceof TraitClass) { writer.endMethod(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/FlasmLexer.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/FlasmLexer.java index 7f55acb47..92ad77855 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/FlasmLexer.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/pcode/FlasmLexer.java @@ -29,7 +29,7 @@ import com.jpexs.decompiler.flash.ecma.Undefined; /** * This class is a scanner generated by * JFlex 1.6.0 - * from the specification file C:/FFDec/jpexs-decompiler/libsrc/ffdec_lib/lexers/actionscript_pcode.flex + * from the specification file C:/Dropbox/Programovani/JavaSE/FFDec/libsrc/ffdec_lib/lexers/actionscript_pcode.flex */ public final class FlasmLexer { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java index 92f77b213..e4059bc82 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -490,6 +490,10 @@ public class Configuration { @ConfigurationCategory("script") public static final ConfigurationItem smartNumberFormatting = null; + @ConfigurationDefaultBoolean(false) + @ConfigurationCategory("script") + public static final ConfigurationItem enableScriptInitializerDisplay = null; + private enum OSId { WINDOWS, OSX, UNIX diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/GraphTextWriter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/GraphTextWriter.java index 91b4da078..e51dae0d5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/GraphTextWriter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/GraphTextWriter.java @@ -33,6 +33,10 @@ public abstract class GraphTextWriter { protected CodeFormatting formatting; + public static final int TRAIT_INSTANCE_INITIALIZER = -1; + public static final int TRAIT_CLASS_INITIALIZER = -2; + public static final int TRAIT_SCRIPT_INITIALIZER = -3; + public CodeFormatting getFormatting() { return formatting; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/TextLexer.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/TextLexer.java index ba771f9b5..96b6119d5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/TextLexer.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/TextLexer.java @@ -2,313 +2,265 @@ /* * Copyright (C) 2010-2015 JPEXS, All rights reserved. - * + * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3.0 of the License, or (at your option) any later version. - * + * * This library 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 * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library. */ package com.jpexs.decompiler.flash.tags.text; + + /** - * This class is a scanner generated by + * This class is a scanner generated by * JFlex 1.6.0 - * from the specification file - * C:/FFDec/jpexs-decompiler/libsrc/ffdec_lib/lexers/text.flex + * from the specification file C:/Dropbox/Programovani/JavaSE/FFDec/libsrc/ffdec_lib/lexers/text.flex */ public final class TextLexer { - /** - * This character denotes the end of file - */ - public static final int YYEOF = -1; + /** This character denotes the end of file */ + public static final int YYEOF = -1; - /** - * initial size of the lookahead buffer - */ - private static final int ZZ_BUFFERSIZE = 16384; + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; - /** - * lexical states - */ - public static final int YYINITIAL = 0; + /** lexical states */ + public static final int YYINITIAL = 0; + public static final int PARAMETER = 2; + public static final int VALUE = 4; - public static final int PARAMETER = 2; + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l + * at the beginning of a line + * l is of the form l = 2*k, k a non negative integer + */ + private static final int ZZ_LEXSTATE[] = { + 0, 0, 1, 1, 2, 2 + }; - public static final int VALUE = 4; + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\12\0\1\20\1\21\1\21\1\20\22\0\1\3\1\0\1\15\4\0"+ + "\1\16\10\0\12\5\7\0\6\4\24\0\1\6\1\7\1\2\1\0"+ + "\1\1\1\0\1\5\1\10\3\5\1\13\7\1\1\12\3\1\1\14"+ + "\1\1\1\11\3\1\1\17\2\1\12\0\1\21\u1fa2\0\1\21\1\21"+ + "\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\udfe6\0"; - /** - * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l - * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l - * at the beginning of a line - * l is of the form l = 2*k, k a non negative integer - */ - private static final int ZZ_LEXSTATE[] = { - 0, 0, 1, 1, 2, 2 - }; + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); - /** - * Translates characters to character classes - */ - private static final String ZZ_CMAP_PACKED - = "\12\0\1\20\1\21\1\21\1\20\22\0\1\3\1\0\1\15\4\0" - + "\1\16\10\0\12\5\7\0\6\4\24\0\1\6\1\7\1\2\1\0" - + "\1\1\1\0\1\5\1\10\3\5\1\13\7\1\1\12\3\1\1\14" - + "\1\1\1\11\3\1\1\17\2\1\12\0\1\21\u1fa2\0\1\21\1\21" - + "\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\udfe6\0"; + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); - /** - * Translates characters to character classes - */ - private static final char[] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + private static final String ZZ_ACTION_PACKED_0 = + "\3\0\1\1\1\2\1\1\1\3\1\4\1\5\1\6"+ + "\1\7\1\10\1\11\1\12\1\13\1\14\1\15\1\16"+ + "\1\17\1\20\1\21\1\22\1\10\1\0\1\23"; - /** - * Translates DFA states to action switch labels. - */ - private static final int[] ZZ_ACTION = zzUnpackAction(); + private static int [] zzUnpackAction() { + int [] result = new int[25]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } - private static final String ZZ_ACTION_PACKED_0 - = "\3\0\1\1\1\2\1\1\1\3\1\4\1\5\1\6" - + "\1\7\1\10\1\11\1\12\1\13\1\14\1\15\1\16" - + "\1\17\1\20\1\21\1\22\1\10\1\0\1\23"; - - private static int[] zzUnpackAction() { - int[] result = new int[25]; - int offset = 0; - offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); - return result; + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); } + return j; + } - private static int zzUnpackAction(String packed, int offset, int[] result) { - int i = 0; /* index in packed string */ - int j = offset; /* index in unpacked array */ + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); - int l = packed.length(); - while (i < l) { - int count = packed.charAt(i++); - int value = packed.charAt(i++); - do { - result[j++] = value; - } while (--count > 0); - } - return j; + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\22\0\44\0\66\0\66\0\110\0\66\0\132"+ + "\0\66\0\154\0\176\0\66\0\66\0\66\0\66\0\66"+ + "\0\66\0\66\0\66\0\66\0\66\0\66\0\220\0\242"+ + "\0\66"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[25]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); } + return j; + } - /** - * Translates a state to a row index in the transition table - */ - private static final int[] ZZ_ROWMAP = zzUnpackRowMap(); + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); - private static final String ZZ_ROWMAP_PACKED_0 - = "\0\0\0\22\0\44\0\66\0\66\0\110\0\66\0\132" - + "\0\66\0\154\0\176\0\66\0\66\0\66\0\66\0\66" - + "\0\66\0\66\0\66\0\66\0\66\0\66\0\220\0\242" - + "\0\66"; + private static final String ZZ_TRANS_PACKED_0 = + "\6\4\1\5\1\6\10\4\3\7\1\10\1\11\1\12"+ + "\1\7\1\10\2\7\5\10\2\7\1\10\1\12\1\7"+ + "\2\13\1\11\1\12\14\13\1\12\1\13\22\0\2\14"+ + "\1\15\3\14\1\16\1\17\1\20\1\21\1\22\1\23"+ + "\1\24\1\25\1\26\1\27\3\0\1\10\3\0\1\10"+ + "\2\0\5\10\2\0\1\10\5\0\1\12\14\0\1\12"+ + "\1\0\2\13\2\0\14\13\1\0\1\13\4\0\2\30"+ + "\2\0\1\30\2\0\1\30\12\0\2\31\2\0\1\31"+ + "\2\0\1\31\6\0"; - private static int[] zzUnpackRowMap() { - int[] result = new int[25]; - int offset = 0; - offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); - return result; + private static int [] zzUnpackTrans() { + int [] result = new int[180]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); } + return j; + } - private static int zzUnpackRowMap(String packed, int offset, int[] result) { - int i = 0; /* index in packed string */ - int j = offset; /* index in unpacked array */ + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; - int l = packed.length(); - while (i < l) { - int high = packed.charAt(i++) << 16; - result[j++] = high | packed.charAt(i++); - } - return j; + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\3\0\2\11\1\1\1\11\1\1\1\11\2\1\13\11"+ + "\1\1\1\0\1\11"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[25]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); } + return j; + } - /** - * The transition table of the DFA - */ - private static final int[] ZZ_TRANS = zzUnpackTrans(); + /** the input device */ + private java.io.Reader zzReader; - private static final String ZZ_TRANS_PACKED_0 - = "\6\4\1\5\1\6\10\4\3\7\1\10\1\11\1\12" - + "\1\7\1\10\2\7\5\10\2\7\1\10\1\12\1\7" - + "\2\13\1\11\1\12\14\13\1\12\1\13\22\0\2\14" - + "\1\15\3\14\1\16\1\17\1\20\1\21\1\22\1\23" - + "\1\24\1\25\1\26\1\27\3\0\1\10\3\0\1\10" - + "\2\0\5\10\2\0\1\10\5\0\1\12\14\0\1\12" - + "\1\0\2\13\2\0\14\13\1\0\1\13\4\0\2\30" - + "\2\0\1\30\2\0\1\30\12\0\2\31\2\0\1\31" - + "\2\0\1\31\6\0"; + /** the current state of the DFA */ + private int zzState; - private static int[] zzUnpackTrans() { - int[] result = new int[180]; - int offset = 0; - offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); - return result; - } + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; - private static int zzUnpackTrans(String packed, int offset, int[] result) { - int i = 0; /* index in packed string */ + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; - int j = offset; /* index in unpacked array */ + /** the textposition at the last accepting state */ + private int zzMarkedPos; - int l = packed.length(); - while (i < l) { - int count = packed.charAt(i++); - int value = packed.charAt(i++); - value--; - do { - result[j++] = value; - } while (--count > 0); - } - return j; - } + /** the current text position in the buffer */ + private int zzCurrentPos; + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; - /* error codes */ - private static final int ZZ_UNKNOWN_ERROR = 0; + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; - private static final int ZZ_NO_MATCH = 1; + /** number of newlines encountered up to the start of the matched text */ + private int yyline; - private static final int ZZ_PUSHBACK_2BIG = 2; + /** the number of characters up to the start of the matched text */ + private int yychar; - /* error messages for the codes above */ - private static final String ZZ_ERROR_MSG[] = { - "Unkown internal scanner error", - "Error: could not match input", - "Error: pushback value was too large" - }; + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; - /** - * ZZ_ATTRIBUTE[aState] contains the attributes of state aState - */ - private static final int[] ZZ_ATTRIBUTE = zzUnpackAttribute(); + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; - private static final String ZZ_ATTRIBUTE_PACKED_0 - = "\3\0\2\11\1\1\1\11\1\1\1\11\2\1\13\11" - + "\1\1\1\0\1\11"; + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; - private static int[] zzUnpackAttribute() { - int[] result = new int[25]; - int offset = 0; - offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); - return result; - } + /** denotes if the user-EOF-code has already been executed */ + private boolean zzEOFDone; + + /** + * The number of occupied positions in zzBuffer beyond zzEndRead. + * When a lead/high surrogate has been read from the input stream + * into the final zzBuffer position, this will have a value of 1; + * otherwise, it will have a value of 0. + */ + private int zzFinalHighSurrogate = 0; - private static int zzUnpackAttribute(String packed, int offset, int[] result) { - int i = 0; /* index in packed string */ + /* user code: */ - int j = offset; /* index in unpacked array */ - - int l = packed.length(); - while (i < l) { - int count = packed.charAt(i++); - int value = packed.charAt(i++); - do { - result[j++] = value; - } while (--count > 0); - } - return j; - } - - /** - * the input device - */ - private java.io.Reader zzReader; - - /** - * the current state of the DFA - */ - private int zzState; - - /** - * the current lexical state - */ - private int zzLexicalState = YYINITIAL; - - /** - * this buffer contains the current text to be matched and is - * the source of the yytext() string - */ - private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; - - /** - * the textposition at the last accepting state - */ - private int zzMarkedPos; - - /** - * the current text position in the buffer - */ - private int zzCurrentPos; - - /** - * startRead marks the beginning of the yytext() string in the buffer - */ - private int zzStartRead; - - /** - * endRead marks the last character in the buffer, that has been read - * from input - */ - private int zzEndRead; - - /** - * number of newlines encountered up to the start of the matched text - */ - private int yyline; - - /** - * the number of characters up to the start of the matched text - */ - private int yychar; - - /** - * the number of characters from the last newline up to the start of the - * matched text - */ - private int yycolumn; - - /** - * zzAtBOL == true <=> the scanner is currently at the beginning of a line - */ - private boolean zzAtBOL = true; - - /** - * zzAtEOF == true <=> the scanner is at the EOF - */ - private boolean zzAtEOF; - - /** - * denotes if the user-EOF-code has already been executed - */ - private boolean zzEOFDone; - - /** - * The number of occupied positions in zzBuffer beyond zzEndRead. - * When a lead/high surrogate has been read from the input stream - * into the final zzBuffer position, this will have a value of 1; - * otherwise, it will have a value of 0. - */ - private int zzFinalHighSurrogate = 0; - - /* user code: */ StringBuilder string = null; - boolean finish = false; - boolean parameter = false; - String parameterName = null; /** @@ -327,537 +279,480 @@ public final class TextLexer { return yyline + 1; } - /** - * Creates a new scanner - * - * @param in the java.io.Reader to read input from. - */ - public TextLexer(java.io.Reader in) { - this.zzReader = in; + + + /** + * Creates a new scanner + * + * @param in the java.io.Reader to read input from. + */ + public TextLexer(java.io.Reader in) { + this.zzReader = in; + } + + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + char [] map = new char[0x110000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 114) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + zzEndRead += zzFinalHighSurrogate; + zzFinalHighSurrogate = 0; + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzStartRead = 0; } - /** - * Unpacks the compressed character translation table. - * - * @param packed the packed character translation table - * @return the unpacked character translation table - */ - private static char[] zzUnpackCMap(String packed) { - char[] map = new char[0x110000]; - int i = 0; /* index in packed string */ + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length - zzFinalHighSurrogate) { + /* if not: blow it up */ + char newBuffer[] = new char[zzBuffer.length*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + zzEndRead += zzFinalHighSurrogate; + zzFinalHighSurrogate = 0; + } - int j = 0; /* index in unpacked array */ + /* fill the buffer with new input */ + int requested = zzBuffer.length - zzEndRead; + int totalRead = 0; + while (totalRead < requested) { + int numRead = zzReader.read(zzBuffer, zzEndRead + totalRead, requested - totalRead); + if (numRead == -1) { + break; + } + totalRead += numRead; + } - while (i < 114) { - int count = packed.charAt(i++); - char value = packed.charAt(i++); - do { - map[j++] = value; - } while (--count > 0); + if (totalRead > 0) { + zzEndRead += totalRead; + if (totalRead == requested) { /* possibly more input available */ + if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) { + --zzEndRead; + zzFinalHighSurrogate = 1; } - return map; + } + return false; } - /** - * Refills the input buffer. - * - * @return false, iff there was new input. - * - * @exception java.io.IOException if any I/O-Error occurs - */ - private boolean zzRefill() throws java.io.IOException { + // totalRead = 0: End of stream + return true; + } - /* first: make room (if you can) */ - if (zzStartRead > 0) { - zzEndRead += zzFinalHighSurrogate; - zzFinalHighSurrogate = 0; - System.arraycopy(zzBuffer, zzStartRead, - zzBuffer, 0, - zzEndRead - zzStartRead); + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ - /* translate stored positions */ - zzEndRead -= zzStartRead; - zzCurrentPos -= zzStartRead; - zzMarkedPos -= zzStartRead; - zzStartRead = 0; + if (zzReader != null) + zzReader.close(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * Internal scan buffer is resized down to its initial length, if it has grown. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEOFDone = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = 0; + zzFinalHighSurrogate = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + if (zzBuffer.length > ZZ_BUFFERSIZE) + zzBuffer = new char[ZZ_BUFFERSIZE]; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public ParsedSymbol yylex() throws java.io.IOException, TextParseException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + yychar+= zzMarkedPosL-zzStartRead; + + boolean zzR = false; + int zzCh; + int zzCharCount; + for (zzCurrentPosL = zzStartRead ; + zzCurrentPosL < zzMarkedPosL ; + zzCurrentPosL += zzCharCount ) { + zzCh = Character.codePointAt(zzBufferL, zzCurrentPosL, zzMarkedPosL); + zzCharCount = Character.charCount(zzCh); + switch (zzCh) { + case '\u000B': + case '\u000C': + case '\u0085': + case '\u2028': + case '\u2029': + yyline++; + yycolumn = 0; + zzR = false; + break; + case '\r': + yyline++; + yycolumn = 0; + zzR = true; + break; + case '\n': + if (zzR) + zzR = false; + else { + yyline++; + yycolumn = 0; + } + break; + default: + zzR = false; + yycolumn += zzCharCount; } + } - /* is the buffer big enough? */ - if (zzCurrentPos >= zzBuffer.length - zzFinalHighSurrogate) { - /* if not: blow it up */ - char newBuffer[] = new char[zzBuffer.length * 2]; - System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); - zzBuffer = newBuffer; - zzEndRead += zzFinalHighSurrogate; - zzFinalHighSurrogate = 0; + if (zzR) { + // peek one character ahead if it is \n (if we have counted one line too much) + boolean zzPeek; + if (zzMarkedPosL < zzEndReadL) + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + else if (zzAtEOF) + zzPeek = false; + else { + boolean eof = zzRefill(); + zzEndReadL = zzEndRead; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + if (eof) + zzPeek = false; + else + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; } + if (zzPeek) yyline--; + } + zzAction = -1; - /* fill the buffer with new input */ - int requested = zzBuffer.length - zzEndRead; - int totalRead = 0; - while (totalRead < requested) { - int numRead = zzReader.read(zzBuffer, zzEndRead + totalRead, requested - totalRead); - if (numRead == -1) { - break; - } - totalRead += numRead; - } + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = ZZ_LEXSTATE[zzLexicalState]; - if (totalRead > 0) { - zzEndRead += totalRead; - if (totalRead == requested) { /* possibly more input available */ + // set up zzAction for empty match case: + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + } - if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) { - --zzEndRead; - zzFinalHighSurrogate = 1; - } - } - return false; - } - - // totalRead = 0: End of stream - return true; - } - - /** - * Closes the input stream. - */ - public final void yyclose() throws java.io.IOException { - zzAtEOF = true; /* indicate end of file */ - - zzEndRead = zzStartRead; /* invalidate buffer */ - - if (zzReader != null) { - zzReader.close(); - } - } - - /** - * Resets the scanner to read from a new input stream. - * Does not close the old reader. - * - * All internal variables are reset, the old input stream - * cannot be reused (internal buffer is discarded and lost). - * Lexical state is set to ZZ_INITIAL. - * - * Internal scan buffer is resized down to its initial length, if it has - * grown. - * - * @param reader the new input stream - */ - public final void yyreset(java.io.Reader reader) { - zzReader = reader; - zzAtBOL = true; - zzAtEOF = false; - zzEOFDone = false; - zzEndRead = zzStartRead = 0; - zzCurrentPos = zzMarkedPos = 0; - zzFinalHighSurrogate = 0; - yyline = yychar = yycolumn = 0; - zzLexicalState = YYINITIAL; - if (zzBuffer.length > ZZ_BUFFERSIZE) { - zzBuffer = new char[ZZ_BUFFERSIZE]; - } - } - - /** - * Returns the current lexical state. - */ - public final int yystate() { - return zzLexicalState; - } - - /** - * Enters a new lexical state - * - * @param newState the new lexical state - */ - public final void yybegin(int newState) { - zzLexicalState = newState; - } - - /** - * Returns the text matched by the current regular expression. - */ - public final String yytext() { - return new String(zzBuffer, zzStartRead, zzMarkedPos - zzStartRead); - } - - /** - * Returns the character at position pos from the - * matched text. - * - * It is equivalent to yytext().charAt(pos), but faster - * - * @param pos the position of the character to fetch. - * A value from 0 to yylength()-1. - * - * @return the character at position pos - */ - public final char yycharat(int pos) { - return zzBuffer[zzStartRead + pos]; - } - - /** - * Returns the length of the matched text region. - */ - public final int yylength() { - return zzMarkedPos - zzStartRead; - } - - /** - * Reports an error that occured while scanning. - * - * In a wellformed scanner (no or only correct usage of - * yypushback(int) and a match-all fallback rule) this method - * will only be called with things that "Can't Possibly Happen". - * If this method is called, something is seriously wrong - * (e.g. a JFlex bug producing a faulty scanner etc.). - * - * Usual syntax/scanner level error handling should be done - * in error fallback rules. - * - * @param errorCode the code of the errormessage to display - */ - private void zzScanError(int errorCode) { - String message; - try { - message = ZZ_ERROR_MSG[errorCode]; - } catch (ArrayIndexOutOfBoundsException e) { - message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; - } - - throw new Error(message); - } - - /** - * Pushes the specified amount of characters back into the input stream. - * - * They will be read again by then next call of the scanning method - * - * @param number the number of characters to be read again. - * This number must not be greater than yylength()! - */ - public void yypushback(int number) { - if (number > yylength()) { - zzScanError(ZZ_PUSHBACK_2BIG); - } - - zzMarkedPos -= number; - } - - /** - * Resumes scanning until the next regular expression is matched, - * the end of input is encountered or an I/O-Error occurs. - * - * @return the next token - * @exception java.io.IOException if any I/O-Error occurs - */ - public ParsedSymbol yylex() throws java.io.IOException, TextParseException { - int zzInput; - int zzAction; - - // cached fields: - int zzCurrentPosL; - int zzMarkedPosL; - int zzEndReadL = zzEndRead; - char[] zzBufferL = zzBuffer; - char[] zzCMapL = ZZ_CMAP; - - int[] zzTransL = ZZ_TRANS; - int[] zzRowMapL = ZZ_ROWMAP; - int[] zzAttrL = ZZ_ATTRIBUTE; + zzForAction: { while (true) { - zzMarkedPosL = zzMarkedPos; - - yychar += zzMarkedPosL - zzStartRead; - - boolean zzR = false; - int zzCh; - int zzCharCount; - for (zzCurrentPosL = zzStartRead; - zzCurrentPosL < zzMarkedPosL; - zzCurrentPosL += zzCharCount) { - zzCh = Character.codePointAt(zzBufferL, zzCurrentPosL, zzMarkedPosL); - zzCharCount = Character.charCount(zzCh); - switch (zzCh) { - case '\u000B': - case '\u000C': - case '\u0085': - case '\u2028': - case '\u2029': - yyline++; - yycolumn = 0; - zzR = false; - break; - case '\r': - yyline++; - yycolumn = 0; - zzR = true; - break; - case '\n': - if (zzR) { - zzR = false; - } else { - yyline++; - yycolumn = 0; - } - break; - default: - zzR = false; - yycolumn += zzCharCount; - } + + if (zzCurrentPosL < zzEndReadL) { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); + zzCurrentPosL += Character.charCount(zzInput); + } + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; } - - if (zzR) { - // peek one character ahead if it is \n (if we have counted one line too much) - boolean zzPeek; - if (zzMarkedPosL < zzEndReadL) { - zzPeek = zzBufferL[zzMarkedPosL] == '\n'; - } else if (zzAtEOF) { - zzPeek = false; - } else { - boolean eof = zzRefill(); - zzEndReadL = zzEndRead; - zzMarkedPosL = zzMarkedPos; - zzBufferL = zzBuffer; - if (eof) { - zzPeek = false; - } else { - zzPeek = zzBufferL[zzMarkedPosL] == '\n'; - } - } - if (zzPeek) { - yyline--; - } + else { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); + zzCurrentPosL += Character.charCount(zzInput); } - zzAction = -1; + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; - zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } - zzState = ZZ_LEXSTATE[zzLexicalState]; - - // set up zzAction for empty match case: - int zzAttributes = zzAttrL[zzState]; - if ((zzAttributes & 1) == 1) { - zzAction = zzState; - } - - zzForAction: - { - while (true) { - - if (zzCurrentPosL < zzEndReadL) { - zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); - zzCurrentPosL += Character.charCount(zzInput); - } else if (zzAtEOF) { - zzInput = YYEOF; - break zzForAction; - } else { - // store back cached positions - zzCurrentPos = zzCurrentPosL; - zzMarkedPos = zzMarkedPosL; - boolean eof = zzRefill(); - // get translated positions and possibly new buffer - zzCurrentPosL = zzCurrentPos; - zzMarkedPosL = zzMarkedPos; - zzBufferL = zzBuffer; - zzEndReadL = zzEndRead; - if (eof) { - zzInput = YYEOF; - break zzForAction; - } else { - zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); - zzCurrentPosL += Character.charCount(zzInput); - } - } - int zzNext = zzTransL[zzRowMapL[zzState] + zzCMapL[zzInput]]; - if (zzNext == -1) { - break zzForAction; - } - zzState = zzNext; - - zzAttributes = zzAttrL[zzState]; - if ((zzAttributes & 1) == 1) { - zzAction = zzState; - zzMarkedPosL = zzCurrentPosL; - if ((zzAttributes & 8) == 8) { - break zzForAction; - } - } - - } - } - - // store back cached position - zzMarkedPos = zzMarkedPosL; - - switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { - case 1: { - if (string == null) { - string = new StringBuilder(); - } - string.append(yytext()); - } - case 20: - break; - case 2: { - parameter = true; - yybegin(PARAMETER); - if (string != null) { - String ret = string.toString(); - string = null; - return new ParsedSymbol(SymbolType.TEXT, ret); - } - } - case 21: - break; - case 3: { - if (!parameter) { - if (string == null) { - string = new StringBuilder(); - } - string.append(yytext()); - } - } - case 22: - break; - case 4: { - parameterName = yytext(); - yybegin(VALUE); - } - case 23: - break; - case 5: { - yybegin(YYINITIAL); - parameter = false; - } - case 24: - break; - case 6: { - } - case 25: - break; - case 7: { - yybegin(PARAMETER); - return new ParsedSymbol(SymbolType.PARAMETER, new Object[]{parameterName, yytext()}); - } - case 26: - break; - case 8: { - throw new TextParseException("Illegal escape sequence \"" + yytext() + "\"", yyline + 1); - } - case 27: - break; - case 9: { - if (string == null) { - string = new StringBuilder(); - } - string.append(']'); - } - case 28: - break; - case 10: { - if (string == null) { - string = new StringBuilder(); - } - string.append('['); - } - case 29: - break; - case 11: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\\'); - } - case 30: - break; - case 12: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\b'); - } - case 31: - break; - case 13: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\t'); - } - case 32: - break; - case 14: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\n'); - } - case 33: - break; - case 15: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\f'); - } - case 34: - break; - case 16: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\r'); - } - case 35: - break; - case 17: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\"'); - } - case 36: - break; - case 18: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\''); - } - case 37: - break; - case 19: { - char val = (char) Integer.parseInt(yytext().substring(2), 16); - string.append(val); - } - case 38: - break; - default: - if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { - zzAtEOF = true; - switch (zzLexicalState) { - case YYINITIAL: { - if (finish) { - return null; - } else { - finish = true; - return new ParsedSymbol(SymbolType.TEXT, string == null ? null : string.toString()); - } - } - case 26: - break; - default: { - return null; - } - } - } else { - zzScanError(ZZ_NO_MATCH); - } - } } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 1: + { if (string == null) string = new StringBuilder(); string.append(yytext()); + } + case 20: break; + case 2: + { parameter = true; + yybegin(PARAMETER); + if (string != null){ + String ret = string.toString(); + string = null; + return new ParsedSymbol(SymbolType.TEXT, ret); + } + } + case 21: break; + case 3: + { if (!parameter) { if (string == null) string = new StringBuilder(); string.append(yytext()); } + } + case 22: break; + case 4: + { parameterName = yytext(); + yybegin(VALUE); + } + case 23: break; + case 5: + { yybegin(YYINITIAL); + parameter = false; + } + case 24: break; + case 6: + { + } + case 25: break; + case 7: + { yybegin(PARAMETER); + return new ParsedSymbol(SymbolType.PARAMETER, new Object[] {parameterName, yytext()}); + } + case 26: break; + case 8: + { throw new TextParseException("Illegal escape sequence \"" + yytext() + "\"", yyline + 1); + } + case 27: break; + case 9: + { if (string == null) string = new StringBuilder(); string.append(']'); + } + case 28: break; + case 10: + { if (string == null) string = new StringBuilder(); string.append('['); + } + case 29: break; + case 11: + { if (string == null) string = new StringBuilder(); string.append('\\'); + } + case 30: break; + case 12: + { if (string == null) string = new StringBuilder(); string.append('\b'); + } + case 31: break; + case 13: + { if (string == null) string = new StringBuilder(); string.append('\t'); + } + case 32: break; + case 14: + { if (string == null) string = new StringBuilder(); string.append('\n'); + } + case 33: break; + case 15: + { if (string == null) string = new StringBuilder(); string.append('\f'); + } + case 34: break; + case 16: + { if (string == null) string = new StringBuilder(); string.append('\r'); + } + case 35: break; + case 17: + { if (string == null) string = new StringBuilder(); string.append('\"'); + } + case 36: break; + case 18: + { if (string == null) string = new StringBuilder(); string.append('\''); + } + case 37: break; + case 19: + { char val = (char) Integer.parseInt(yytext().substring(2), 16); + string.append(val); + } + case 38: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + switch (zzLexicalState) { + case YYINITIAL: { + if (finish) {return null;} else {finish=true; return new ParsedSymbol(SymbolType.TEXT, string == null ? null : string.toString());} + } + case 26: break; + default: + { + return null; + } + } + } + else { + zzScanError(ZZ_NO_MATCH); + } + } } + } + + } diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3Test.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3Test.java index 6d3f41161..df2232c21 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3Test.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3Test.java @@ -17,6 +17,7 @@ package com.jpexs.decompiler.flash; import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.types.traits.Traits; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.CodeFormatting; @@ -30,6 +31,7 @@ import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.List; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; import static org.testng.Assert.assertTrue; @@ -75,7 +77,9 @@ public class ActionScript3Test extends ActionScriptTestBase { assertTrue(bodyIndex > -1); HighlightedTextWriter writer = null; try { - abc.bodies.get(bodyIndex).convert(methodName, ScriptExportMode.AS, isStatic, -1/*FIX?*/, clsIndex, abc, null, abc.constants, abc.method_info, new ScopeStack(), false, new NulWriter(), new ArrayList<>(), abc.instance_info.get(clsIndex).instance_traits, true); + List ts = new ArrayList<>(); + ts.add(abc.instance_info.get(clsIndex).instance_traits); + abc.bodies.get(bodyIndex).convert(methodName, ScriptExportMode.AS, isStatic, -1/*FIX?*/, -1/*FIX?*/, clsIndex, abc, null, abc.constants, abc.method_info, new ScopeStack(), 0, new NulWriter(), new ArrayList<>(), ts, true); writer = new HighlightedTextWriter(new CodeFormatting(), false); abc.bodies.get(bodyIndex).toString(methodName, ScriptExportMode.AS, abc, null, abc.constants, abc.method_info, writer, new ArrayList<>()); } catch (InterruptedException ex) { diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/generators/AS3Generator.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/generators/AS3Generator.java index 7ae192e6f..6a89e294d 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/generators/AS3Generator.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/generators/AS3Generator.java @@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.types.MethodBody; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; +import com.jpexs.decompiler.flash.abc.types.traits.Traits; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.CodeFormatting; @@ -33,6 +34,7 @@ import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.List; /** * @@ -66,7 +68,9 @@ public class AS3Generator { s.append("\", "); HighlightedTextWriter src = new HighlightedTextWriter(new CodeFormatting(), false); MethodBody b = abc.findBody(((TraitMethodGetterSetter) t).method_info); - b.convert("", ScriptExportMode.AS, false, -1/*FIX?*/, classId, abc, null, abc.constants, abc.method_info, new ScopeStack(), false, new NulWriter(), new ArrayList<>(), abc.instance_info.get(classId).instance_traits, true); + List ts = new ArrayList<>(); + ts.add(abc.instance_info.get(classId).instance_traits); + b.convert("", ScriptExportMode.AS, false, -1/*FIX?*/, -1/*FIX?*/, classId, abc, null, abc.constants, abc.method_info, new ScopeStack(), 0, new NulWriter(), new ArrayList<>(), ts, true); b.toString("", ScriptExportMode.AS, abc, null, abc.constants, abc.method_info, src, new ArrayList<>()); String[] srcs = src.toString().split("[\r\n]+"); for (int i = 0; i < srcs.length; i++) { diff --git a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java index 891050978..8b533f87a 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/DecompiledEditorPane.java @@ -37,6 +37,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; import com.jpexs.decompiler.flash.gui.AppStrings; import com.jpexs.decompiler.flash.gui.View; import com.jpexs.decompiler.flash.gui.editor.LineMarkedEditorPane; +import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.helpers.hilight.HighlightData; import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; import com.jpexs.decompiler.flash.helpers.hilight.Highlighting; @@ -516,8 +517,8 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL Highlighting cm = Highlighting.searchPos(classHighlights, pos); if (cm != null) { classIndex = (int) cm.getProperties().index; - displayClass(classIndex, script.scriptIndex); } + displayClass(classIndex, script.scriptIndex); Highlighting tm = Highlighting.searchPos(methodHighlights, pos); if (tm != null) { String name = ""; @@ -594,13 +595,11 @@ public class DecompiledEditorPane extends LineMarkedEditorPane implements CaretL } public void gotoTrait(int traitId) { - if (traitId == -1) { - return; - } + boolean isScriptInit = traitId == GraphTextWriter.TRAIT_SCRIPT_INITIALIZER; Highlighting tc = Highlighting.searchIndex(classHighlights, classIndex); - if (tc != null) { - Highlighting th = Highlighting.searchIndex(traitHighlights, traitId, tc.startPos, tc.startPos + tc.len); + if (tc != null || isScriptInit) { + Highlighting th = Highlighting.searchIndex(traitHighlights, traitId, isScriptInit ? 0 : tc.startPos, isScriptInit ? -1 : tc.startPos + tc.len); int pos; if (th != null) { if (th.len > 1) { diff --git a/src/com/jpexs/decompiler/flash/gui/abc/IconListRenderer.java b/src/com/jpexs/decompiler/flash/gui/abc/IconListRenderer.java index 9bd740357..bb008a125 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/IconListRenderer.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/IconListRenderer.java @@ -70,6 +70,10 @@ public class IconListRenderer extends DefaultListCellRenderer { if (tli.getType() == TraitsListItem.Type.INITIALIZER) { label.setIcon(functionIcon); } + + if (tli.getType() == TraitsListItem.Type.SCRIPT_INITIALIZER) { + label.setIcon(functionIcon); + } return label; } } diff --git a/src/com/jpexs/decompiler/flash/gui/abc/TraitsList.java b/src/com/jpexs/decompiler/flash/gui/abc/TraitsList.java index dfd41d6f5..0f3bbb3fc 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/TraitsList.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/TraitsList.java @@ -71,11 +71,8 @@ public class TraitsList extends JList implements ListSelectionListener { return; } this.classIndex = classIndex; - if (classIndex == -1) { - setModel(new DefaultListModel<>()); - } else { - setModel(new TraitsListModel(abc, classIndex, scriptIndex, sorted)); - } + setModel(new TraitsListModel(abc, classIndex, scriptIndex, sorted)); + } private int lastSelected = -1; diff --git a/src/com/jpexs/decompiler/flash/gui/abc/TraitsListItem.java b/src/com/jpexs/decompiler/flash/gui/abc/TraitsListItem.java index 901325a91..d268da758 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/TraitsListItem.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/TraitsListItem.java @@ -51,6 +51,8 @@ public class TraitsListItem { public String STR_CLASS_INITIALIZER = AppStrings.translate("abc.traitslist.classinitializer"); + public String STR_SCRIPT_INITIALIZER = AppStrings.translate("abc.traitslist.scriptinitializer"); + public TraitsListItem(Type type, int index, boolean isStatic, ABC abc, int classIndex, int scriptIndex) { this.type = type; this.index = index; @@ -63,11 +65,17 @@ public class TraitsListItem { public int getGlobalTraitId() { if (type == Type.INITIALIZER) { if (!isStatic) { - return abc.class_info.get(classIndex).static_traits.traits.size() + abc.instance_info.get(classIndex).instance_traits.traits.size(); + return -1; + //return abc.class_info.get(classIndex).static_traits.traits.size() + abc.instance_info.get(classIndex).instance_traits.traits.size(); } else { - return abc.class_info.get(classIndex).static_traits.traits.size() + abc.instance_info.get(classIndex).instance_traits.traits.size() + 1; + return -2; + //return abc.class_info.get(classIndex).static_traits.traits.size() + abc.instance_info.get(classIndex).instance_traits.traits.size() + 1; } } + if (type == Type.SCRIPT_INITIALIZER) { + //return abc.class_info.get(classIndex).static_traits.traits.size() + abc.instance_info.get(classIndex).instance_traits.traits.size() + 2; + return -3; + } if (isStatic) { return index; } else { @@ -76,14 +84,21 @@ public class TraitsListItem { } public String toStringName() { - if ((type != Type.INITIALIZER) && isStatic) { + + if (type == Type.INITIALIZER) { + if (!isStatic) { + return "__" + STR_INSTANCE_INITIALIZER; + } else { + return "__" + STR_CLASS_INITIALIZER; + } + } + if (type == Type.SCRIPT_INITIALIZER) { + return "__" + STR_SCRIPT_INITIALIZER; + } + if (isStatic) { return abc.class_info.get(classIndex).static_traits.traits.get(index).getName(abc).getName(abc.constants, null, false); - } else if ((type != Type.INITIALIZER) && (!isStatic)) { - return abc.instance_info.get(classIndex).instance_traits.traits.get(index).getName(abc).getName(abc.constants, null, false); - } else if (!isStatic) { - return "__" + STR_INSTANCE_INITIALIZER; } else { - return "__" + STR_CLASS_INITIALIZER; + return abc.instance_info.get(classIndex).instance_traits.traits.get(index).getName(abc).getName(abc.constants, null, false); } } @@ -91,20 +106,24 @@ public class TraitsListItem { public String toString() { String s = ""; try { - if ((type != Type.INITIALIZER) && isStatic) { + if (type == Type.SCRIPT_INITIALIZER) { + s = STR_SCRIPT_INITIALIZER; + } else if (type == Type.INITIALIZER) { + if (!isStatic) { + s = STR_INSTANCE_INITIALIZER; + } else { + s = STR_CLASS_INITIALIZER; + } + } else if (isStatic) { abc.class_info.get(classIndex).static_traits.traits.get(index).convertHeader(null, "", abc, true, ScriptExportMode.AS, scriptIndex, classIndex, new NulWriter(), new ArrayList<>(), false); HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false); abc.class_info.get(classIndex).static_traits.traits.get(index).toStringHeader(null, "", abc, true, ScriptExportMode.AS, scriptIndex, classIndex, writer, new ArrayList<>(), false); s = writer.toString(); - } else if ((type != Type.INITIALIZER) && (!isStatic)) { + } else { abc.instance_info.get(classIndex).instance_traits.traits.get(index).convertHeader(null, "", abc, false, ScriptExportMode.AS, scriptIndex, classIndex, new NulWriter(), new ArrayList<>(), false); HighlightedTextWriter writer = new HighlightedTextWriter(Configuration.getCodeFormatting(), false); abc.instance_info.get(classIndex).instance_traits.traits.get(index).toStringHeader(null, "", abc, false, ScriptExportMode.AS, scriptIndex, classIndex, writer, new ArrayList<>(), false); s = writer.toString(); - } else if (!isStatic) { - s = STR_INSTANCE_INITIALIZER; - } else { - s = STR_CLASS_INITIALIZER; } } catch (InterruptedException ex) { Logger.getLogger(TraitsListItem.class.getName()).log(Level.SEVERE, null, ex); @@ -126,7 +145,8 @@ public class TraitsListItem { METHOD, VAR, CONST, - INITIALIZER; + INITIALIZER, + SCRIPT_INITIALIZER; public static Type getTypeForTrait(Trait t) { if (t instanceof TraitMethodGetterSetter) { diff --git a/src/com/jpexs/decompiler/flash/gui/abc/TraitsListModel.java b/src/com/jpexs/decompiler/flash/gui/abc/TraitsListModel.java index 7002f05ea..3b323fe95 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/TraitsListModel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/TraitsListModel.java @@ -49,14 +49,17 @@ public final class TraitsListModel implements ListModel { private void reset() { items = new ArrayList<>(); - for (int t = 0; t < abc.class_info.get(classIndex).static_traits.traits.size(); t++) { - items.add(new TraitsListItem(TraitsListItem.Type.getTypeForTrait(abc.class_info.get(classIndex).static_traits.traits.get(t)), t, true, abc, classIndex, scriptIndex)); + if (classIndex > -1) { + for (int t = 0; t < abc.class_info.get(classIndex).static_traits.traits.size(); t++) { + items.add(new TraitsListItem(TraitsListItem.Type.getTypeForTrait(abc.class_info.get(classIndex).static_traits.traits.get(t)), t, true, abc, classIndex, scriptIndex)); + } + for (int t = 0; t < abc.instance_info.get(classIndex).instance_traits.traits.size(); t++) { + items.add(new TraitsListItem(TraitsListItem.Type.getTypeForTrait(abc.instance_info.get(classIndex).instance_traits.traits.get(t)), t, false, abc, classIndex, scriptIndex)); + } + items.add(new TraitsListItem(TraitsListItem.Type.INITIALIZER, 0, false, abc, classIndex, scriptIndex)); + items.add(new TraitsListItem(TraitsListItem.Type.INITIALIZER, 0, true, abc, classIndex, scriptIndex)); } - for (int t = 0; t < abc.instance_info.get(classIndex).instance_traits.traits.size(); t++) { - items.add(new TraitsListItem(TraitsListItem.Type.getTypeForTrait(abc.instance_info.get(classIndex).instance_traits.traits.get(t)), t, false, abc, classIndex, scriptIndex)); - } - items.add(new TraitsListItem(TraitsListItem.Type.INITIALIZER, 0, false, abc, classIndex, scriptIndex)); - items.add(new TraitsListItem(TraitsListItem.Type.INITIALIZER, 0, true, abc, classIndex, scriptIndex)); + items.add(new TraitsListItem(TraitsListItem.Type.SCRIPT_INITIALIZER, 0, true, abc, classIndex, scriptIndex)); } public TraitsListModel(ABC abc, int classIndex, int scriptIndex, boolean sorted) { diff --git a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties index 8aff7357f..6585b91cb 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/AdvancedSettingsDialog.properties @@ -177,19 +177,19 @@ config.name.gui.window.maximized.vertical = (Internal) Window maximized vertical config.description.gui.window.maximized.vertical = Last window state - maximized vertically config.name.gui.avm2.splitPane.dividerLocationPercent = (Internal) AS3 Splitter location -config.description.gui.avm2.splitPane.dividerLocationPercent = +config.description.gui.avm2.splitPane.dividerLocationPercent = config.name.gui.actionSplitPane.dividerLocationPercent = (Internal) AS1/2 splitter location -config.description.gui.actionSplitPane.dividerLocationPercent = +config.description.gui.actionSplitPane.dividerLocationPercent = config.name.gui.previewSplitPane.dividerLocationPercent = (Internal) Preview splitter location -config.description.gui.previewSplitPane.dividerLocationPercent = +config.description.gui.previewSplitPane.dividerLocationPercent = config.name.gui.splitPane1.dividerLocationPercent = (Internal) Splitter location 1 -config.description.gui.splitPane1.dividerLocationPercent = +config.description.gui.splitPane1.dividerLocationPercent = config.name.gui.splitPane2.dividerLocationPercent = (Internal) Splitter location 2 -config.description.gui.splitPane2.dividerLocationPercent = +config.description.gui.splitPane2.dividerLocationPercent = config.name.saveAsExeScaleMode = Save as EXE scale mode config.description.saveAsExeScaleMode = Scaling mode for EXE export @@ -201,16 +201,16 @@ config.name.guiFontPreviewSampleText = (Internal) Last font preview sample text config.description.guiFontPreviewSampleText = Last font preview sample text list index config.name.gui.fontPreviewWindow.width = (Internal) Last font preview window width -config.description.gui.fontPreviewWindow.width = +config.description.gui.fontPreviewWindow.width = config.name.gui.fontPreviewWindow.height = (Internal) Last font preview window height -config.description.gui.fontPreviewWindow.height = +config.description.gui.fontPreviewWindow.height = config.name.gui.fontPreviewWindow.posX = (Internal) Last font preview window X -config.description.gui.fontPreviewWindow.posX = +config.description.gui.fontPreviewWindow.posX = config.name.gui.fontPreviewWindow.posY = (Internal) Last font preview window Y -config.description.gui.fontPreviewWindow.posY = +config.description.gui.fontPreviewWindow.posY = config.name.formatting.indent.size = Characters per indent config.description.formatting.indent.size = Number or spaces(or tabs) for one indentation @@ -307,7 +307,7 @@ config.name.textImportResizeTextBoundsMode = Text bounds resize mode config.description.textImportResizeTextBoundsMode = Text bounds resize mode after text editing. config.name.showCloseConfirmation = Show again SWF close confirmation -config.description.showCloseConfirmation = Show again SWF close confirmation for modified files. +config.description.showCloseConfirmation = Show again SWF close confirmation for modified files. config.name.showCodeSavedMessage = Show again code saved message config.description.showCodeSavedMessage = Show again code saved message @@ -352,7 +352,7 @@ config.name.loopMedia = Loop sounds and sprites config.description.loopMedia = Automatically restarts the playing of the sounds and sprites config.name.gui.timeLineSplitPane.dividerLocationPercent = (Internal) Timeline Splitter location -config.description.gui.timeLineSplitPane.dividerLocationPercent = +config.description.gui.timeLineSplitPane.dividerLocationPercent = config.name.cacheImages = Cache images config.description.cacheImages = Cache the decoded image objects @@ -374,3 +374,6 @@ config.description.overwriteExistingFiles = Overwrite the existing files during config.name.smartNumberFormatting = Use smart number formatting config.description.smartNumberFormatting = Format special numbers (for example colors and times) + +config.name.enableScriptInitializerDisplay = Display script initializers +config.description.enableScriptInitializerDisplay = Enable script initializers display and editation. This setting may add one newline to each class file for highlighting. diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index f2b262379..79ee78546 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -629,3 +629,4 @@ error.image.alpha.invalid = Invalid alpha channel data. #after version 6.0.2 contextmenu.saveUncompressedToFile = Save to Uncompressed File +abc.traitslist.scriptinitializer = script initializer \ No newline at end of file diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties index 5c86b17fd..2d53d4b1b 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame_cs.properties @@ -199,7 +199,7 @@ button.viewgraph = Zobrazit Graf button.viewhex = Zobrazit Hex abc.traitslist.instanceinitializer = inicializ\u00e1tor instance -abc.traitslist.classinitializer = inicializ\u00e1tor t\u0159\u00eddy +abc.traitslist.classinitializer = inicializ\u00e1tor t\u0159\u00eddy action.edit.experimental = (Experiment\u00e1ln\u00ed) @@ -603,4 +603,29 @@ tagInfo.neededCharacters = Pot\u0159ebn\u00e9 charaktery button.viewhexpcode = Zobrazit Hex s instrukcemi taginfo.header = Z\u00e1kladn\u00ed informace o tagu -tagInfo.dependentCharacters = Z\u00e1visl\u00e9 charaktery \ No newline at end of file +tagInfo.dependentCharacters = Z\u00e1visl\u00e9 charaktery + +#after version 5.3.0 +header.uncompressed = Bez komprese +header.warning.unsupportedGfxCompression = GFX podporuje pouze soubor se Zlib nebo \u017e\u00e1dnou kompres\u00ed. +header.warning.minimumZlibVersion = Zlib komprese vy\u017eaduje SWF verze 6 \u010di vy\u0161\u0161\u00ed. +header.warning.minimumLzmaVersion = LZMA komprese vy\u017eaduje SWF verze 13 \u010di vy\u0161\u0161\u00ed. + +tagInfo.codecName = N\u00e1zev kodeku +tagInfo.exportFormat = Form\u00e1t exportu +tagInfo.samplingRate = Vzorkovac\u00ed frekvence +tagInfo.stereo = Stereo +tagInfo.sampleCount = Po\u010det vzork\u016f + +filter.dmg = Spustieln\u00e9 soubory Macu (*.dmg) +filter.linuxExe = Linuxov\u00e9 spustiteln\u00e9 soubory + +import.script.result = %count% skript\u016f importov\u00e1no. +import.script.as12warning = Import skript\u016f funguje jen pro AS1/2 skripty. + +error.constantPoolTooBig = Seznam konstant je moc velk\u00fd index=%index%, velikost=%size% +error.image.alpha.invalid = Neplatn\u00e1 data alpha kan\u00e1lu. + +#after version 6.0.2 +contextmenu.saveUncompressedToFile = Ulo\u017eit nekomprimovan\u011b +abc.traitslist.scriptinitializer = inicializ\u00e1tor skriptu \ No newline at end of file