diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java index e2eedbc43..232303cac 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/IdentifiersDeobfuscation.java @@ -214,7 +214,7 @@ public class IdentifiersDeobfuscation { String name = nChain.getLast(); boolean changed = false; - if ((pkg != null) && (!pkg.isEmpty())) { + if ((pkg != null) && (!pkg.isEmpty()) && (!pkg.isTopLevel())) { DottedChain changedPkg = deobfuscatePackage(as3, pkg, namesMap, renameType, selected); if (changedPkg != null) { changed = true; @@ -344,7 +344,7 @@ public class IdentifiersDeobfuscation { * @return */ public static String printIdentifier(boolean as3, String s, String... validExceptions) { - if (s.isEmpty()) { + if (s == null || s.isEmpty()) { return ""; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java index fa31413a6..6b490863b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java @@ -58,7 +58,7 @@ public class SourceGeneratorLocalData implements Serializable { public Map> traitUsages = new HashMap<>(); - public DottedChain pkg = DottedChain.EMPTY; + public DottedChain pkg = DottedChain.TOPLEVEL; public List scopeStack = new ArrayList<>(); @@ -68,8 +68,11 @@ public class SourceGeneratorLocalData implements Serializable { public boolean subMethod = false; + public int privateNs = 0; + public int protectedNs = 0; + public String getFullClass() { - return pkg == null || pkg.isEmpty() ? currentClass : pkg.toRawString() + "." + currentClass; + return pkg.add(currentClass).toRawString(); } public SourceGeneratorLocalData(HashMap registerVars, Integer inFunction, Boolean inMethod, Integer forInLevel) { 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 01f32861f..9588969b0 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 @@ -1274,7 +1274,6 @@ public class ABC { } List otherAbcs = new ArrayList<>(pack.allABCs); - otherAbcs.remove(this); ActionScript3Parser.compile(as, this, otherAbcs, isDocumentClass, scriptName, newClassIndex); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ClassPath.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ClassPath.java index 537c74506..a7c0beb4d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ClassPath.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ClassPath.java @@ -37,7 +37,7 @@ public class ClassPath { @Override public String toString() { - return packageStr.isEmpty() ? IdentifiersDeobfuscation.printIdentifier(true, className) + return packageStr.isEmpty() || packageStr.isTopLevel() ? IdentifiersDeobfuscation.printIdentifier(true, className) : packageStr.toPrintableString(true) + "." + IdentifiersDeobfuscation.printIdentifier(true, className); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ApplyTypeAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ApplyTypeAVM2Item.java index 7fa3d8dea..d5c5acd3f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ApplyTypeAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ApplyTypeAVM2Item.java @@ -28,6 +28,7 @@ import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.LocalData; import java.util.ArrayList; import java.util.List; +import java.util.Objects; public class ApplyTypeAVM2Item extends AVM2Item { @@ -41,6 +42,32 @@ public class ApplyTypeAVM2Item extends AVM2Item { this.object = object; } + @Override + public int hashCode() { + int hash = 3; + hash = 79 * hash + Objects.hashCode(this.object); + hash = 79 * hash + Objects.hashCode(this.params); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final ApplyTypeAVM2Item other = (ApplyTypeAVM2Item) obj; + if (!Objects.equals(this.object, other.object)) { + return false; + } + if (!Objects.equals(this.params, other.params)) { + return false; + } + return true; + } + @Override public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { object.toString(writer, localData); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java index 19021b7a6..ca20065f5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/CoerceAVM2Item.java @@ -129,7 +129,7 @@ public class CoerceAVM2Item extends AVM2Item { ins = new AVM2Instruction(0, AVM2Instructions.ConvertD, null); break; default: - int type_index = AVM2SourceGenerator.resolveType(localData, typeObj, ((AVM2SourceGenerator) generator).abc, (((AVM2SourceGenerator) generator).allABCs)); + int type_index = AVM2SourceGenerator.resolveType(localData, typeObj, ((AVM2SourceGenerator) generator).abcIndex); ins = new AVM2Instruction(0, AVM2Instructions.Coerce, new int[]{type_index}); break; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FloatValueAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FloatValueAVM2Item.java index 705b6843c..b7be15f4f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FloatValueAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/FloatValueAVM2Item.java @@ -57,7 +57,7 @@ public class FloatValueAVM2Item extends NumberValueAVM2Item { @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { return toSourceMerge(localData, generator, - new AVM2Instruction(0, AVM2Instructions.PushDouble, new int[]{((AVM2SourceGenerator) generator).abc.constants.getDoubleId(value, true)}) + new AVM2Instruction(0, AVM2Instructions.PushDouble, new int[]{((AVM2SourceGenerator) generator).abcIndex.getSelectedAbc().constants.getDoubleId(value, true)}) ); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/InitVectorAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/InitVectorAVM2Item.java index 309a102ff..29b399fe0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/InitVectorAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/InitVectorAVM2Item.java @@ -112,8 +112,8 @@ public class InitVectorAVM2Item extends AVM2Item { public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { AVM2SourceGenerator g = (AVM2SourceGenerator) generator; List ret = toSourceMerge(localData, generator, - ins(AVM2Instructions.FindPropertyStrict, g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, g.abc.constants.getStringId("Vector", true), 0, g.abc.constants.getNamespaceSetId(new NamespaceSet(new int[]{g.abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, g.abc.constants.getStringId("__AS3__.vec", true)), 0, true)}), true), 0, new ArrayList<>()), true)), - ins(AVM2Instructions.GetProperty, g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, g.abc.constants.getStringId("Vector", true), 0, allNsSet(g.abc), 0, new ArrayList<>()), true)), + ins(AVM2Instructions.FindPropertyStrict, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.MULTINAME, g.abcIndex.getSelectedAbc().constants.getStringId("Vector", true), 0, g.abcIndex.getSelectedAbc().constants.getNamespaceSetId(new NamespaceSet(new int[]{g.abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, g.abcIndex.getSelectedAbc().constants.getStringId("__AS3__.vec", true)), 0, true)}), true), 0, new ArrayList<>()), true)), + ins(AVM2Instructions.GetProperty, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.MULTINAME, g.abcIndex.getSelectedAbc().constants.getStringId("Vector", true), 0, allNsSet(g.abcIndex.getSelectedAbc()), 0, new ArrayList<>()), true)), subtype, ins(AVM2Instructions.ApplyType, 1), new IntegerValueAVM2Item(null, (long) arguments.size()), @@ -124,7 +124,7 @@ public class InitVectorAVM2Item extends AVM2Item { ins(AVM2Instructions.Dup), new IntegerValueAVM2Item(null, (long) i), arguments.get(i), - ins(AVM2Instructions.SetProperty, g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, g.abc.constants.getNamespaceSetId(new NamespaceSet(new int[]{g.abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, g.abc.constants.getStringId("", true)), 0, true)}), true), precedence, openedNamespaces), true)) + ins(AVM2Instructions.SetProperty, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, g.abcIndex.getSelectedAbc().constants.getNamespaceSetId(new NamespaceSet(new int[]{g.abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, g.abcIndex.getSelectedAbc().constants.getStringId("", true)), 0, true)}), true), precedence, openedNamespaces), true)) )); } return ret; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IntegerValueAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IntegerValueAVM2Item.java index fbf7c8d71..99e7694bf 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IntegerValueAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/IntegerValueAVM2Item.java @@ -134,7 +134,7 @@ public class IntegerValueAVM2Item extends NumberValueAVM2Item implements Integer } else if (value >= -32768 && value <= 32767) { ins = new AVM2Instruction(0, AVM2Instructions.PushShort, new int[]{((int) (long) value) & 0xffff}); } else { - ins = new AVM2Instruction(0, AVM2Instructions.PushInt, new int[]{((AVM2SourceGenerator) generator).abc.constants.getIntId(value, true)}); + ins = new AVM2Instruction(0, AVM2Instructions.PushInt, new int[]{((AVM2SourceGenerator) generator).abcIndex.getSelectedAbc().constants.getIntId(value, true)}); } return toSourceMerge(localData, generator, ins); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java index b55984a81..895111ec1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java @@ -110,9 +110,7 @@ import java.util.regex.Pattern; */ public class AVM2SourceGenerator implements SourceGenerator { - public final ABC abc; - - public List allABCs; + public final AbcIndexing abcIndex; public static final int MARK_E_START = 0; @@ -145,11 +143,11 @@ public class AVM2SourceGenerator implements SourceGenerator { for (int i = 0; i < item.openedNamespaces.size(); i++) { nssa[i] = item.openedNamespaces.get(i); } - int nsset = abc.constants.getNamespaceSetId(new NamespaceSet(nssa), true); + int nsset = abcIndex.getSelectedAbc().constants.getNamespaceSetId(new NamespaceSet(nssa), true); return GraphTargetItem.toSourceMerge(localData, this, item.object, - ins(AVM2Instructions.GetDescendants, abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, abc.constants.getStringId(item.nameStr, true), 0, nsset, 0, new ArrayList<>()), true)) + ins(AVM2Instructions.GetDescendants, abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.MULTINAME, abcIndex.getSelectedAbc().constants.getStringId(item.nameStr, true), 0, nsset, 0, new ArrayList<>()), true)) ); } @@ -292,8 +290,8 @@ public class AVM2SourceGenerator implements SourceGenerator { ins(AVM2Instructions.CheckFilter), NameAVM2Item.generateCoerce(localData, this, TypeItem.UNBOUNDED), AssignableAVM2Item.setTemp(localData, this, collectionReg), - ins(AVM2Instructions.GetLex, abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId("XMLList", true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true), 0, 0, new ArrayList<>()), true)), - ins(AVM2Instructions.PushString, abc.constants.getStringId("", true)), + ins(AVM2Instructions.GetLex, abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, abcIndex.getSelectedAbc().constants.getStringId("XMLList", true), abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId("", true)), 0, true), 0, 0, new ArrayList<>()), true)), + ins(AVM2Instructions.PushString, abcIndex.getSelectedAbc().constants.getStringId("", true)), ins(AVM2Instructions.Construct, 1), xmlListSetTemp )); @@ -319,7 +317,7 @@ public class AVM2SourceGenerator implements SourceGenerator { for (int i = 0; i < item.openedNamespaces.size(); i++) { nss[i] = item.openedNamespaces.get(i); } - trueBody.add(ins(AVM2Instructions.SetProperty, abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, abc.constants.getNamespaceSetId(new NamespaceSet(nss), true), 0, new ArrayList<>()), true))); + trueBody.add(ins(AVM2Instructions.SetProperty, abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, abcIndex.getSelectedAbc().constants.getNamespaceSetId(new NamespaceSet(nss), true), 0, new ArrayList<>()), true))); forBody.add(ins(AVM2Instructions.IfFalse, insToBytes(trueBody).length)); forBody.addAll(trueBody); forBody.add(ins(AVM2Instructions.PopScope)); @@ -690,14 +688,14 @@ public class AVM2SourceGenerator implements SourceGenerator { ret.add(ins(AVM2Instructions.NewObject, 0)); ret.add(ins(AVM2Instructions.PushWith)); scope = localData.scopeStack.size(); - localData.scopeStack.add(new PropertyAVM2Item(null, item.functionName, abc, allABCs, new ArrayList<>(), localData.callStack)); + localData.scopeStack.add(new PropertyAVM2Item(null, item.functionName, abcIndex, new ArrayList<>(), localData.callStack)); } - ret.add(ins(AVM2Instructions.NewFunction, method(abc.constants.getStringId(item.functionName, true), true, false, localData.callStack, localData.pkg, item.needsActivation, item.subvariables, 0 /*Set later*/, item.hasRest, item.line, localData.currentClass, null, false, localData, item.paramTypes, item.paramNames, item.paramValues, item.body, item.retType))); + ret.add(ins(AVM2Instructions.NewFunction, method(abcIndex.getSelectedAbc().constants.getStringId(item.functionName, true), true, false, localData.callStack, localData.pkg, item.needsActivation, item.subvariables, 0 /*Set later*/, item.hasRest, item.line, localData.currentClass, null, false, localData, item.paramTypes, item.paramNames, item.paramValues, item.body, item.retType))); if (!item.functionName.isEmpty()) { ret.add(ins(AVM2Instructions.Dup)); ret.add(ins(AVM2Instructions.GetScopeObject, scope)); ret.add(ins(AVM2Instructions.Swap)); - ret.add(ins(AVM2Instructions.SetProperty, abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(item.functionName, true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(localData.pkg, true)), 0, true), 0, 0, new ArrayList<>()), true))); + ret.add(ins(AVM2Instructions.SetProperty, abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, abcIndex.getSelectedAbc().constants.getStringId(item.functionName, true), abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId(localData.pkg, true)), 0, true), 0, 0, new ArrayList<>()), true))); ret.add(ins(AVM2Instructions.PopScope)); localData.scopeStack.remove(localData.scopeStack.size() - 1); } @@ -719,7 +717,7 @@ public class AVM2SourceGenerator implements SourceGenerator { int finallyEx = -1; for (NameAVM2Item e : item.catchExceptions2) { ABCException aex = new ABCException(); - aex.name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(e.getVariableName(), true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true), 0, 0, new ArrayList<>()), true); + aex.name_index = abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, abcIndex.getSelectedAbc().constants.getStringId(e.getVariableName(), true), abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId("", true)), 0, true), 0, 0, new ArrayList<>()), true); aex.type_index = typeName(localData, e.type); newex.add(aex); } @@ -1151,18 +1149,18 @@ public class AVM2SourceGenerator implements SourceGenerator { return tmpReg; } - public AVM2SourceGenerator(ABC abc, List allABCs) { - this.abc = abc; - this.allABCs = allABCs; + public AVM2SourceGenerator(AbcIndexing abc) { + this.abcIndex = abc; } - public ABC getABC() { - return abc; - } - - public void generateClass(List importedClasses, List sinitVariables, boolean staticNeedsActivation, List staticInit, List openedNamespaces, int namespace, int initScope, DottedChain pkg, ClassInfo classInfo, InstanceInfo instanceInfo, SourceGeneratorLocalData localData, boolean isInterface, String name, String superName, GraphTargetItem extendsVal, List implementsStr, GraphTargetItem constructor, List traitItems, Reference class_index) throws AVM2ParseException, CompilationException { + /*public ABC getABC() { + return abc; + }*/ + public void generateClass(int privateNs, int protectedNs, List importedClasses, List sinitVariables, boolean staticNeedsActivation, List staticInit, List openedNamespaces, int namespace, int initScope, DottedChain pkg, ClassInfo classInfo, InstanceInfo instanceInfo, SourceGeneratorLocalData localData, boolean isInterface, String name, String superName, GraphTargetItem extendsVal, List implementsStr, GraphTargetItem constructor, List traitItems, Reference class_index) throws AVM2ParseException, CompilationException { localData.currentClass = name; localData.pkg = pkg; + localData.privateNs = privateNs; + localData.protectedNs = protectedNs; if (extendsVal == null && !isInterface) { extendsVal = new TypeItem(DottedChain.OBJECT); } @@ -1172,6 +1170,7 @@ public class AVM2SourceGenerator implements SourceGenerator { Trait[] st = generateTraitsPhase1(name, superName, true, localData, traitItems, classInfo.static_traits, class_index); generateTraitsPhase2(importedClasses, pkg, traitItems, it, openedNamespaces, localData); generateTraitsPhase2(importedClasses, pkg, traitItems, st, openedNamespaces, localData); + abcIndex.refreshSelected(); generateTraitsPhase3(initScope, isInterface, name, superName, false, localData, traitItems, instanceInfo.instance_traits, it, new HashMap<>(), class_index); generateTraitsPhase3(initScope, isInterface, name, superName, true, localData, traitItems, classInfo.static_traits, st, new HashMap<>(), class_index); int init = 0; @@ -1184,7 +1183,7 @@ public class AVM2SourceGenerator implements SourceGenerator { //Class initializer int staticMi = method(0, false, false, new ArrayList<>(), pkg, staticNeedsActivation, sinitVariables, initScope + (implementsStr.isEmpty() ? 0 : 1), false, 0, isInterface ? null : name, superName, false, localData, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), staticInit, TypeItem.UNBOUNDED); - MethodBody sinitBody = abc.findBody(staticMi); + MethodBody sinitBody = abcIndex.getSelectedAbc().findBody(staticMi); List sinitcode = new ArrayList<>(); List initcode = new ArrayList<>(); @@ -1225,7 +1224,7 @@ public class AVM2SourceGenerator implements SourceGenerator { } MethodBody initBody = null; if (!isInterface) { - initBody = abc.findBody(init); + initBody = abcIndex.getSelectedAbc().findBody(init); initBody.getCode().code.addAll(constructor == null ? 0 : 2, initcode);//after getlocal0,pushscope if (sinitBody.getCode().code.get(sinitBody.getCode().code.size() - 1).definition instanceof ReturnVoidIns) { @@ -1233,11 +1232,11 @@ public class AVM2SourceGenerator implements SourceGenerator { } } sinitBody.markOffsets(); - sinitBody.autoFillStats(abc, initScope + (implementsStr.isEmpty() ? 0 : 1), true); + sinitBody.autoFillStats(abcIndex.getSelectedAbc(), initScope + (implementsStr.isEmpty() ? 0 : 1), true); classInfo.cinit_index = staticMi; if (!isInterface) { - initBody.autoFillStats(abc, initScope + 1, true); + initBody.autoFillStats(abcIndex.getSelectedAbc(), initScope + 1, true); } instanceInfo.interfaces = new int[implementsStr.size()]; for (int i = 0; i < implementsStr.size(); i++) { @@ -1268,7 +1267,7 @@ public class AVM2SourceGenerator implements SourceGenerator { */ if (cls instanceof ClassAVM2Item) { ClassAVM2Item cai = (ClassAVM2Item) cls; - generateClass(cai.importedClasses, cai.sinitVariables, cai.staticInitActivation, cai.staticInit, cai.openedNamespaces, namespace, initScope, pkg, ci, ii, localData, false, cai.className, cai.extendsOp == null ? "Object" : cai.extendsOp.toString(), cai.extendsOp, cai.implementsOp, cai.constructor, cai.traits, class_index); + generateClass(cai.privateNs, cai.protectedNs, cai.importedClasses, cai.sinitVariables, cai.staticInitActivation, cai.staticInit, cai.openedNamespaces, namespace, initScope, pkg, ci, ii, localData, false, cai.className, cai.extendsOp == null ? "Object" : cai.extendsOp.toString(), cai.extendsOp, cai.implementsOp, cai.constructor, cai.traits, class_index); if (!cai.isDynamic) { ii.flags |= InstanceInfo.CLASS_SEALED; } @@ -1282,14 +1281,14 @@ public class AVM2SourceGenerator implements SourceGenerator { InterfaceAVM2Item iai = (InterfaceAVM2Item) cls; ii.flags |= InstanceInfo.CLASS_INTERFACE; ii.flags |= InstanceInfo.CLASS_SEALED; - generateClass(iai.importedClasses, new ArrayList<>(), false, new ArrayList<>(), iai.openedNamespaces, namespace, initScope, pkg, ci, ii, localData, true, iai.name, null, null, iai.superInterfaces, null, iai.methods, class_index); + generateClass(0, 0, iai.importedClasses, new ArrayList<>(), false, new ArrayList<>(), iai.openedNamespaces, namespace, initScope, pkg, ci, ii, localData, true, iai.name, null, null, iai.superInterfaces, null, iai.methods, class_index); } - return abc.instance_info.size() - 1; + return abcIndex.getSelectedAbc().instance_info.size() - 1; } public int traitName(int namespace, String var) { - return abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(var), namespace, 0, 0, new ArrayList<>()), true); + return abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, str(var), namespace, 0, 0, new ArrayList<>()), true); } public int typeName(SourceGeneratorLocalData localData, GraphTargetItem type) throws CompilationException { @@ -1300,7 +1299,7 @@ public class AVM2SourceGenerator implements SourceGenerator { return 0; } - return resolveType(localData, type, abc, allABCs); + return resolveType(localData, type, abcIndex); /* TypeItem nameItem = (TypeItem) type; name = nameItem.fullTypeName; @@ -1311,12 +1310,12 @@ public class AVM2SourceGenerator implements SourceGenerator { if (!nameItem.subtypes.isEmpty()) { //It's vector => TypeName List params = new ArrayList<>(); for (GraphTargetItem p : nameItem.subtypes) { - params.add(typeName(localData, p));//abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(p), namespace(Namespace.KIND_PACKAGE, ppkg), 0, 0, new ArrayList()), true)); + params.add(typeName(localData, p));//abc.getLastAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, str(p), namespace(Namespace.KIND_PACKAGE, ppkg), 0, 0, new ArrayList()), true)); } - int qname = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(name), namespace(Namespace.KIND_PACKAGE, pkg), 0, 0, new ArrayList()), true); - return abc.constants.getMultinameId(new Multiname(Multiname.TYPENAME, 0, 0, 0, qname, params), true); + int qname = abc.getLastAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, str(name), namespace(Namespace.KIND_PACKAGE, pkg), 0, 0, new ArrayList()), true); + return abc.getLastAbc().constants.getMultinameId(new Multiname(Multiname.TYPENAME, 0, 0, 0, qname, params), true); } else { - return abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(name), namespace(Namespace.KIND_PACKAGE, pkg), 0, 0, new ArrayList()), true); + return abc.getLastAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, str(name), namespace(Namespace.KIND_PACKAGE, pkg), 0, 0, new ArrayList()), true); }*/ } @@ -1328,17 +1327,17 @@ public class AVM2SourceGenerator implements SourceGenerator { } public int namespace(int nsKind, String name) { - return abc.constants.getNamespaceId(new Namespace(nsKind, str(name)), 0, true); + return abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(nsKind, str(name)), 0, true); } public int str(String name) { - return abc.constants.getStringId(name, true); + return abcIndex.getSelectedAbc().constants.getStringId(name, true); } public int propertyName(GraphTargetItem name) { if (name instanceof NameAVM2Item) { NameAVM2Item va = (NameAVM2Item) name; - return abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(va.getVariableName()), namespace(Namespace.KIND_PACKAGE, ""), 0, 0, new ArrayList<>()), true); + return abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, str(va.getVariableName()), namespace(Namespace.KIND_PACKAGE, ""), 0, 0, new ArrayList<>()), true); } throw new RuntimeException("no prop"); //FIXME } @@ -1377,6 +1376,8 @@ public class AVM2SourceGenerator implements SourceGenerator { newlocalData.traitUsages = localData.traitUsages; newlocalData.currentScript = localData.currentScript; newlocalData.documentClass = localData.documentClass; + newlocalData.privateNs = localData.privateNs; + newlocalData.protectedNs = localData.protectedNs; newlocalData.subMethod = subMethod; localData = newlocalData; @@ -1388,7 +1389,7 @@ public class AVM2SourceGenerator implements SourceGenerator { UnresolvedAVM2Item n = (UnresolvedAVM2Item) an; if (n.resolved == null) { String fullClass = localData.getFullClass(); - GraphTargetItem res = n.resolve(new TypeItem(fullClass), paramTypes, paramNames, abc, allABCs, callStack, subvariables); + GraphTargetItem res = n.resolve(new TypeItem(fullClass), paramTypes, paramNames, abcIndex, callStack, subvariables); if (res instanceof AssignableAVM2Item) { subvariables.set(i, (AssignableAVM2Item) res); } else { @@ -1405,7 +1406,7 @@ public class AVM2SourceGenerator implements SourceGenerator { UnresolvedAVM2Item n = (UnresolvedAVM2Item) an; if (n.resolved == null) { String fullClass = localData.getFullClass(); - GraphTargetItem res = n.resolve(new TypeItem(fullClass), paramTypes, paramNames, abc, allABCs, callStack, subvariables); + GraphTargetItem res = n.resolve(new TypeItem(fullClass), paramTypes, paramNames, abcIndex, callStack, subvariables); paramTypes.set(t, res); } } @@ -1420,7 +1421,7 @@ public class AVM2SourceGenerator implements SourceGenerator { List registerNames = new ArrayList<>(); List registerTypes = new ArrayList<>(); if (className != null) { - String fullClassName = pkg == null || pkg.isEmpty() ? className : pkg.toRawString() + "." + className; + String fullClassName = pkg.add(className).toRawString(); registerTypes.add(fullClassName); localData.scopeStack.add(new LocalRegAVM2Item(null, registerNames.size(), null)); registerNames.add("this"); @@ -1627,14 +1628,14 @@ public class AVM2SourceGenerator implements SourceGenerator { int mindex; if (!isInterface) { - MethodBody mbody = new MethodBody(abc, new Traits(), new byte[0], new ABCException[0]); + MethodBody mbody = new MethodBody(abcIndex.getSelectedAbc(), new Traits(), new byte[0], new ABCException[0]); if (needsActivation) { int slotId = 1; for (int i = 1; i < slotNames.size(); i++) { TraitSlotConst tsc = new TraitSlotConst(); tsc.slot_id = slotId++; - tsc.name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(slotNames.get(i), true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abc.constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList<>()), true); + tsc.name_index = abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, abcIndex.getSelectedAbc().constants.getStringId(slotNames.get(i), true), abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abcIndex.getSelectedAbc().constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList<>()), true); tsc.type_index = typeName(localData, new TypeItem(slotTypes.get(i))); mbody.traits.traits.add(tsc); } @@ -1655,7 +1656,7 @@ public class AVM2SourceGenerator implements SourceGenerator { localData.callStack.add(mbody); List src = body == null ? new ArrayList<>() : generate(localData, body); - mbody.method_info = abc.addMethodInfo(mi); + mbody.method_info = abcIndex.getSelectedAbc().addMethodInfo(mi); mi.setBody(mbody); List mbodyCode = toInsList(src); mbody.setCode(new AVM2Code()); @@ -1669,9 +1670,9 @@ public class AVM2SourceGenerator implements SourceGenerator { TraitSlotConst tsc = (TraitSlotConst) mbody.traits.traits.get(i); GraphTargetItem type = TypeItem.UNBOUNDED; if (tsc.type_index > 0) { - type = new TypeItem(abc.constants.constant_multiname.get(tsc.type_index).getNameWithNamespace(abc.constants)); + type = new TypeItem(abcIndex.getSelectedAbc().constants.constant_multiname.get(tsc.type_index).getNameWithNamespace(abcIndex.getSelectedAbc().constants)); } - NameAVM2Item d = new NameAVM2Item(type, 0, tsc.getName(abc).getName(abc.constants, null, true), NameAVM2Item.getDefaultValue("" + type), true, new ArrayList<>()); + NameAVM2Item d = new NameAVM2Item(type, 0, tsc.getName(abcIndex.getSelectedAbc()).getName(abcIndex.getSelectedAbc().constants, null, true), NameAVM2Item.getDefaultValue("" + type), true, new ArrayList<>()); d.setSlotNumber(tsc.slot_id); d.setSlotScope(slotScope); mbodyCode.addAll(0, toInsList(d.toSourceIgnoreReturnValue(localData, this))); @@ -1689,21 +1690,19 @@ public class AVM2SourceGenerator implements SourceGenerator { } if (constructor) { - List abcs = new ArrayList<>(); - abcs.add(abc); - abcs.addAll(allABCs); - + /* List abcs = new ArrayList<>(); + abcs.add(abc); + abcs.addAll(allABCs); + */ int parentConstMinAC = 0; - for (ABC a : abcs) { - int ci = a.findClassByName(superType); - if (ci > -1) { - MethodInfo pmi = a.method_info.get(a.instance_info.get(ci).iinit_index); - parentConstMinAC = pmi.param_types.length; - if (pmi.flagHas_optional()) { - parentConstMinAC -= pmi.optional.length; - } + AbcIndexing.ClassIndex ci = abcIndex.findClass(new TypeItem(superType)); + if (ci != null) { + MethodInfo pmi = ci.abc.method_info.get(ci.abc.instance_info.get(ci.index).iinit_index); + parentConstMinAC = pmi.param_types.length; + if (pmi.flagHas_optional()) { + parentConstMinAC -= pmi.optional.length; } } int ac = -1; @@ -1772,11 +1771,11 @@ public class AVM2SourceGenerator implements SourceGenerator { } mbody.markOffsets(); - mbody.autoFillStats(abc, initScope, className != null); - abc.addMethodBody(mbody); + mbody.autoFillStats(abcIndex.getSelectedAbc(), initScope, className != null); + abcIndex.getSelectedAbc().addMethodBody(mbody); mindex = mbody.method_info; } else { - mindex = abc.addMethodInfo(mi); + mindex = abcIndex.getSelectedAbc().addMethodInfo(mi); } return mindex; @@ -1813,13 +1812,13 @@ public class AVM2SourceGenerator implements SourceGenerator { } } if (val instanceof IntegerValueAVM2Item) { - return new ValueKind(abc.constants.getIntId(((IntegerValueAVM2Item) val).value, true), ValueKind.CONSTANT_Int); + return new ValueKind(abcIndex.getSelectedAbc().constants.getIntId(((IntegerValueAVM2Item) val).value, true), ValueKind.CONSTANT_Int); } if (val instanceof FloatValueAVM2Item) { - return new ValueKind(abc.constants.getDoubleId(((FloatValueAVM2Item) val).value, true), ValueKind.CONSTANT_Double); + return new ValueKind(abcIndex.getSelectedAbc().constants.getDoubleId(((FloatValueAVM2Item) val).value, true), ValueKind.CONSTANT_Double); } if (val instanceof NanAVM2Item) { - return new ValueKind(abc.constants.getDoubleId(Double.NaN, true), ValueKind.CONSTANT_Double); + return new ValueKind(abcIndex.getSelectedAbc().constants.getDoubleId(Double.NaN, true), ValueKind.CONSTANT_Double); } if (val instanceof NullAVM2Item) { return new ValueKind(0, ValueKind.CONSTANT_Null); @@ -1832,7 +1831,7 @@ public class AVM2SourceGenerator implements SourceGenerator { private int genNs(List importedClasses, DottedChain pkg, String custom, int namespace, List openedNamespaces, SourceGeneratorLocalData localData, int line) throws CompilationException { if (custom != null) { - PropertyAVM2Item prop = new PropertyAVM2Item(null, custom, abc, allABCs, openedNamespaces, new ArrayList<>()); + PropertyAVM2Item prop = new PropertyAVM2Item(null, custom, abcIndex, openedNamespaces, new ArrayList<>()); Reference value = new Reference<>(null); prop.resolve(localData, new Reference<>(null), new Reference<>(null), new Reference<>(0), value); boolean resolved = true; @@ -1849,21 +1848,16 @@ public class AVM2SourceGenerator implements SourceGenerator { } } - List aas = new ArrayList<>(); - aas.add(abc); - aas.addAll(allABCs); - for (ABC a : aas) { - for (ScriptInfo si : a.script_info) { - for (Trait t : si.traits.traits) { - Multiname m = t.getName(a); - if (fullCustom != null && fullCustom.equals(m.getNameWithNamespace(a.constants))) { - if (t instanceof TraitSlotConst) { - if (((TraitSlotConst) t).isNamespace()) { - Namespace ns = a.constants.getNamespace(((TraitSlotConst) t).value_index); - return abc.constants.getNamespaceId(new Namespace(ns.kind, abc.constants.getStringId(ns.getName(a.constants), true)), 0, true); - } - } - } + /*List aas = new ArrayList<>(); + aas.add(abc); + aas.addAll(allABCs);*/ + AbcIndexing.TraitIndex ti = abcIndex.findScriptProperty(fullCustom); + + if (ti != null) { + if (ti.trait instanceof TraitSlotConst) { + if (((TraitSlotConst) ti.trait).isNamespace()) { + Namespace ns = ti.abc.constants.getNamespace(((TraitSlotConst) ti.trait).value_index); + return abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(ns.kind, abcIndex.getSelectedAbc().constants.getStringId(ns.getName(ti.abc.constants), true)), 0, true); } } } @@ -1901,14 +1895,18 @@ public class AVM2SourceGenerator implements SourceGenerator { continue; } if (item instanceof ClassAVM2Item) { - InstanceInfo instanceInfo = abc.instance_info.get(((TraitClass) traits[k]).class_info); - instanceInfo.name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(((ClassAVM2Item) item).className, true), - abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList<>()), true); + + InstanceInfo instanceInfo = abcIndex.getSelectedAbc().instance_info.get(((TraitClass) traits[k]).class_info); + instanceInfo.name_index = abcIndex.getSelectedAbc().constants.getMultinameId( + new Multiname( + Multiname.QNAME, + abcIndex.getSelectedAbc().constants.getStringId(((ClassAVM2Item) item).className, true), + abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId(((ClassAVM2Item) item).pkg, true)), 0, true), 0, 0, new ArrayList<>()), true); if (((ClassAVM2Item) item).extendsOp != null) { instanceInfo.super_index = typeName(localData, ((ClassAVM2Item) item).extendsOp); } else { - instanceInfo.super_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str("Object"), namespace(Namespace.KIND_PACKAGE, ""), 0, 0, new ArrayList<>()), true); + instanceInfo.super_index = abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, str("Object"), namespace(Namespace.KIND_PACKAGE, ""), 0, 0, new ArrayList<>()), true); } instanceInfo.interfaces = new int[((ClassAVM2Item) item).implementsOp.size()]; for (int i = 0; i < ((ClassAVM2Item) item).implementsOp.size(); i++) { @@ -1916,9 +1914,9 @@ public class AVM2SourceGenerator implements SourceGenerator { } } if (item instanceof InterfaceAVM2Item) { - InstanceInfo instanceInfo = abc.instance_info.get(((TraitClass) traits[k]).class_info); - instanceInfo.name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(((InterfaceAVM2Item) item).name, true), - abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList<>()), true); + InstanceInfo instanceInfo = abcIndex.getSelectedAbc().instance_info.get(((TraitClass) traits[k]).class_info); + instanceInfo.name_index = abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, abcIndex.getSelectedAbc().constants.getStringId(((InterfaceAVM2Item) item).name, true), + abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId(((InterfaceAVM2Item) item).pkg, true)), 0, true), 0, 0, new ArrayList<>()), true); instanceInfo.interfaces = new int[((InterfaceAVM2Item) item).superInterfaces.size()]; for (int i = 0; i < ((InterfaceAVM2Item) item).superInterfaces.size(); i++) { @@ -1931,16 +1929,16 @@ public class AVM2SourceGenerator implements SourceGenerator { public int superIntName(SourceGeneratorLocalData localData, GraphTargetItem un) throws CompilationException { if (un instanceof UnresolvedAVM2Item) { - ((UnresolvedAVM2Item) un).resolve(null, new ArrayList<>(), new ArrayList<>(), abc, allABCs, new ArrayList<>(), new ArrayList<>()); + ((UnresolvedAVM2Item) un).resolve(null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), new ArrayList<>()); un = ((UnresolvedAVM2Item) un).resolved; } if (!(un instanceof TypeItem)) { //not applyType throw new CompilationException("Invalid type", 0); } TypeItem sup = (TypeItem) un; - int propId = resolveType(localData, sup, abc, allABCs); - int[] nss = new int[]{abc.constants.constant_multiname.get(propId).namespace_index}; - return abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, abc.constants.constant_multiname.get(propId).name_index, 0, abc.constants.getNamespaceSetId(new NamespaceSet(nss), true), 0, new ArrayList<>()), true); + int propId = resolveType(localData, sup, abcIndex); + int[] nss = new int[]{abcIndex.getSelectedAbc().constants.constant_multiname.get(propId).namespace_index}; + return abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.MULTINAME, abcIndex.getSelectedAbc().constants.constant_multiname.get(propId).name_index, 0, abcIndex.getSelectedAbc().constants.getNamespaceSetId(new NamespaceSet(nss), true), 0, new ArrayList<>()), true); } @@ -1952,13 +1950,13 @@ public class AVM2SourceGenerator implements SourceGenerator { int values[] = new int[en.getValue().size()]; int j = 0; for (String key : en.getValue().keySet()) { - keys[j] = abc.constants.getStringId(key, true); - values[j] = abc.constants.getStringId(en.getValue().get(key), true); + keys[j] = abcIndex.getSelectedAbc().constants.getStringId(key, true); + values[j] = abcIndex.getSelectedAbc().constants.getStringId(en.getValue().get(key), true); j++; } - MetadataInfo mi = new MetadataInfo(abc.constants.getStringId(en.getKey(), true), keys, values); - ret[i] = abc.metadata_info.size(); - abc.metadata_info.add(mi); + MetadataInfo mi = new MetadataInfo(abcIndex.getSelectedAbc().constants.getStringId(en.getKey(), true), keys, values); + ret[i] = abcIndex.getSelectedAbc().metadata_info.size(); + abcIndex.getSelectedAbc().metadata_info.add(mi); } return ret; } @@ -1971,21 +1969,21 @@ public class AVM2SourceGenerator implements SourceGenerator { continue; } if (item instanceof InterfaceAVM2Item) { - generateClass(((InterfaceAVM2Item) item).namespace, abc.class_info.get(((TraitClass) traits[k]).class_info), abc.instance_info.get(((TraitClass) traits[k]).class_info), initScopes.get(traits[k]), ((InterfaceAVM2Item) item).pkg, localData, (InterfaceAVM2Item) item, class_index); + generateClass(((InterfaceAVM2Item) item).namespace, abcIndex.getSelectedAbc().class_info.get(((TraitClass) traits[k]).class_info), abcIndex.getSelectedAbc().instance_info.get(((TraitClass) traits[k]).class_info), initScopes.get(traits[k]), ((InterfaceAVM2Item) item).pkg, localData, (InterfaceAVM2Item) item, class_index); } if (item instanceof ClassAVM2Item) { - generateClass(((ClassAVM2Item) item).namespace, abc.class_info.get(((TraitClass) traits[k]).class_info), abc.instance_info.get(((TraitClass) traits[k]).class_info), initScopes.get(traits[k]), ((ClassAVM2Item) item).pkg, localData, (ClassAVM2Item) item, class_index); + generateClass(((ClassAVM2Item) item).namespace, abcIndex.getSelectedAbc().class_info.get(((TraitClass) traits[k]).class_info), abcIndex.getSelectedAbc().instance_info.get(((TraitClass) traits[k]).class_info), initScopes.get(traits[k]), ((ClassAVM2Item) item).pkg, localData, (ClassAVM2Item) item, class_index); } if ((item instanceof MethodAVM2Item) || (item instanceof GetterAVM2Item) || (item instanceof SetterAVM2Item)) { MethodAVM2Item mai = (MethodAVM2Item) item; if (mai.isStatic() != generateStatic) { continue; } - ((TraitMethodGetterSetter) traits[k]).method_info = method(abc.constants.getStringId(mai.functionName, true), false, isInterface, new ArrayList<>(), mai.pkg, mai.needsActivation, mai.subvariables, methodInitScope + (mai.isStatic() ? 0 : 1), mai.hasRest, mai.line, className, superName, false, localData, mai.paramTypes, mai.paramNames, mai.paramValues, mai.body, mai.retType); + ((TraitMethodGetterSetter) traits[k]).method_info = method(abcIndex.getSelectedAbc().constants.getStringId(mai.functionName, true), false, isInterface, new ArrayList<>(), mai.pkg, mai.needsActivation, mai.subvariables, methodInitScope + (mai.isStatic() ? 0 : 1), mai.hasRest, mai.line, className, superName, false, localData, mai.paramTypes, mai.paramNames, mai.paramValues, mai.body, mai.retType); } else if (item instanceof FunctionAVM2Item) { FunctionAVM2Item fai = (FunctionAVM2Item) item; - ((TraitFunction) traits[k]).method_info = method(abc.constants.getStringId(fai.functionName, true), false, isInterface, new ArrayList<>(), fai.pkg, fai.needsActivation, fai.subvariables, methodInitScope, fai.hasRest, fai.line, className, superName, false, localData, fai.paramTypes, fai.paramNames, fai.paramValues, fai.body, fai.retType); + ((TraitFunction) traits[k]).method_info = method(abcIndex.getSelectedAbc().constants.getStringId(fai.functionName, true), false, isInterface, new ArrayList<>(), fai.pkg, fai.needsActivation, fai.subvariables, methodInitScope, fai.hasRest, fai.line, className, superName, false, localData, fai.paramTypes, fai.paramNames, fai.paramValues, fai.body, fai.retType); } } } @@ -2003,10 +2001,10 @@ public class AVM2SourceGenerator implements SourceGenerator { /*abc.class_info.add(ci); abc.instance_info.add(ii);*/ tc.class_info = classIndex.getVal(); - abc.addClass(ci, ii, classIndex.getVal()); + abcIndex.getSelectedAbc().addClass(ci, ii, classIndex.getVal()); classIndex.setVal(classIndex.getVal() + 1); ii.flags |= InstanceInfo.CLASS_INTERFACE; - ii.name_index = traitName(((InterfaceAVM2Item) item).namespace, ((InterfaceAVM2Item) item).name); + //ii.name_index = traitName(((InterfaceAVM2Item) item).namespace, ((InterfaceAVM2Item) item).name); //tc.class_info = abc.instance_info.size() - 1; tc.kindType = Trait.TRAIT_CLASS; //tc.name_index = traitName(((InterfaceAVM2Item) item).namespace, ((InterfaceAVM2Item) item).name); @@ -2020,22 +2018,22 @@ public class AVM2SourceGenerator implements SourceGenerator { TraitClass tc = new TraitClass(); ClassInfo ci = new ClassInfo(); InstanceInfo ii = new InstanceInfo(); - ii.name_index = traitName(((ClassAVM2Item) item).namespace, ((ClassAVM2Item) item).className); + //ii.name_index = traitName(((ClassAVM2Item) item).namespace, ((ClassAVM2Item) item).className); /*abc.class_info.add(ci); abc.instance_info.add(instanceInfo);*/ tc.class_info = classIndex.getVal(); - abc.addClass(ci, ii, classIndex.getVal()); + abcIndex.getSelectedAbc().addClass(ci, ii, classIndex.getVal()); classIndex.setVal(classIndex.getVal() + 1); //tc.class_info = abc.instance_info.size() - 1; - /*instanceInfo.name_index = abc.constants.addMultiname(new Multiname(Multiname.QNAME, abc.constants.getStringId(((ClassAVM2Item) item).className, true), - abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(pkg.packageName, true)), 0, true), 0, 0, new ArrayList())); + /*instanceInfo.name_index = abc.getLastAbc().constants.addMultiname(new Multiname(Multiname.QNAME, abc.getLastAbc().constants.getStringId(((ClassAVM2Item) item).className, true), + abc.getLastAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.getLastAbc().constants.getStringId(pkg.packageName, true)), 0, true), 0, 0, new ArrayList())); */ /*if (((ClassAVM2Item) item).extendsOp != null) { instanceInfo.super_index = typeName(localData, ((ClassAVM2Item) item).extendsOp); } else { - instanceInfo.super_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str("Object"), namespace(Namespace.KIND_PACKAGE, ""), 0, 0, new ArrayList()), true); + instanceInfo.super_index = abc.getLastAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, str("Object"), namespace(Namespace.KIND_PACKAGE, ""), 0, 0, new ArrayList()), true); }*/ tc.kindType = Trait.TRAIT_CLASS; // tc.name_index = traitName(((ClassAVM2Item) item).namespace, ((ClassAVM2Item) item).className); @@ -2136,9 +2134,12 @@ public class AVM2SourceGenerator implements SourceGenerator { localData.currentScript = si; Trait[] traitArr = generateTraitsPhase1(null, null, true, localData, commands, si.traits, class_index); generateTraitsPhase2(new ArrayList<>(), null/*FIXME*/, commands, traitArr, new ArrayList<>(), localData); + + abcIndex.refreshSelected(); + MethodInfo mi = new MethodInfo(new int[0], 0, 0, 0, new ValueKind[0], new int[0]); - MethodBody mb = new MethodBody(abc, new Traits(), new byte[0], new ABCException[0]); - mb.method_info = abc.addMethodInfo(mi); + MethodBody mb = new MethodBody(abcIndex.getSelectedAbc(), new Traits(), new byte[0], new ABCException[0]); + mb.method_info = abcIndex.getSelectedAbc().addMethodInfo(mi); mb.setCode(new AVM2Code()); List mbCode = mb.getCode().code; mbCode.add(ins(AVM2Instructions.GetLocal0)); @@ -2156,14 +2157,26 @@ public class AVM2SourceGenerator implements SourceGenerator { mbCode.add(ins(AVM2Instructions.GetScopeObject, 0)); traitScope++; } else { - NamespaceSet nsset = new NamespaceSet(new int[]{abc.constants.constant_multiname.get(tc.name_index).namespace_index}); - mbCode.add(ins(AVM2Instructions.FindPropertyStrict, abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, abc.constants.constant_multiname.get(tc.name_index).name_index, 0, abc.constants.getNamespaceSetId(nsset, true), 0, new ArrayList<>()), true))); + NamespaceSet nsset = new NamespaceSet(new int[]{abcIndex.getSelectedAbc().constants.constant_multiname.get(tc.name_index).namespace_index}); + mbCode.add(ins(AVM2Instructions.FindPropertyStrict, abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.MULTINAME, abcIndex.getSelectedAbc().constants.constant_multiname.get(tc.name_index).name_index, 0, abcIndex.getSelectedAbc().constants.getNamespaceSetId(nsset, true), 0, new ArrayList<>()), true))); } - if (abc.instance_info.get(tc.class_info).isInterface()) { + if (abcIndex.getSelectedAbc().instance_info.get(tc.class_info).isInterface()) { mbCode.add(ins(AVM2Instructions.PushNull)); } else { - parentNamesAddNames(abc, allABCs, abc.instance_info.get(tc.class_info).name_index, parents, new ArrayList<>(), new ArrayList<>()); - parents.remove(0); //remove this class + + AbcIndexing.ClassIndex ci = abcIndex.findClass(AbcIndexing.multinameToType(abcIndex.getSelectedAbc().instance_info.get(tc.class_info).name_index, abcIndex.getSelectedAbc().constants)); + while (ci != null && ci.parent != null) { + ci = ci.parent; + Multiname origM = ci.abc.constants.getMultiname(ci.abc.instance_info.get(ci.index).name_index); + Namespace origNs = ci.abc.constants.getNamespace(origM.namespace_index); + parents.add(abcIndex.getSelectedAbc().constants.getMultinameId( + new Multiname(origM.kind, + abcIndex.getSelectedAbc().constants.getStringId(ci.abc.constants.getString(origM.name_index), true), + abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(origNs.kind, abcIndex.getSelectedAbc().constants.getStringId( + ci.abc.constants.getString(origNs.name_index) + )), 0, true), 0, 0, new ArrayList()) + )); + } //add all parent objects to scopestack for (int i = parents.size() - 1; i >= 0; i--) { @@ -2186,52 +2199,52 @@ public class AVM2SourceGenerator implements SourceGenerator { } mbCode.add(ins(AVM2Instructions.ReturnVoid)); - mb.autoFillStats(abc, 1, false); - abc.addMethodBody(mb); + mb.autoFillStats(abcIndex.getSelectedAbc(), 1, false); + abcIndex.getSelectedAbc().addMethodBody(mb); si.init_index = mb.method_info; localData.pkg = null; //FIXME: pkg.packageName; generateTraitsPhase3(1/*??*/, false, null, null, true, localData, commands, si.traits, traitArr, initScopes, class_index); return si; } - public static void parentNamesAddNames(ABC abc, List allABCs, int name_index, List indices, List names, List namespaces) { + public static void parentNamesAddNames(AbcIndexing abc, int name_index, List indices, List names, List namespaces) { List cindices = new ArrayList<>(); List outABCs = new ArrayList<>(); - parentNames(abc, allABCs, name_index, cindices, names, namespaces, outABCs); + parentNames(abc, name_index, cindices, names, namespaces, outABCs); for (int i = 0; i < cindices.size(); i++) { ABC a = outABCs.get(i); int m = cindices.get(i); - if (a == abc) { + if (a == abc.getSelectedAbc()) { indices.add(m); continue; } Multiname superName = a.constants.constant_multiname.get(m); indices.add( - abc.constants.getMultinameId( + abc.getSelectedAbc().constants.getMultinameId( new Multiname(Multiname.QNAME, - abc.constants.getStringId(superName.getName(a.constants, null, true), true), - abc.constants.getNamespaceId(new Namespace(superName.getNamespace(a.constants).kind, abc.constants.getStringId(superName.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList<>()), true) + abc.getSelectedAbc().constants.getStringId(superName.getName(a.constants, null, true), true), + abc.getSelectedAbc().constants.getNamespaceId(new Namespace(superName.getNamespace(a.constants).kind, abc.getSelectedAbc().constants.getStringId(superName.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList<>()), true) ); } } - public static GraphTargetItem getTraitReturnType(ABC abc, Trait t) { + public static GraphTargetItem getTraitReturnType(AbcIndexing abc, Trait t) { if (t instanceof TraitSlotConst) { TraitSlotConst tsc = (TraitSlotConst) t; if (tsc.type_index == 0) { return TypeItem.UNBOUNDED; } - return PropertyAVM2Item.multinameToType(tsc.type_index, abc.constants); + return PropertyAVM2Item.multinameToType(tsc.type_index, abc.getSelectedAbc().constants); } if (t instanceof TraitMethodGetterSetter) { TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t; if (tmgs.kindType == Trait.TRAIT_GETTER) { - return PropertyAVM2Item.multinameToType(abc.method_info.get(tmgs.method_info).ret_type, abc.constants); + return PropertyAVM2Item.multinameToType(abc.getSelectedAbc().method_info.get(tmgs.method_info).ret_type, abc.getSelectedAbc().constants); } if (tmgs.kindType == Trait.TRAIT_SETTER) { - if (abc.method_info.get(tmgs.method_info).param_types.length > 0) { - return PropertyAVM2Item.multinameToType(abc.method_info.get(tmgs.method_info).param_types[0], abc.constants); + if (abc.getSelectedAbc().method_info.get(tmgs.method_info).param_types.length > 0) { + return PropertyAVM2Item.multinameToType(abc.getSelectedAbc().method_info.get(tmgs.method_info).param_types[0], abc.getSelectedAbc().constants); } else { return TypeItem.UNBOUNDED; } @@ -2243,127 +2256,51 @@ public class AVM2SourceGenerator implements SourceGenerator { return TypeItem.UNBOUNDED; } - public static boolean searchPrototypeChain(boolean instanceOnly, List abcs, DottedChain pkg, String obj, String propertyName, Reference outName, Reference outNs, Reference outPropNs, Reference outPropNsKind, Reference outPropNsIndex, Reference outPropType, Reference outPropValue) { - - for (ABC abc : abcs) { - if (!instanceOnly) { - for (ScriptInfo ii : abc.script_info) { - if (ii.deleted) { - continue; - } - for (Trait t : ii.traits.traits) { - if (Objects.equals(pkg, t.getName(abc).getNamespace(abc.constants).getName(abc.constants))) { - if (propertyName.equals(t.getName(abc).getName(abc.constants, null, true))) { - outName.setVal(obj); - outNs.setVal(pkg); - outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants)); - outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind); - outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index)); - outPropType.setVal(getTraitReturnType(abc, t)); - if (t instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) t; - outPropValue.setVal(new ValueKind(tsc.value_index, tsc.value_kind)); - } - return true; - } - } - } - } - } - for (int i = 0; i < abc.instance_info.size(); i++) { - InstanceInfo ii = abc.instance_info.get(i); - if (ii.deleted) { - continue; - } - Multiname clsName = ii.getName(abc.constants); - if (obj.equals(clsName.getName(abc.constants, null, true))) { - if (Objects.equals(pkg, clsName.getNamespace(abc.constants).getName(abc.constants))) { - //class found - - for (Trait t : ii.instance_traits.traits) { - if (t.getName(abc) == null) { //in traits phase 2 - continue; - } - if (propertyName.equals(t.getName(abc).getName(abc.constants, null, true))) { - outName.setVal(obj); - outNs.setVal(pkg); - outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants)); - outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind); - outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index)); - outPropType.setVal(getTraitReturnType(abc, t)); - if (t instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) t; - outPropValue.setVal(new ValueKind(tsc.value_index, tsc.value_kind)); - } - return true; - } - } - - if (!instanceOnly) { - for (Trait t : abc.class_info.get(i).static_traits.traits) { - if (t.getName(abc) == null) { //in traits phase 2 - continue; - } - if (propertyName.equals(t.getName(abc).getName(abc.constants, null, true))) { - outName.setVal(obj); - outNs.setVal(pkg); - outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants)); - outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind); - outPropNsIndex.setVal(abc.constants.getNamespaceSubIndex(t.getName(abc).namespace_index)); - outPropType.setVal(getTraitReturnType(abc, t)); - if (t instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) t; - outPropValue.setVal(new ValueKind(tsc.value_index, tsc.value_kind)); - } - return true; - } - } - } - - Multiname superName = abc.constants.constant_multiname.get(ii.super_index); - if (superName != null) { - return searchPrototypeChain(instanceOnly, abcs, superName.getNamespace(abc.constants).getName(abc.constants), superName.getName(abc.constants, null, true), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue); - } else { - return false; - } - } - } - } + public static boolean searchPrototypeChain(int privateNs, int protectedNs, boolean instanceOnly, AbcIndexing abc, DottedChain pkg, String obj, String propertyName, Reference outName, Reference outNs, Reference outPropNs, Reference outPropNsKind, Reference outPropNsIndex, Reference outPropType, Reference outPropValue) { + if (searchPrototypeChain(privateNs, instanceOnly, abc, pkg, obj, propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue)) { + return true; + } + if (searchPrototypeChain(protectedNs, instanceOnly, abc, pkg, obj, propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue)) { + return true; + } + if (searchPrototypeChain(0, instanceOnly, abc, pkg, obj, propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue)) { + return true; } return false; } - public static void parentNames(ABC abc, List allABCs, int name_index, List indices, List names, List namespaces, List outABCs) { - indices.add(name_index); - names.add(abc.constants.constant_multiname.get(name_index).getName(abc.constants, null, true)); - namespaces.add(abc.constants.constant_multiname.get(name_index).getNamespace(abc.constants).getName(abc.constants).toRawString()); - Multiname mname = abc.constants.constant_multiname.get(name_index); + private static boolean searchPrototypeChain(int selectedNs, boolean instanceOnly, AbcIndexing abc, DottedChain pkg, String obj, String propertyName, Reference outName, Reference outNs, Reference outPropNs, Reference outPropNsKind, Reference outPropNsIndex, Reference outPropType, Reference outPropValue) { - outABCs.add(abc); - - List abcs = new ArrayList<>(); - abcs.add(abc); - abcs.addAll(allABCs); - - for (ABC a : abcs) { - for (int i = 0; i < a.instance_info.size(); i++) { - Multiname m = a.constants.constant_multiname.get(a.instance_info.get(i).name_index); - if (m.getName(a.constants, null, true).equals(mname.getName(abc.constants, null, true))) { - - if (m.getNamespace(a.constants).hasName(mname.getNamespace(abc.constants).getName(abc.constants).toRawString(), a.constants)) { - //Multiname superName = a.constants.constant_multiname.get(a.instance_info.get(i).super_index); - abcs.remove(a); - if (a.instance_info.get(i).super_index != 0) { - parentNames(a, abcs, a.instance_info.get(i).super_index, indices, names, namespaces, outABCs); - } - /*parentNames(abc,allABCs,abc.constants.getMultinameId( - new Multiname(superName.kind, - abc.constants.getStringId(superName.getName(a.constants, new ArrayList<>()),true), - abc.constants.getNamespaceId(new Namespace(superName.getNamespace(a.constants).kind, abc.constants.getStringId(superName.getNamespace(a.constants).getName(a.constants),true)),0,true), 0, 0, new ArrayList()), true),indices,names,namespaces,outABCs);*/ - return; - } - } + AbcIndexing.TraitIndex sp = abc.findScriptProperty(pkg.add(propertyName)); + if (sp == null) { + sp = abc.findProperty(new AbcIndexing.PropertyDef(propertyName, new TypeItem(pkg.add(obj)), abc.getSelectedAbc(), selectedNs), !instanceOnly, true); + } + if (sp != null) { + if (sp.objType instanceof TypeItem) { + outName.setVal(((TypeItem) sp.objType).fullTypeName.getLast()); + outNs.setVal(((TypeItem) sp.objType).fullTypeName.getWithoutLast()); + } else { + //FIXME? Vector? } + outPropNs.setVal(sp.trait.getName(sp.abc).getNamespace(sp.abc.constants).getName(sp.abc.constants)); + outPropNsKind.setVal(sp.trait.getName(sp.abc).getNamespace(sp.abc.constants).kind); + outPropNsIndex.setVal(selectedNs == 0 ? 0 : sp.abc.constants.getNamespaceSubIndex(selectedNs)); + outPropType.setVal(sp.returnType); + outPropValue.setVal(sp.value); + return true; + } + return false; + } + + public static void parentNames(AbcIndexing abc, int name_index, List indices, List names, List namespaces, List outABCs) { + AbcIndexing.ClassIndex ci = abc.findClass(new TypeItem(abc.getSelectedAbc().constants.constant_multiname.get(name_index).getNameWithNamespace(abc.getSelectedAbc().constants))); + while (ci != null) { + int ni = ci.abc.instance_info.get(ci.index).name_index; + indices.add(ni); + outABCs.add(ci.abc); + names.add(abc.getSelectedAbc().constants.constant_multiname.get(ni).getName(abc.getSelectedAbc().constants, null, true)); + namespaces.add(abc.getSelectedAbc().constants.constant_multiname.get(ni).getNamespace(abc.getSelectedAbc().constants).getName(abc.getSelectedAbc().constants).toRawString()); + ci = ci.parent; } } @@ -2381,9 +2318,9 @@ public class AVM2SourceGenerator implements SourceGenerator { int ci = a.findClassByName(objType); if (ci != -1) { Multiname tname = a.instance_info.get(ci).getName(a.constants); - return abc.constants.getMultinameId(new Multiname(tname.kind, - abc.constants.getStringId(tname.getName(a.constants, new ArrayList<>()), true), - abc.constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abc.constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList()), true); + return abc.getLastAbc().constants.getMultinameId(new Multiname(tname.kind, + abc.getLastAbc().constants.getStringId(tname.getName(a.constants, new ArrayList<>()), true), + abc.getLastAbc().constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abc.getLastAbc().constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList()), true); } } return 0; @@ -2394,7 +2331,7 @@ public class AVM2SourceGenerator implements SourceGenerator { if (localData.documentClass && item.toString().equals(currentFullClassName)) { int slotId = 0; - int c = abc.findClassByName(currentFullClassName); + int c = abcIndex.getSelectedAbc().findClassByName(currentFullClassName); for (Trait t : localData.currentScript.traits.traits) { if (t instanceof TraitClass) { TraitClass tc = (TraitClass) t; @@ -2406,17 +2343,17 @@ public class AVM2SourceGenerator implements SourceGenerator { } return GraphTargetItem.toSourceMerge(localData, this, ins(AVM2Instructions.GetGlobalScope), ins(AVM2Instructions.GetSlot, slotId)); } else { - return GraphTargetItem.toSourceMerge(localData, this, ins(AVM2Instructions.GetLex, resolveType(localData, item, abc, allABCs))); + return GraphTargetItem.toSourceMerge(localData, this, ins(AVM2Instructions.GetLex, resolveType(localData, item, abcIndex))); } } - public static int resolveType(SourceGeneratorLocalData localData, GraphTargetItem item, ABC abc, List allABCs) throws CompilationException { + public static int resolveType(SourceGeneratorLocalData localData, GraphTargetItem item, AbcIndexing abc) throws CompilationException { int name_index = 0; GraphTargetItem typeItem = null; if (item instanceof UnresolvedAVM2Item) { String fullClass = localData.getFullClass(); - item = ((UnresolvedAVM2Item) item).resolve(new TypeItem(fullClass), new ArrayList<>(), new ArrayList<>(), abc, allABCs, new ArrayList<>(), new ArrayList<>()); + item = ((UnresolvedAVM2Item) item).resolve(new TypeItem(fullClass), new ArrayList<>(), new ArrayList<>(), abc, new ArrayList<>(), new ArrayList<>()); } if (item instanceof TypeItem) { typeItem = item; @@ -2427,7 +2364,7 @@ public class AVM2SourceGenerator implements SourceGenerator { } if (typeItem instanceof UnresolvedAVM2Item) { String fullClass = localData.getFullClass(); - typeItem = ((UnresolvedAVM2Item) typeItem).resolve(new TypeItem(fullClass), new ArrayList<>(), new ArrayList<>(), abc, allABCs, new ArrayList<>(), new ArrayList<>()); + typeItem = ((UnresolvedAVM2Item) typeItem).resolve(new TypeItem(fullClass), new ArrayList<>(), new ArrayList<>(), abc, new ArrayList<>(), new ArrayList<>()); } if (!(typeItem instanceof TypeItem)) { @@ -2439,19 +2376,19 @@ public class AVM2SourceGenerator implements SourceGenerator { DottedChain dname = type.fullTypeName; String pkg = dname.getWithoutLast().toRawString(); String name = dname.getLast(); - for (InstanceInfo ii : abc.instance_info) { - Multiname mname = abc.constants.constant_multiname.get(ii.name_index); - if (mname != null && name.equals(mname.getName(abc.constants, null, true))) { - if (mname.getNamespace(abc.constants).hasName(pkg, abc.constants)) { + for (InstanceInfo ii : abc.getSelectedAbc().instance_info) { + Multiname mname = abc.getSelectedAbc().constants.constant_multiname.get(ii.name_index); + if (mname != null && name.equals(mname.getName(abc.getSelectedAbc().constants, null, true))) { + if (mname.getNamespace(abc.getSelectedAbc().constants).hasName(pkg, abc.getSelectedAbc().constants)) { name_index = ii.name_index; break; } } } - for (int i = 1; i < abc.constants.constant_multiname.size(); i++) { - Multiname mname = abc.constants.constant_multiname.get(i); - if (mname != null && name.equals(mname.getName(abc.constants, null, true))) { - if (mname.getNamespace(abc.constants) != null && pkg.equals(mname.getNamespace(abc.constants).getName(abc.constants))) { + for (int i = 1; i < abc.getSelectedAbc().constants.constant_multiname.size(); i++) { + Multiname mname = abc.getSelectedAbc().constants.constant_multiname.get(i); + if (mname != null && name.equals(mname.getName(abc.getSelectedAbc().constants, null, true))) { + if (mname.getNamespace(abc.getSelectedAbc().constants) != null && pkg.equals(mname.getNamespace(abc.getSelectedAbc().constants).getName(abc.getSelectedAbc().constants))) { name_index = i; break; } @@ -2460,14 +2397,14 @@ public class AVM2SourceGenerator implements SourceGenerator { if (name_index == 0) { if (pkg.isEmpty() && localData.currentScript != null /*FIXME!*/) { for (Trait t : localData.currentScript.traits.traits) { - if (t.getName(abc).getName(abc.constants, null, true).equals(name)) { + if (t.getName(abc.getSelectedAbc()).getName(abc.getSelectedAbc().constants, null, true).equals(name)) { name_index = t.name_index; break; } } } if (name_index == 0) { - name_index = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, abc.constants.getStringId(name, true), abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList<>()), true); + name_index = abc.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, abc.getSelectedAbc().constants.getStringId(name, true), abc.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.getSelectedAbc().constants.getStringId(pkg, true)), 0, true), 0, 0, new ArrayList<>()), true); } } @@ -2475,9 +2412,9 @@ public class AVM2SourceGenerator implements SourceGenerator { ApplyTypeAVM2Item atype = (ApplyTypeAVM2Item) item; List params = new ArrayList<>(); for (GraphTargetItem s : atype.params) { - params.add(resolveType(localData, s, abc, allABCs)); + params.add(resolveType(localData, s, abc)); } - return abc.constants.getMultinameId(new Multiname(Multiname.TYPENAME, 0, 0, 0, name_index, params), true); + return abc.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.TYPENAME, 0, 0, 0, name_index, params), true); } return name_index; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java new file mode 100644 index 000000000..8537e2dbf --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java @@ -0,0 +1,550 @@ +/* + * 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.abc.avm2.parser.script; + +import com.jpexs.decompiler.flash.SWF; +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.model.ApplyTypeAVM2Item; +import com.jpexs.decompiler.flash.abc.types.ClassInfo; +import com.jpexs.decompiler.flash.abc.types.InstanceInfo; +import com.jpexs.decompiler.flash.abc.types.Multiname; +import com.jpexs.decompiler.flash.abc.types.Namespace; +import com.jpexs.decompiler.flash.abc.types.ValueKind; +import com.jpexs.decompiler.flash.abc.types.traits.Trait; +import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; +import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; +import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; +import com.jpexs.decompiler.flash.abc.types.traits.Traits; +import com.jpexs.decompiler.flash.tags.ABCContainerTag; +import com.jpexs.decompiler.graph.DottedChain; +import com.jpexs.decompiler.graph.GraphTargetItem; +import com.jpexs.decompiler.graph.TypeItem; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; + +/** + * Indexing of ABCs for faster access. Indexes ABC classes for faster class and + * property resolving + * + * @author JPEXS + */ +public class AbcIndexing { + + private AbcIndexing parent = null; + private List abcs = new ArrayList<>(); + private ABC selectedAbc = null; + + /** + * Creates empty index with parent. + * + * @param parent If not property/class found, search also in this parent + */ + public AbcIndexing(AbcIndexing parent) { + this(null, parent); + } + + /** + * Creates index from SWF file with parent + * + * @param swf SWF file to load initial ABCs from + * @param parent If not property/class found, search also in this parent + */ + public AbcIndexing(SWF swf, AbcIndexing parent) { + this.parent = parent; + if (swf != null) { + for (ABCContainerTag at : swf.getAbcList()) { + addAbc(at.getABC()); + } + } + } + + /** + * Creates index from SWF file. + * + * @param swf SWF file to load initial ABCs from + */ + public AbcIndexing(SWF swf) { + this(swf, null); + } + + /** + * Creates empty index + */ + public AbcIndexing() { + this(null, null); + } + + /** + * Property key + */ + public static class PropertyDef { + + private final String propName; + private final GraphTargetItem parent; + private int propNsIndex = 0; + private ABC abc = null; + + @Override + public String toString() { + return parent.toString() + ":" + propName + (propNsIndex > 0 ? "[ns:" + propNsIndex + "]" : ""); + } + + public void setPrivate(ABC abc, int propNsIndex) { + this.propNsIndex = propNsIndex; + this.abc = abc; + } + + public String getPropertyName() { + return propName; + } + + /** + * Creates key to property. + * + * @param propName Name of the property + * @param parent Parent type (usually TypeItem) + * @param abc ABC for private/protected namespace resolving + * @param propNsIndex Index of property(trait) namespace for + * private/protected namespace reolving + */ + public PropertyDef(String propName, GraphTargetItem parent, ABC abc, int propNsIndex) { + this.propName = propName; + this.parent = parent; + if (abc == null || propNsIndex <= 0) { + return; + } + int k = abc.constants.getNamespace(propNsIndex).kind; + if (k != Namespace.KIND_PACKAGE) { + setPrivate(abc, propNsIndex); + } + } + + @Override + public int hashCode() { + int hash = 7; + hash = 17 * hash + Objects.hashCode(this.propName); + hash = 17 * hash + Objects.hashCode(this.parent); + hash = 17 * hash + this.propNsIndex; + hash = 17 * hash + System.identityHashCode(this.abc); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final PropertyDef other = (PropertyDef) obj; + if (!Objects.equals(this.propName, other.propName)) { + return false; + } + if (!Objects.equals(this.parent, other.parent)) { + return false; + } + if (this.propNsIndex != other.propNsIndex) { + return false; + } + if (this.abc != other.abc) { + return false; + } + return true; + } + + } + + /** + * Namespaced property key + */ + public static class PropertyNsDef { + + private final String propName; + private final DottedChain ns; + + private int propNsIndex = 0; + private ABC abc = null; + + public void setPrivate(ABC abc, int propNsIndex) { + this.propNsIndex = propNsIndex; + this.abc = abc; + } + + public String getPropertyName() { + return propName; + } + + public PropertyNsDef(String propName, DottedChain ns, ABC abc, int nsIndex) { + this.propName = propName; + this.ns = ns; + if (abc == null || nsIndex <= 0) { + return; + } + int k = abc.constants.getNamespace(nsIndex).kind; + if (k != Namespace.KIND_PACKAGE) { + setPrivate(abc, nsIndex); + } + } + + @Override + public int hashCode() { + int hash = 7; + hash = 19 * hash + Objects.hashCode(this.propName); + hash = 19 * hash + Objects.hashCode(this.ns); + hash = 19 * hash + this.propNsIndex; + hash = 19 * hash + System.identityHashCode(this.abc); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final PropertyNsDef other = (PropertyNsDef) obj; + if (!Objects.equals(this.propName, other.propName)) { + return false; + } + if (!Objects.equals(this.ns, other.ns)) { + return false; + } + if (this.propNsIndex != other.propNsIndex) { + return false; + } + if (this.abc != other.abc) { + return false; + } + return true; + } + + } + + public static class TraitIndex { + + public Trait trait; + public ABC abc; + public GraphTargetItem returnType; + public ValueKind value; + public GraphTargetItem objType; + + public TraitIndex(Trait trait, ABC abc, GraphTargetItem type, ValueKind value, GraphTargetItem objType) { + this.trait = trait; + this.abc = abc; + this.returnType = type; + this.value = value; + this.objType = objType; + } + + } + + public static class ClassIndex { + + public int index; + public ABC abc; + public ClassIndex parent; + + @Override + public String toString() { + return abc.constants.getMultiname(abc.instance_info.get(index).name_index).getNameWithNamespace(abc.constants).toPrintableString(true); + } + + public ClassIndex(int index, ABC abc, ClassIndex parent) { + this.index = index; + this.abc = abc; + this.parent = parent; + } + } + + private final Map classes = new HashMap<>(); + private final Map instanceProperties = new HashMap<>(); + private final Map classProperties = new HashMap<>(); + + private final Map instanceNsProperties = new HashMap<>(); + private final Map classNsProperties = new HashMap<>(); + private final Map scriptProperties = new HashMap<>(); + + public ClassIndex findClass(GraphTargetItem cls) { + if (!classes.containsKey(cls)) { + if (parent == null) { + return null; + } + return parent.findClass(cls); + } + return classes.get(cls); + } + + public TraitIndex findScriptProperty(DottedChain ns) { + return findScriptProperty(ns.getLast(), ns.getWithoutLast()); + } + + public TraitIndex findScriptProperty(String propName, DottedChain ns) { + return scriptProperties.get(new PropertyNsDef(propName, ns, null, 0)); + } + + public TraitIndex findNsProperty(PropertyNsDef prop, boolean findStatic, boolean findInstance) { + + if (findStatic && classNsProperties.containsKey(prop)) { + if (!classNsProperties.containsKey(prop)) { + if (parent != null) { + TraitIndex ret = parent.findNsProperty(prop, findStatic, findInstance); + if (ret != null) { + return ret; + } + } + } else { + return classNsProperties.get(prop); + } + } + if (findInstance && instanceNsProperties.containsKey(prop)) { + if (!instanceNsProperties.containsKey(prop)) { + if (parent != null) { + TraitIndex ret = parent.findNsProperty(prop, findStatic, findInstance); + if (ret != null) { + return ret; + } + } + } else { + return instanceNsProperties.get(prop); + } + } + return null; + } + + public TraitIndex findProperty(PropertyDef prop, boolean findStatic, boolean findInstance) { + + //search all static first + if (findStatic && classProperties.containsKey(prop)) { + if (!classProperties.containsKey(prop)) { + if (parent != null) { + TraitIndex ret = parent.findProperty(prop, findStatic, findInstance); + if (ret != null) { + return ret; + } + } + } else { + return classProperties.get(prop); + } + } + + //now search instance + if (findInstance && instanceProperties.containsKey(prop)) { + if (!instanceProperties.containsKey(prop)) { + if (parent != null) { + TraitIndex ret = parent.findProperty(prop, findStatic, findInstance); + if (ret != null) { + return ret; + } + } + } else { + return instanceProperties.get(prop); + } + } + + //now search parent class + AbcIndexing.ClassIndex ci = findClass(prop.parent); + if (ci != null && ci.parent != null) { + ci = ci.parent; + DottedChain parentClass = ci.abc.instance_info.get(ci.index).getName(ci.abc.constants).getNameWithNamespace(ci.abc.constants); + return findProperty(new PropertyDef(prop.propName, new TypeItem(parentClass), ci.abc, ci.abc.instance_info.get(ci.index).getName(ci.abc.constants).namespace_index), findStatic, findInstance); + } + + return null; + } + + public static GraphTargetItem multinameToType(int m_index, AVM2ConstantPool constants) { + if (m_index == 0) { + return TypeItem.UNBOUNDED; + } + Multiname m = constants.constant_multiname.get(m_index); + if (m.kind == Multiname.TYPENAME) { + GraphTargetItem obj = multinameToType(m.qname_index, constants); + List params = new ArrayList<>(); + for (int pm : m.params) { + params.add(multinameToType(pm, constants)); + } + return new ApplyTypeAVM2Item(null, obj, params); + } else { + return new TypeItem(m.getNameWithNamespace(constants)); + } + } + + private static GraphTargetItem getTraitReturnType(ABC abc, Trait t) { + if (t instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) t; + if (tsc.type_index == 0) { + return TypeItem.UNBOUNDED; + } + return PropertyAVM2Item.multinameToType(tsc.type_index, abc.constants); + } + if (t instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t; + if (tmgs.kindType == Trait.TRAIT_GETTER) { + return PropertyAVM2Item.multinameToType(abc.method_info.get(tmgs.method_info).ret_type, abc.constants); + } + if (tmgs.kindType == Trait.TRAIT_SETTER) { + if (abc.method_info.get(tmgs.method_info).param_types.length > 0) { + return PropertyAVM2Item.multinameToType(abc.method_info.get(tmgs.method_info).param_types[0], abc.constants); + } else { + return TypeItem.UNBOUNDED; + } + } + } + if (t instanceof TraitFunction) { + return new TypeItem(DottedChain.FUNCTION); + } + return TypeItem.UNBOUNDED; + } + + protected void indexTraits(ABC abc, int name_index, Traits ts, Map map, Map mapNs) { + for (Trait t : ts.traits) { + ValueKind propValue = null; + if (t instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) t; + propValue = new ValueKind(tsc.value_index, tsc.value_kind); + } + if (map != null) { + PropertyDef dp = new PropertyDef(t.getName(abc).getName(abc.constants, new ArrayList<>() /*?*/, true), multinameToType(name_index, abc.constants), abc, abc.constants.getMultiname(t.name_index).namespace_index); + map.put(dp, new TraitIndex(t, abc, getTraitReturnType(abc, t), propValue, multinameToType(name_index, abc.constants))); + } + if (mapNs != null) { + PropertyNsDef ndp = new PropertyNsDef(t.getName(abc).getName(abc.constants, new ArrayList<>() /*?*/, true), abc.constants.getMultiname(t.name_index).getNameWithNamespace(abc.constants), abc, abc.constants.getMultiname(t.name_index).namespace_index); + TraitIndex ti = new TraitIndex(t, abc, getTraitReturnType(abc, t), propValue, multinameToType(name_index, abc.constants)); + if (!mapNs.containsKey(ndp)) { + mapNs.put(ndp, ti); + } + } + + } + } + + public void refreshSelected() { + refreshAbc(getSelectedAbc()); + } + + public void refreshAbc(ABC abc) { + if (abc == null) { + return; + } + removeAbc(abc); + addAbc(abc); + } + + public void removeAbc(ABC abc) { + abcs.remove(abc); + Set gti_keys = new HashSet<>(classes.keySet()); + for (GraphTargetItem key : gti_keys) { + if (classes.get(key).abc == abc) { + classes.remove(key); + } + } + Set pd_keys = new HashSet<>(instanceProperties.keySet()); + + for (PropertyDef key : pd_keys) { + if (instanceProperties.get(key).abc == abc) { + instanceProperties.remove(key); + } + } + pd_keys = new HashSet<>(classProperties.keySet()); + for (PropertyDef key : pd_keys) { + if (classProperties.get(key).abc == abc) { + classProperties.remove(key); + } + } + + Set pnd_keys = new HashSet<>(scriptProperties.keySet()); + + for (PropertyNsDef key : pnd_keys) { + if (scriptProperties.get(key).abc == abc) { + scriptProperties.remove(key); + } + } + + pnd_keys = new HashSet<>(classNsProperties.keySet()); + for (PropertyNsDef key : pnd_keys) { + if (classNsProperties.get(key).abc == abc) { + classNsProperties.remove(key); + } + } + + pnd_keys = new HashSet<>(instanceNsProperties.keySet()); + for (PropertyNsDef key : pnd_keys) { + if (instanceNsProperties.get(key).abc == abc) { + instanceNsProperties.remove(key); + } + } + + } + + public void addAbc(ABC abc) { + if (abc == null) { + return; + } + List addedClasses = new ArrayList<>(); + for (int i = 0; i < abc.instance_info.size(); i++) { + InstanceInfo ii = abc.instance_info.get(i); + if (ii.deleted) { + continue; + } + ClassInfo ci = abc.class_info.get(i); + ClassIndex cindex = new ClassIndex(i, abc, null); + addedClasses.add(cindex); + classes.put(multinameToType(ii.name_index, abc.constants), cindex); + + indexTraits(abc, ii.name_index, ii.instance_traits, instanceProperties, instanceNsProperties); + indexTraits(abc, ii.name_index, ci.static_traits, classProperties, classNsProperties); + } + for (int i = 0; i < abc.script_info.size(); i++) { + indexTraits(abc, 0, abc.script_info.get(i).traits, null, scriptProperties); + } + for (ClassIndex cindex : addedClasses) { + int parentClassName = abc.instance_info.get(cindex.index).super_index; + if (parentClassName > 0) { + TypeItem parentClass = new TypeItem(abc.constants.getMultiname(parentClassName).getNameWithNamespace(abc.constants)); + ClassIndex parentClassIndex = findClass(parentClass); + if (parentClassIndex == null) { + throw new RuntimeException("Parent class " + parentClass + " definition not found!"); + } + cindex.parent = parentClassIndex; + } + } + abcs.add(abc); + selectedAbc = abc; + } + + public void selectAbc(ABC abc) { + if (abcs.contains(abc)) { + selectedAbc = abc; + } else { + addAbc(abc); + } + } + + public ABC getSelectedAbc() { + return selectedAbc; + } + +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java index 8848dbde1..2f40156d5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java @@ -134,11 +134,11 @@ public class ActionScript3Parser { private static final String AS3_NAMESPACE = "http://adobe.com/AS3/2006/builtin"; - private final ABC abc; + private final AbcIndexing abcIndex; - private final List otherABCs; - - private static final List playerABCs = new ArrayList<>(); +// private final AbcIndexing otherABCs; + //private static final List playerABCs = new ArrayList<>(); + private static AbcIndexing playerGlobalAbcIndex; private long uniqId() { uniqLast++; @@ -305,7 +305,7 @@ public class ActionScript3Parser { if (ns != null) { ret = new NamespacedAVM2Item(ns, propName, propItem, ret, attr, openedNamespaces, null); } else { - ret = new PropertyAVM2Item(ret, (attr ? "@" : "") + propName, abc, otherABCs, openedNamespaces, new ArrayList<>()); + ret = new PropertyAVM2Item(ret, (attr ? "@" : "") + propName, abcIndex, openedNamespaces, new ArrayList<>()); } s = lex(); } @@ -683,7 +683,7 @@ public class ActionScript3Parser { } if (namespace == -1) { if (isInterface) { - namespace = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_NAMESPACE, abc.constants.getStringId(pkg == null || pkg.isEmpty() ? classNameStr : pkg + ":" + classNameStr, true)), 0, true); + namespace = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_NAMESPACE, abcIndex.getSelectedAbc().constants.getStringId(pkg == null || pkg.isEmpty() ? classNameStr : pkg + ":" + classNameStr, true)), 0, true); } else { namespace = packageInternalNs; } @@ -855,7 +855,7 @@ public class ActionScript3Parser { nval = s.value.toString(); s = lex(); } else { - nval = (pkg == null || pkg.isEmpty() ? classNameStr : pkg + ":" + classNameStr) + "/" + nname; + nval = (pkg == null || pkg.isEmpty() || pkg.isTopLevel() ? classNameStr : pkg + ":" + classNameStr) + "/" + nname; } if (s.type != SymbolType.SEMICOLON) { lexer.pushback(s); @@ -940,37 +940,37 @@ public class ActionScript3Parser { int privateNs = 0; int packageInternalNs = 0; if (pkg != null) { - openedNamespaces.add(packageInternalNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abc.constants.getStringId(pkg, true)), 0, true)); + openedNamespaces.add(packageInternalNs = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abcIndex.getSelectedAbc().constants.getStringId(pkg, true)), 0, true)); } if (pkg != null && !pkg.isEmpty()) { - openedNamespaces.add(publicNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true)); + openedNamespaces.add(publicNs = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId("", true)), 0, true)); } else { publicNs = gpublicNs; } - openedNamespaces.add(privateNs = abc.constants.addNamespace(new Namespace(Namespace.KIND_PRIVATE, 0))); //abc.constants.getStringId(fileName + "$", true) + openedNamespaces.add(privateNs = abcIndex.getSelectedAbc().constants.addNamespace(new Namespace(Namespace.KIND_PRIVATE, 0))); //abc.getLastAbc().constants.getStringId(fileName + "$", true) - openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_NAMESPACE, abc.constants.getStringId(AS3_NAMESPACE, true)), 0, true)); + openedNamespaces.add(abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_NAMESPACE, abcIndex.getSelectedAbc().constants.getStringId(AS3_NAMESPACE, true)), 0, true)); //int privateNs = 0; int protectedNs = 0; //int publicNs = namespace; int protectedStaticNs = 0; - openedNamespaces.add(protectedNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PROTECTED, abc.constants.getStringId(packageName == null ? (scriptName + "$0:"/*FIXME?*/ + classNameStr) : packageName.isEmpty() ? classNameStr : packageName.toRawString() + ":" + classNameStr, true)), 0, true)); - openedNamespaces.add(protectedStaticNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_STATIC_PROTECTED, abc.constants.getStringId(packageName == null || packageName.isEmpty() ? classNameStr : packageName.toRawString() + ":" + classNameStr, true)), 0, true)); + openedNamespaces.add(protectedNs = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PROTECTED, abcIndex.getSelectedAbc().constants.getStringId(packageName == null ? (scriptName + "$0:"/*FIXME?*/ + classNameStr) : packageName.isTopLevel() ? classNameStr : packageName.toRawString() + ":" + classNameStr, true)), 0, true)); + openedNamespaces.add(protectedStaticNs = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_STATIC_PROTECTED, abcIndex.getSelectedAbc().constants.getStringId(packageName == null || packageName.isTopLevel() ? classNameStr : packageName.toRawString() + ":" + classNameStr, true)), 0, true)); if (extendsStr != null) { List indices = new ArrayList<>(); List names = new ArrayList<>(); List namespaces = new ArrayList<>(); //FIXME for Private classes in script!!! - AVM2SourceGenerator.parentNamesAddNames(abc, otherABCs, AVM2SourceGenerator.resolveType(new SourceGeneratorLocalData(new HashMap<>(), 0, false, 0), ((TypeItem) ((UnresolvedAVM2Item) extendsStr).resolve(null, new ArrayList<>(), new ArrayList<>(), abc, otherABCs, new ArrayList<>(), new ArrayList<>())), abc, otherABCs), indices, names, namespaces); + AVM2SourceGenerator.parentNamesAddNames(abcIndex, AVM2SourceGenerator.resolveType(new SourceGeneratorLocalData(new HashMap<>(), 0, false, 0), ((TypeItem) ((UnresolvedAVM2Item) extendsStr).resolve(null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), new ArrayList<>())), abcIndex), indices, names, namespaces); for (int i = 0; i < names.size(); i++) { if (namespaces.get(i).isEmpty()) { continue; } - openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_STATIC_PROTECTED, abc.constants.getStringId(namespaces.get(i) + ":" + names.get(i), true)), 0, true)); + openedNamespaces.add(abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_STATIC_PROTECTED, abcIndex.getSelectedAbc().constants.getStringId(namespaces.get(i) + ":" + names.get(i), true)), 0, true)); } } @@ -982,7 +982,7 @@ public class ActionScript3Parser { if (isInterface) { return new InterfaceAVM2Item(metadata, importedClasses, packageName, openedNamespaces, isFinal, namespace, classNameStr, implementsStr, traits); } else { - return new ClassAVM2Item(metadata, importedClasses, packageName, openedNamespaces, protectedNs, isDynamic, isFinal, namespace, classNameStr, extendsStr, implementsStr, staticInit, staticNeedsActivation.getVal(), sinitVariables, constr, traits); + return new ClassAVM2Item(metadata, importedClasses, packageName, openedNamespaces, privateNs, protectedNs, isDynamic, isFinal, namespace, classNameStr, extendsStr, implementsStr, staticInit, staticNeedsActivation.getVal(), sinitVariables, constr, traits); } } @@ -1267,7 +1267,7 @@ public class ActionScript3Parser { case USE: expectedType(SymbolType.NAMESPACE); GraphTargetItem ns = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); - openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE /*FIXME?*/, abc.constants.getStringId(ns.toString(), true)), 0, true)); + openedNamespaces.add(abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE /*FIXME?*/, abcIndex.getSelectedAbc().constants.getStringId(ns.toString(), true)), 0, true)); break; case WITH: needsActivation.setVal(true); @@ -1620,7 +1620,7 @@ public class ActionScript3Parser { UnresolvedAVM2Item ui = (UnresolvedAVM2Item) a; if (ui.getVariableName().equals(e.getVariableName())) { try { - ui.resolve(null, new ArrayList<>(), new ArrayList<>(), abc, otherABCs, new ArrayList<>(), variables); + ui.resolve(null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), variables); } catch (CompilationException ex) { // ignore } @@ -1643,7 +1643,7 @@ public class ActionScript3Parser { for (NameAVM2Item e : catchExceptions) { if (ui.getVariableName().equals(e.getVariableName())) { try { - ui.resolve(null, new ArrayList<>(), new ArrayList<>(), abc, otherABCs, new ArrayList<>(), variables); + ui.resolve(null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), variables); } catch (CompilationException ex) { // ignore } @@ -1710,34 +1710,6 @@ public class ActionScript3Parser { return expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, allowRemainder, variables); } - private GraphTargetItem fixPrecedence(GraphTargetItem expr) { - System.out.println("Fixing " + expr); - GraphTargetItem ret = expr; - - /* - fix > : - a || b > c => a || (b > c) - - a < 0 || (b > c) + 1 - - */ - if (expr instanceof BinaryOp) { - BinaryOp bo = (BinaryOp) expr; - GraphTargetItem left = bo.getLeftSide(); - GraphTargetItem right = bo.getRightSide(); - if (left.getPrecedence() > bo.getPrecedence()) { - if (left instanceof BinaryOp) { - BinaryOp leftBo = (BinaryOp) left; - bo.setLeftSide(leftBo.getRightSide()); - leftBo.setRightSide(expr); - System.out.println("fixed"); - return left; - } - } - } - return ret; - } - /*private GraphTargetItem expressionRemainder(TypeItem thisType, String pkg, Reference needsActivation, List openedNamespaces, GraphTargetItem expr, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables, List importedClasses) throws IOException, AVM2ParseException { GraphTargetItem ret = null; ParsedSymbol s = lex(); @@ -2341,7 +2313,7 @@ public class ActionScript3Parser { } if (isStar) { - openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(imp.toString(), true)), 0, true)); + openedNamespaces.add(abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId(imp.toString(), true)), 0, true)); } else { importedClasses.add(imp); } @@ -2352,7 +2324,7 @@ public class ActionScript3Parser { lexer.pushback(s); int publicNs; - openedNamespaces.add(publicNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(name, true)), 0, true)); + openedNamespaces.add(publicNs = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId(name, true)), 0, true)); //traits(false, new ArrayList(), new Reference(false), new ArrayList(), importedClasses, privateNs, 0, publicNs, packageInternalNs, 0, openedNamespaces, name, null, false, items); //expectedType(SymbolType.CURLY_CLOSE); @@ -2375,10 +2347,10 @@ public class ActionScript3Parser { if (className.endsWith(".as")) { className = className.substring(0, className.length() - 3); } - openedNamespaces.add(scriptPrivateNs = abc.constants.addNamespace(new Namespace(Namespace.KIND_PRIVATE, 0))); //abc.constants.getStringId(name + ":" + className, true) + openedNamespaces.add(scriptPrivateNs = abcIndex.getSelectedAbc().constants.addNamespace(new Namespace(Namespace.KIND_PRIVATE, 0))); //abc.getLastAbc().constants.getStringId(name + ":" + className, true) int publicNs; - openedNamespaces.add(publicNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true)); + openedNamespaces.add(publicNs = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId("", true)), 0, true)); List items = new ArrayList<>(); traits(fileName, true, new ArrayList<>(), new Reference<>(false), new ArrayList<>(), new ArrayList<>(), scriptPrivateNs, 0, publicNs, 0, 0, openedNamespaces, null, null, false, items); @@ -2396,11 +2368,11 @@ public class ActionScript3Parser { } public void addScriptFromTree(List items, boolean documentClass, int classPos) throws AVM2ParseException, CompilationException { - AVM2SourceGenerator gen = new AVM2SourceGenerator(abc, otherABCs); + AVM2SourceGenerator gen = new AVM2SourceGenerator(abcIndex); SourceGeneratorLocalData localData = new SourceGeneratorLocalData( new HashMap<>(), 0, Boolean.FALSE, 0); localData.documentClass = documentClass; - abc.script_info.add(gen.generateScriptInfo(localData, items, classPos)); + abcIndex.getSelectedAbc().script_info.add(gen.generateScriptInfo(localData, items, classPos)); } public void addScript(String s, boolean documentClass, String fileName, int classPos) throws AVM2ParseException, IOException, CompilationException { @@ -2408,32 +2380,34 @@ public class ActionScript3Parser { addScriptFromTree(traits, documentClass, classPos); } - public ActionScript3Parser(ABC abc, List otherABCs) { - this.abc = abc; - this.otherABCs = otherABCs; + public ActionScript3Parser(ABC abc, List otherAbcs) { + try { + initPlayer(); + } catch (IOException | InterruptedException ex) { + + } + abcIndex = new AbcIndexing(playerGlobalAbcIndex); + for (ABC a : otherAbcs) { + abcIndex.addAbc(a); + } + abcIndex.addAbc(abc); } private static void initPlayer() throws IOException, InterruptedException { - if (playerABCs.isEmpty()) { + if (playerGlobalAbcIndex == null) { if (Configuration.getPlayerSWC() == null) { throw new IOException("Player SWC library not found, please place it to " + Configuration.getFlashLibPath()); } SWC swc = new SWC(new FileInputStream(Configuration.getPlayerSWC())); SWF swf = new SWF(swc.getSWF("library.swf"), true); - for (Tag t : swf.tags) { - if (t instanceof ABCContainerTag) { - playerABCs.add(((ABCContainerTag) t).getABC()); - } - } + playerGlobalAbcIndex = new AbcIndexing(swf); } } public static void compile(String src, ABC abc, List otherABCs, boolean documentClass, String fileName, int classPos) throws AVM2ParseException, IOException, InterruptedException, CompilationException { - List parABCs = new ArrayList<>(); + //List parABCs = new ArrayList<>(); initPlayer(); - parABCs.addAll(playerABCs); - parABCs.addAll(otherABCs); - ActionScript3Parser parser = new ActionScript3Parser(abc, parABCs); + ActionScript3Parser parser = new ActionScript3Parser(abc, otherABCs); boolean success = false; ABC originalAbc = ((ABCContainerTag) ((Tag) abc.parentTag).cloneTag()).getABC(); try { @@ -2459,7 +2433,7 @@ public class ActionScript3Parser { try { initPlayer(); ABC abc = new ABC(null); - ActionScript3Parser parser = new ActionScript3Parser(abc, playerABCs); + ActionScript3Parser parser = new ActionScript3Parser(abc, new ArrayList<>()); parser.addScript(new String(Helper.readFile(src), Utf8Helper.charset), true, src, classPos); try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(new File(dst)))) { abc.saveToStream(fos); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/CallAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/CallAVM2Item.java index d9bc80637..99d118efe 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/CallAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/CallAVM2Item.java @@ -68,9 +68,9 @@ public class CallAVM2Item extends AVM2Item { } if (callable instanceof NameAVM2Item) { NameAVM2Item n = (NameAVM2Item) callable; - List allAbcs = new ArrayList<>(); - allAbcs.add(g.abc); - allAbcs.addAll(g.allABCs); + /*List allAbcs = new ArrayList<>(); + allAbcs.add(g.abc); + allAbcs.addAll(g.allABCs);*/ String cname = localData.currentClass; DottedChain pkgName = localData.pkg; GraphTargetItem obj = null; @@ -81,12 +81,12 @@ public class CallAVM2Item extends AVM2Item { Reference outPropNsIndex = new Reference<>(0); Reference outPropType = new Reference<>(null); Reference outPropValue = new Reference<>(null); - if (cname != null && AVM2SourceGenerator.searchPrototypeChain(true, allAbcs, pkgName, cname, n.getVariableName(), outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue)) { + if (cname != null && AVM2SourceGenerator.searchPrototypeChain(localData.privateNs, localData.protectedNs, true, g.abcIndex, pkgName, cname, n.getVariableName(), outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue)) { NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.getFullClass()), n.line, "this", null, false, n.openedNamespaces); nobj.setRegNumber(0); obj = nobj; } - PropertyAVM2Item p = new PropertyAVM2Item(obj, n.getVariableName(), g.abc, g.allABCs, n.openedNamespaces, new ArrayList<>()); + PropertyAVM2Item p = new PropertyAVM2Item(obj, n.getVariableName(), g.abcIndex, n.openedNamespaces, new ArrayList<>()); p.setAssignedValue(n.getAssignedValue()); callable = p; } @@ -94,7 +94,7 @@ public class CallAVM2Item extends AVM2Item { int propIndex = -1; if (callable instanceof TypeItem) { TypeItem t = (TypeItem) callable; - propIndex = AVM2SourceGenerator.resolveType(localData, t, ((AVM2SourceGenerator) generator).abc, ((AVM2SourceGenerator) generator).allABCs); + propIndex = AVM2SourceGenerator.resolveType(localData, t, ((AVM2SourceGenerator) generator).abcIndex); } Object obj = null; @@ -103,10 +103,10 @@ public class CallAVM2Item extends AVM2Item { obj = prop.object; if (obj == null) { - List allAbcs = new ArrayList<>(); - allAbcs.add(g.abc); - allAbcs.addAll(g.allABCs); - String cname = localData.currentClass; + /*List allAbcs = new ArrayList<>(); + allAbcs.add(g.abc); + allAbcs.addAll(g.allABCs); + */ String cname = localData.currentClass; DottedChain pkgName = localData.pkg; Reference outName = new Reference<>(""); Reference outNs = new Reference<>(DottedChain.EMPTY); @@ -115,7 +115,7 @@ public class CallAVM2Item extends AVM2Item { Reference outPropNsIndex = new Reference<>(0); Reference outPropType = new Reference<>(null); Reference outPropValue = new Reference<>(null); - if (cname != null && AVM2SourceGenerator.searchPrototypeChain(true, allAbcs, pkgName, cname, prop.propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue) && (localData.currentClass.equals("".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal()))) { + if (cname != null && AVM2SourceGenerator.searchPrototypeChain(localData.privateNs, localData.protectedNs, true, g.abcIndex, pkgName, cname, prop.propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue) && (localData.currentClass.equals("".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal()))) { NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.getFullClass()), 0, "this", null, false, new ArrayList<>()); nobj.setRegNumber(0); obj = nobj; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java index e341d2348..b7825052f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java @@ -43,6 +43,7 @@ public class ClassAVM2Item extends AVM2Item implements Block { public int namespace; public int protectedNs; + public int privateNs; public boolean isDynamic; @@ -71,11 +72,12 @@ public class ClassAVM2Item extends AVM2Item implements Block { return ret; } - public ClassAVM2Item(List>> metadata, List importedClasses, DottedChain pkg, List openedNamespaces, int protectedNs, boolean isDynamic, boolean isFinal, int namespace, String className, GraphTargetItem extendsOp, List implementsOp, List staticInit, boolean staticInitActivation, List sinitVariables, GraphTargetItem constructor, List traits) { + public ClassAVM2Item(List>> metadata, List importedClasses, DottedChain pkg, List openedNamespaces, int privateNs, int protectedNs, boolean isDynamic, boolean isFinal, int namespace, String className, GraphTargetItem extendsOp, List implementsOp, List staticInit, boolean staticInitActivation, List sinitVariables, GraphTargetItem constructor, List traits) { super(null, NOPRECEDENCE); this.metadata = metadata; this.importedClasses = importedClasses; this.pkg = pkg; + this.privateNs = privateNs; this.protectedNs = protectedNs; this.className = className; this.traits = traits; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstructSomethingAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstructSomethingAVM2Item.java index ccd78b8be..27ba50f39 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstructSomethingAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstructSomethingAVM2Item.java @@ -67,7 +67,7 @@ public class ConstructSomethingAVM2Item extends CallAVM2Item { if (resname instanceof TypeItem) { TypeItem prop = (TypeItem) resname; - int type_index = AVM2SourceGenerator.resolveType(localData, resname, ((AVM2SourceGenerator) generator).abc, ((AVM2SourceGenerator) generator).allABCs); + int type_index = AVM2SourceGenerator.resolveType(localData, resname, ((AVM2SourceGenerator) generator).abcIndex); return toSourceMerge(localData, generator, new AVM2Instruction(0, AVM2Instructions.FindPropertyStrict, new int[]{type_index, arguments.size()}), arguments, new AVM2Instruction(0, AVM2Instructions.ConstructProp, new int[]{type_index, arguments.size()}) diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java index 7168942d0..0b3563844 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java @@ -88,7 +88,7 @@ public class IndexAVM2Item extends AssignableAVM2Item { Reference index_temp = new Reference<>(-1); Reference val_temp = new Reference<>(-1); AVM2SourceGenerator g = (AVM2SourceGenerator) generator; - int indexPropIndex = g.abc.constants.getMultinameId(new Multiname(attr ? Multiname.MULTINAMELA : Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<>()), true); + int indexPropIndex = g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(attr ? Multiname.MULTINAMELA : Multiname.MULTINAMEL, 0, 0, allNsSet(g.abcIndex.getSelectedAbc()), 0, new ArrayList<>()), true); return toSourceMerge(localData, generator, object, dupSetTemp(localData, generator, obj_temp), @@ -110,7 +110,7 @@ public class IndexAVM2Item extends AssignableAVM2Item { public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator, boolean needsReturn, boolean call, List callargs, boolean delete, boolean construct) throws CompilationException { AVM2SourceGenerator g = (AVM2SourceGenerator) generator; - int indexPropIndex = g.abc.constants.getMultinameId(new Multiname(attr ? Multiname.MULTINAMELA : Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<>()), true); + int indexPropIndex = g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(attr ? Multiname.MULTINAMELA : Multiname.MULTINAMEL, 0, 0, allNsSet(g.abcIndex.getSelectedAbc()), 0, new ArrayList<>()), true); Reference ret_temp = new Reference<>(-1); if (assignedValue != null) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java index 1f3e72f55..f66cc89a2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java @@ -198,7 +198,7 @@ public class NameAVM2Item extends AssignableAVM2Item { ins = ins(AVM2Instructions.ConvertU); break; default: - int type_index = AVM2SourceGenerator.resolveType(localData, ttype, ((AVM2SourceGenerator) generator).abc, ((AVM2SourceGenerator) generator).allABCs); + int type_index = AVM2SourceGenerator.resolveType(localData, ttype, ((AVM2SourceGenerator) generator).abcIndex); ins = ins(AVM2Instructions.Coerce, type_index); break; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespacedAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespacedAVM2Item.java index c5a3a1aa9..08a0a7a86 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespacedAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespacedAVM2Item.java @@ -84,11 +84,11 @@ public class NamespacedAVM2Item extends AssignableAVM2Item { /*if (name == null && index != null) { return toSourceMerge(localData, generator, ns, generateCoerce(generator, new TypeItem("Namespace")), index, ins(AVM2Instructions.ConvertS), - ins(AVM2Instructions.FindPropertyStrict, g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList()), true)), + ins(AVM2Instructions.FindPropertyStrict, g.abc.getLastAbc().constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList()), true)), dupSetTemp(localData, generator, name_temp), ns, generateCoerce(generator, new TypeItem("Namespace")), dupSetTemp(localData, generator, ns_temp), - ins(AVM2Instructions.GetProperty, g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList()), true)), + ins(AVM2Instructions.GetProperty, g.abc.getLastAbc().constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList()), true)), !isInteger ? ins(AVM2Instructions.ConvertD) : null, //End get original (!post) ? (decrement ? ins(isInteger ? AVM2Instructions.DecrementI : AVM2Instructions.Decrement) : ins(isInteger ? AVM2Instructions.IncrementI : AVM2Instructions.Increment())) : null, @@ -98,21 +98,21 @@ public class NamespacedAVM2Item extends AssignableAVM2Item { getTemp(localData, generator, name_temp), getTemp(localData, generator, ns_temp), getTemp(localData, generator, ret_temp), - ins(AVM2Instructions.SetProperty, g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList()), true)), + ins(AVM2Instructions.SetProperty, g.abc.getLastAbc().constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList()), true)), killTemp(localData, generator, Arrays.asList(ret_temp, name_temp, ns_temp))); } else */ if (name != null) { return toSourceMerge(localData, generator, ns, NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)), - ins(AVM2Instructions.FindPropertyStrict, g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.constants.getStringId(name, true), 0, 0, 0, new ArrayList<>()), true)), + ins(AVM2Instructions.FindPropertyStrict, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abcIndex.getSelectedAbc().constants.getStringId(name, true), 0, 0, 0, new ArrayList<>()), true)), dupSetTemp(localData, generator, name_temp), ns, NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)), dupSetTemp(localData, generator, ns_temp), //Start get original - //getTemp(localData, generator, ns_temp), generateCoerce(generator, "Namespace"), ins(AVM2Instructions.FindPropertyStrict, g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.constants.getStringId(variableName, true), 0, 0, 0, new ArrayList()), true)), + //getTemp(localData, generator, ns_temp), generateCoerce(generator, "Namespace"), ins(AVM2Instructions.FindPropertyStrict, g.abc.getLastAbc().constants.getMultinameId(new Multiname(Multiname.RTQNAME, g.abc.getLastAbc().constants.getStringId(variableName, true), 0, 0, 0, new ArrayList()), true)), //getTemp(localData, generator, ns_temp), generateCoerce(generator, "Namespace"), - ins(AVM2Instructions.GetProperty, g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<>()), true)), + ins(AVM2Instructions.GetProperty, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abcIndex.getSelectedAbc()), 0, new ArrayList<>()), true)), !isInteger ? ins(AVM2Instructions.ConvertD) : null, //End get original (!post) ? (decrement ? ins(isInteger ? AVM2Instructions.DecrementI : AVM2Instructions.Decrement) : ins(isInteger ? AVM2Instructions.IncrementI : AVM2Instructions.Increment)) : null, @@ -122,7 +122,7 @@ public class NamespacedAVM2Item extends AssignableAVM2Item { getTemp(localData, generator, name_temp), getTemp(localData, generator, ns_temp), getTemp(localData, generator, ret_temp), - ins(AVM2Instructions.SetProperty, g.abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList<>()), true)), + ins(AVM2Instructions.SetProperty, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, 0, 0, allNsSet(g.abcIndex.getSelectedAbc()), 0, new ArrayList<>()), true)), killTemp(localData, generator, Arrays.asList(ret_temp, name_temp, ns_temp)) ); } else { @@ -156,20 +156,20 @@ public class NamespacedAVM2Item extends AssignableAVM2Item { if (name == null) { if (assignedValue != null) { return toSourceMerge(localData, generator, - obj == null ? ns : null, obj == null ? NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)) : null, nameItem, ins(AVM2Instructions.ConvertS), obj != null ? obj : ins(AVM2Instructions.FindPropertyStrict, g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<>()), true)), + obj == null ? ns : null, obj == null ? NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)) : null, nameItem, ins(AVM2Instructions.ConvertS), obj != null ? obj : ins(AVM2Instructions.FindPropertyStrict, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<>()), true)), ns, NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)), nameItem, ins(AVM2Instructions.ConvertS), assignedValue, needsReturn ? dupSetTemp(localData, generator, ret_temp) : null, - ins(AVM2Instructions.SetProperty, g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<>()), true)), + ins(AVM2Instructions.SetProperty, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<>()), true)), needsReturn ? getTemp(localData, generator, ret_temp) : null, killTemp(localData, generator, Arrays.asList(ns_temp, index_temp, ret_temp)) ); } else { return toSourceMerge(localData, generator, - obj == null ? ns : null, obj == null ? NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)) : null, nameItem, ins(AVM2Instructions.ConvertS), obj != null ? obj : ins(AVM2Instructions.FindPropertyStrict, g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<>()), true)), + obj == null ? ns : null, obj == null ? NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)) : null, nameItem, ins(AVM2Instructions.ConvertS), obj != null ? obj : ins(AVM2Instructions.FindPropertyStrict, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<>()), true)), call ? dupSetTemp(localData, generator, obj_temp) : null, ns, NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)), nameItem, ins(AVM2Instructions.ConvertS), construct ? callargs : null, - ins(construct ? AVM2Instructions.ConstructProp : delete ? AVM2Instructions.DeleteProperty : AVM2Instructions.GetProperty, g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<>()), true), construct ? callargs.size() : null), + ins(construct ? AVM2Instructions.ConstructProp : delete ? AVM2Instructions.DeleteProperty : AVM2Instructions.GetProperty, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList<>()), true), construct ? callargs.size() : null), call ? getTemp(localData, generator, obj_temp) : null, call ? callargs : null, call ? ins(AVM2Instructions.Call, callargs.size()) : null, @@ -180,20 +180,20 @@ public class NamespacedAVM2Item extends AssignableAVM2Item { } else { if (assignedValue != null) { return toSourceMerge(localData, generator, - obj == null ? ns : null, obj == null ? NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)) : null, obj != null ? obj : ins(AVM2Instructions.FindPropertyStrict, g.abc.constants.getMultinameId(new Multiname(attr ? Multiname.RTQNAMEA : Multiname.RTQNAME, g.abc.constants.getStringId(name, true), 0, 0, 0, new ArrayList<>()), true)), + obj == null ? ns : null, obj == null ? NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)) : null, obj != null ? obj : ins(AVM2Instructions.FindPropertyStrict, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(attr ? Multiname.RTQNAMEA : Multiname.RTQNAME, g.abcIndex.getSelectedAbc().constants.getStringId(name, true), 0, 0, 0, new ArrayList<>()), true)), ns, NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)), assignedValue, needsReturn ? dupSetTemp(localData, generator, ret_temp) : null, - ins(AVM2Instructions.SetProperty, g.abc.constants.getMultinameId(new Multiname(attr ? Multiname.RTQNAMEA : Multiname.RTQNAME, g.abc.constants.getStringId(name, true), 0, 0, 0, new ArrayList<>()), true)), + ins(AVM2Instructions.SetProperty, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(attr ? Multiname.RTQNAMEA : Multiname.RTQNAME, g.abcIndex.getSelectedAbc().constants.getStringId(name, true), 0, 0, 0, new ArrayList<>()), true)), needsReturn ? getTemp(localData, generator, ret_temp) : null, killTemp(localData, generator, Arrays.asList(ns_temp, index_temp, ret_temp)) ); } else { return toSourceMerge(localData, generator, - obj == null ? ns : null, obj == null ? NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)) : null, obj != null ? obj : ins(AVM2Instructions.FindPropertyStrict, g.abc.constants.getMultinameId(new Multiname(attr ? Multiname.RTQNAMEA : Multiname.RTQNAME, g.abc.constants.getStringId(name, true), 0, 0, 0, new ArrayList<>()), true)), + obj == null ? ns : null, obj == null ? NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)) : null, obj != null ? obj : ins(AVM2Instructions.FindPropertyStrict, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(attr ? Multiname.RTQNAMEA : Multiname.RTQNAME, g.abcIndex.getSelectedAbc().constants.getStringId(name, true), 0, 0, 0, new ArrayList<>()), true)), call ? dupSetTemp(localData, generator, obj_temp) : null, ns, NameAVM2Item.generateCoerce(localData, generator, new TypeItem(DottedChain.NAMESPACE)), construct ? callargs : null, - ins(construct ? AVM2Instructions.ConstructProp : delete ? AVM2Instructions.DeleteProperty : AVM2Instructions.GetProperty, g.abc.constants.getMultinameId(new Multiname(attr ? Multiname.RTQNAMEA : Multiname.RTQNAME, g.abc.constants.getStringId(name, true), 0, 0, 0, new ArrayList<>()), true), construct ? callargs.size() : null), + ins(construct ? AVM2Instructions.ConstructProp : delete ? AVM2Instructions.DeleteProperty : AVM2Instructions.GetProperty, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(attr ? Multiname.RTQNAMEA : Multiname.RTQNAME, g.abcIndex.getSelectedAbc().constants.getStringId(name, true), 0, 0, 0, new ArrayList<>()), true), construct ? callargs.size() : null), call ? getTemp(localData, generator, obj_temp) : null, call ? callargs : null, call ? ins(AVM2Instructions.Call, callargs.size()) : null, diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java index 79ca435f9..d47afb701 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java @@ -57,9 +57,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item { public GraphTargetItem object; - public ABC abc; - - public List otherABCs; + public AbcIndexing abc; private final List openedNamespaces; @@ -69,14 +67,13 @@ public class PropertyAVM2Item extends AssignableAVM2Item { @Override public AssignableAVM2Item copy() { - PropertyAVM2Item p = new PropertyAVM2Item(object, propertyName, abc, otherABCs, openedNamespaces, callStack); + PropertyAVM2Item p = new PropertyAVM2Item(object, propertyName, abc, openedNamespaces, callStack); return p; } - public PropertyAVM2Item(GraphTargetItem object, String propertyName, ABC abc, List otherABCs, List openedNamespaces, List callStack) { + public PropertyAVM2Item(GraphTargetItem object, String propertyName, AbcIndexing abc, List openedNamespaces, List callStack) { this.propertyName = propertyName; this.object = object; - this.otherABCs = otherABCs; this.abc = abc; this.openedNamespaces = openedNamespaces; this.callStack = callStack; @@ -92,7 +89,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item { for (int i = 0; i < openedNamespaces.size(); i++) { nssa[i] = openedNamespaces.get(i); } - return abc.constants.getNamespaceSetId(new NamespaceSet(nssa), true); + return abc.getSelectedAbc().constants.getNamespaceSetId(new NamespaceSet(nssa), true); } public static GraphTargetItem multinameToType(int m_index, AVM2ConstantPool constants) { @@ -185,9 +182,6 @@ public class PropertyAVM2Item extends AssignableAVM2Item { } { - List abcs = new ArrayList<>(); - abcs.add(abc); - abcs.addAll(otherABCs); if (ttype.equals(new TypeItem(InitVectorAVM2Item.VECTOR_FQN))) { switch ("" + objSubType) { case "int": @@ -203,151 +197,144 @@ public class PropertyAVM2Item extends AssignableAVM2Item { ttype = new TypeItem(InitVectorAVM2Item.VECTOR_OBJECT); } } - loopa: - for (ABC a : abcs) { - for (InstanceInfo ii : a.instance_info) { - if (ii.deleted) { - continue; - } - Multiname m = ii.getName(a.constants); - if (multinameToType(ii.name_index, a.constants).equals(ttype)) { - Reference outName = new Reference<>(""); - Reference outNs = new Reference<>(DottedChain.EMPTY); - Reference outPropNs = new Reference<>(DottedChain.EMPTY); - Reference outPropNsKind = new Reference<>(1); - Reference outPropNsIndex = new Reference<>(0); - Reference outPropType = new Reference<>(null); - Reference outPropValue = new Reference<>(null); - if (AVM2SourceGenerator.searchPrototypeChain(false, abcs, m.getNamespace(a.constants).getName(a.constants), m.getName(a.constants, null, true), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue)) { - objType = new TypeItem(outNs.getVal().isEmpty() ? outName.getVal() : outNs.getVal().toRawString() + "." + outName.getVal()); - propType = outPropType.getVal(); - propIndex = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, - abc.constants.getStringId(propertyName, true), - abc.constants.getNamespaceId(new Namespace(outPropNsKind.getVal(), abc.constants.getStringId(outPropNs.getVal(), true)), outPropNsIndex.getVal(), true), 0, 0, new ArrayList<>()), true - ); - propValue = outPropValue.getVal(); - - break loopa; - } - } + /* AbcIndexing.TraitIndex p = abc.findProperty(new AbcIndexing.PropertyDef(propertyName, ttype), false, true); + if(p!=null){ + objType = new TypeItem(outNs.getVal().isEmpty() ? outName.getVal() : outNs.getVal().toRawString() + "." + outName.getVal()); + propType = p.type; + propIndex = abc.getLastAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, + abc.getLastAbc().getStringId(propertyName, true), + abc.getLastAbc().getNamespaceId(new Namespace(outPropNsKind.getVal(), abc.constants.getStringId(outPropNs.getVal(), true)), outPropNsIndex.getVal(), true), 0, 0, new ArrayList<>()), true + ); + propValue = outPropValue.getVal(); + }*/ + if (ttype instanceof TypeItem) { + DottedChain ftn = ((TypeItem) ttype).fullTypeName; + Reference outName = new Reference<>(""); + Reference outNs = new Reference<>(DottedChain.EMPTY); + Reference outPropNs = new Reference<>(DottedChain.EMPTY); + Reference outPropNsKind = new Reference<>(1); + Reference outPropNsIndex = new Reference<>(0); + Reference outPropType = new Reference<>(null); + Reference outPropValue = new Reference<>(null); + if (AVM2SourceGenerator.searchPrototypeChain(localData.privateNs, localData.protectedNs, false, abc, ftn.getWithoutLast(), ftn.getLast(), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue)) { + objType = new TypeItem(outNs.getVal().add(outName.getVal())); + propType = outPropType.getVal(); + propIndex = abc.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, + abc.getSelectedAbc().constants.getStringId(propertyName, true), + abc.getSelectedAbc().constants.getNamespaceId(new Namespace(outPropNsKind.getVal(), outPropNs.getVal() == null || outPropNs.getVal().isEmpty() ? 0 : abc.getSelectedAbc().constants.getStringId(outPropNs.getVal(), true)), outPropNsIndex.getVal(), true), 0, 0, new ArrayList<>()), true + ); + propValue = outPropValue.getVal(); } } - } - if (objType == null) { - for (MethodBody b : callStack) { - for (int i = 0; i < b.traits.traits.size(); i++) { - Trait t = b.traits.traits.get(i); - if (t.getName(abc).getName(abc.constants, null, true).equals(propertyName)) { - if (t instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) t; - objType = new TypeItem(DottedChain.FUNCTION); - propType = multinameToType(tsc.type_index, abc.constants); - propIndex = tsc.name_index; - if (!localData.traitUsages.containsKey(b)) { - localData.traitUsages.put(b, new ArrayList<>()); - } - localData.traitUsages.get(b).add(i); - } - } - } - } if (objType == null) { - loopobjType: - for (int i = 0; i < openedNamespaces.size(); i++) { - int nsindex = openedNamespaces.get(i); - int nsKind = abc.constants.constant_namespace.get(openedNamespaces.get(i)).kind; - DottedChain nsname = abc.constants.constant_namespace.get(openedNamespaces.get(i)).getName(abc.constants); - int name_index = 0; - for (int m = 1; m < abc.constants.constant_multiname.size(); m++) { - Multiname mname = abc.constants.constant_multiname.get(m); - if (mname.kind == Multiname.QNAME && mname.getName(abc.constants, null, true).equals(propertyName) && mname.namespace_index == nsindex) { - name_index = m; - break; + for (MethodBody b : callStack) { + for (int i = 0; i < b.traits.traits.size(); i++) { + Trait t = b.traits.traits.get(i); + if (t.getName(abc.getSelectedAbc()).getName(abc.getSelectedAbc().constants, null, true).equals(propertyName)) { + if (t instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) t; + objType = new TypeItem(DottedChain.FUNCTION); + propType = multinameToType(tsc.type_index, abc.getSelectedAbc().constants); + propIndex = tsc.name_index; + if (!localData.traitUsages.containsKey(b)) { + localData.traitUsages.put(b, new ArrayList<>()); + } + localData.traitUsages.get(b).add(i); + } } } - if (name_index > 0) { - for (int c = 0; c < abc.instance_info.size(); c++) { - if (abc.instance_info.get(c).deleted) { - continue; - } - for (Trait t : abc.instance_info.get(c).instance_traits.traits) { - if (t.name_index == name_index) { - objType = multinameToType(abc.instance_info.get(c).name_index, abc.constants); - propType = AVM2SourceGenerator.getTraitReturnType(abc, t); - propIndex = t.name_index; - if (t instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) t; - propValue = new ValueKind(tsc.value_index, tsc.value_kind); - } - break loopobjType; - } - } - for (Trait t : abc.class_info.get(c).static_traits.traits) { - if (t.name_index == name_index) { - objType = multinameToType(abc.instance_info.get(c).name_index, abc.constants); - propType = AVM2SourceGenerator.getTraitReturnType(abc, t); - propIndex = t.name_index; - if (t instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) t; - propValue = new ValueKind(tsc.value_index, tsc.value_kind); - } - break loopobjType; - } - } - } + } + if (objType == null) { + loopobjType: + for (int i = 0; i < openedNamespaces.size(); i++) { + int nsindex = openedNamespaces.get(i); - for (ScriptInfo si : abc.script_info) { - if (si.deleted) { - continue; - } - for (Trait t : si.traits.traits) { - if (t.name_index == name_index) { - objType = new TypeItem(DottedChain.OBJECT); - propType = AVM2SourceGenerator.getTraitReturnType(abc, t); - propIndex = t.name_index; - if (t instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) t; - propValue = new ValueKind(tsc.value_index, tsc.value_kind); - } - break loopobjType; - } + int nsKind = abc.getSelectedAbc().constants.constant_namespace.get(openedNamespaces.get(i)).kind; + DottedChain nsname = abc.getSelectedAbc().constants.constant_namespace.get(openedNamespaces.get(i)).getName(abc.getSelectedAbc().constants); + int name_index = 0; + for (int m = 1; m < abc.getSelectedAbc().constants.constant_multiname.size(); m++) { + Multiname mname = abc.getSelectedAbc().constants.constant_multiname.get(m); + if (mname.kind == Multiname.QNAME && mname.getName(abc.getSelectedAbc().constants, null, true).equals(propertyName) && mname.namespace_index == nsindex) { + name_index = m; + break; } } - } - if (nsKind == Namespace.KIND_PACKAGE) { - List abcs = new ArrayList<>(); - abcs.add(abc); - abcs.addAll(otherABCs); - loopabc: - for (ABC a : otherABCs) { - for (int h = 0; h < a.instance_info.size(); h++) { - InstanceInfo ii = a.instance_info.get(h); - if (ii.deleted) { + if (name_index > 0) { + for (int c = 0; c < abc.getSelectedAbc().instance_info.size(); c++) { + if (abc.getSelectedAbc().instance_info.get(c).deleted) { continue; } - Multiname n = a.constants.constant_multiname.get(ii.name_index); - if (n.getNamespace(a.constants).kind == Namespace.KIND_PACKAGE && n.getNamespace(a.constants).getName(a.constants).equals(nsname)) { - Reference outName = new Reference<>(""); - Reference outNs = new Reference<>(DottedChain.EMPTY); - Reference outPropNs = new Reference<>(DottedChain.EMPTY); - Reference outPropNsKind = new Reference<>(1); - Reference outPropNsIndex = new Reference<>(0); - Reference outPropType = new Reference<>(null); - Reference outPropValue = new Reference<>(null); - - if (propertyName != null && AVM2SourceGenerator.searchPrototypeChain(false, abcs, nsname, n.getName(a.constants, null, true), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue)) { - objType = new TypeItem("".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal()); - propType = outPropType.getVal(); - propIndex = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, - abc.constants.getStringId(propertyName, true), - abc.constants.getNamespaceId(new Namespace(outPropNsKind.getVal(), abc.constants.getStringId(outPropNs.getVal(), true)), outPropNsIndex.getVal(), true), 0, 0, new ArrayList<>()), true - ); - propValue = outPropValue.getVal(); + for (Trait t : abc.getSelectedAbc().instance_info.get(c).instance_traits.traits) { + if (t.name_index == name_index) { + objType = multinameToType(abc.getSelectedAbc().instance_info.get(c).name_index, abc.getSelectedAbc().constants); + propType = AVM2SourceGenerator.getTraitReturnType(abc, t); + propIndex = t.name_index; + if (t instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) t; + propValue = new ValueKind(tsc.value_index, tsc.value_kind); + } + break loopobjType; + } + } + for (Trait t : abc.getSelectedAbc().class_info.get(c).static_traits.traits) { + if (t.name_index == name_index) { + objType = multinameToType(abc.getSelectedAbc().instance_info.get(c).name_index, abc.getSelectedAbc().constants); + propType = AVM2SourceGenerator.getTraitReturnType(abc, t); + propIndex = t.name_index; + if (t instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) t; + propValue = new ValueKind(tsc.value_index, tsc.value_kind); + } break loopobjType; } } } + + for (ScriptInfo si : abc.getSelectedAbc().script_info) { + if (si.deleted) { + continue; + } + for (Trait t : si.traits.traits) { + if (t.name_index == name_index) { + objType = new TypeItem(DottedChain.OBJECT); + propType = AVM2SourceGenerator.getTraitReturnType(abc, t); + propIndex = t.name_index; + if (t instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) t; + propValue = new ValueKind(tsc.value_index, tsc.value_kind); + } + break loopobjType; + } + } + } + } + if (nsKind == Namespace.KIND_PACKAGE && propertyName != null) { + AbcIndexing.TraitIndex p = abc.findNsProperty(new AbcIndexing.PropertyNsDef(propertyName, nsname, abc.getSelectedAbc(), openedNamespaces.get(i)), true, true); + + Reference outName = new Reference<>(""); + Reference outNs = new Reference<>(DottedChain.EMPTY); + Reference outPropNs = new Reference<>(DottedChain.EMPTY); + Reference outPropNsKind = new Reference<>(1); + Reference outPropNsIndex = new Reference<>(0); + Reference outPropType = new Reference<>(null); + Reference outPropValue = new Reference<>(null); + if (p != null && (p.objType instanceof TypeItem)) { + if (AVM2SourceGenerator.searchPrototypeChain(localData.privateNs, localData.protectedNs, false, abc, nsname, (((TypeItem) p.objType).fullTypeName.getLast()), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue)) { + objType = new TypeItem("".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal()); + propType = p.returnType; + propIndex = abc.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, + abc.getSelectedAbc().constants.getStringId(propertyName, true), + abc.getSelectedAbc().constants.getNamespaceId(new Namespace(outPropNsKind.getVal(), outPropNs.getVal() == null || outPropNs.getVal().isEmpty() ? 0 : abc.getSelectedAbc().constants.getStringId(outPropNs.getVal(), true)), outPropNsIndex.getVal(), true), 0, 0, new ArrayList<>()), true + ); + propValue = p.value; + break loopobjType; + } + } + + //if (propertyName != null && AVM2SourceGenerator.searchPrototypeChain(false, abcs, nsname, n.getName(a.constants, null, true), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue)) { + // + //} } } } @@ -363,9 +350,9 @@ public class PropertyAVM2Item extends AssignableAVM2Item { if (attr) { pname = pname.substring(1); } - propIndex = abc.constants.getMultinameId(new Multiname(attr ? (pname.isEmpty() ? Multiname.MULTINAMELA : Multiname.MULTINAMEA) : Multiname.MULTINAME, - abc.constants.getStringId("*".equals(pname) ? null : pname, true), 0, //Note: name = * is for .@* attribute - attr && pname.isEmpty() ? abc.constants.getNamespaceSetId(new NamespaceSet(new int[]{abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abc.constants.getStringId(localData.pkg, true)), 0, true)}), true) : allNsSet(), 0, new ArrayList<>()), true); + propIndex = abc.getSelectedAbc().constants.getMultinameId(new Multiname(attr ? (pname.isEmpty() ? Multiname.MULTINAMELA : Multiname.MULTINAMEA) : Multiname.MULTINAME, + abc.getSelectedAbc().constants.getStringId("*".equals(pname) ? null : pname, true), 0, //Note: name = * is for .@* attribute + attr && pname.isEmpty() ? abc.getSelectedAbc().constants.getNamespaceSetId(new NamespaceSet(new int[]{abc.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, localData.pkg == null || localData.pkg.isEmpty() ? 0 : abc.getSelectedAbc().constants.getStringId(localData.pkg, true)), 0, true)}), true) : allNsSet(), 0, new ArrayList<>()), true); propType = TypeItem.UNBOUNDED; objType = TypeItem.UNBOUNDED; propValue = null; @@ -624,10 +611,10 @@ public class PropertyAVM2Item extends AssignableAVM2Item { Reference outPropNsIndex = new Reference<>(0); Reference outPropType = new Reference<>(null); Reference outPropValue = new Reference<>(null); - List abcs = new ArrayList<>(); - abcs.add(abc); - abcs.addAll(otherABCs); - if (!localData.subMethod && cname != null && AVM2SourceGenerator.searchPrototypeChain(true, abcs, pkgName, cname, propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue) && (localData.currentClass.equals("".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal()))) { + /*List abcs = new ArrayList<>(); + abcs.add(abc); + abcs.addAll(otherABCs);*/ + if (!localData.subMethod && cname != null && AVM2SourceGenerator.searchPrototypeChain(localData.privateNs, localData.protectedNs, true, abc, pkgName, cname, propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue) && (localData.currentClass.equals(DottedChain.EMPTY.equals(outNs.getVal()) ? outName.getVal() : outNs.getVal().add(outName.getVal())))) { NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.getFullClass()), 0, "this", null, false, openedNamespaces); nobj.setRegNumber(0); obj = nobj; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java index 60472e6ba..7df4e8120 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java @@ -218,7 +218,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { ins = ins(AVM2Instructions.CoerceS); break; default: - int type_index = AVM2SourceGenerator.resolveType(localData, type, ((AVM2SourceGenerator) generator).abc, ((AVM2SourceGenerator) generator).allABCs); + int type_index = AVM2SourceGenerator.resolveType(localData, type, ((AVM2SourceGenerator) generator).abcIndex); ins = ins(AVM2Instructions.Coerce, type_index); break; } @@ -287,7 +287,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { throw new RuntimeException("Cannot assign"); } - public GraphTargetItem resolve(GraphTargetItem thisType, List paramTypes, List paramNames, ABC abc, List otherAbcs, List callStack, List variables) throws CompilationException { + public GraphTargetItem resolve(GraphTargetItem thisType, List paramTypes, List paramNames, AbcIndexing abc, List callStack, List variables) throws CompilationException { if (scopeStack.isEmpty()) { //Everything is multiname property in with command //search for variable @@ -301,7 +301,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { ret.setRegNumber(n.getRegNumber()); resolved = ret; for (int i = 1; i < name.size(); i++) { - resolved = new PropertyAVM2Item(resolved, name.get(i), abc, otherAbcs, openedNamespaces, new ArrayList<>()); + resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>()); if (i == name.size() - 1) { ((PropertyAVM2Item) resolved).assignedValue = assignedValue; } @@ -323,7 +323,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { TypeItem ret = new TypeItem(imp); resolved = ret; for (int i = 1; i < name.size(); i++) { - resolved = new PropertyAVM2Item(resolved, name.get(i), abc, otherAbcs, openedNamespaces, new ArrayList<>()); + resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>()); if (i == name.size() - 1) { ((PropertyAVM2Item) resolved).assignedValue = assignedValue; } @@ -336,95 +336,66 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { } //Search all fully qualitfied types - List allAbcs = new ArrayList<>(); - allAbcs.add(abc); - allAbcs.addAll(otherAbcs); + /*List allAbcs = new ArrayList<>(); + allAbcs.add(abc); + allAbcs.addAll(otherAbcs);*/ for (int i = 0; i < name.size(); i++) { DottedChain fname = name.subChain(i + 1); - for (ABC a : allAbcs) { - for (int c = 0; c < a.instance_info.size(); c++) { - if (a.instance_info.get(c).deleted) { - continue; - } - if (a.instance_info.get(c).name_index > 0 && fname.equals(a.instance_info.get(c).getName(a.constants).getNameWithNamespace(a.constants))) { - if (!subtypes.isEmpty() && name.size() > i + 1) { - continue; - } - TypeItem ret = new TypeItem(fname); - resolved = ret; - for (int j = i + 1; j < name.size(); j++) { - resolved = new PropertyAVM2Item(resolved, name.get(j), abc, otherAbcs, openedNamespaces, new ArrayList<>()); - if (j == name.size() - 1) { - ((PropertyAVM2Item) resolved).assignedValue = assignedValue; - } - } - if (name.size() == i + 1 && assignedValue != null) { - throw new CompilationException("Cannot assign type", line); - } - - return resolvedRoot = ret; + AbcIndexing.ClassIndex ci = abc.findClass(new TypeItem(fname)); + if (ci != null) { + if (!subtypes.isEmpty() && name.size() > i + 1) { + continue; + } + TypeItem ret = new TypeItem(fname); + resolved = ret; + for (int j = i + 1; j < name.size(); j++) { + resolved = new PropertyAVM2Item(resolved, name.get(j), abc, openedNamespaces, new ArrayList<>()); + if (j == name.size() - 1) { + ((PropertyAVM2Item) resolved).assignedValue = assignedValue; } } + if (name.size() == i + 1 && assignedValue != null) { + throw new CompilationException("Cannot assign type", line); + } + + return resolvedRoot = ret; } } //Search for types in opened namespaces for (int ni : openedNamespaces) { - Namespace ons = abc.constants.getNamespace(ni); - if (ons == null) { - continue; - } - for (ABC a : allAbcs) { - for (int c = 0; c < a.instance_info.size(); c++) { - if (a.instance_info.get(c).deleted) { - continue; - } - Multiname mname = a.instance_info.get(c).getName(a.constants); - if (mname != null) { - if ((a == abc && mname.namespace_index == ni) - || (ons.kind != Namespace.KIND_PRIVATE && mname.getNamespace(a.constants) != null && mname.getNamespace(a.constants).hasName(ons.getName(abc.constants).toRawString(), a.constants))) { - String cname = mname.getName(a.constants, null, true); - if (name.get(0).equals(cname)) { - if (!subtypes.isEmpty() && name.size() > 1) { - continue; - } - TypeItem ret = new TypeItem(mname.getNameWithNamespace(a.constants)); - /*for (String s : subtypes) { - UnresolvedAVM2Item su = new UnresolvedAVM2Item(new ArrayList<>(), importedClasses, true, null, line, s, null, openedNamespaces); - su.resolve(thisType, paramTypes, paramNames, abc, otherAbcs, callStack, variables); - if (!(su.resolved instanceof TypeItem)) { - throw new CompilationException("Not a type", line); - } - TypeItem st = (TypeItem) su.resolved; - ret.subtypes.add(st.fullTypeName); - }*/ - resolved = ret; - for (int i = 1; i < name.size(); i++) { - resolved = new PropertyAVM2Item(resolved, name.get(i), abc, otherAbcs, openedNamespaces, new ArrayList<>()); - if (i == name.size() - 1) { - ((PropertyAVM2Item) resolved).assignedValue = assignedValue; - } - } - if (name.size() == 1 && assignedValue != null) { - throw new CompilationException("Cannot assign type", line); - } - - return resolvedRoot = ret; - } - } + Namespace ons = abc.getSelectedAbc().constants.getNamespace(ni); + TypeItem ti = new TypeItem(ons.getName(abc.getSelectedAbc().constants).add(name.get(0))); + AbcIndexing.ClassIndex ci = abc.findClass(ti); + if (ci != null) { + if (!subtypes.isEmpty() && name.size() > 1) { + continue; + } + TypeItem ret = ti; + resolved = ret; + for (int i = 1; i < name.size(); i++) { + resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>()); + if (i == name.size() - 1) { + ((PropertyAVM2Item) resolved).assignedValue = assignedValue; } } + if (name.size() == 1 && assignedValue != null) { + throw new CompilationException("Cannot assign type", line); + } + + return resolvedRoot = ret; } } - if (name.get(0).equals("this") || name.get(0).equals("super")) { + if (name.get( + 0).equals("this") || name.get(0).equals("super")) { if (thisType == null) { throw new CompilationException("Cannot use this in that context", line); } NameAVM2Item ret = new NameAVM2Item(thisType, line, name.get(0), null, false, openedNamespaces); resolved = ret; for (int i = 1; i < name.size(); i++) { - resolved = new PropertyAVM2Item(resolved, name.get(i), abc, otherAbcs, openedNamespaces, new ArrayList<>()); + resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>()); if (i == name.size() - 1) { ((PropertyAVM2Item) resolved).assignedValue = assignedValue; } @@ -447,7 +418,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { GraphTargetItem ret = new NameAVM2Item(t, line, name.get(0), null, false, openedNamespaces); resolved = ret; for (int i = 1; i < name.size(); i++) { - resolved = new PropertyAVM2Item(resolved, name.get(i), abc, otherAbcs, openedNamespaces, new ArrayList<>()); + resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>()); if (i == name.size() - 1) { ((PropertyAVM2Item) resolved).assignedValue = assignedValue; } @@ -458,7 +429,8 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { return resolvedRoot = ret; } - if (/*!subtypes.isEmpty() && */name.size() == 1 && name.get(0).equals("Vector")) { + if (/*!subtypes.isEmpty() && */name.size() + == 1 && name.get(0).equals("Vector")) { TypeItem ret = new TypeItem(InitVectorAVM2Item.VECTOR_FQN); /*for (String s : subtypes) { UnresolvedAVM2Item su = new UnresolvedAVM2Item(new ArrayList<>(), importedClasses, true, null, line, s, null, openedNamespaces); @@ -478,8 +450,10 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { } resolved = null; GraphTargetItem ret = null; - for (int i = 0; i < name.size(); i++) { - resolved = new PropertyAVM2Item(resolved, name.get(i), abc, otherAbcs, openedNamespaces, callStack); + for (int i = 0; + i < name.size(); + i++) { + resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, callStack); if (ret == null) { ((PropertyAVM2Item) resolved).scopeStack = scopeStack; ret = resolved; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/XMLAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/XMLAVM2Item.java index 2af62f970..05d758ba4 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/XMLAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/XMLAVM2Item.java @@ -61,7 +61,7 @@ public class XMLAVM2Item extends AVM2Item { public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { AVM2SourceGenerator g = (AVM2SourceGenerator) generator; return toSourceMerge(localData, generator, - ins(AVM2Instructions.GetLex, g.abc.constants.getMultinameId(new Multiname(Multiname.QNAME, g.abc.constants.getStringId("XML", true), g.abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, g.abc.constants.getStringId("", true)), 0, true), 0, 0, new ArrayList<>()), true)), + ins(AVM2Instructions.GetLex, g.abcIndex.getSelectedAbc().constants.getMultinameId(new Multiname(Multiname.QNAME, g.abcIndex.getSelectedAbc().constants.getStringId("XML", true), g.abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, g.abcIndex.getSelectedAbc().constants.getStringId("", true)), 0, true), 0, 0, new ArrayList<>()), true)), value, ins(AVM2Instructions.Construct, 1) ); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java index 5e1298dfa..af68978ff 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/InstanceInfo.java @@ -101,8 +101,11 @@ public class InstanceInfo { if (super_index > 0) { String typeName = abc.constants.getMultiname(super_index).getNameWithNamespace(abc.constants).toPrintableString(true); - writer.appendNoHilight(" extends "); - writer.hilightSpecial(abc.constants.getMultiname(super_index).getName(abc.constants, fullyQualifiedNames, false), HighlightSpecialType.TYPE_NAME, typeName); + String parentName = abc.constants.getMultiname(super_index).getName(abc.constants, fullyQualifiedNames, false); + if (!parentName.equals("Object")) { + writer.appendNoHilight(" extends "); + writer.hilightSpecial(parentName, HighlightSpecialType.TYPE_NAME, typeName); + } } if (interfaces.length > 0) { if (isInterface()) { 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 f1beb16ce..1dfa9019c 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 @@ -118,7 +118,7 @@ public class TraitClass extends Trait implements TraitWithSlot { return true; } - if (!newname.isEmpty()) { + if (!newname.isEmpty() && !newname.isTopLevel()) { newimport = newname; break; } @@ -127,7 +127,7 @@ public class TraitClass extends Trait implements TraitWithSlot { newimport = oldimport.add(name); }*/ - if (!newimport.isEmpty()) { + if (!newimport.isEmpty() && !newimport.isTopLevel()) { /* if(ns.kind==Namespace.KIND_PACKAGE){ newimport+=".*"; }*/ diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/DottedChain.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/DottedChain.java index 204e3cad4..231a1b3e9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/DottedChain.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/DottedChain.java @@ -30,7 +30,9 @@ import java.util.List; */ public class DottedChain implements Serializable { - public static final DottedChain EMPTY = new DottedChain(); + public static final DottedChain EMPTY = new DottedChain(true); + + public static final DottedChain TOPLEVEL = new DottedChain(""); public static final DottedChain BOOLEAN = new DottedChain("Boolean"); @@ -65,6 +67,7 @@ public class DottedChain implements Serializable { private final int length; private final int hash; + private boolean isNull = false; public static final DottedChain parse(String name) { if (name == null || name.isEmpty()) { @@ -74,6 +77,17 @@ public class DottedChain implements Serializable { } } + private DottedChain(boolean isNull) { + this.isNull = isNull; + this.parts = new String[0]; + this.length = 0; + this.hash = 0; + } + + public DottedChain(DottedChain src) { + this(src.parts); + } + public DottedChain(List parts) { length = parts.size(); this.parts = parts.toArray(new String[length]); @@ -92,8 +106,12 @@ public class DottedChain implements Serializable { hash = calcHash(); } + public boolean isTopLevel() { + return !isNull && length == 0; + } + public boolean isEmpty() { - return length == 0; + return isNull; } public int size() { @@ -117,6 +135,9 @@ public class DottedChain implements Serializable { } public String getLast() { + if (isNull) { + return null; + } if (length == 0) { return ""; } else { @@ -125,6 +146,9 @@ public class DottedChain implements Serializable { } public DottedChain getWithoutLast() { + if (isNull) { + return null; + } if (length < 2) { return EMPTY; } @@ -133,6 +157,9 @@ public class DottedChain implements Serializable { } public DottedChain add(String name) { + if (name == null) { + return new DottedChain(this); + } String[] nparts = new String[length + 1]; if (length > 0) { System.arraycopy(parts, 0, nparts, 0, length); @@ -142,7 +169,10 @@ public class DottedChain implements Serializable { return new DottedChain(nparts); } - private String toString(boolean as3, boolean raw) { + protected String toString(boolean as3, boolean raw) { + if (isNull) { + return ""; + } if (length == 0) { return ""; } @@ -161,6 +191,9 @@ public class DottedChain implements Serializable { } public String toFilePath() { + if (isNull) { + return ""; + } if (length == 0) { return ""; } @@ -199,6 +232,9 @@ public class DottedChain implements Serializable { } private int calcHash() { + if (isNull) { + return 0; + } int result = 1; for (int i = 0; i < length; i++) { result = 31 * result + parts[i].hashCode(); @@ -216,6 +252,9 @@ public class DottedChain implements Serializable { return false; } final DottedChain other = (DottedChain) obj; + if (isNull && other.isNull) { + return true; + } if (length != other.length) { return false; } 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 b0f82cd82..cefa59ce3 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3Test.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript3Test.java @@ -957,7 +957,7 @@ public class ActionScript3Test extends ActionScriptTestBase { public void testMyPackage1TestClass() { decompileScriptPack("classes.mypackage1.TestClass", "package classes.mypackage1\n" + "{\n" - + " public class TestClass extends Object implements classes.mypackage1.TestInterface\n" + + " public class TestClass implements classes.mypackage1.TestInterface\n" + " {\n" + " \n" + " public function TestClass()\n" @@ -994,7 +994,7 @@ public class ActionScript3Test extends ActionScriptTestBase { public void testMyPackage1TestClass2() { decompileScriptPack("classes.mypackage1.TestClass2", "package classes.mypackage1\n" + "{\n" - + " public class TestClass2 extends Object\n" + + " public class TestClass2\n" + " {\n" + " \n" + " public function TestClass2()\n" @@ -1057,7 +1057,7 @@ public class ActionScript3Test extends ActionScriptTestBase { public void testMyPackage2TestClass() { decompileScriptPack("classes.mypackage2.TestClass", "package classes.mypackage2\n" + "{\n" - + " public class TestClass extends Object implements TestInterface\n" + + " public class TestClass implements TestInterface\n" + " {\n" + " \n" + " public function TestClass()\n" @@ -1094,7 +1094,7 @@ public class ActionScript3Test extends ActionScriptTestBase { public void testMyPackage3TestClass() { decompileScriptPack("classes.mypackage3.TestClass", "package classes.mypackage3\n" + "{\n" - + " public class TestClass extends Object\n" + + " public class TestClass\n" + " {\n" + " \n" + " public function TestClass()\n"