diff --git a/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java b/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java
index e202fb06c..ea69ef907 100644
--- a/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java
+++ b/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java
@@ -1,565 +1,562 @@
-/*
- * Copyright (C) 2010-2014 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 .
- */
-package com.jpexs.decompiler.flash.abc.types.traits;
-
-import com.jpexs.decompiler.flash.abc.ABC;
-import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
-import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
-import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewFunctionIns;
-import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyIns;
-import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns;
-import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns;
-import com.jpexs.decompiler.flash.abc.avm2.instructions.types.AsTypeIns;
-import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceIns;
-import com.jpexs.decompiler.flash.abc.types.ABCException;
-import com.jpexs.decompiler.flash.abc.types.MethodBody;
-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.exporters.modes.ScriptExportMode;
-import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
-import com.jpexs.decompiler.flash.helpers.NulWriter;
-import com.jpexs.decompiler.flash.tags.ABCContainerTag;
-import com.jpexs.decompiler.graph.GraphTargetItem;
-import com.jpexs.helpers.Helper;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Stack;
-
-public class TraitClass extends Trait implements TraitWithSlot {
-
- public int slot_id;
- public int class_info;
- private static final String[] builtInClasses = {"ArgumentError", "arguments", "Array", "Boolean", "Class", "Date", "DefinitionError", "Error", "EvalError", "Function", "int", "JSON", "Math", "Namespace", "Number", "Object", "QName", "RangeError", "ReferenceError", "RegExp", "SecurityError", "String", "SyntaxError", "TypeError", "uint", "URIError", "VerifyError", "XML", "XMLList"};
-
- private boolean classInitializerIsEmpty;
-
- @Override
- public void delete(ABC abc, boolean d) {
- abc.class_info.get(class_info).deleted = d;
- abc.instance_info.get(class_info).deleted = d;
-
- abc.class_info.get(class_info).static_traits.delete(abc, d);
- abc.method_info.get(abc.class_info.get(class_info).cinit_index).delete(abc, d);
-
- abc.instance_info.get(class_info).instance_traits.delete(abc, d);
- abc.method_info.get(abc.instance_info.get(class_info).iinit_index).delete(abc, d);
-
- abc.constants.constant_namespace.get(abc.instance_info.get(class_info).protectedNS).deleted = d;
-
- abc.constants.constant_multiname.get(name_index).deleted = d;
- }
-
- @Override
- public int getSlotIndex() {
- return slot_id;
- }
-
- private static boolean isBuiltInClass(String name) {
- for (String g : builtInClasses) {
- if (g.equals(name)) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public String toString(ABC abc, List fullyQualifiedNames) {
- return "Class " + abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " slot=" + slot_id + " class_info=" + class_info + " metadata=" + Helper.intArrToString(metadata);
- }
-
- private boolean parseUsagesFromNS(List abcTags, ABC abc, List imports, List uses, int namespace_index, String ignorePackage, String name) {
- Namespace ns = abc.constants.getNamespace(namespace_index);
- if (name.isEmpty()) {
- name = "*";
- }
- String newimport = ns.getName(abc.constants);
- /*if ((ns.kind != Namespace.KIND_PACKAGE)
- && (ns.kind != Namespace.KIND_NAMESPACE)
- && (ns.kind != Namespace.KIND_STATIC_PROTECTED)) {
- return false;
- }*/
- /*if (ns.kind == Namespace.KIND_NAMESPACE)*/ {
- String oldimport = newimport;
- newimport = null;
- for (ABCContainerTag abcTag : abcTags) {
- String newname = abcTag.getABC().nsValueToName(oldimport);
- if (newname.equals("-")) {
- return true;
- }
- if (!newname.isEmpty()) {
- newimport = newname;
- break;
- }
- }
- if (newimport == null) {
- newimport = oldimport;
- newimport += "." + name;
- }
- if (newimport != null && newimport.isEmpty()) {
- newimport = null;
- }
- if (newimport != null) {
- /* if(ns.kind==Namespace.KIND_PACKAGE){
- newimport+=".*";
- }*/
-
- if (!imports.contains(newimport)) {
- if (newimport.contains(":")) {
- return true;
- }
- String pkg = "";
- if (newimport.contains(".")) {
- pkg = newimport.substring(0, newimport.lastIndexOf('.'));
- }
- String usname = newimport;
- if (usname.contains(".")) {
- usname = usname.substring(usname.lastIndexOf('.') + 1);
- }
- if (ns.kind == Namespace.KIND_PACKAGE) {
- if (!pkg.equals(ignorePackage)) {
- if (!pkg.equals("__AS3__.vec")) { //Automatic import
- imports.add(newimport);
- }
- }
- }
- if (ns.kind == Namespace.KIND_NAMESPACE) {
- if (!usname.equals("*")) {
- /*if (!uses.contains(usname)) {
- uses.add(usname);
- }*/
- if (!pkg.equals(ignorePackage)) {
- imports.add(newimport);
- }
- }
- }
- }
- return true;
- }
- }
- return false;
- }
-
- private void parseImportsUsagesFromNS(List abcTags, ABC abc, List imports, List uses, int namespace_index, String ignorePackage, String name) {
- Namespace ns = abc.constants.getNamespace(namespace_index);
- if (name.isEmpty()) {
- name = "*";
- }
- String newimport = ns.getName(abc.constants);
- if (parseUsagesFromNS(abcTags, abc, imports, uses, namespace_index, ignorePackage, name)) {
- return;
- } else if ((ns.kind != Namespace.KIND_PACKAGE) && (ns.kind != Namespace.KIND_PACKAGE_INTERNAL)) {
- return;
- }
- if (newimport == null) {
- newimport = "";
- }
- //if (!newimport.equals("")) {
- newimport += "." + name;
- if (newimport.contains(":")) {
- return;
- }
- if (!imports.contains(newimport)) {
- String pkg = newimport.substring(0, newimport.lastIndexOf('.'));
- if (pkg.equals("__AS3__.vec")) { //special case - is imported always
- return;
- }
- if (!pkg.equals(ignorePackage)) {
- imports.add(newimport);
- }
- }
- //}
- }
-
- private void parseUsagesFromMultiname(List abcTags, ABC abc, List imports, List uses, Multiname m, String ignorePackage, List fullyQualifiedNames) {
- if (m != null) {
- if (m.kind == Multiname.TYPENAME) {
- if (m.qname_index != 0) {
- parseUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames);
- }
- for (Integer i : m.params) {
- if (i != 0) {
- parseUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames);
- }
- }
- return;
- }
- Namespace ns = m.getNamespace(abc.constants);
- String name = m.getName(abc.constants, fullyQualifiedNames);
- NamespaceSet nss = m.getNamespaceSet(abc.constants);
- if (ns != null) {
- parseUsagesFromNS(abcTags, abc, imports, uses, m.namespace_index, ignorePackage, name);
- }
- if (nss != null) {
- if (nss.namespaces.length == 1) {
- parseUsagesFromNS(abcTags, abc, imports, uses, nss.namespaces[0], ignorePackage, name);
- } else {
- for (int n : nss.namespaces) {
- parseUsagesFromNS(abcTags, abc, imports, uses, n, ignorePackage, "");
- }
- }
- }
- }
- }
-
- private void parseImportsUsagesFromMultiname(List abcTags, ABC abc, List imports, List uses, Multiname m, String ignorePackage, List fullyQualifiedNames) {
- if (m != null) {
- if (m.kind == Multiname.TYPENAME) {
- if (m.qname_index != 0) {
- parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames);
- }
- for (Integer i : m.params) {
- if (i != 0) {
- parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames);
- }
- }
- return;
- }
- Namespace ns = m.getNamespace(abc.constants);
- String name = m.getName(abc.constants, fullyQualifiedNames);
- NamespaceSet nss = m.getNamespaceSet(abc.constants);
- if (ns != null) {
- parseImportsUsagesFromNS(abcTags, abc, imports, uses, m.namespace_index, ignorePackage, name);
- }
- if (nss != null) {
- if (nss.namespaces.length == 1) {
- parseImportsUsagesFromNS(abcTags, abc, imports, uses, nss.namespaces[0], ignorePackage, name);
- }
- }
- }
- }
-
- private void parseImportsUsagesFromMethodInfo(List abcTags, ABC abc, int method_index, List imports, List uses, String ignorePackage, List fullyQualifiedNames, List visitedMethods) {
- if ((method_index < 0) || (method_index >= abc.method_info.size())) {
- return;
- }
- visitedMethods.add(method_index);
- if (abc.method_info.get(method_index).ret_type != 0) {
- parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(abc.method_info.get(method_index).ret_type), ignorePackage, fullyQualifiedNames);
- }
- for (int t : abc.method_info.get(method_index).param_types) {
- if (t != 0) {
- parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(t), ignorePackage, fullyQualifiedNames);
- }
- }
- MethodBody body = abc.findBody(method_index);
- if (body != null) {
- parseImportsUsagesFromTraits(abcTags, abc, body.traits, imports, uses, ignorePackage, fullyQualifiedNames);
- for (ABCException ex : body.exceptions) {
- parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(ex.type_index), ignorePackage, fullyQualifiedNames);
- }
- for (AVM2Instruction ins : body.code.code) {
- if (ins.definition instanceof NewFunctionIns) {
- if (ins.operands[0] != method_index) {
- if (!visitedMethods.contains(ins.operands[0])) {
- parseImportsUsagesFromMethodInfo(abcTags, abc, ins.operands[0], imports, uses, ignorePackage, fullyQualifiedNames, visitedMethods);
- }
- }
- }
- if ((ins.definition instanceof FindPropertyStrictIns)
- || (ins.definition instanceof FindPropertyIns)
- || (ins.definition instanceof GetLexIns)
- || (ins.definition instanceof CoerceIns)
- || (ins.definition instanceof AsTypeIns)) {
- int m = ins.operands[0];
- if (m != 0) {
- parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(m), ignorePackage, fullyQualifiedNames);
- }
- } else {
- for (int k = 0; k < ins.definition.operands.length; k++) {
-
- if (ins.definition.operands[k] == AVM2Code.DAT_MULTINAME_INDEX) {
- int multinameIndex = ins.operands[k];
- parseUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(multinameIndex), ignorePackage, fullyQualifiedNames);
- }
- }
- }
- }
- }
- }
-
- private void parseImportsUsagesFromTraits(List abcTags, ABC abc, Traits ts, List imports, List uses, String ignorePackage, List fullyQualifiedNames) {
- for (Trait t : ts.traits) {
- parseImportsUsagesFromTrait(abcTags, abc, t, imports, uses, ignorePackage, fullyQualifiedNames);
- }
- }
-
- private void parseImportsUsagesFromTrait(List abcTags, ABC abc, Trait t, List imports, List uses, String ignorePackage, List fullyQualifiedNames) {
- if (t instanceof TraitMethodGetterSetter) {
- TraitMethodGetterSetter tm = (TraitMethodGetterSetter) t;
- parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(tm.name_index), ignorePackage, fullyQualifiedNames);
- if (tm.method_info != 0) {
- parseImportsUsagesFromMethodInfo(abcTags, abc, tm.method_info, imports, uses, ignorePackage, fullyQualifiedNames, new ArrayList());
- }
- }
- parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, t.getName(abc), ignorePackage, fullyQualifiedNames);
- if (t instanceof TraitSlotConst) {
- TraitSlotConst ts = (TraitSlotConst) t;
- parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(ts.name_index), ignorePackage, fullyQualifiedNames);
- parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(ts.type_index), ignorePackage, fullyQualifiedNames);
- }
- }
-
- private List getImportsUsages(List abcTags, ABC abc, List imports, List uses, List fullyQualifiedNames) {
- //constructor
-
- String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants); //assume not null name
-
- parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(abc.instance_info.get(class_info).name_index), packageName, fullyQualifiedNames);
-
- if (abc.instance_info.get(class_info).super_index > 0) {
- parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(abc.instance_info.get(class_info).super_index), packageName, fullyQualifiedNames);
- }
- for (int i : abc.instance_info.get(class_info).interfaces) {
- parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(i), packageName, fullyQualifiedNames);
- }
-
- //static
- parseImportsUsagesFromTraits(abcTags, abc, abc.class_info.get(class_info).static_traits, imports, uses, packageName, fullyQualifiedNames);
-
- //static initializer
- parseImportsUsagesFromMethodInfo(abcTags, abc, abc.class_info.get(class_info).cinit_index, imports, uses, packageName, fullyQualifiedNames, new ArrayList());
-
- //instance
- parseImportsUsagesFromTraits(abcTags, abc, abc.instance_info.get(class_info).instance_traits, imports, uses, packageName, fullyQualifiedNames);
-
- //instance initializer
- parseImportsUsagesFromMethodInfo(abcTags, abc, abc.instance_info.get(class_info).iinit_index, imports, uses, packageName, fullyQualifiedNames, new ArrayList());
- return imports;
- }
-
- @Override
- public GraphTextWriter toStringHeader(Trait parent, String path, List abcTags, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) {
- String classHeader = abc.instance_info.get(class_info).getClassHeaderStr(abc, fullyQualifiedNames);
- return writer.appendNoHilight(classHeader);
- }
-
- @Override
- public void convertHeader(Trait parent, String path, List abcTags, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) {
- }
-
- @Override
- public GraphTextWriter toString(Trait parent, String path, List abcTags, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException {
-
- writer.startClass(class_info);
- String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants); //assume not null name
- List namesInThisPackage = new ArrayList<>();
- for (ABCContainerTag tag : abcTags) {
- for (ScriptInfo si : tag.getABC().script_info) {
- for (Trait t : si.traits.traits) {
- String spath = t.getPath(tag.getABC());
- String pkg = "";
- String name = spath;
- if (spath.contains(".")) {
- pkg = spath.substring(0, spath.lastIndexOf('.'));
- name = spath.substring(spath.lastIndexOf('.') + 1);
- }
- if (pkg.equals(packageName)) {
- namesInThisPackage.add(name);
- }
- }
-
- }
- }
- //imports
- List imports = new ArrayList<>();
- List uses = new ArrayList<>();
- getImportsUsages(abcTags, abc, imports, uses, new ArrayList());
-
- fullyQualifiedNames = new ArrayList<>();
-
- List importnames = new ArrayList<>();
- importnames.addAll(namesInThisPackage);
- for (String ipath : imports) {
- String name = ipath;
- String pkg = "";
- if (name.contains(".")) {
- pkg = name.substring(0, name.lastIndexOf('.'));
- name = name.substring(name.lastIndexOf('.') + 1);
- }
- if (importnames.contains(name) || ((!pkg.isEmpty()) && isBuiltInClass(name))) {
- fullyQualifiedNames.add(name);
- } else {
- importnames.add(name);
- }
- }
- /*List imports2 = new ArrayList();
- for (String path : imports) {
- String name = path;
- String pkg = "";
- if (name.contains(".")) {
- pkg = name.substring(0, name.lastIndexOf("."));
- name = name.substring(name.lastIndexOf(".") + 1);
- }
-
- if ((!packageName.equals(pkg)) && (!fullyQualifiedNames.contains(name))) {
- imports2.add(path);
- }
- }
- imports = imports2;*/
-
- for (int i = 0; i < imports.size(); i++) {
- String imp = imports.get(i);
- String pkg = imp.substring(0, imp.lastIndexOf('.'));
- String name = imp.substring(imp.lastIndexOf('.') + 1);
- if (name.equals("*")) {
- continue;
- }
- if (imports.contains(pkg + ".*")) {
- imports.remove(i);
- i--;
- }
- }
-
- boolean hasImport = false;
- for (String imp : imports) {
- if (!imp.startsWith(".")) {
- writer.appendNoHilight("import " + imp + ";").newLine();
- hasImport = true;
- }
- }
- if (hasImport) {
- writer.newLine();
- }
- for (String us : uses) {
- writer.appendNoHilight("use namespace " + us + ";").newLine();
- }
- if (uses.size() > 0) {
- writer.newLine();
- }
-
- //class header
- String classHeader = abc.instance_info.get(class_info).getClassHeaderStr(abc, fullyQualifiedNames);
- if (classHeader.startsWith("private ")) {
- classHeader = classHeader.substring("private ".length());
- }
- writer.appendNoHilight(classHeader).newLine();
- writer.appendNoHilight("{").newLine();
- writer.indent();
-
- int bodyIndex = abc.findBodyIndex(abc.class_info.get(class_info).cinit_index);
- if (bodyIndex != -1) {
- if (!classInitializerIsEmpty) {
- writer.newLine();
- writer.startTrait(abc.class_info.get(class_info).static_traits.traits.size() + abc.instance_info.get(class_info).instance_traits.traits.size() + 1);
- writer.appendNoHilight("{").newLine();
- abc.bodies.get(bodyIndex).toString(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames) + ".staticinitializer", exportMode, true, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new Stack(), true, writer, fullyQualifiedNames, abc.class_info.get(class_info).static_traits);
- writer.appendNoHilight("}").newLine();
- writer.endTrait();
- }
- } else {
- //"/*classInitializer*/";
- }
-
- //constructor
- if (!abc.instance_info.get(class_info).isInterface()) {
- String modifier = "";
- Multiname m = abc.constants.getMultiname(abc.instance_info.get(class_info).name_index);
- if (m != null) {
- Namespace ns = m.getNamespace(abc.constants);
- if (ns != null) {
- modifier = ns.getPrefix(abc) + " ";
- if (modifier.equals(" ")) {
- modifier = "";
- }
- if (modifier.startsWith("private")) { //cannot have private constuctor
- modifier = "";
- }
- }
- }
-
- writer.newLine();
- writer.startTrait(abc.class_info.get(class_info).static_traits.traits.size() + abc.instance_info.get(class_info).instance_traits.traits.size());
- writer.appendNoHilight(modifier);
- writer.appendNoHilight("function ");
- writer.appendNoHilight(abc.constants.getMultiname(abc.instance_info.get(class_info).name_index).getName(abc.constants, new ArrayList()/*do not want full names here*/));
- writer.appendNoHilight("(");
- bodyIndex = abc.findBodyIndex(abc.instance_info.get(class_info).iinit_index);
- if (bodyIndex != -1) {
- abc.method_info.get(abc.instance_info.get(class_info).iinit_index).getParamStr(writer, abc.constants, abc.bodies.get(bodyIndex), abc, fullyQualifiedNames);
- } else {
- abc.method_info.get(abc.instance_info.get(class_info).iinit_index).getParamStr(writer, abc.constants, null, abc, fullyQualifiedNames);
- }
- writer.appendNoHilight(") {").newLine();
- if (bodyIndex != -1) {
- abc.bodies.get(bodyIndex).toString(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames) + ".initializer", exportMode, false, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new Stack(), false, writer, fullyQualifiedNames, abc.instance_info.get(class_info).instance_traits);
- }
- writer.appendNoHilight("}").newLine();
- writer.endTrait();
- }
-
- //static variables,constants & methods
- abc.class_info.get(class_info).static_traits.toString(this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames), abcTags, abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel);
-
- abc.instance_info.get(class_info).instance_traits.toString(this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames), abcTags, abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel);
-
- writer.unindent();
- writer.appendNoHilight("}"); // class
- writer.endClass();
- writer.newLine();
- return writer;
- }
-
- @Override
- public void convert(Trait parent, String path, List abcTags, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException {
-
- fullyQualifiedNames = new ArrayList<>();
-
- int bodyIndex = abc.findBodyIndex(abc.class_info.get(class_info).cinit_index);
- if (bodyIndex != -1) {
- writer.mark();
- abc.bodies.get(bodyIndex).convert(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames) + ".staticinitializer", exportMode, true, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new Stack(), true, writer, fullyQualifiedNames, abc.class_info.get(class_info).static_traits, true);
- classInitializerIsEmpty = !writer.getMark();
- }
-
- //constructor
- if (!abc.instance_info.get(class_info).isInterface()) {
- bodyIndex = abc.findBodyIndex(abc.instance_info.get(class_info).iinit_index);
- if (bodyIndex != -1) {
- abc.bodies.get(bodyIndex).convert(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames) + ".initializer", exportMode, false, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new Stack(), false, writer, fullyQualifiedNames, abc.instance_info.get(class_info).instance_traits, true);
- }
- }
-
- //static variables,constants & methods
- abc.class_info.get(class_info).static_traits.convert(this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames), abcTags, abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel);
-
- abc.instance_info.get(class_info).instance_traits.convert(this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames), abcTags, abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel);
- }
-
- @Override
- public Multiname getName(ABC abc) {
- return abc.constants.getMultiname(abc.instance_info.get(class_info).name_index);
- }
-
- @Override
- public int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) throws InterruptedException {
- int iInitializer = abc.findBodyIndex(abc.instance_info.get(class_info).iinit_index);
- int ret = 0;
- if (iInitializer != -1) {
- ret += abc.bodies.get(iInitializer).removeTraps(abc.constants, abc, this, scriptIndex, class_info, false, path);
- }
- int sInitializer = abc.findBodyIndex(abc.class_info.get(class_info).cinit_index);
- if (sInitializer != -1) {
- ret += abc.bodies.get(sInitializer).removeTraps(abc.constants, abc, this, scriptIndex, class_info, true, path);
- }
- ret += abc.instance_info.get(class_info).instance_traits.removeTraps(scriptIndex, class_info, false, abc, path);
- ret += abc.class_info.get(class_info).static_traits.removeTraps(scriptIndex, class_info, true, abc, path);
- return ret;
- }
-}
+/*
+ * Copyright (C) 2010-2014 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 .
+ */
+package com.jpexs.decompiler.flash.abc.types.traits;
+
+import com.jpexs.decompiler.flash.abc.ABC;
+import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
+import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
+import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewFunctionIns;
+import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyIns;
+import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns;
+import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns;
+import com.jpexs.decompiler.flash.abc.avm2.instructions.types.AsTypeIns;
+import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceIns;
+import com.jpexs.decompiler.flash.abc.types.ABCException;
+import com.jpexs.decompiler.flash.abc.types.MethodBody;
+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.exporters.modes.ScriptExportMode;
+import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
+import com.jpexs.decompiler.flash.helpers.NulWriter;
+import com.jpexs.decompiler.flash.tags.ABCContainerTag;
+import com.jpexs.decompiler.graph.GraphTargetItem;
+import com.jpexs.helpers.Helper;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+public class TraitClass extends Trait implements TraitWithSlot {
+
+ public int slot_id;
+ public int class_info;
+ private static final String[] builtInClasses = {"ArgumentError", "arguments", "Array", "Boolean", "Class", "Date", "DefinitionError", "Error", "EvalError", "Function", "int", "JSON", "Math", "Namespace", "Number", "Object", "QName", "RangeError", "ReferenceError", "RegExp", "SecurityError", "String", "SyntaxError", "TypeError", "uint", "URIError", "VerifyError", "XML", "XMLList"};
+
+ private boolean classInitializerIsEmpty;
+
+ @Override
+ public void delete(ABC abc, boolean d) {
+ abc.class_info.get(class_info).deleted = d;
+ abc.instance_info.get(class_info).deleted = d;
+
+ abc.class_info.get(class_info).static_traits.delete(abc, d);
+ abc.method_info.get(abc.class_info.get(class_info).cinit_index).delete(abc, d);
+
+ abc.instance_info.get(class_info).instance_traits.delete(abc, d);
+ abc.method_info.get(abc.instance_info.get(class_info).iinit_index).delete(abc, d);
+
+ abc.constants.constant_namespace.get(abc.instance_info.get(class_info).protectedNS).deleted = d;
+
+ abc.constants.constant_multiname.get(name_index).deleted = d;
+ }
+
+ @Override
+ public int getSlotIndex() {
+ return slot_id;
+ }
+
+ private static boolean isBuiltInClass(String name) {
+ for (String g : builtInClasses) {
+ if (g.equals(name)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public String toString(ABC abc, List fullyQualifiedNames) {
+ return "Class " + abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " slot=" + slot_id + " class_info=" + class_info + " metadata=" + Helper.intArrToString(metadata);
+ }
+
+ private boolean parseUsagesFromNS(List abcTags, ABC abc, List imports, List uses, int namespace_index, String ignorePackage, String name) {
+ Namespace ns = abc.constants.getNamespace(namespace_index);
+ if (name.isEmpty()) {
+ name = "*";
+ }
+ String newimport = ns.getName(abc.constants);
+ /*if ((ns.kind != Namespace.KIND_PACKAGE)
+ && (ns.kind != Namespace.KIND_NAMESPACE)
+ && (ns.kind != Namespace.KIND_STATIC_PROTECTED)) {
+ return false;
+ }*/
+ /*if (ns.kind == Namespace.KIND_NAMESPACE)*/ {
+ String oldimport = newimport;
+ newimport = null;
+ for (ABCContainerTag abcTag : abcTags) {
+ String newname = abcTag.getABC().nsValueToName(oldimport);
+ if (newname.equals("-")) {
+ return true;
+ }
+ if (!newname.isEmpty()) {
+ newimport = newname;
+ break;
+ }
+ }
+ if (newimport == null) {
+ newimport = oldimport;
+ newimport += "." + name;
+ }
+ if (newimport != null && newimport.isEmpty()) {
+ newimport = null;
+ }
+ if (newimport != null) {
+ /* if(ns.kind==Namespace.KIND_PACKAGE){
+ newimport+=".*";
+ }*/
+
+ if (!imports.contains(newimport)) {
+ if (newimport.contains(":")) {
+ return true;
+ }
+ String pkg = "";
+ if (newimport.contains(".")) {
+ pkg = newimport.substring(0, newimport.lastIndexOf('.'));
+ }
+ String usname = newimport;
+ if (usname.contains(".")) {
+ usname = usname.substring(usname.lastIndexOf('.') + 1);
+ }
+ if (ns.kind == Namespace.KIND_PACKAGE) {
+ if (!pkg.equals(ignorePackage)) {
+ if (!pkg.equals("__AS3__.vec")) { //Automatic import
+ imports.add(newimport);
+ }
+ }
+ }
+ if (ns.kind == Namespace.KIND_NAMESPACE) {
+ if (!usname.equals("*")) {
+ /*if (!uses.contains(usname)) {
+ uses.add(usname);
+ }*/
+ if (!pkg.equals(ignorePackage)) {
+ imports.add(newimport);
+ }
+ }
+ }
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void parseImportsUsagesFromNS(List abcTags, ABC abc, List imports, List uses, int namespace_index, String ignorePackage, String name) {
+ Namespace ns = abc.constants.getNamespace(namespace_index);
+ if (name.isEmpty()) {
+ name = "*";
+ }
+ String newimport = ns.getName(abc.constants);
+ if (parseUsagesFromNS(abcTags, abc, imports, uses, namespace_index, ignorePackage, name)) {
+ return;
+ } else if ((ns.kind != Namespace.KIND_PACKAGE) && (ns.kind != Namespace.KIND_PACKAGE_INTERNAL)) {
+ return;
+ }
+ if (newimport == null) {
+ newimport = "";
+ }
+ //if (!newimport.equals("")) {
+ newimport += "." + name;
+ if (newimport.contains(":")) {
+ return;
+ }
+ if (!imports.contains(newimport)) {
+ String pkg = newimport.substring(0, newimport.lastIndexOf('.'));
+ if (pkg.equals("__AS3__.vec")) { //special case - is imported always
+ return;
+ }
+ if (!pkg.equals(ignorePackage)) {
+ imports.add(newimport);
+ }
+ }
+ //}
+ }
+
+ private void parseUsagesFromMultiname(List abcTags, ABC abc, List imports, List uses, Multiname m, String ignorePackage, List fullyQualifiedNames) {
+ if (m != null) {
+ if (m.kind == Multiname.TYPENAME) {
+ if (m.qname_index != 0) {
+ parseUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames);
+ }
+ for (Integer i : m.params) {
+ if (i != 0) {
+ parseUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames);
+ }
+ }
+ return;
+ }
+ Namespace ns = m.getNamespace(abc.constants);
+ String name = m.getName(abc.constants, fullyQualifiedNames);
+ NamespaceSet nss = m.getNamespaceSet(abc.constants);
+ if (ns != null) {
+ parseUsagesFromNS(abcTags, abc, imports, uses, m.namespace_index, ignorePackage, name);
+ }
+ if (nss != null) {
+ if (nss.namespaces.length == 1) {
+ parseUsagesFromNS(abcTags, abc, imports, uses, nss.namespaces[0], ignorePackage, name);
+ } else {
+ for (int n : nss.namespaces) {
+ parseUsagesFromNS(abcTags, abc, imports, uses, n, ignorePackage, "");
+ }
+ }
+ }
+ }
+ }
+
+ private void parseImportsUsagesFromMultiname(List abcTags, ABC abc, List imports, List uses, Multiname m, String ignorePackage, List fullyQualifiedNames) {
+ if (m != null) {
+ if (m.kind == Multiname.TYPENAME) {
+ if (m.qname_index != 0) {
+ parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames);
+ }
+ for (Integer i : m.params) {
+ if (i != 0) {
+ parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames);
+ }
+ }
+ return;
+ }
+ Namespace ns = m.getNamespace(abc.constants);
+ String name = m.getName(abc.constants, fullyQualifiedNames);
+ NamespaceSet nss = m.getNamespaceSet(abc.constants);
+ if (ns != null) {
+ parseImportsUsagesFromNS(abcTags, abc, imports, uses, m.namespace_index, ignorePackage, name);
+ }
+ if (nss != null) {
+ if (nss.namespaces.length == 1) {
+ parseImportsUsagesFromNS(abcTags, abc, imports, uses, nss.namespaces[0], ignorePackage, name);
+ }
+ }
+ }
+ }
+
+ private void parseImportsUsagesFromMethodInfo(List abcTags, ABC abc, int method_index, List imports, List uses, String ignorePackage, List fullyQualifiedNames, List visitedMethods) {
+ if ((method_index < 0) || (method_index >= abc.method_info.size())) {
+ return;
+ }
+ visitedMethods.add(method_index);
+ if (abc.method_info.get(method_index).ret_type != 0) {
+ parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(abc.method_info.get(method_index).ret_type), ignorePackage, fullyQualifiedNames);
+ }
+ for (int t : abc.method_info.get(method_index).param_types) {
+ if (t != 0) {
+ parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(t), ignorePackage, fullyQualifiedNames);
+ }
+ }
+ MethodBody body = abc.findBody(method_index);
+ if (body != null) {
+ parseImportsUsagesFromTraits(abcTags, abc, body.traits, imports, uses, ignorePackage, fullyQualifiedNames);
+ for (ABCException ex : body.exceptions) {
+ parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(ex.type_index), ignorePackage, fullyQualifiedNames);
+ }
+ for (AVM2Instruction ins : body.code.code) {
+ if (ins.definition instanceof NewFunctionIns) {
+ if (ins.operands[0] != method_index) {
+ if (!visitedMethods.contains(ins.operands[0])) {
+ parseImportsUsagesFromMethodInfo(abcTags, abc, ins.operands[0], imports, uses, ignorePackage, fullyQualifiedNames, visitedMethods);
+ }
+ }
+ }
+ if ((ins.definition instanceof FindPropertyStrictIns)
+ || (ins.definition instanceof FindPropertyIns)
+ || (ins.definition instanceof GetLexIns)
+ || (ins.definition instanceof CoerceIns)
+ || (ins.definition instanceof AsTypeIns)) {
+ int m = ins.operands[0];
+ if (m != 0) {
+ parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(m), ignorePackage, fullyQualifiedNames);
+ }
+ } else {
+ for (int k = 0; k < ins.definition.operands.length; k++) {
+
+ if (ins.definition.operands[k] == AVM2Code.DAT_MULTINAME_INDEX) {
+ int multinameIndex = ins.operands[k];
+ parseUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(multinameIndex), ignorePackage, fullyQualifiedNames);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private void parseImportsUsagesFromTraits(List abcTags, ABC abc, Traits ts, List imports, List uses, String ignorePackage, List fullyQualifiedNames) {
+ for (Trait t : ts.traits) {
+ parseImportsUsagesFromTrait(abcTags, abc, t, imports, uses, ignorePackage, fullyQualifiedNames);
+ }
+ }
+
+ private void parseImportsUsagesFromTrait(List abcTags, ABC abc, Trait t, List imports, List uses, String ignorePackage, List fullyQualifiedNames) {
+ if (t instanceof TraitMethodGetterSetter) {
+ TraitMethodGetterSetter tm = (TraitMethodGetterSetter) t;
+ parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(tm.name_index), ignorePackage, fullyQualifiedNames);
+ if (tm.method_info != 0) {
+ parseImportsUsagesFromMethodInfo(abcTags, abc, tm.method_info, imports, uses, ignorePackage, fullyQualifiedNames, new ArrayList());
+ }
+ }
+ parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, t.getName(abc), ignorePackage, fullyQualifiedNames);
+ if (t instanceof TraitSlotConst) {
+ TraitSlotConst ts = (TraitSlotConst) t;
+ parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(ts.name_index), ignorePackage, fullyQualifiedNames);
+ parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(ts.type_index), ignorePackage, fullyQualifiedNames);
+ }
+ }
+
+ private List getImportsUsages(List abcTags, ABC abc, List imports, List uses, List fullyQualifiedNames) {
+ //constructor
+
+ String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants); //assume not null name
+
+ parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(abc.instance_info.get(class_info).name_index), packageName, fullyQualifiedNames);
+
+ if (abc.instance_info.get(class_info).super_index > 0) {
+ parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(abc.instance_info.get(class_info).super_index), packageName, fullyQualifiedNames);
+ }
+ for (int i : abc.instance_info.get(class_info).interfaces) {
+ parseImportsUsagesFromMultiname(abcTags, abc, imports, uses, abc.constants.getMultiname(i), packageName, fullyQualifiedNames);
+ }
+
+ //static
+ parseImportsUsagesFromTraits(abcTags, abc, abc.class_info.get(class_info).static_traits, imports, uses, packageName, fullyQualifiedNames);
+
+ //static initializer
+ parseImportsUsagesFromMethodInfo(abcTags, abc, abc.class_info.get(class_info).cinit_index, imports, uses, packageName, fullyQualifiedNames, new ArrayList());
+
+ //instance
+ parseImportsUsagesFromTraits(abcTags, abc, abc.instance_info.get(class_info).instance_traits, imports, uses, packageName, fullyQualifiedNames);
+
+ //instance initializer
+ parseImportsUsagesFromMethodInfo(abcTags, abc, abc.instance_info.get(class_info).iinit_index, imports, uses, packageName, fullyQualifiedNames, new ArrayList());
+ return imports;
+ }
+
+ @Override
+ public GraphTextWriter toStringHeader(Trait parent, String path, List abcTags, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) {
+ String classHeader = abc.instance_info.get(class_info).getClassHeaderStr(abc, fullyQualifiedNames);
+ return writer.appendNoHilight(classHeader);
+ }
+
+ @Override
+ public void convertHeader(Trait parent, String path, List abcTags, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) {
+ }
+
+ @Override
+ public GraphTextWriter toString(Trait parent, String path, List abcTags, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException {
+
+ writer.startClass(class_info);
+ String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants); //assume not null name
+ List namesInThisPackage = new ArrayList<>();
+ for (ABCContainerTag tag : abcTags) {
+ for (ScriptInfo si : tag.getABC().script_info) {
+ for (Trait t : si.traits.traits) {
+ String spath = t.getPath(tag.getABC());
+ String pkg = "";
+ String name = spath;
+ if (spath.contains(".")) {
+ pkg = spath.substring(0, spath.lastIndexOf('.'));
+ name = spath.substring(spath.lastIndexOf('.') + 1);
+ }
+ if (pkg.equals(packageName)) {
+ namesInThisPackage.add(name);
+ }
+ }
+
+ }
+ }
+ //imports
+ List imports = new ArrayList<>();
+ List uses = new ArrayList<>();
+ getImportsUsages(abcTags, abc, imports, uses, new ArrayList());
+
+ fullyQualifiedNames = new ArrayList<>();
+
+ List importnames = new ArrayList<>();
+ importnames.addAll(namesInThisPackage);
+ for (String ipath : imports) {
+ String name = ipath;
+ String pkg = "";
+ if (name.contains(".")) {
+ pkg = name.substring(0, name.lastIndexOf('.'));
+ name = name.substring(name.lastIndexOf('.') + 1);
+ }
+ if (importnames.contains(name) || ((!pkg.isEmpty()) && isBuiltInClass(name))) {
+ fullyQualifiedNames.add(name);
+ } else {
+ importnames.add(name);
+ }
+ }
+ /*List imports2 = new ArrayList();
+ for (String path : imports) {
+ String name = path;
+ String pkg = "";
+ if (name.contains(".")) {
+ pkg = name.substring(0, name.lastIndexOf("."));
+ name = name.substring(name.lastIndexOf(".") + 1);
+ }
+
+ if ((!packageName.equals(pkg)) && (!fullyQualifiedNames.contains(name))) {
+ imports2.add(path);
+ }
+ }
+ imports = imports2;*/
+
+ for (int i = 0; i < imports.size(); i++) {
+ String imp = imports.get(i);
+ String pkg = imp.substring(0, imp.lastIndexOf('.'));
+ String name = imp.substring(imp.lastIndexOf('.') + 1);
+ if (name.equals("*")) {
+ continue;
+ }
+ if (imports.contains(pkg + ".*")) {
+ imports.remove(i);
+ i--;
+ }
+ }
+
+ boolean hasImport = false;
+ for (String imp : imports) {
+ if (!imp.startsWith(".")) {
+ writer.appendNoHilight("import " + imp + ";").newLine();
+ hasImport = true;
+ }
+ }
+ if (hasImport) {
+ writer.newLine();
+ }
+ for (String us : uses) {
+ writer.appendNoHilight("use namespace " + us + ";").newLine();
+ }
+ if (uses.size() > 0) {
+ writer.newLine();
+ }
+
+ //class header
+ String classHeader = abc.instance_info.get(class_info).getClassHeaderStr(abc, fullyQualifiedNames);
+ if (classHeader.startsWith("private ")) {
+ classHeader = classHeader.substring("private ".length());
+ }
+ writer.appendNoHilight(classHeader).startBlock();
+
+ int bodyIndex = abc.findBodyIndex(abc.class_info.get(class_info).cinit_index);
+ if (bodyIndex != -1) {
+ if (!classInitializerIsEmpty) {
+ writer.newLine();
+ writer.startTrait(abc.class_info.get(class_info).static_traits.traits.size() + abc.instance_info.get(class_info).instance_traits.traits.size() + 1);
+ writer.appendNoHilight("{").newLine();
+ abc.bodies.get(bodyIndex).toString(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames) + ".staticinitializer", exportMode, true, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new Stack(), true, writer, fullyQualifiedNames, abc.class_info.get(class_info).static_traits);
+ writer.appendNoHilight("}").newLine();
+ writer.endTrait();
+ }
+ } else {
+ //"/*classInitializer*/";
+ }
+
+ //constructor
+ if (!abc.instance_info.get(class_info).isInterface()) {
+ String modifier = "";
+ Multiname m = abc.constants.getMultiname(abc.instance_info.get(class_info).name_index);
+ if (m != null) {
+ Namespace ns = m.getNamespace(abc.constants);
+ if (ns != null) {
+ modifier = ns.getPrefix(abc) + " ";
+ if (modifier.equals(" ")) {
+ modifier = "";
+ }
+ if (modifier.startsWith("private")) { //cannot have private constuctor
+ modifier = "";
+ }
+ }
+ }
+
+ writer.newLine();
+ writer.startTrait(abc.class_info.get(class_info).static_traits.traits.size() + abc.instance_info.get(class_info).instance_traits.traits.size());
+ writer.appendNoHilight(modifier);
+ writer.appendNoHilight("function ");
+ writer.appendNoHilight(abc.constants.getMultiname(abc.instance_info.get(class_info).name_index).getName(abc.constants, new ArrayList()/*do not want full names here*/));
+ writer.appendNoHilight("(");
+ bodyIndex = abc.findBodyIndex(abc.instance_info.get(class_info).iinit_index);
+ if (bodyIndex != -1) {
+ abc.method_info.get(abc.instance_info.get(class_info).iinit_index).getParamStr(writer, abc.constants, abc.bodies.get(bodyIndex), abc, fullyQualifiedNames);
+ } else {
+ abc.method_info.get(abc.instance_info.get(class_info).iinit_index).getParamStr(writer, abc.constants, null, abc, fullyQualifiedNames);
+ }
+ writer.appendNoHilight(")").startBlock();
+ if (bodyIndex != -1) {
+ abc.bodies.get(bodyIndex).toString(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames) + ".initializer", exportMode, false, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new Stack(), false, writer, fullyQualifiedNames, abc.instance_info.get(class_info).instance_traits);
+ }
+ writer.endBlock().newLine();
+ writer.endTrait();
+ }
+
+ //static variables,constants & methods
+ abc.class_info.get(class_info).static_traits.toString(this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames), abcTags, abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel);
+
+ abc.instance_info.get(class_info).instance_traits.toString(this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames), abcTags, abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel);
+
+ writer.endBlock(); // class
+ writer.endClass();
+ writer.newLine();
+ return writer;
+ }
+
+ @Override
+ public void convert(Trait parent, String path, List abcTags, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List fullyQualifiedNames, boolean parallel) throws InterruptedException {
+
+ fullyQualifiedNames = new ArrayList<>();
+
+ int bodyIndex = abc.findBodyIndex(abc.class_info.get(class_info).cinit_index);
+ if (bodyIndex != -1) {
+ writer.mark();
+ abc.bodies.get(bodyIndex).convert(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames) + ".staticinitializer", exportMode, true, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new Stack(), true, writer, fullyQualifiedNames, abc.class_info.get(class_info).static_traits, true);
+ classInitializerIsEmpty = !writer.getMark();
+ }
+
+ //constructor
+ if (!abc.instance_info.get(class_info).isInterface()) {
+ bodyIndex = abc.findBodyIndex(abc.instance_info.get(class_info).iinit_index);
+ if (bodyIndex != -1) {
+ abc.bodies.get(bodyIndex).convert(path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames) + ".initializer", exportMode, false, scriptIndex, class_info, abc, this, abc.constants, abc.method_info, new Stack(), false, writer, fullyQualifiedNames, abc.instance_info.get(class_info).instance_traits, true);
+ }
+ }
+
+ //static variables,constants & methods
+ abc.class_info.get(class_info).static_traits.convert(this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames), abcTags, abc, true, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel);
+
+ abc.instance_info.get(class_info).instance_traits.convert(this, path +/*packageName +*/ "/" + abc.instance_info.get(class_info).getName(abc.constants).getName(abc.constants, fullyQualifiedNames), abcTags, abc, false, exportMode, false, scriptIndex, class_info, writer, fullyQualifiedNames, parallel);
+ }
+
+ @Override
+ public Multiname getName(ABC abc) {
+ return abc.constants.getMultiname(abc.instance_info.get(class_info).name_index);
+ }
+
+ @Override
+ public int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) throws InterruptedException {
+ int iInitializer = abc.findBodyIndex(abc.instance_info.get(class_info).iinit_index);
+ int ret = 0;
+ if (iInitializer != -1) {
+ ret += abc.bodies.get(iInitializer).removeTraps(abc.constants, abc, this, scriptIndex, class_info, false, path);
+ }
+ int sInitializer = abc.findBodyIndex(abc.class_info.get(class_info).cinit_index);
+ if (sInitializer != -1) {
+ ret += abc.bodies.get(sInitializer).removeTraps(abc.constants, abc, this, scriptIndex, class_info, true, path);
+ }
+ ret += abc.instance_info.get(class_info).instance_traits.removeTraps(scriptIndex, class_info, false, abc, path);
+ ret += abc.class_info.get(class_info).static_traits.removeTraps(scriptIndex, class_info, true, abc, path);
+ return ret;
+ }
+}
diff --git a/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/src/com/jpexs/decompiler/flash/configuration/Configuration.java
index ce5397bf4..ce6e9a49c 100644
--- a/src/com/jpexs/decompiler/flash/configuration/Configuration.java
+++ b/src/com/jpexs/decompiler/flash/configuration/Configuration.java
@@ -1,694 +1,702 @@
-/*
- * Copyright (C) 2010-2014 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 .
- */
-package com.jpexs.decompiler.flash.configuration;
-
-import com.jpexs.decompiler.flash.ApplicationInfo;
-import com.jpexs.decompiler.flash.helpers.CodeFormatting;
-import com.jpexs.helpers.Helper;
-import com.jpexs.helpers.utf8.Utf8InputStreamReader;
-import com.jpexs.helpers.utf8.Utf8OutputStreamWriter;
-import com.jpexs.proxy.Replacement;
-import java.io.BufferedOutputStream;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FilenameFilter;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.PrintWriter;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.swing.JOptionPane;
-
-public class Configuration {
-
- private static final String CONFIG_NAME = "config.bin";
- private static final String REPLACEMENTS_NAME = "replacements.cfg";
- private static final File unspecifiedFile = new File("unspecified");
- private static File directory = unspecifiedFile;
-
- /**
- * List of replacements
- */
- private static List replacements = new ArrayList<>();
-
- public static final Level logLevel;
-
- @ConfigurationDefaultBoolean(true)
- @ConfigurationCategory("ui")
- public static final ConfigurationItem openMultipleFiles = null;
-
- @ConfigurationDefaultBoolean(true)
- @ConfigurationCategory("script")
- public static final ConfigurationItem decompile = null;
-
- @ConfigurationDefaultBoolean(true)
- @ConfigurationCategory("decompilation")
- public static final ConfigurationItem parallelSpeedUp = null;
-
- @ConfigurationDefaultInt(20)
- @ConfigurationCategory("decompilation")
- public static final ConfigurationItem parallelThreadCount = null;
-
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("script")
- public static final ConfigurationItem autoDeobfuscate = null;
-
- @ConfigurationDefaultBoolean(true)
- @ConfigurationCategory("decompilation")
- public static final ConfigurationItem cacheOnDisk = null;
-
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("display")
- public static final ConfigurationItem internalFlashViewer = null;
-
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("display")
- public static final ConfigurationItem dumpView = null;
-
- @ConfigurationDefaultBoolean(true)
- @ConfigurationCategory("display")
- public static final ConfigurationItem dumpInfoCollecting = null;
-
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("ui")
- public static final ConfigurationItem gotoMainClassOnStartup = null;
-
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("script")
- public static final ConfigurationItem autoRenameIdentifiers = null;
-
- @ConfigurationDefaultBoolean(false)
- public static final ConfigurationItem offeredAssociation = null;
-
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("script")
- public static final ConfigurationItem decimalAddress = null;
-
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("script")
- public static final ConfigurationItem showAllAddresses = null;
-
- @ConfigurationDefaultBoolean(true)
- @ConfigurationCategory("display")
- public static final ConfigurationItem useFrameCache = null;
-
- @ConfigurationDefaultBoolean(true)
- @ConfigurationCategory("ui")
- public static final ConfigurationItem useRibbonInterface = null;
-
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("export")
- public static final ConfigurationItem openFolderAfterFlaExport = null;
-
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("debug")
- public static final ConfigurationItem useDetailedLogging = null;
-
- /**
- * Debug mode = throwing an error when comparing original file and
- * recompiled
- */
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("debug")
- public static final ConfigurationItem debugMode = null;
- /**
- * Turn off resolving constants in ActionScript 2
- */
- @ConfigurationDefaultBoolean(true)
- @ConfigurationCategory("script")
- public static final ConfigurationItem resolveConstants = null;
- /**
- * Limit of code subs (for obfuscated code)
- */
- @ConfigurationDefaultInt(500)
- @ConfigurationCategory("limit")
- public static final ConfigurationItem sublimiter = null;
- /**
- * Total export timeout in seconds
- */
- @ConfigurationDefaultInt(30 * 60)
- @ConfigurationCategory("limit")
- public static final ConfigurationItem exportTimeout = null;
- /**
- * Decompilation timeout in seconds for a single file
- */
- @ConfigurationDefaultInt(5 * 60)
- @ConfigurationCategory("limit")
- public static final ConfigurationItem decompilationTimeoutFile = null;
- /**
- * Using parameter names in decompiling may cause problems because official
- * programs like Flash CS 5.5 inserts wrong parameter names indices
- */
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("script")
- public static final ConfigurationItem paramNamesEnable = null;
-
- @ConfigurationDefaultBoolean(true)
- @ConfigurationCategory("ui")
- public static final ConfigurationItem displayFileName = null;
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("debug")
- public static final ConfigurationItem debugCopy = null;
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("debug")
- public static final ConfigurationItem dumpTags = null;
-
- @ConfigurationDefaultInt(60)
- @ConfigurationCategory("limit")
- public static final ConfigurationItem decompilationTimeoutSingleMethod = null;
- @ConfigurationDefaultInt(1)
- public static final ConfigurationItem lastRenameType = null;
-
- @ConfigurationDefaultString(".")
- public static final ConfigurationItem lastSaveDir = null;
-
- @ConfigurationDefaultString(".")
- public static final ConfigurationItem lastOpenDir = null;
-
- @ConfigurationDefaultString(".")
- public static final ConfigurationItem lastExportDir = null;
-
- @ConfigurationDefaultString("en")
- @ConfigurationCategory("ui")
- public static final ConfigurationItem locale = null;
-
- @ConfigurationDefaultString("_loc%d_")
- @ConfigurationCategory("script")
- public static final ConfigurationItem registerNameFormat = null;
-
- @ConfigurationDefaultInt(10)
- public static final ConfigurationItem maxRecentFileCount = null;
-
- public static final ConfigurationItem recentFiles = null;
-
- public static final ConfigurationItem fontPairing = null;
-
- public static final ConfigurationItem lastUpdatesCheckDate = null;
-
- @ConfigurationDefaultInt(1000)
- @ConfigurationName("gui.window.width")
- public static final ConfigurationItem guiWindowWidth = null;
- @ConfigurationDefaultInt(700)
- @ConfigurationName("gui.window.height")
- public static final ConfigurationItem guiWindowHeight = null;
- @ConfigurationDefaultBoolean(false)
- @ConfigurationName("gui.window.maximized.horizontal")
- public static final ConfigurationItem guiWindowMaximizedHorizontal = null;
- @ConfigurationDefaultBoolean(false)
- @ConfigurationName("gui.window.maximized.vertical")
- public static final ConfigurationItem guiWindowMaximizedVertical = null;
- @ConfigurationName("gui.avm2.splitPane.dividerLocation")
- public static final ConfigurationItem guiAvm2SplitPaneDividerLocation = null;
- @ConfigurationName("guiActionSplitPaneDividerLocation")
- public static final ConfigurationItem guiActionSplitPaneDividerLocation = null;
- @ConfigurationName("guiPreviewSplitPaneDividerLocation")
- public static final ConfigurationItem guiPreviewSplitPaneDividerLocation = null;
- @ConfigurationName("gui.splitPane1.dividerLocation")
- public static final ConfigurationItem guiSplitPane1DividerLocation = null;
- @ConfigurationName("gui.splitPane2.dividerLocation")
- public static final ConfigurationItem guiSplitPane2DividerLocation = null;
- @ConfigurationDefaultInt(3)
- @ConfigurationCategory("export")
- public static final ConfigurationItem saveAsExeScaleMode = null;
-
- @ConfigurationDefaultInt(1024 * 100/*100KB*/)
- @ConfigurationCategory("limit")
- public static final ConfigurationItem syntaxHighlightLimit = null;
- public static final ConfigurationItem guiFontPreviewSampleText = null;
- @ConfigurationName("gui.fontPreviewWindow.width")
- public static final ConfigurationItem guiFontPreviewWidth = null;
- @ConfigurationName("gui.fontPreviewWindow.height")
- public static final ConfigurationItem guiFontPreviewHeight = null;
- @ConfigurationName("gui.fontPreviewWindow.posX")
- public static final ConfigurationItem guiFontPreviewPosX = null;
- @ConfigurationName("gui.fontPreviewWindow.posY")
- public static final ConfigurationItem guiFontPreviewPosY = null;
-
- @ConfigurationDefaultInt(3)
- @ConfigurationName("formatting.indent.size")
- @ConfigurationCategory("format")
- public static final ConfigurationItem indentSize = null;
-
- @ConfigurationDefaultBoolean(false)
- @ConfigurationName("formatting.indent.useTabs")
- @ConfigurationCategory("format")
- public static final ConfigurationItem indentUseTabs = null;
-
- @ConfigurationDefaultBoolean(true)
- @ConfigurationCategory("format")
- public static final ConfigurationItem beginBlockOnNewLine = null;
-
- @ConfigurationDefaultInt(1000 * 60 * 60 * 24)
- @ConfigurationCategory("update")
- @ConfigurationName("check.updates.delay")
- public static final ConfigurationItem checkForUpdatesDelay = null;
-
- @ConfigurationDefaultBoolean(true)
- @ConfigurationCategory("update")
- @ConfigurationName("check.updates.stable")
- public static final ConfigurationItem checkForUpdatesStable = null;
-
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("update")
- @ConfigurationName("check.updates.nightly")
- public static final ConfigurationItem checkForUpdatesNightly = null;
-
- @ConfigurationDefaultBoolean(true)
- @ConfigurationCategory("update")
- @ConfigurationName("check.updates.enabled")
- public static final ConfigurationItem checkForUpdatesAuto = null;
-
- @ConfigurationDefaultString("")
- @ConfigurationName("export.formats")
- public static final ConfigurationItem lastSelectedExportFormats = null;
-
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("export")
- public static final ConfigurationItem textExportSingleFile = null;
-
- @ConfigurationDefaultString("--- SEPARATOR ---")
- @ConfigurationCategory("export")
- public static final ConfigurationItem textExportSingleFileSeparator = null;
-
- @ConfigurationDefaultString("--- RECORDSEPARATOR ---")
- @ConfigurationCategory("export")
- public static final ConfigurationItem textExportSingleFileRecordSeparator = null;
-
- @ConfigurationDefaultBoolean(true)
- @ConfigurationName("warning.experimental.as12edit")
- @ConfigurationCategory("script")
- public static final ConfigurationItem warningExperimentalAS12Edit = null;
-
- @ConfigurationDefaultBoolean(true)
- @ConfigurationName("warning.experimental.as3edit")
- @ConfigurationCategory("script")
- public static final ConfigurationItem warningExperimentalAS3Edit = null;
-
- @ConfigurationDefaultBoolean(true)
- @ConfigurationCategory("export")
- public static final ConfigurationItem packJavaScripts = null;
-
- @ConfigurationDefaultBoolean(false)
- @ConfigurationCategory("export")
- public static final ConfigurationItem textExportExportFontFace = null;
-
- private enum OSId {
-
- WINDOWS, OSX, UNIX
- }
-
- private static OSId getOSId() {
- PrivilegedAction doGetOSName = new PrivilegedAction() {
- @Override
- public String run() {
- return System.getProperty("os.name");
- }
- };
- OSId id = OSId.UNIX;
- String osName = AccessController.doPrivileged(doGetOSName);
- if (osName != null) {
- if (osName.toLowerCase().startsWith("mac os x")) {
- id = OSId.OSX;
- } else if (osName.contains("Windows")) {
- id = OSId.WINDOWS;
- }
- }
- return id;
- }
-
- public static String getFFDecHome() {
- if (directory == unspecifiedFile) {
- directory = null;
- String userHome = null;
- try {
- userHome = System.getProperty("user.home");
- } catch (SecurityException ignore) {
- }
- if (userHome != null) {
- String applicationId = ApplicationInfo.SHORT_APPLICATION_NAME;
- OSId osId = getOSId();
- if (osId == OSId.WINDOWS) {
- File appDataDir = null;
- try {
- String appDataEV = System.getenv("APPDATA");
- if ((appDataEV != null) && (appDataEV.length() > 0)) {
- appDataDir = new File(appDataEV);
- }
- } catch (SecurityException ignore) {
- }
- String vendorId = ApplicationInfo.VENDOR;
- if ((appDataDir != null) && appDataDir.isDirectory()) {
- // ${APPDATA}\{vendorId}\${applicationId}
- String path = vendorId + "\\" + applicationId + "\\";
- directory = new File(appDataDir, path);
- } else {
- // ${userHome}\Application Data\${vendorId}\${applicationId}
- String path = "Application Data\\" + vendorId + "\\" + applicationId + "\\";
- directory = new File(userHome, path);
- }
- } else if (osId == OSId.OSX) {
- // ${userHome}/Library/Application Support/${applicationId}
- String path = "Library/Application Support/" + applicationId + "/";
- directory = new File(userHome, path);
- } else {
- // ${userHome}/.${applicationId}/
- String path = "." + applicationId + "/";
- directory = new File(userHome, path);
- }
- } else {
- //no home, then use application directory
- directory = new File(".");
- }
- }
- if (!directory.exists()) {
- if (!directory.mkdirs()) {
- if (!directory.exists()) {
- directory = new File("."); //fallback to current directory
- }
- }
- }
- String ret = directory.getAbsolutePath();
- if (!ret.endsWith(File.separator)) {
- ret += File.separator;
- }
- return ret;
- }
-
- public static List getRecentFiles() {
- String files = recentFiles.get();
- if (files == null || files.isEmpty()) {
- return new ArrayList<>();
- }
- return Arrays.asList(files.split("::"));
- }
-
- public static void addRecentFile(String path) {
- List recentFilesArray = new ArrayList<>(getRecentFiles());
- int idx = recentFilesArray.indexOf(path);
- if (idx != -1) {
- recentFilesArray.remove(idx);
- }
- recentFilesArray.add(path);
- while (recentFilesArray.size() > maxRecentFileCount.get()) {
- recentFilesArray.remove(0);
- }
- recentFiles.set(Helper.joinStrings(recentFilesArray, "::"));
- }
-
- public static void removeRecentFile(String path) {
- List recentFilesArray = new ArrayList<>(getRecentFiles());
- int idx = recentFilesArray.indexOf(path);
- if (idx != -1) {
- recentFilesArray.remove(idx);
- }
- recentFiles.set(Helper.joinStrings(recentFilesArray, "::"));
- }
-
- public static Map getFontPairs() {
- String fonts = fontPairing.get();
- if (fonts == null) {
- return new HashMap<>();
- }
-
- Map result = new HashMap<>();
- for (String pair : fonts.split("::")) {
- String[] splittedPair = pair.split("=");
- result.put(splittedPair[0], splittedPair[1]);
- }
- return result;
- }
-
- public static void addFontPair(String fileName, int fontId, String fontName, String systemFontName) {
- String key = fileName + "_" + fontId + "_" + fontName;
- Map fontPairs = getFontPairs();
- fontPairs.put(key, systemFontName);
- fontPairs.put(fontName, systemFontName);
- StringBuilder sb = new StringBuilder();
- int i = 0;
- for (Entry pair : fontPairs.entrySet()) {
- if (i != 0) {
- sb.append("::");
- }
- sb.append(pair.getKey()).append("=").append(pair.getValue());
- i++;
- }
- fontPairing.set(sb.toString());
- }
-
- /**
- * Saves replacements to file for future use
- */
- private static void saveReplacements(String replacementsFile) {
- if (replacements.isEmpty()) {
- File rf = new File(replacementsFile);
- if (rf.exists()) {
- if (!rf.delete()) {
- Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, "Cannot delete replacements file");
- }
- }
- } else {
- try (PrintWriter pw = new PrintWriter(new Utf8OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(replacementsFile))))) {
- for (Replacement r : replacements) {
- pw.println(r.urlPattern);
- pw.println(r.targetFile);
- }
- } catch (IOException ex) {
- Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, "Exception during saving replacements", ex);
- }
- }
- }
-
- /**
- * Load replacements from file
- */
- private static void loadReplacements(String replacementsFile) {
- if (!(new File(replacementsFile)).exists()) {
- return;
- }
- replacements = new ArrayList<>();
- try (BufferedReader br = new BufferedReader(new Utf8InputStreamReader(new FileInputStream(replacementsFile)))) {
- String s;
- while ((s = br.readLine()) != null) {
- Replacement r = new Replacement(s, br.readLine());
- replacements.add(r);
- }
- } catch (IOException e) {
- //ignore
- }
- }
-
- private static String getReplacementsFile() throws IOException {
- return getFFDecHome() + REPLACEMENTS_NAME;
- }
-
- private static String getConfigFile() throws IOException {
- return getFFDecHome() + CONFIG_NAME;
- }
-
- private static HashMap loadFromFile(String file, String replacementsFile) {
- HashMap config = new HashMap<>();
- try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) {
-
- @SuppressWarnings("unchecked")
- HashMap cfg = (HashMap) ois.readObject();
- config = cfg;
- } catch (ClassNotFoundException | IOException ex) {
- //ignore
- }
- if (replacementsFile != null) {
- loadReplacements(replacementsFile);
- }
- if (config.containsKey("paralelSpeedUp")) {
- config.put("parallelSpeedUp", config.get("paralelSpeedUp"));
- config.remove("paralelSpeedUp");
- }
- return config;
- }
-
- private static void saveToFile(String file, String replacementsFile) {
- HashMap config = new HashMap<>();
- for (Entry entry : getConfigurationFields().entrySet()) {
- try {
- String name = entry.getKey();
- Field field = entry.getValue();
- ConfigurationItem item = (ConfigurationItem) field.get(null);
- if (item.hasValue) {
- config.put(name, item.get());
- }
- } catch (IllegalArgumentException | IllegalAccessException ex) {
- Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
- try (ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) {
- oos.writeObject(config);
- } catch (IOException ex) {
- //TODO: move this to GUI
- JOptionPane.showMessageDialog(null, "Cannot save configuration.", "Error", JOptionPane.ERROR_MESSAGE);
- Logger.getLogger(Configuration.class.getName()).severe("Configuration directory is read only.");
- }
- if (replacementsFile != null) {
- saveReplacements(replacementsFile);
- }
- }
-
- public static List getReplacements() {
- return replacements;
- }
-
- public static void saveConfig() {
- try {
- saveToFile(getConfigFile(), getReplacementsFile());
- } catch (IOException ex) {
- //ignore
- }
- }
-
- static {
- setConfigurationFields();
- if (useDetailedLogging.get() || debugMode.get()) {
- logLevel = Level.CONFIG;
- } else {
- logLevel = Level.WARNING;
- }
- int processorCount = Runtime.getRuntime().availableProcessors();
- if (parallelThreadCount.get() > processorCount) {
- parallelThreadCount.set(processorCount);
- }
- }
-
- @SuppressWarnings("unchecked")
- public static void setConfigurationFields() {
- try {
- HashMap config = loadFromFile(getConfigFile(), getReplacementsFile());
- for (Entry entry : getConfigurationFields().entrySet()) {
- String name = entry.getKey();
- Field field = entry.getValue();
- // remove final modifier from field
- Field modifiersField = field.getClass().getDeclaredField("modifiers");
- modifiersField.setAccessible(true);
- modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
-
- Object defaultValue = getDefaultValue(field);
- Object value = null;
- if (config.containsKey(name)) {
- value = config.get(name);
- }
-
- if (value != null) {
- field.set(null, new ConfigurationItem(name, defaultValue, value));
- } else {
- field.set(null, new ConfigurationItem(name, defaultValue));
- }
- }
- } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException ex) {
- // Reflection exceptions. This should never happen
- throw new Error(ex.getMessage());
- } catch (IOException ex) {
- Logger.getLogger(Configuration.class.getName()).log(Level.SEVERE, null, ex);
- }
- }
-
- public static Object getDefaultValue(Field field) {
- Object defaultValue = null;
- ConfigurationDefaultBoolean aBool = field.getAnnotation(ConfigurationDefaultBoolean.class);
- if (aBool != null) {
- defaultValue = aBool.value();
- }
- ConfigurationDefaultInt aInt = field.getAnnotation(ConfigurationDefaultInt.class);
- if (aInt != null) {
- defaultValue = aInt.value();
- }
- ConfigurationDefaultString aString = field.getAnnotation(ConfigurationDefaultString.class);
- if (aString != null) {
- defaultValue = aString.value();
- }
- return defaultValue;
- }
-
- public static Map getConfigurationFields() {
- Field[] fields = Configuration.class.getFields();
- Map result = new HashMap<>();
- for (Field field : fields) {
- if (ConfigurationItem.class.isAssignableFrom(field.getType())) {
- ConfigurationName annotation = field.getAnnotation(ConfigurationName.class);
- String name = annotation == null ? field.getName() : annotation.value();
- result.put(name, field);
- }
- }
- return result;
- }
-
- public static CodeFormatting getCodeFormatting() {
- CodeFormatting ret = new CodeFormatting();
- String indentString = "";
- for (int i = 0; i < indentSize.get(); i++) {
- indentString += indentUseTabs.get() ? "\t" : " ";
- }
- ret.indentString = indentString;
- ret.beginBlockOnNewLine = beginBlockOnNewLine.get();
- return ret;
- }
-
- public static File getFlashLibPath() {
- String home = getFFDecHome();
- File libsdir = new File(home + "flashlib");
- if (!libsdir.exists()) {
- libsdir.mkdirs();
- }
- return libsdir;
- }
-
- public static File getPlayerSWC() {
- File libsdir = getFlashLibPath();
- if (libsdir != null && libsdir.exists()) {
- File libs[] = libsdir.listFiles(new FilenameFilter() {
-
- @Override
- public boolean accept(File dir, String name) {
- return name.toLowerCase().startsWith("playerglobal");
- }
- });
- List libnames = new ArrayList<>();
- for (File f : libs) {
- libnames.add(f.getName());
- }
- Collections.sort(libnames);
- if (!libnames.isEmpty()) {
- return new File(libsdir.getAbsolutePath() + File.separator + libnames.get(libnames.size() - 1));
- } else {
- return null;
- }
- }
-
- return null;
- }
-}
+/*
+ * Copyright (C) 2010-2014 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 .
+ */
+package com.jpexs.decompiler.flash.configuration;
+
+import com.jpexs.decompiler.flash.ApplicationInfo;
+import com.jpexs.decompiler.flash.helpers.CodeFormatting;
+import com.jpexs.helpers.Helper;
+import com.jpexs.helpers.utf8.Utf8InputStreamReader;
+import com.jpexs.helpers.utf8.Utf8OutputStreamWriter;
+import com.jpexs.proxy.Replacement;
+import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.PrintWriter;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JOptionPane;
+
+public class Configuration {
+
+ private static final String CONFIG_NAME = "config.bin";
+ private static final String REPLACEMENTS_NAME = "replacements.cfg";
+ private static final File unspecifiedFile = new File("unspecified");
+ private static File directory = unspecifiedFile;
+
+ /**
+ * List of replacements
+ */
+ private static List replacements = new ArrayList<>();
+
+ public static final Level logLevel;
+
+ @ConfigurationDefaultBoolean(true)
+ @ConfigurationCategory("ui")
+ public static final ConfigurationItem openMultipleFiles = null;
+
+ @ConfigurationDefaultBoolean(true)
+ @ConfigurationCategory("script")
+ public static final ConfigurationItem decompile = null;
+
+ @ConfigurationDefaultBoolean(true)
+ @ConfigurationCategory("decompilation")
+ public static final ConfigurationItem parallelSpeedUp = null;
+
+ @ConfigurationDefaultInt(20)
+ @ConfigurationCategory("decompilation")
+ public static final ConfigurationItem parallelThreadCount = null;
+
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationCategory("script")
+ public static final ConfigurationItem autoDeobfuscate = null;
+
+ @ConfigurationDefaultBoolean(true)
+ @ConfigurationCategory("decompilation")
+ public static final ConfigurationItem cacheOnDisk = null;
+
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationCategory("display")
+ public static final ConfigurationItem internalFlashViewer = null;
+
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationCategory("display")
+ public static final ConfigurationItem dumpView = null;
+
+ @ConfigurationDefaultBoolean(true)
+ @ConfigurationCategory("display")
+ public static final ConfigurationItem dumpInfoCollecting = null;
+
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationCategory("ui")
+ public static final ConfigurationItem gotoMainClassOnStartup = null;
+
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationCategory("script")
+ public static final ConfigurationItem autoRenameIdentifiers = null;
+
+ @ConfigurationDefaultBoolean(false)
+ public static final ConfigurationItem offeredAssociation = null;
+
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationCategory("script")
+ public static final ConfigurationItem decimalAddress = null;
+
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationCategory("script")
+ public static final ConfigurationItem showAllAddresses = null;
+
+ @ConfigurationDefaultBoolean(true)
+ @ConfigurationCategory("display")
+ public static final ConfigurationItem useFrameCache = null;
+
+ @ConfigurationDefaultBoolean(true)
+ @ConfigurationCategory("ui")
+ public static final ConfigurationItem useRibbonInterface = null;
+
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationCategory("export")
+ public static final ConfigurationItem openFolderAfterFlaExport = null;
+
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationCategory("debug")
+ public static final ConfigurationItem useDetailedLogging = null;
+
+ /**
+ * Debug mode = throwing an error when comparing original file and
+ * recompiled
+ */
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationCategory("debug")
+ public static final ConfigurationItem debugMode = null;
+ /**
+ * Turn off resolving constants in ActionScript 2
+ */
+ @ConfigurationDefaultBoolean(true)
+ @ConfigurationCategory("script")
+ public static final ConfigurationItem resolveConstants = null;
+ /**
+ * Limit of code subs (for obfuscated code)
+ */
+ @ConfigurationDefaultInt(500)
+ @ConfigurationCategory("limit")
+ public static final ConfigurationItem sublimiter = null;
+ /**
+ * Total export timeout in seconds
+ */
+ @ConfigurationDefaultInt(30 * 60)
+ @ConfigurationCategory("limit")
+ public static final ConfigurationItem exportTimeout = null;
+ /**
+ * Decompilation timeout in seconds for a single file
+ */
+ @ConfigurationDefaultInt(5 * 60)
+ @ConfigurationCategory("limit")
+ public static final ConfigurationItem decompilationTimeoutFile = null;
+ /**
+ * Using parameter names in decompiling may cause problems because official
+ * programs like Flash CS 5.5 inserts wrong parameter names indices
+ */
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationCategory("script")
+ public static final ConfigurationItem paramNamesEnable = null;
+
+ @ConfigurationDefaultBoolean(true)
+ @ConfigurationCategory("ui")
+ public static final ConfigurationItem displayFileName = null;
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationCategory("debug")
+ public static final ConfigurationItem debugCopy = null;
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationCategory("debug")
+ public static final ConfigurationItem dumpTags = null;
+
+ @ConfigurationDefaultInt(60)
+ @ConfigurationCategory("limit")
+ public static final ConfigurationItem decompilationTimeoutSingleMethod = null;
+ @ConfigurationDefaultInt(1)
+ public static final ConfigurationItem lastRenameType = null;
+
+ @ConfigurationDefaultString(".")
+ public static final ConfigurationItem lastSaveDir = null;
+
+ @ConfigurationDefaultString(".")
+ public static final ConfigurationItem lastOpenDir = null;
+
+ @ConfigurationDefaultString(".")
+ public static final ConfigurationItem lastExportDir = null;
+
+ @ConfigurationDefaultString("en")
+ @ConfigurationCategory("ui")
+ public static final ConfigurationItem locale = null;
+
+ @ConfigurationDefaultString("_loc%d_")
+ @ConfigurationCategory("script")
+ public static final ConfigurationItem registerNameFormat = null;
+
+ @ConfigurationDefaultInt(10)
+ public static final ConfigurationItem maxRecentFileCount = null;
+
+ public static final ConfigurationItem recentFiles = null;
+
+ public static final ConfigurationItem fontPairing = null;
+
+ public static final ConfigurationItem lastUpdatesCheckDate = null;
+
+ @ConfigurationDefaultInt(1000)
+ @ConfigurationName("gui.window.width")
+ public static final ConfigurationItem guiWindowWidth = null;
+ @ConfigurationDefaultInt(700)
+ @ConfigurationName("gui.window.height")
+ public static final ConfigurationItem guiWindowHeight = null;
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationName("gui.window.maximized.horizontal")
+ public static final ConfigurationItem guiWindowMaximizedHorizontal = null;
+ @ConfigurationDefaultBoolean(false)
+ @ConfigurationName("gui.window.maximized.vertical")
+ public static final ConfigurationItem guiWindowMaximizedVertical = null;
+ @ConfigurationName("gui.avm2.splitPane.dividerLocation")
+ public static final ConfigurationItem guiAvm2SplitPaneDividerLocation = null;
+ @ConfigurationName("guiActionSplitPaneDividerLocation")
+ public static final ConfigurationItem guiActionSplitPaneDividerLocation = null;
+ @ConfigurationName("guiPreviewSplitPaneDividerLocation")
+ public static final ConfigurationItem guiPreviewSplitPaneDividerLocation = null;
+ @ConfigurationName("gui.splitPane1.dividerLocation")
+ public static final ConfigurationItem guiSplitPane1DividerLocation = null;
+ @ConfigurationName("gui.splitPane2.dividerLocation")
+ public static final ConfigurationItem guiSplitPane2DividerLocation = null;
+ @ConfigurationDefaultInt(3)
+ @ConfigurationCategory("export")
+ public static final ConfigurationItem saveAsExeScaleMode = null;
+
+ @ConfigurationDefaultInt(1024 * 100/*100KB*/)
+ @ConfigurationCategory("limit")
+ public static final ConfigurationItem syntaxHighlightLimit = null;
+ public static final ConfigurationItem guiFontPreviewSampleText = null;
+ @ConfigurationName("gui.fontPreviewWindow.width")
+ public static final ConfigurationItem