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 769a7e3ba..30b14b9d8 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java @@ -52,6 +52,9 @@ public class SourceGeneratorLocalData implements Serializable { public String currentClass; + public String superClass = null; + public DottedChain superPkg = null; + public int activationReg = 0; public List callStack = new ArrayList<>(); 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 56110fc18..3fc4f2087 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 @@ -1269,7 +1269,7 @@ public class ABC { } List otherAbcs = new ArrayList<>(pack.allABCs); otherAbcs.remove(this); - ActionScript3Parser.compile(as, this, otherAbcs, isDocumentClass, scriptName, newClassIndex); + ActionScript3Parser.compile(as, this, otherAbcs, isDocumentClass, scriptName, newClassIndex, oldIndex); if (isSimple) { // Move newly added script to its position diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java index 69f9c2311..135b50408 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ScriptPack.java @@ -155,9 +155,9 @@ public class ScriptPack extends AS3ClassTreeItem { }*/ public void convert(final NulWriter writer, final List traits, final ConvertData convertData, final ScriptExportMode exportMode, final boolean parallel) throws InterruptedException { - int script_init = abc.script_info.get(scriptIndex).init_index; - int bodyIndex = abc.findBodyIndex(script_init); - if (bodyIndex != -1) { + int sinit_index = abc.script_info.get(scriptIndex).init_index; + int sinit_bodyIndex = abc.findBodyIndex(sinit_index); + if (sinit_bodyIndex != -1) { List ts = new ArrayList<>(); //initialize all classes traits for (Trait t : traits) { @@ -165,9 +165,9 @@ public class ScriptPack extends AS3ClassTreeItem { ts.add(abc.class_info.get(((TraitClass) t).class_info).static_traits); } } - + ts.add(abc.script_info.get(scriptIndex).traits); writer.mark(); - abc.bodies.get(bodyIndex).convert(convertData, path +/*packageName +*/ "/.scriptinitializer", exportMode, true, script_init, scriptIndex, -1, abc, null, new ScopeStack(), GraphTextWriter.TRAIT_SCRIPT_INITIALIZER, writer, new ArrayList<>(), ts, true); + abc.bodies.get(sinit_bodyIndex).convert(convertData, path +/*packageName +*/ "/.scriptinitializer", exportMode, true, sinit_index, scriptIndex, -1, abc, null, new ScopeStack(), GraphTextWriter.TRAIT_SCRIPT_INITIALIZER, writer, new ArrayList<>(), ts, true); scriptInitializerIsEmpty = !writer.getMark(); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 32445d5ac..0a675f2c1 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -1937,6 +1937,11 @@ public class AVM2Code implements Cloneable { if (((TraitSlotConst) t).isConst() || initializerType == GraphTextWriter.TRAIT_CLASS_INITIALIZER || initializerType == GraphTextWriter.TRAIT_SCRIPT_INITIALIZER) { TraitSlotConst tsc = (TraitSlotConst) t; if (value != null && !convertData.assignedValues.containsKey(tsc)) { + + if (value instanceof NewFunctionAVM2Item) { + NewFunctionAVM2Item f = (NewFunctionAVM2Item) value; + f.functionName = tsc.getName(abc).getName(abc.constants, fullyQualifiedNames, true); + } AssignedValue av = new AssignedValue(value, initializerType, methodIndex); convertData.assignedValues.put(tsc, av); list.remove(i); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetDescendantsAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetDescendantsAVM2Item.java index f0bcbfb78..773476737 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetDescendantsAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/GetDescendantsAVM2Item.java @@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.abc.avm2.model; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator; +import com.jpexs.decompiler.flash.abc.avm2.parser.script.NamespaceItem; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.GraphSourceItem; @@ -34,12 +35,12 @@ public class GetDescendantsAVM2Item extends AVM2Item { public GraphTargetItem multiname; - public List openedNamespaces; + public List openedNamespaces; public String nameStr; //constructor for compiler - public GetDescendantsAVM2Item(GraphTargetItem object, String nameStr, List openedNamespaces) { + public GetDescendantsAVM2Item(GraphTargetItem object, String nameStr, List openedNamespaces) { super(null, PRECEDENCE_PRIMARY); this.object = object; this.nameStr = nameStr; 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 e5ee8cd2f..ceb97a0e9 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 @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator; +import com.jpexs.decompiler.flash.abc.avm2.parser.script.NamespaceItem; import com.jpexs.decompiler.flash.abc.types.Multiname; import com.jpexs.decompiler.flash.abc.types.Namespace; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; @@ -58,11 +59,10 @@ public class InitVectorAVM2Item extends AVM2Item { public List arguments; - List openedNamespaces; + List openedNamespaces; private int allNsSet(ABC abc) { - int[] nssa = Helper.toIntArray(openedNamespaces); - return abc.constants.getNamespaceSetId(nssa, true); + return NamespaceItem.getCpoolSetIndex(abc.constants, openedNamespaces); } public InitVectorAVM2Item(AVM2Instruction ins, GraphTargetItem subtype, List arguments) { @@ -71,7 +71,7 @@ public class InitVectorAVM2Item extends AVM2Item { this.arguments = arguments; } - public InitVectorAVM2Item(GraphTargetItem subtype, List arguments, List openedNamespaces) { + public InitVectorAVM2Item(GraphTargetItem subtype, List arguments, List openedNamespaces) { super(null, PRECEDENCE_PRIMARY); this.subtype = subtype; this.arguments = arguments; @@ -120,13 +120,11 @@ public class InitVectorAVM2Item extends AVM2Item { ins(AVM2Instructions.Construct, 1) ); for (int i = 0; i < arguments.size(); i++) { - // qname_index == precedence and params == openedNamespaced ??? - int[] arr = Helper.toIntArray(openedNamespaces); ret.addAll(toSourceMerge(localData, generator, ins(AVM2Instructions.Dup), new IntegerValueAVM2Item(null, (long) i), arguments.get(i), - ins(AVM2Instructions.SetProperty, constants.getMultinameId(Multiname.createMultinameL(false, constants.getNamespaceSetId(new int[]{constants.getNamespaceId(Namespace.KIND_PACKAGE, "", 0, true)}, true)), true)) + ins(AVM2Instructions.SetProperty, constants.getMultinameId(Multiname.createMultinameL(false, NamespaceItem.getCpoolSetIndex(constants, openedNamespaces)), true)) )); } return ret; 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 ce4e8b0c8..0ab552421 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 @@ -139,12 +139,13 @@ public class AVM2SourceGenerator implements SourceGenerator { } public List generate(SourceGeneratorLocalData localData, GetDescendantsAVM2Item item) throws CompilationException { - int[] nssa = new int[item.openedNamespaces.size()]; - for (int i = 0; i < item.openedNamespaces.size(); i++) { - nssa[i] = item.openedNamespaces.get(i); - } AVM2ConstantPool constants = abcIndex.getSelectedAbc().constants; + int[] nssa = new int[item.openedNamespaces.size()]; + for (int i = 0; i < item.openedNamespaces.size(); i++) { + nssa[i] = item.openedNamespaces.get(i).getCpoolIndex(constants); + } + int nsset = constants.getNamespaceSetId(nssa, true); return GraphTargetItem.toSourceMerge(localData, this, @@ -316,8 +317,7 @@ public class AVM2SourceGenerator implements SourceGenerator { trueBody.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, xmlListReg))); trueBody.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, counterReg))); trueBody.addAll(toInsList(AssignableAVM2Item.getTemp(localData, this, tempVal1))); - int[] nss = Helper.toIntArray(item.openedNamespaces); - trueBody.add(ins(AVM2Instructions.SetProperty, constants.getMultinameId(Multiname.createMultinameL(false, constants.getNamespaceSetId(nss, true)), true))); + trueBody.add(ins(AVM2Instructions.SetProperty, constants.getMultinameId(Multiname.createMultinameL(false, NamespaceItem.getCpoolSetIndex(constants, item.openedNamespaces)), true))); forBody.add(ins(AVM2Instructions.IfFalse, insToBytes(trueBody).length)); forBody.addAll(trueBody); forBody.add(ins(AVM2Instructions.PopScope)); @@ -1157,11 +1157,11 @@ public class AVM2SourceGenerator implements SourceGenerator { /*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 { + public void generateClass(List importedClasses, List cinitVariables, boolean cinitNeedsActivation, List cinit, 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 iinit, List iinitVariables, boolean iinitNeedsActivation, List traitItems, Reference class_index) throws AVM2ParseException, CompilationException { localData.currentClass = name; localData.pkg = pkg; - localData.privateNs = privateNs; - localData.protectedNs = protectedNs; + localData.privateNs = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PRIVATE, pkg.toRawString() + ":" + name, 0, true); + localData.protectedNs = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PROTECTED, pkg.toRawString() + ":" + name, 0, true); if (extendsVal == null && !isInterface) { extendsVal = new TypeItem(DottedChain.OBJECT); } @@ -1175,16 +1175,16 @@ public class AVM2SourceGenerator implements SourceGenerator { 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; - if (constructor == null || isInterface) { + if (iinit == null || isInterface) { instanceInfo.iinit_index = init = method(false, 0, false, isInterface, new ArrayList<>(), pkg, false, new ArrayList<>(), initScope + 1, false, 0, isInterface ? null : name, extendsVal != null ? extendsVal.toString() : null, true, localData, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), TypeItem.UNBOUNDED/*?? FIXME*/); } else { - MethodAVM2Item m = (MethodAVM2Item) constructor; + MethodAVM2Item m = (MethodAVM2Item) iinit; instanceInfo.iinit_index = init = method(false, str(pkg.toRawString() + ":" + name + "/" + name), false, false, new ArrayList<>(), pkg, m.needsActivation, m.subvariables, initScope + 1, m.hasRest, m.line, name, extendsVal != null ? extendsVal.toString() : null, true, localData, m.paramTypes, m.paramNames, m.paramValues, m.body, TypeItem.UNBOUNDED/*?? FIXME*/); } //Class initializer - int staticMi = method(true, str(""), 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 = abcIndex.getSelectedAbc().findBody(staticMi); + int cinit_index = method(true, str(""), false, false, new ArrayList<>(), pkg, cinitNeedsActivation, cinitVariables, initScope + (implementsStr.isEmpty() ? 0 : 1), false, 0, isInterface ? null : name, superName, false, localData, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), cinit, TypeItem.UNBOUNDED); + MethodBody cinitBody = abcIndex.getSelectedAbc().findBody(cinit_index); List sinitcode = new ArrayList<>(); List initcode = new ArrayList<>(); @@ -1198,13 +1198,13 @@ public class AVM2SourceGenerator implements SourceGenerator { if (ti instanceof SlotAVM2Item) { val = ((SlotAVM2Item) ti).value; isStatic = ((SlotAVM2Item) ti).isStatic(); - ns = genNs(importedClasses, pkg, ((SlotAVM2Item) ti).customNamespace, ((SlotAVM2Item) ti).getNamespace(), openedNamespaces, localData, ((SlotAVM2Item) ti).line); + ns = genNs(importedClasses, pkg, ((SlotAVM2Item) ti).customNamespace, ((SlotAVM2Item) ti).pkg == null ? 0 : ((SlotAVM2Item) ti).pkg.getCpoolIndex(abcIndex.getSelectedAbc().constants), openedNamespaces, localData, ((SlotAVM2Item) ti).line); tname = ((SlotAVM2Item) ti).var; } if (ti instanceof ConstAVM2Item) { val = ((ConstAVM2Item) ti).value; isStatic = ((ConstAVM2Item) ti).isStatic(); - ns = genNs(importedClasses, pkg, ((ConstAVM2Item) ti).customNamespace, ((ConstAVM2Item) ti).getNamespace(), openedNamespaces, localData, ((ConstAVM2Item) ti).line); + ns = genNs(importedClasses, pkg, ((ConstAVM2Item) ti).customNamespace, ((ConstAVM2Item) ti).pkg == null ? 0 : ((ConstAVM2Item) ti).pkg.getCpoolIndex(abcIndex.getSelectedAbc().constants), openedNamespaces, localData, ((ConstAVM2Item) ti).line); tname = ((ConstAVM2Item) ti).var; isConst = true; } @@ -1228,16 +1228,16 @@ public class AVM2SourceGenerator implements SourceGenerator { MethodBody initBody = null; if (!isInterface) { initBody = abcIndex.getSelectedAbc().findBody(init); - initBody.insertAll(constructor == null ? 0 : 2, initcode);//after getlocal0,pushscope + initBody.insertAll(iinit == null ? 0 : 2, initcode);//after getlocal0,pushscope - if (sinitBody.getCode().code.get(sinitBody.getCode().code.size() - 1).definition instanceof ReturnVoidIns) { - sinitBody.insertAll(2, sinitcode); //after getlocal0,pushscope + if (cinitBody.getCode().code.get(cinitBody.getCode().code.size() - 1).definition instanceof ReturnVoidIns) { + cinitBody.insertAll(2, sinitcode); //after getlocal0,pushscope } } - sinitBody.markOffsets(); - sinitBody.autoFillStats(abcIndex.getSelectedAbc(), initScope + (implementsStr.isEmpty() ? 0 : 1), true); + cinitBody.markOffsets(); + cinitBody.autoFillStats(abcIndex.getSelectedAbc(), initScope + (implementsStr.isEmpty() ? 0 : 1), true); - classInfo.cinit_index = staticMi; + classInfo.cinit_index = cinit_index; if (initBody != null) { initBody.autoFillStats(abcIndex.getSelectedAbc(), initScope + 1, true); } @@ -1270,7 +1270,16 @@ public class AVM2SourceGenerator implements SourceGenerator { */ if (cls instanceof ClassAVM2Item) { ClassAVM2Item cai = (ClassAVM2Item) cls; - 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); + //TODO: iinit variables, iinit activation + generateClass(cai.importedClasses, cai.cinitVariables, cai.cinitActivation, 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.iinit, + cai.iinitVariables, cai.iinitActivation, cai.traits, class_index + ); if (!cai.isDynamic) { ii.flags |= InstanceInfo.CLASS_SEALED; } @@ -1278,13 +1287,16 @@ public class AVM2SourceGenerator implements SourceGenerator { ii.flags |= InstanceInfo.CLASS_FINAL; } ii.flags |= InstanceInfo.CLASS_PROTECTEDNS; - ii.protectedNS = cai.protectedNs; + ii.protectedNS = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PROTECTED, pkg.toRawString() + ":" + cai.className, 0, true); } if (cls instanceof InterfaceAVM2Item) { InterfaceAVM2Item iai = (InterfaceAVM2Item) cls; ii.flags |= InstanceInfo.CLASS_INTERFACE; ii.flags |= InstanceInfo.CLASS_SEALED; - 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); + generateClass(iai.importedClasses, new ArrayList<>(), false, new ArrayList<>(), + iai.openedNamespaces, namespace, initScope, pkg, ci, ii, localData, true, iai.name, null, null, iai.superInterfaces, null, null, false, iai.methods, + class_index + ); } return abcIndex.getSelectedAbc().instance_info.size() - 1; @@ -1835,7 +1847,7 @@ public class AVM2SourceGenerator implements SourceGenerator { return null; } - private int genNs(List importedClasses, DottedChain pkg, String custom, int namespace, List openedNamespaces, SourceGeneratorLocalData localData, int line) throws CompilationException { + 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, abcIndex, openedNamespaces, new ArrayList<>()); Reference value = new Reference<>(null); @@ -1878,23 +1890,23 @@ public class AVM2SourceGenerator implements SourceGenerator { return namespace; } - public void generateTraitsPhase2(List importedClasses, DottedChain pkg, List items, Trait[] traits, List openedNamespaces, SourceGeneratorLocalData localData) throws CompilationException { + public void generateTraitsPhase2(List importedClasses, DottedChain pkg, List items, Trait[] traits, List openedNamespaces, SourceGeneratorLocalData localData) throws CompilationException { for (int k = 0; k < items.size(); k++) { GraphTargetItem item = items.get(k); if (traits[k] == null) { } else if (item instanceof InterfaceAVM2Item) { - traits[k].name_index = traitName(((InterfaceAVM2Item) item).namespace, ((InterfaceAVM2Item) item).name); + traits[k].name_index = traitName(((InterfaceAVM2Item) item).pkg == null ? 0 : ((InterfaceAVM2Item) item).pkg.getCpoolIndex(abcIndex.getSelectedAbc().constants), ((InterfaceAVM2Item) item).name); } else if (item instanceof ClassAVM2Item) { - traits[k].name_index = traitName(((ClassAVM2Item) item).namespace, ((ClassAVM2Item) item).className); + traits[k].name_index = traitName(((ClassAVM2Item) item).pkg == null ? 0 : ((ClassAVM2Item) item).pkg.getCpoolIndex(abcIndex.getSelectedAbc().constants), ((ClassAVM2Item) item).className); } else if ((item instanceof MethodAVM2Item) || (item instanceof GetterAVM2Item) || (item instanceof SetterAVM2Item)) { - traits[k].name_index = traitName(genNs(importedClasses, pkg, ((MethodAVM2Item) item).customNamespace, ((MethodAVM2Item) item).namespace, openedNamespaces, localData, ((MethodAVM2Item) item).line), ((MethodAVM2Item) item).functionName); + traits[k].name_index = traitName(genNs(importedClasses, pkg, ((MethodAVM2Item) item).customNamespace, ((MethodAVM2Item) item).pkg == null ? 0 : ((MethodAVM2Item) item).pkg.getCpoolIndex(abcIndex.getSelectedAbc().constants), openedNamespaces, localData, ((MethodAVM2Item) item).line), ((MethodAVM2Item) item).functionName); } else if (item instanceof FunctionAVM2Item) { - traits[k].name_index = traitName(((FunctionAVM2Item) item).namespace, ((FunctionAVM2Item) item).functionName); + traits[k].name_index = traitName(((FunctionAVM2Item) item).pkg == null ? 0 : ((FunctionAVM2Item) item).pkg.getCpoolIndex(abcIndex.getSelectedAbc().constants), ((FunctionAVM2Item) item).functionName); } else if (item instanceof ConstAVM2Item) { - traits[k].name_index = traitName(genNs(importedClasses, pkg, ((ConstAVM2Item) item).customNamespace, ((ConstAVM2Item) item).getNamespace(), openedNamespaces, localData, ((ConstAVM2Item) item).line), ((ConstAVM2Item) item).var); + traits[k].name_index = traitName(genNs(importedClasses, pkg, ((ConstAVM2Item) item).customNamespace, ((ConstAVM2Item) item).pkg == null ? 0 : ((ConstAVM2Item) item).pkg.getCpoolIndex(abcIndex.getSelectedAbc().constants), openedNamespaces, localData, ((ConstAVM2Item) item).line), ((ConstAVM2Item) item).var); } else if (item instanceof SlotAVM2Item) { - traits[k].name_index = traitName(genNs(importedClasses, pkg, ((SlotAVM2Item) item).customNamespace, ((SlotAVM2Item) item).getNamespace(), openedNamespaces, localData, ((SlotAVM2Item) item).line), ((SlotAVM2Item) item).var); + traits[k].name_index = traitName(genNs(importedClasses, pkg, ((SlotAVM2Item) item).customNamespace, ((SlotAVM2Item) item).pkg == null ? 0 : ((SlotAVM2Item) item).pkg.getCpoolIndex(abcIndex.getSelectedAbc().constants), openedNamespaces, localData, ((SlotAVM2Item) item).line), ((SlotAVM2Item) item).var); } } @@ -1910,7 +1922,7 @@ public class AVM2SourceGenerator implements SourceGenerator { Multiname.createQName( false, abcIndex.getSelectedAbc().constants.getStringId(((ClassAVM2Item) item).className, true), - ((ClassAVM2Item) item).namespace), true); + ((ClassAVM2Item) item).pkg.getCpoolIndex(abcIndex.getSelectedAbc().constants)), true); if (((ClassAVM2Item) item).extendsOp != null) { instanceInfo.super_index = typeName(localData, ((ClassAVM2Item) item).extendsOp); @@ -1927,7 +1939,7 @@ public class AVM2SourceGenerator implements SourceGenerator { AVM2ConstantPool constants = abc.constants; InstanceInfo instanceInfo = abc.instance_info.get(((TraitClass) traits[k]).class_info); instanceInfo.name_index = constants.getMultinameId(Multiname.createQName(false, constants.getStringId(((InterfaceAVM2Item) item).name, true), - constants.getNamespaceId(Namespace.KIND_PACKAGE, ((InterfaceAVM2Item) item).pkg, 0, true)), true); + ((InterfaceAVM2Item) item).pkg.getCpoolIndex(constants)), true); instanceInfo.interfaces = new int[((InterfaceAVM2Item) item).superInterfaces.size()]; for (int i = 0; i < ((InterfaceAVM2Item) item).superInterfaces.size(); i++) { @@ -1980,25 +1992,61 @@ public class AVM2SourceGenerator implements SourceGenerator { continue; } if (item instanceof InterfaceAVM2Item) { - 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); + generateClass(((InterfaceAVM2Item) item).pkg.getCpoolIndex(abcIndex.getSelectedAbc().constants), 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.name, localData, (InterfaceAVM2Item) item, class_index); } if (item instanceof ClassAVM2Item) { - 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); + generateClass(((ClassAVM2Item) item).pkg.getCpoolIndex(abcIndex.getSelectedAbc().constants), 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.name, 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(mai.isStatic(), abcIndex.getSelectedAbc().constants.getStringId(localData.pkg.toRawString() + ":" + localData.currentClass + "/" + (mai.isPrivate() ? "private:" : "") + 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(mai.isStatic(), methodName(mai.outsidePackage, localData.pkg, mai.functionName, mai.pkg, className, mai.customNamespace), false, isInterface, new ArrayList<>(), localData.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(false, 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); + ((TraitFunction) traits[k]).method_info = method(false, methodName(false/*?*/, localData.pkg, fai.functionName, fai.pkg, null, null), false, isInterface, new ArrayList<>(), localData.pkg, fai.needsActivation, fai.subvariables, methodInitScope, fai.hasRest, fai.line, className, superName, false, localData, fai.paramTypes, fai.paramNames, fai.paramValues, fai.body, fai.retType); } } } + private int methodName(boolean outsidePkg, DottedChain pkg, String methodName, NamespaceItem ns, String className, String customNs) { + StringBuilder sb = new StringBuilder(); + /*if (ns != null) { + sb.append(ns.name.toRawString()); + }*/ + if (className != null) { + if (pkg != null && !pkg.isEmpty() && !pkg.isTopLevel()) { + sb.append(pkg.toRawString()); + sb.append(":"); + } + sb.append(className); + } + if (customNs != null) { + sb.append(customNs); + } else if (ns != null) { + switch (ns.kind) { + case Namespace.KIND_PACKAGE_INTERNAL: + sb.append(pkg.toRawString()); + break; + case Namespace.KIND_PRIVATE: + + if (!outsidePkg) { + sb.append("/private"); + } + break; + case Namespace.KIND_PROTECTED: + case Namespace.KIND_STATIC_PROTECTED: + sb.append("/protected"); + break; + } + } + sb.append(":"); + sb.append(methodName); + return abcIndex.getSelectedAbc().constants.getStringId(sb.toString(), true); + } + public Trait[] generateTraitsPhase1(String className, String superName, boolean generateStatic, SourceGeneratorLocalData localData, List items, Traits ts, Reference classIndex) throws AVM2ParseException, CompilationException { Trait[] traits = new Trait[items.size()]; int slot_id = 1; @@ -2073,7 +2121,7 @@ public class AVM2SourceGenerator implements SourceGenerator { val = sai.value; type = sai.type; isStatic = sai.isStatic(); - namespace = sai.getNamespace(); + namespace = sai.pkg == null ? 0 : sai.pkg.getCpoolIndex(abcIndex.getSelectedAbc().constants); metadata = generateMetadata(((SlotAVM2Item) item).metadata); } if (item instanceof ConstAVM2Item) { @@ -2084,7 +2132,7 @@ public class AVM2SourceGenerator implements SourceGenerator { var = cai.var; val = cai.value; type = cai.type; - namespace = cai.getNamespace(); + namespace = cai.pkg == null ? 0 : cai.pkg.getCpoolIndex(abcIndex.getSelectedAbc().constants); isNamespace = type.toString().equals("Namespace"); isStatic = cai.isStatic(); metadata = generateMetadata(((ConstAVM2Item) item).metadata); @@ -2115,7 +2163,7 @@ public class AVM2SourceGenerator implements SourceGenerator { tmgs.kindType = (item instanceof GetterAVM2Item) ? Trait.TRAIT_GETTER : ((item instanceof SetterAVM2Item) ? Trait.TRAIT_SETTER : Trait.TRAIT_METHOD); //tmgs.name_index = traitName(((MethodAVM2Item) item).namespace, ((MethodAVM2Item) item).functionName); tmgs.disp_id = mai.isStatic() ? disp_id++ : 0; //For a reason, there is disp_id only for static methods (or not?) - if (mai.isFinal() || mai.isStatic()) { + if (mai.isFinal() || (className != null && mai.isStatic())) { tmgs.kindFlags |= Trait.ATTR_Final; } if (mai.isOverride()) { @@ -2212,12 +2260,45 @@ public class AVM2SourceGenerator implements SourceGenerator { } } - mbCode.add(ins(AVM2Instructions.ReturnVoid)); - mb.autoFillStats(abc, 1, false); abc.addMethodBody(mb); si.init_index = mb.method_info; - localData.pkg = DottedChain.EMPTY; //FIXME: pkg.packageName; + localData.pkg = DottedChain.EMPTY; generateTraitsPhase3(1/*??*/, false, null, null, true, localData, commands, si.traits, traitArr, initScopes, class_index); + + int maxSlotId = 0; + for (int k = 0; k < si.traits.traits.size(); k++) { + if (si.traits.traits.get(k) instanceof TraitSlotConst) { + TraitSlotConst ti = (TraitSlotConst) si.traits.traits.get(k); + if (ti.slot_id > maxSlotId) { + maxSlotId = ti.slot_id; + } + } + } + for (int k = 0; k < si.traits.traits.size(); k++) { + if ((si.traits.traits.get(k) instanceof TraitMethodGetterSetter) && (commands.get(k) instanceof MethodAVM2Item)) { + MethodAVM2Item mai = (MethodAVM2Item) commands.get(k); + if (mai.outsidePackage) { + TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) si.traits.traits.get(k); + TraitSlotConst nts = new TraitSlotConst(); + nts.name_index = si.traits.traits.get(k).name_index; + nts.metadata = si.traits.traits.get(k).metadata; + + nts.slot_id = maxSlotId + 1; + maxSlotId++; + nts.type_index = abcIndex.getSelectedAbc().constants.getQnameId("Function", Namespace.KIND_PACKAGE, "", true); + nts.value_index = 0; + nts.value_kind = 0; + int methodinfo = tmgs.method_info; + si.traits.traits.set(k, nts); + mbCode.add(ins(AVM2Instructions.NewFunction, methodinfo)); + mbCode.add(ins(AVM2Instructions.InitProperty, nts.name_index)); + } + } + } + + mbCode.add(ins(AVM2Instructions.ReturnVoid)); + mb.autoFillStats(abc, 1, false); + return si; } 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 28870550a..88753fe99 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 @@ -38,6 +38,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.NameValuePair; import com.jpexs.decompiler.flash.abc.avm2.model.NanAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.NewArrayAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.model.NewFunctionAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.NewObjectAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.PostDecrementAVM2Item; @@ -145,13 +146,13 @@ public class ActionScript3Parser { return uniqLast; } - private List commands(TypeItem thisType, DottedChain pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, List variables) throws IOException, AVM2ParseException { + private List commands(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, List variables) throws IOException, AVM2ParseException { List ret = new ArrayList<>(); if (debugMode) { System.out.println("commands:"); } GraphTargetItem cmd; - while ((cmd = command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)) != null) { + while ((cmd = command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)) != null) { ret.add(cmd); } if (debugMode) { @@ -160,7 +161,7 @@ public class ActionScript3Parser { return ret; } - private GraphTargetItem type(TypeItem thisType, DottedChain pkg, Reference needsActivation, List importedClasses, List openedNamespaces, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem type(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, List variables) throws IOException, AVM2ParseException { ParsedSymbol s = lex(); if (s.type == SymbolType.MULTIPLY) { return new UnboundedTypeItem(); @@ -170,12 +171,12 @@ public class ActionScript3Parser { lexer.pushback(s); } - GraphTargetItem t = name(thisType, pkg, needsActivation, true, openedNamespaces, null, false, false, variables, importedClasses); - t = applyType(thisType, pkg, needsActivation, importedClasses, openedNamespaces, t, new HashMap<>(), false, false, variables); + GraphTargetItem t = name(allOpenedNamespaces, thisType, pkg, needsActivation, true, openedNamespaces, null, false, false, variables, importedClasses); + t = applyType(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, t, new HashMap<>(), false, false, variables); return t; } - private GraphTargetItem memberOrCall(TypeItem thisType, DottedChain pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem newcmds, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem memberOrCall(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem newcmds, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { if (debugMode) { System.out.println("memberOrCall:"); } @@ -187,15 +188,15 @@ public class ActionScript3Parser { case DOT: case TYPENAME: lexer.pushback(s); - ret = member(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); + ret = member(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); break; case FILTER: needsActivation.setVal(true); - ret = new XMLFilterAVM2Item(ret, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, inMethod, variables), openedNamespaces); + ret = new XMLFilterAVM2Item(ret, expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, inMethod, variables), openedNamespaces); expectedType(SymbolType.PARENT_CLOSE); break; case PARENT_OPEN: - ret = new CallAVM2Item(lexer.yyline(), ret, call(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); + ret = new CallAVM2Item(lexer.yyline(), ret, call(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); break; case DESCENDANTS: s = lex(); @@ -229,7 +230,7 @@ public class ActionScript3Parser { return ret; } - private GraphTargetItem applyType(TypeItem thisType, DottedChain pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem applyType(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { GraphTargetItem ret = obj; ParsedSymbol s = lex(); if (s.type == SymbolType.TYPENAME) { @@ -240,7 +241,7 @@ public class ActionScript3Parser { params.add(new NullAVM2Item(null)); } else { lexer.pushback(s); - params.add(expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables)); + params.add(expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables)); } s = lex(); } while (s.type == SymbolType.COMMA); @@ -261,7 +262,7 @@ public class ActionScript3Parser { return ret; } - private GraphTargetItem member(TypeItem thisType, DottedChain pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem member(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { if (debugMode) { System.out.println("member:"); } @@ -282,10 +283,10 @@ public class ActionScript3Parser { } if (s.type == SymbolType.TYPENAME) { lexer.pushback(s); - ret = applyType(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); + ret = applyType(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); s = lex(); } else if (s.type == SymbolType.BRACKET_OPEN) { - GraphTargetItem index = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem index = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); expectedType(SymbolType.BRACKET_CLOSE); ret = new IndexAVM2Item(attr, ret, index, null, openedNamespaces); s = lex(); @@ -301,7 +302,7 @@ public class ActionScript3Parser { variables.add((UnresolvedAVM2Item) ns); s = lex(); if (s.type == SymbolType.BRACKET_OPEN) { - propItem = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + propItem = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); expectedType(SymbolType.BRACKET_CLOSE); propName = null; } else { @@ -328,7 +329,7 @@ public class ActionScript3Parser { return ret; } - private GraphTargetItem name(TypeItem thisType, DottedChain pkg, Reference needsActivation, boolean typeOnly, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, List importedClasses) throws IOException, AVM2ParseException { + private GraphTargetItem name(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, boolean typeOnly, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, List importedClasses) throws IOException, AVM2ParseException { ParsedSymbol s = lex(); DottedChain name = new DottedChain(); String name2 = ""; @@ -376,7 +377,7 @@ public class ActionScript3Parser { if (s.group == SymbolGroup.IDENTIFIER) { nsprop = s.value.toString(); } else if (s.type == SymbolType.BRACKET_OPEN) { - nspropItem = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + nspropItem = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); expectedType(SymbolType.BRACKET_CLOSE); } name = name.getWithoutLast(); @@ -405,7 +406,7 @@ public class ActionScript3Parser { lexer.pushback(new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.ATTRIBUTE, "@")); lexer.pushback(new ParsedSymbol(SymbolGroup.OPERATOR, SymbolType.DOT, ".")); } - ret = member(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); + ret = member(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); } else { lexer.pushback(s); } @@ -450,7 +451,7 @@ public class ActionScript3Parser { return ret; } - private List call(TypeItem thisType, DottedChain pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + private List call(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { List ret = new ArrayList<>(); //expected(SymbolType.PARENT_OPEN); //MUST BE HANDLED BY CALLER ParsedSymbol s = lex(); @@ -458,21 +459,22 @@ public class ActionScript3Parser { if (s.type != SymbolType.COMMA) { lexer.pushback(s); } - ret.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + ret.add(expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); s = lex(); expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.PARENT_CLOSE); } return ret; } - private MethodAVM2Item method(boolean isPrivate, List>> metadata, DottedChain pkg, boolean isInterface, String customAccess, Reference needsActivation, List importedClasses, boolean override, boolean isFinal, TypeItem thisType, List openedNamespaces, boolean isStatic, int namespace, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException { - FunctionAVM2Item f = function(metadata, pkg, isInterface, needsActivation, importedClasses, namespace, thisType, openedNamespaces, functionName, isMethod, variables); - return new MethodAVM2Item(isPrivate, f.metadata, f.pkg, f.isInterface, customAccess, f.needsActivation, f.hasRest, f.line, override, isFinal, isStatic, f.namespace, functionName, f.paramTypes, f.paramNames, f.paramValues, f.body, f.subvariables, f.retType); + private MethodAVM2Item method(List> allOpenedNamespaces, boolean outsidePackage, boolean isPrivate, List>> metadata, NamespaceItem pkg, boolean isInterface, String customAccess, Reference needsActivation, List importedClasses, boolean override, boolean isFinal, TypeItem thisType, List openedNamespaces, boolean isStatic, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException { + FunctionAVM2Item f = function(allOpenedNamespaces, metadata, pkg, isInterface, needsActivation, importedClasses, thisType, openedNamespaces, functionName, isMethod, variables); + return new MethodAVM2Item(outsidePackage, isPrivate, f.metadata, f.pkg, f.isInterface, customAccess, f.needsActivation, f.hasRest, f.line, override, isFinal, isStatic, functionName, f.paramTypes, f.paramNames, f.paramValues, f.body, f.subvariables, f.retType); } - private FunctionAVM2Item function(List>> metadata, DottedChain pkg, boolean isInterface, Reference needsActivation, List importedClasses, int namespace, TypeItem thisType, List openedNamespaces, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException { + private FunctionAVM2Item function(List> allOpenedNamespaces, List>> metadata, NamespaceItem pkg, boolean isInterface, Reference needsActivation, List importedClasses, TypeItem thisType, List openedNamespaces, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException { openedNamespaces = new ArrayList<>(openedNamespaces); //local copy + allOpenedNamespaces.add(openedNamespaces); int line = lexer.yyline(); ParsedSymbol s; expectedType(SymbolType.PARENT_OPEN); @@ -496,13 +498,13 @@ public class ActionScript3Parser { s = lex(); if (!hasRest) { if (s.type == SymbolType.COLON) { - paramTypes.add(type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables)); + paramTypes.add(type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables)); s = lex(); } else { paramTypes.add(new UnboundedTypeItem()); } if (s.type == SymbolType.ASSIGN) { - paramValues.add(expression(thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, null, isMethod, isMethod, isMethod, variables)); + paramValues.add(expression(allOpenedNamespaces, thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, null, isMethod, isMethod, isMethod, variables)); s = lex(); } else { if (!paramValues.isEmpty()) { @@ -521,7 +523,7 @@ public class ActionScript3Parser { s = lex(); GraphTargetItem retType; if (s.type == SymbolType.COLON) { - retType = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); + retType = type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); } else { retType = new UnboundedTypeItem(); lexer.pushback(s); @@ -540,7 +542,7 @@ public class ActionScript3Parser { Reference needsActivation2 = new Reference<>(false); if (!isInterface) { expectedType(SymbolType.CURLY_OPEN); - body = commands(thisType, pkg, needsActivation2, importedClasses, openedNamespaces, new Stack<>(), new HashMap<>(), new HashMap<>(), true, isMethod, 0, subvariables); + body = commands(allOpenedNamespaces, thisType, pkg, needsActivation2, importedClasses, openedNamespaces, new Stack<>(), new HashMap<>(), new HashMap<>(), true, isMethod, 0, subvariables); expectedType(SymbolType.CURLY_CLOSE); } else { expectedType(SymbolType.SEMICOLON); @@ -549,320 +551,167 @@ public class ActionScript3Parser { for (int i = 0; i < parCnt; i++) { subvariables.remove(0); } - return new FunctionAVM2Item(metadata, pkg, isInterface, needsActivation2.getVal(), namespace, hasRest, line, functionName, paramTypes, paramNames, paramValues, body, subvariables, retType); + return new FunctionAVM2Item(metadata, pkg, isInterface, needsActivation2.getVal(), hasRest, line, functionName, paramTypes, paramNames, paramValues, body, subvariables, retType); } - private GraphTargetItem traits(String scriptName, boolean scriptTraits, List sinitVariables, Reference sinitNeedsActivation, List staticInitializer, List importedClasses, int privateNs, int protectedNs, int publicNs, int packageInternalNs, int protectedStaticNs, List openedNamespaces, DottedChain pkg, String classNameStr, boolean isInterface, List traits) throws AVM2ParseException, IOException, CompilationException { - ParsedSymbol s; - GraphTargetItem constr = null; - TypeItem thisType = pkg == null && classNameStr == null ? null : new TypeItem(pkg == null || pkg.isEmpty() ? new DottedChain(classNameStr) : pkg.add(classNameStr)); - List constrVariables = new ArrayList<>(); - List originalOpenedNamespaces = openedNamespaces; - int originalPrivateNs = privateNs; - boolean inPkg = pkg != null; - int cpos = 0; - int emptyNs = 0; - looptrait: - while (true) { + private List>> parseMetadata() throws IOException, AVM2ParseException { + List>> metadata = new ArrayList<>(); + ParsedSymbol s = lex(); + while (s.isType(SymbolType.BRACKET_OPEN)) { s = lex(); - boolean isStatic = false; - int namespace = -1; + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String name = s.value.toString(); + Map.Entry> en = new AbstractMap.SimpleEntry<>(name, new HashMap()); + s = lex(); + if (s.isType(SymbolType.PARENT_OPEN)) { + s = lex(); + if (s.isType(SymbolGroup.STRING)) { + en.getValue().put("", s.value.toString()); + s = lex(); + } else { + lexer.pushback(s); + do { + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String key = s.value.toString(); + expectedType(SymbolType.ASSIGN); + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.STRING); + String value = s.value.toString(); + en.getValue().put(key, value); + s = lex(); + } while (s.isType(SymbolType.COMMA)); + } + expected(s, lexer.yyline(), SymbolType.PARENT_CLOSE); + s = lex(); + } + metadata.add(en); + expected(s, lexer.yyline(), SymbolType.BRACKET_CLOSE); + s = lex(); + } + lexer.pushback(s); + return metadata; + } + + private void classTraits(List> allOpenedNamespaces, boolean outsidePackage, List cinitVariables, Reference cinitNeedsActivation, List cinit, List importedClasses, List openedNamespaces, NamespaceItem pkg, String classNameStr, boolean isInterface, List traits, List iinitVariables, Reference iinitNeedsActivation, Reference iinit) throws AVM2ParseException, IOException, CompilationException { + + NamespaceItem publicNs = new NamespaceItem("", Namespace.KIND_PACKAGE); + NamespaceItem privateNs = new NamespaceItem(pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_PRIVATE); + NamespaceItem protectedNs = new NamespaceItem(pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_PROTECTED); + NamespaceItem staticProtectedNs = new NamespaceItem(pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_STATIC_PROTECTED); + NamespaceItem packageInternalNs = new NamespaceItem(pkg.name, Namespace.KIND_PACKAGE_INTERNAL); + + openedNamespaces = new ArrayList<>(openedNamespaces); + allOpenedNamespaces.add(openedNamespaces); + for (List ln : allOpenedNamespaces) { + if (!ln.contains(publicNs)) { + ln.add(publicNs); + } + } + openedNamespaces.add(privateNs); + openedNamespaces.add(protectedNs); + openedNamespaces.add(staticProtectedNs); + + looptraits: + while (true) { + TypeItem thisType = new TypeItem(pkg.name.add(classNameStr)); boolean isGetter = false; boolean isSetter = false; boolean isOverride = false; + boolean isStatic = false; boolean isFinal = false; - boolean isDynamic = false; - String customAccess = null; boolean isPrivate = false; - if (scriptTraits && s.type == SymbolType.PACKAGE) { - if (inPkg) { - throw new AVM2ParseException("No subpackages allowed", lexer.yyline()); - } - openedNamespaces = new ArrayList<>(); - lexer.pushback(s); - PackageAVM2Item p = parsePackage(openedNamespaces); - pkg = p.packageName; - inPkg = true; - //publicNs = p.publicNs; - importedClasses = p.importedClasses; - s = lex(); - - //GraphTargetItem ret = null; - //ParsedSymbol s = null; - //List traits = new ArrayList<>(); - //String classNameStr = nameStr; - openedNamespaces = new ArrayList<>(openedNamespaces); - - openedNamespaces.add(publicNs = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PACKAGE, pkg, 0, true)); - //openedNamespaces.add(packageInternalNs = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PACKAGE_INTERNAL, pkg, 0, true)); - - if (pkg != null && !pkg.isEmpty()) { - openedNamespaces.add(packageInternalNs = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PACKAGE_INTERNAL, abcIndex.getSelectedAbc().constants.getStringId(pkg, true), 0, true)); - } else { - openedNamespaces.add(packageInternalNs = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PACKAGE_INTERNAL, abcIndex.getSelectedAbc().constants.getStringId("", true), 0, true)); - } - emptyNs = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PACKAGE, "", 0, true); - if (pkg != null && !pkg.isEmpty()) { //add "" namespace if not already present - openedNamespaces.add(emptyNs); - } - openedNamespaces.add(privateNs = abcIndex.getSelectedAbc().constants.addNamespace(new Namespace(Namespace.KIND_PRIVATE, abcIndex.getSelectedAbc().constants.getStringId(pkg == null ? "" : pkg.toRawString() + ":?"/* + nameStr*/, true)))); - - openedNamespaces.add(abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_NAMESPACE, AS3_NAMESPACE, 0, true)); - - openedNamespaces.add(protectedNs = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PROTECTED, pkg == null ? (scriptName + "$0:"/*FIXME?*/ + classNameStr) : pkg.isTopLevel() ? classNameStr : pkg.toRawString() + ":" + classNameStr, 0, true)); - openedNamespaces.add(protectedStaticNs = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_STATIC_PROTECTED, pkg == null || pkg.isTopLevel() ? classNameStr : pkg.toRawString() + ":" + classNameStr, 0, true)); - } - - List>> metadata = new ArrayList<>(); - while (s.isType(SymbolType.BRACKET_OPEN)) { - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - String name = s.value.toString(); - Map.Entry> en = new AbstractMap.SimpleEntry<>(name, new HashMap()); - s = lex(); - if (s.isType(SymbolType.PARENT_OPEN)) { - s = lex(); - if (s.isType(SymbolGroup.STRING)) { - en.getValue().put("", s.value.toString()); - s = lex(); - } else { - lexer.pushback(s); - do { - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - String key = s.value.toString(); - expectedType(SymbolType.ASSIGN); - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.STRING); - String value = s.value.toString(); - en.getValue().put(key, value); - s = lex(); - } while (s.isType(SymbolType.COMMA)); - } - expected(s, lexer.yyline(), SymbolType.PARENT_CLOSE); - s = lex(); - } - metadata.add(en); - expected(s, lexer.yyline(), SymbolType.BRACKET_CLOSE); - s = lex(); - } - - if (inPkg || classNameStr != null) { - if (s.type == SymbolType.CURLY_OPEN) { - staticInitializer.addAll(commands(thisType, pkg, sinitNeedsActivation, importedClasses, openedNamespaces, new Stack<>(), new HashMap<>(), new HashMap<>(), true, false, 0, sinitVariables)); - expectedType(SymbolType.CURLY_CLOSE); - s = lex(); - } - - while (s.isType(SymbolType.STATIC, SymbolType.PUBLIC, SymbolType.PRIVATE, SymbolType.PROTECTED, SymbolType.OVERRIDE, SymbolType.FINAL, SymbolType.DYNAMIC, SymbolGroup.IDENTIFIER)) { - if (s.type == SymbolType.FINAL) { - if (isFinal) { - throw new AVM2ParseException("Only one final keyword allowed", lexer.yyline()); - } - isFinal = true; - } else if (s.type == SymbolType.DYNAMIC) { - if (isDynamic) { - throw new AVM2ParseException("Only one dynamic keyword allowed", lexer.yyline()); - } - isDynamic = true; - } else if (s.type == SymbolType.OVERRIDE) { - if (isOverride) { - throw new AVM2ParseException("Only one override keyword allowed", lexer.yyline()); - } - isOverride = true; - } else if (s.type == SymbolType.STATIC) { - if (isInterface) { - throw new AVM2ParseException("Interface cannot have static traits", lexer.yyline()); - } - if (classNameStr == null) { - throw new AVM2ParseException("No static keyword allowed here", lexer.yyline()); - } - if (isStatic) { - throw new AVM2ParseException("Only one static keyword allowed", lexer.yyline()); - } - isStatic = true; - } else if (s.type == SymbolType.NAMESPACE) { - break; - } else if (s.type == SymbolType.NATIVE) { - throw new AVM2ParseException("Cannot compile native code", lexer.yyline()); - } else if (s.group == SymbolGroup.IDENTIFIER) { - customAccess = s.value.toString(); - namespace = -2; - } else { - if (namespace != -1) { - throw new AVM2ParseException("Only one access identifier allowed", lexer.yyline()); - } - } - switch (s.type) { - case PUBLIC: - namespace = publicNs; - if (isInterface) { - throw new AVM2ParseException("Interface cannot have public, private or protected modifier", lexer.yyline()); - } - break; - case PRIVATE: - isPrivate = true; - namespace = privateNs; - if (isInterface) { - throw new AVM2ParseException("Interface cannot have public, private or protected modifier", lexer.yyline()); - } - break; - case PROTECTED: - namespace = protectedNs; - if (isInterface) { - throw new AVM2ParseException("Interface cannot have public, private or protected modifier", lexer.yyline()); - } - break; - } - s = lex(); - } + String customNs = null; + NamespaceItem namespace = null; + ParsedSymbol s = lex(); + //static class initializer + if (s.type == SymbolType.CURLY_OPEN) { + cinit.addAll(commands(allOpenedNamespaces, thisType, pkg, cinitNeedsActivation, importedClasses, openedNamespaces, new Stack<>(), new HashMap<>(), new HashMap<>(), true, false, 0, cinitVariables)); + expectedType(SymbolType.CURLY_CLOSE); } else { - namespace = privateNs; + lexer.pushback(s); } - if (namespace == -1) { - if (isInterface) { - namespace = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_NAMESPACE, pkg == null || pkg.isEmpty() ? classNameStr : pkg + ":" + classNameStr, 0, true); - } else { - if (packageInternalNs == 0) { - packageInternalNs = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PACKAGE_INTERNAL, abcIndex.getSelectedAbc().constants.getStringId(pkg == null ? "" : pkg.toRawString(), true), 0, true); + List>> metadata = parseMetadata(); + s = lex(); + + while (s.isType(SymbolType.STATIC, SymbolType.PUBLIC, SymbolType.PRIVATE, SymbolType.PROTECTED, SymbolType.OVERRIDE, SymbolType.FINAL, SymbolType.DYNAMIC, SymbolGroup.IDENTIFIER)) { + if (s.type == SymbolType.FINAL) { + if (isFinal) { + throw new AVM2ParseException("Only one final keyword allowed", lexer.yyline()); + } + isFinal = true; + } else if (s.type == SymbolType.OVERRIDE) { + if (isOverride) { + throw new AVM2ParseException("Only one override keyword allowed", lexer.yyline()); + } + isOverride = true; + } else if (s.type == SymbolType.STATIC) { + if (isInterface) { + throw new AVM2ParseException("Interface cannot have static traits", lexer.yyline()); + } + if (classNameStr == null) { + throw new AVM2ParseException("No static keyword allowed here", lexer.yyline()); + } + if (isStatic) { + throw new AVM2ParseException("Only one static keyword allowed", lexer.yyline()); + } + isStatic = true; + } else if (s.type == SymbolType.NAMESPACE) { + break; + } else if (s.type == SymbolType.NATIVE) { + throw new AVM2ParseException("Cannot compile native code", lexer.yyline()); + } else if (s.group == SymbolGroup.IDENTIFIER) { + customNs = s.value.toString(); + } else { + if (namespace != null) { + throw new AVM2ParseException("Only one access identifier allowed", lexer.yyline()); } - namespace = packageInternalNs; } + switch (s.type) { + case PUBLIC: + namespace = publicNs; + if (isInterface) { + throw new AVM2ParseException("Interface cannot have public, private or protected modifier", lexer.yyline()); + } + break; + case PRIVATE: + isPrivate = true; + namespace = privateNs; + if (isInterface) { + throw new AVM2ParseException("Interface cannot have public, private or protected modifier", lexer.yyline()); + } + break; + case PROTECTED: + namespace = protectedNs; + if (isInterface) { + throw new AVM2ParseException("Interface cannot have public, private or protected modifier", lexer.yyline()); + } + break; + } + s = lex(); + } + if (namespace == null && customNs == null) { + namespace = packageInternalNs; } if (namespace == protectedNs && isStatic) { - namespace = protectedStaticNs; + namespace = staticProtectedNs; } + switch (s.type) { - /*case PACKAGE: - lexer.pushback(s); - traits.add(parsePackage(openedNamespaces)); - break;*/ - case CLASS: - case INTERFACE: - - boolean nisInterface = false; - if (s.type == SymbolType.INTERFACE) { - nisInterface = true; - } - GraphTargetItem extendsTypeStr = null; - List interfaces = new ArrayList<>(); - String subNameStr = null; - List subNamespaces = new ArrayList<>(openedNamespaces); - - if (!nisInterface) { - - if (classNameStr != null) { - throw new AVM2ParseException("Nested classes not supported", lexer.yyline()); - } - if (isOverride) { - throw new AVM2ParseException("Override flag not allowed for classes", lexer.yyline()); - } - - //GraphTargetItem classTypeStr = type(thisType,pkg,needsActivation, importedClasses, openedNamespaces, variables); - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - subNameStr = s.value.toString(); - - s = lex(); - if (s.type == SymbolType.EXTENDS) { - extendsTypeStr = type(thisType, pkg, new Reference<>(false), importedClasses, subNamespaces, new ArrayList<>()); - s = lex(); - } - if (s.type == SymbolType.IMPLEMENTS) { - do { - GraphTargetItem implementsTypeStr = type(thisType, pkg, new Reference<>(false), importedClasses, subNamespaces, new ArrayList<>()); - interfaces.add(implementsTypeStr); - s = lex(); - } while (s.type == SymbolType.COMMA); - } - expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); - if (customAccess != null) { - throw new AVM2ParseException("Class cannot have custom namespace", lexer.yyline()); - } - } else { - if (classNameStr != null) { - throw new AVM2ParseException("Nested interfaces not supported", lexer.yyline()); - } - if (isOverride) { - throw new AVM2ParseException("Override flag not allowed for interfaces", lexer.yyline()); - } - if (isFinal) { - throw new AVM2ParseException("Final flag not allowed for interfaces", lexer.yyline()); - } - if (isDynamic) { - throw new AVM2ParseException("Dynamic flag not allowed for interfaces", lexer.yyline()); - } - //GraphTargetItem interfaceTypeStr = type(thisType,pkg,needsActivation, importedClasses, openedNamespaces, variables); - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - subNameStr = s.value.toString(); - s = lex(); - - if (s.type == SymbolType.EXTENDS) { - do { - GraphTargetItem intExtendsTypeStr = type(thisType, pkg, new Reference<>(false), importedClasses, subNamespaces, new ArrayList<>()); - interfaces.add(intExtendsTypeStr); - s = lex(); - } while (s.type == SymbolType.COMMA); - } - expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); - if (customAccess != null) { - throw new AVM2ParseException("Interface cannot have custom namespace", lexer.yyline()); - } - - } - - if (extendsTypeStr != null) { - List indices = new ArrayList<>(); - List names = new ArrayList<>(); - List namespaces = new ArrayList<>(); - //FIXME for Private classes in script!!! - AVM2SourceGenerator.parentNamesAddNames(abcIndex, AVM2SourceGenerator.resolveType(new SourceGeneratorLocalData(new HashMap<>(), 0, false, 0), ((TypeItem) ((UnresolvedAVM2Item) extendsTypeStr).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) == null || namespaces.get(i).isEmpty()) { - continue; - } - openedNamespaces.add(abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_STATIC_PROTECTED, namespaces.get(i) + ":" + names.get(i), 0, true)); - } - } - Reference staticNeedsActivation = new Reference<>(false); - List staticInit = new ArrayList<>(); - List sinit2Variables = new ArrayList<>(); - List traits2 = new ArrayList<>(); - GraphTargetItem constr2 = traits(scriptName, false, sinit2Variables, staticNeedsActivation, staticInit, importedClasses, privateNs, protectedNs, emptyNs, packageInternalNs, protectedStaticNs, subNamespaces, pkg, subNameStr, nisInterface, traits2); - - if (nisInterface) { - traits.add(new InterfaceAVM2Item(metadata, importedClasses, pkg, subNamespaces, isFinal, namespace, subNameStr, interfaces, traits2)); - } else { - traits.add(new ClassAVM2Item(metadata, importedClasses, pkg, subNamespaces, privateNs, protectedNs, isDynamic, isFinal, namespace, subNameStr, extendsTypeStr, interfaces, staticInit, staticNeedsActivation.getVal(), sinit2Variables, constr2, traits2)); - } - - // traits.add((classTraits(metadata, scriptName, publicNs, pkg, importedClasses, isDynamic, isFinal, subNamespaces, pkg, namespace, false, classTypeStr, extendsTypeStr, implementsTypeStrs, new ArrayList<>()))); - expectedType(SymbolType.CURLY_CLOSE); - break; case FUNCTION: - - if (isDynamic) { - throw new AVM2ParseException("Dynamic flag not allowed for methods", lexer.yyline()); - } s = lex(); if (s.type == SymbolType.GET) { - if (classNameStr == null) { - throw new AVM2ParseException("No get keyword allowed here", lexer.yyline()); - } isGetter = true; s = lex(); } else if (s.type == SymbolType.SET) { - if (classNameStr == null) { - throw new AVM2ParseException("No set keyword allowed here", lexer.yyline()); - } isSetter = true; s = lex(); } - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.PARENT_OPEN); String fname = null; + + //fix for methods with name "get" or "set" - they are not getters/setters! if (s.isType(SymbolType.PARENT_OPEN)) { lexer.pushback(s); if (isGetter) { @@ -877,10 +726,7 @@ public class ActionScript3Parser { } else { fname = s.value.toString(); } - if (classNameStr != null && fname.equals(classNameStr)) { //constructor - if (isStatic) { - throw new AVM2ParseException("Constructor cannot be static", lexer.yyline()); - } + if (fname.equals(classNameStr)) { //constructor if (isStatic) { throw new AVM2ParseException("Constructor cannot be static", lexer.yyline()); } @@ -893,14 +739,14 @@ public class ActionScript3Parser { if (isInterface) { throw new AVM2ParseException("Interface cannot have constructor", lexer.yyline()); } - constr = (method(isPrivate, metadata, pkg, false, customAccess, new Reference<>(false), importedClasses, false, false, thisType, openedNamespaces, false, namespace, "", true, constrVariables)); + iinit.setVal(method(allOpenedNamespaces, outsidePackage, isPrivate, metadata, pkg, false, customNs, iinitNeedsActivation, importedClasses, false, false, thisType, openedNamespaces, false, "", true, iinitVariables)); } else { GraphTargetItem t; if (classNameStr == null) { isStatic = true; } { - MethodAVM2Item ft = method(isPrivate, metadata, pkg, isInterface, customAccess, new Reference<>(false), importedClasses, isOverride, isFinal, thisType, openedNamespaces, isStatic, namespace, fname, true, new ArrayList<>()); + MethodAVM2Item ft = method(allOpenedNamespaces, outsidePackage, isPrivate, metadata, namespace, isInterface, customNs, new Reference<>(false), importedClasses, isOverride, isFinal, thisType, openedNamespaces, isStatic, fname, true, new ArrayList<>()); if (isGetter) { if (!ft.paramTypes.isEmpty()) { @@ -920,10 +766,10 @@ public class ActionScript3Parser { } } if (isGetter) { - GetterAVM2Item g = new GetterAVM2Item(ft.isPrivate(), ft.metadata, ft.pkg, isInterface, customAccess, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); + GetterAVM2Item g = new GetterAVM2Item(outsidePackage, ft.isPrivate(), ft.metadata, ft.pkg, isInterface, customNs, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); t = g; } else if (isSetter) { - SetterAVM2Item st = new SetterAVM2Item(ft.isPrivate(), ft.metadata, ft.pkg, isInterface, customAccess, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); + SetterAVM2Item st = new SetterAVM2Item(outsidePackage, ft.isPrivate(), ft.metadata, ft.pkg, isInterface, customNs, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); t = st; } else { t = ft; @@ -955,13 +801,13 @@ public class ActionScript3Parser { nval = s.value.toString(); s = lex(); } else { - nval = (pkg == null || pkg.isEmpty() || pkg.isTopLevel() ? classNameStr : pkg + ":" + classNameStr) + "/" + nname; + nval = (pkg.name.toRawString() + ":" + classNameStr) + "/" + nname; } if (s.type != SymbolType.SEMICOLON) { lexer.pushback(s); } - ConstAVM2Item ns = new ConstAVM2Item(metadata, pkg, customAccess, true, namespace, nname, new TypeItem(DottedChain.NAMESPACE), new StringAVM2Item(null, nval), lexer.yyline()); + ConstAVM2Item ns = new ConstAVM2Item(metadata, namespace, customNs, true, nname, new TypeItem(DottedChain.NAMESPACE), new StringAVM2Item(null, nval), lexer.yyline()); traits.add(ns); break; case CONST: @@ -973,9 +819,6 @@ public class ActionScript3Parser { if (isFinal) { throw new AVM2ParseException("Final flag not allowed for " + (isConst ? "consts" : "vars"), lexer.yyline()); } - if (isDynamic) { - throw new AVM2ParseException("Dynamic flag not allowed for " + (isConst ? "consts" : "vars"), lexer.yyline()); - } if (isInterface) { throw new AVM2ParseException("Interface cannot have variable/const fields", lexer.yyline()); } @@ -986,7 +829,7 @@ public class ActionScript3Parser { s = lex(); GraphTargetItem type; if (s.type == SymbolType.COLON) { - type = type(thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, new ArrayList<>()); + type = type(allOpenedNamespaces, thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, new ArrayList<>()); s = lex(); } else { type = TypeItem.UNBOUNDED; @@ -995,14 +838,14 @@ public class ActionScript3Parser { GraphTargetItem value = null; if (s.type == SymbolType.ASSIGN) { - value = expression(thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, new HashMap<>(), false, false, true, isStatic || isConst ? sinitVariables : constrVariables); + value = expression(allOpenedNamespaces, thisType, pkg, new Reference<>(false), importedClasses, openedNamespaces, new HashMap<>(), false, false, true, isStatic || isConst ? cinitVariables : iinitVariables); s = lex(); } GraphTargetItem tar; if (isConst) { - tar = new ConstAVM2Item(metadata, pkg, customAccess, isStatic, namespace, vcname, type, value, lexer.yyline()); + tar = new ConstAVM2Item(metadata, namespace, customNs, isStatic, vcname, type, value, lexer.yyline()); } else { - tar = new SlotAVM2Item(metadata, pkg, customAccess, isStatic, namespace, vcname, type, value, lexer.yyline()); + tar = new SlotAVM2Item(metadata, namespace, customNs, isStatic, vcname, type, value, lexer.yyline()); } traits.add(tar); if (s.type != SymbolType.SEMICOLON) { @@ -1010,24 +853,261 @@ public class ActionScript3Parser { } break; default: - if (s.type == SymbolType.CURLY_CLOSE && inPkg && classNameStr == null) { - inPkg = true; - openedNamespaces = new ArrayList<>(); - privateNs = originalPrivateNs; - packageInternalNs = originalPrivateNs; - publicNs = privateNs; - //publicNs = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId("")), 0); - List newOpenedNs = new ArrayList<>(); - importedClasses = parseImports(newOpenedNs); - pkg = DottedChain.TOPLEVEL; - } else { - lexer.pushback(s); - break looptrait; - } - + lexer.pushback(s); + break looptraits; } } - return constr; + } + + private void scriptTraits(int scriptIndex, String scriptName, List traits) throws AVM2ParseException, IOException, CompilationException { + List> allOpenedNamespaces = new ArrayList<>(); + while (scriptTraitsBlock(allOpenedNamespaces, scriptIndex, scriptName, traits)) { + //empty + } + } + + private boolean scriptTraitsBlock(List> allOpenedNamespaces, int scriptIndex, String scriptName, List traits) throws AVM2ParseException, IOException, CompilationException { + ParsedSymbol s; + boolean inPackage = false; + s = lex(); + List sinitVariables = new ArrayList<>(); + NamespaceItem publicNs; + NamespaceItem packageInternalNs; + if (s.type == SymbolType.PACKAGE) { + DottedChain pkgName = DottedChain.TOPLEVEL; + s = lex(); + if (s.type != SymbolType.CURLY_OPEN) { + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + pkgName = pkgName.add(s.value.toString()); + s = lex(); + } + while (s.type == SymbolType.DOT) { + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + pkgName = pkgName.add(s.value.toString()); + s = lex(); + } + expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); + publicNs = new NamespaceItem(pkgName, Namespace.KIND_PACKAGE); + packageInternalNs = new NamespaceItem(pkgName, Namespace.KIND_PACKAGE_INTERNAL); + s = lex(); + inPackage = true; + } else { + publicNs = null; + packageInternalNs = new NamespaceItem(scriptName + "$" + scriptIndex, Namespace.KIND_PRIVATE); + } + lexer.pushback(s); + + List openedNamespaces = new ArrayList<>(); + allOpenedNamespaces.add(openedNamespaces); + NamespaceItem emptyNs = new NamespaceItem("", Namespace.KIND_PACKAGE); + openedNamespaces.add(emptyNs); + openedNamespaces.add(new NamespaceItem(AS3_NAMESPACE, Namespace.KIND_NAMESPACE)); + + for (List ln : allOpenedNamespaces) { + if (publicNs != null && !ln.contains(publicNs)) { + ln.add(publicNs); + } + if (!ln.contains(packageInternalNs)) { + ln.add(packageInternalNs); + } + } + + List importedClasses = parseImports(openedNamespaces); + + boolean isEmpty = true; + + looptrait: + while (true) { + List>> metadata = parseMetadata(); + s = lex(); + boolean isFinal = false; + boolean isDynamic = false; + boolean isPublic = false; + NamespaceItem ns = packageInternalNs; + while (s.isType(SymbolType.FINAL, SymbolType.DYNAMIC, SymbolType.PUBLIC)) { + if (s.type == SymbolType.FINAL) { + if (isFinal) { + throw new AVM2ParseException("Only one final keyword allowed", lexer.yyline()); + } + isFinal = true; + } + if (s.type == SymbolType.PUBLIC) { + if (!inPackage) { + throw new AVM2ParseException("public only allowed inside package", lexer.yyline()); + + } + if (isPublic) { + throw new AVM2ParseException("Only one public keyword allowed", lexer.yyline()); + } + isPublic = true; + ns = publicNs; + } + if (s.type == SymbolType.DYNAMIC) { + if (isDynamic) { + throw new AVM2ParseException("Only one dynamic keyword allowed", lexer.yyline()); + } + isDynamic = true; + } + s = lex(); + } + + switch (s.type) { + case CLASS: + case INTERFACE: + isEmpty = false; + List subOpenedNamespaces = new ArrayList<>(openedNamespaces); + boolean isInterface = false; + if (s.type == SymbolType.INTERFACE) { + isInterface = true; + } + GraphTargetItem extendsTypeStr = null; + List interfaces = new ArrayList<>(); + String subNameStr; + + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + subNameStr = s.value.toString(); + s = lex(); + if (!isInterface) { + + if (s.type == SymbolType.EXTENDS) { + extendsTypeStr = type(allOpenedNamespaces, null, ns, new Reference<>(false), importedClasses, openedNamespaces, new ArrayList<>()); + s = lex(); + } + if (s.type == SymbolType.IMPLEMENTS) { + do { + GraphTargetItem implementsTypeStr = type(allOpenedNamespaces, null, ns, new Reference<>(false), importedClasses, openedNamespaces, new ArrayList<>()); + interfaces.add(implementsTypeStr); + s = lex(); + } while (s.type == SymbolType.COMMA); + } + expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); + } else { + if (s.type == SymbolType.EXTENDS) { + do { + GraphTargetItem intExtendsTypeStr = type(allOpenedNamespaces, null, ns, new Reference<>(false), importedClasses, openedNamespaces, new ArrayList<>()); + interfaces.add(intExtendsTypeStr); + s = lex(); + } while (s.type == SymbolType.COMMA); + } + expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); + } + + if (extendsTypeStr != null) { + List indices = new ArrayList<>(); + List names = new ArrayList<>(); + List namespaces = new ArrayList<>(); + //FIXME for Private classes in script (?) + AVM2SourceGenerator.parentNamesAddNames(abcIndex, AVM2SourceGenerator.resolveType(new SourceGeneratorLocalData(new HashMap<>(), 0, false, 0), ((TypeItem) ((UnresolvedAVM2Item) extendsTypeStr).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) == null || namespaces.get(i).isEmpty()) { + continue; + } + subOpenedNamespaces.add(new NamespaceItem(namespaces.get(i) + ":" + names.get(i), Namespace.KIND_STATIC_PROTECTED)); + } + } + + List cinit = new ArrayList<>(); + Reference cinitNeedsActivation = new Reference<>(false); + + Reference iinit = new Reference<>(null); + List cinitVariables = new ArrayList<>(); + List iinitVariables = new ArrayList<>(); + Reference iinitNeedsActivation = new Reference<>(false); + + List subTraits = new ArrayList<>(); + + classTraits(allOpenedNamespaces, !inPackage, cinitVariables, cinitNeedsActivation, cinit, importedClasses, subOpenedNamespaces, ns, subNameStr, isInterface, subTraits, iinitVariables, iinitNeedsActivation, iinit); + + if (isInterface) { + traits.add(new InterfaceAVM2Item(metadata, importedClasses, ns, subOpenedNamespaces, isFinal, subNameStr, interfaces, subTraits)); + } else { + traits.add(new ClassAVM2Item(metadata, importedClasses, ns, subOpenedNamespaces, isFinal, isDynamic, subNameStr, extendsTypeStr, interfaces, cinit, cinitNeedsActivation.getVal(), cinitVariables, iinit.getVal(), iinitVariables, subTraits, iinitNeedsActivation.getVal())); + } + + expectedType(SymbolType.CURLY_CLOSE); + break; + case FUNCTION: + isEmpty = false; + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String fname = s.value.toString(); + + traits.add(method(allOpenedNamespaces, !inPackage, false, metadata, ns, false, null, new Reference<>(false), importedClasses, false, isFinal, null, openedNamespaces, true, fname, true, new ArrayList<>())); + break; + case CONST: + case VAR: + isEmpty = false; + boolean isConst = s.type == SymbolType.CONST; + if (isFinal) { + throw new AVM2ParseException("Final flag not allowed for " + (isConst ? "consts" : "vars"), lexer.yyline()); + } + + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String vcname = s.value.toString(); + s = lex(); + GraphTargetItem type; + if (s.type == SymbolType.COLON) { + type = type(allOpenedNamespaces, null, ns, new Reference<>(false), importedClasses, openedNamespaces, new ArrayList<>()); + s = lex(); + } else { + type = TypeItem.UNBOUNDED; + } + + GraphTargetItem value = null; + + if (s.type == SymbolType.ASSIGN) { + value = expression(allOpenedNamespaces, null, ns, new Reference<>(false), importedClasses, openedNamespaces, new HashMap<>(), false, false, true, sinitVariables); + s = lex(); + } + GraphTargetItem tar; + if (isConst) { + tar = new ConstAVM2Item(metadata, ns, null, false, vcname, type, value, lexer.yyline()); + } else { + tar = new SlotAVM2Item(metadata, ns, null, false, vcname, type, value, lexer.yyline()); + } + traits.add(tar); + if (s.type != SymbolType.SEMICOLON) { + lexer.pushback(s); + } + break; + case NAMESPACE: + isEmpty = false; + if (isFinal) { + throw new AVM2ParseException("Final flag not allowed for namespaces", lexer.yyline()); + } + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + String nname = s.value.toString(); + String nval; + s = lex(); + + if (s.type == SymbolType.ASSIGN) { + s = lex(); + expected(s, lexer.yyline(), SymbolType.STRING); + nval = s.value.toString(); + s = lex(); + } else { + nval = ns + "/" + nname; + } + if (s.type != SymbolType.SEMICOLON) { + lexer.pushback(s); + } + + traits.add(new ConstAVM2Item(metadata, ns, null, true, nname, new TypeItem(DottedChain.NAMESPACE), new StringAVM2Item(null, nval), lexer.yyline())); + break; + default: + lexer.pushback(s); + break looptrait; + } + + } + if (inPackage) { + expectedType(SymbolType.CURLY_CLOSE); + } + return !isEmpty; } private GraphTargetItem expressionCommands(ParsedSymbol s, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, List variables) throws IOException, AVM2ParseException { @@ -1035,7 +1115,7 @@ public class ActionScript3Parser { switch (s.type) { /*case INT: expectedType(SymbolType.PARENT_OPEN); - ret = new ToIntegerAVM2Item(null, expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); + ret = new ToIntegerAVM2Item(null, expression(allOpenedNamespaces, thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.PARENT_CLOSE); break; case NUMBER_OP: @@ -1043,10 +1123,10 @@ public class ActionScript3Parser { if (s.type == SymbolType.DOT) { VariableAVM2Item vi = new VariableAVM2Item(s.value.toString(), null, false); variables.add(vi); - ret = memberOrCall(thisType,vi, registerVars, inFunction, inMethod, variables); + ret = memberOrCall(allOpenedNamespaces, thisType,vi, registerVars, inFunction, inMethod, variables); } else { expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); - ret = new ToNumberAVM2Item(null, expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); + ret = new ToNumberAVM2Item(null, expression(allOpenedNamespaces, thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.PARENT_CLOSE); } break; @@ -1057,12 +1137,12 @@ public class ActionScript3Parser { lexer.pushback(s); VariableAVM2Item vi2 = new VariableAVM2Item(sop.value.toString(), null, false); variables.add(vi2); - ret = memberOrCall(thisType,vi2, registerVars, inFunction, inMethod, variables); + ret = memberOrCall(allOpenedNamespaces, thisType,vi2, registerVars, inFunction, inMethod, variables); } else { expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); - ret = new ToStringAVM2Item(null, expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); + ret = new ToStringAVM2Item(null, expression(allOpenedNamespaces, thisType,pkg,needsActivation, importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.PARENT_CLOSE); - ret = memberOrCall(thisType,ret, registerVars, inFunction, inMethod, variables); + ret = memberOrCall(allOpenedNamespaces, thisType,ret, registerVars, inFunction, inMethod, variables); } break;*/ default: @@ -1127,7 +1207,7 @@ public class ActionScript3Parser { } } - private List xmltag(TypeItem thisType, DottedChain pkg, Reference usesVars, List openedTags, Reference closedVarTags, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + private List xmltag(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference usesVars, List openedTags, Reference closedVarTags, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { ParsedSymbol s; List rets = new ArrayList<>(); //GraphTargetItem ret = null; @@ -1142,7 +1222,7 @@ public class ActionScript3Parser { case XML_ATTRNAMEVAR_BEGIN: //add usesVars.setVal(true); addS(rets, sb); - rets.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + rets.add(expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.CURLY_CLOSE); expectedType(SymbolType.ASSIGN); sb.append("="); @@ -1152,7 +1232,7 @@ public class ActionScript3Parser { usesVars.setVal(true); sb.append("\""); addS(rets, sb); - rets.add(new EscapeXAttrAVM2Item(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables))); + rets.add(new EscapeXAttrAVM2Item(null, expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables))); sb.append("\""); expectedType(SymbolType.CURLY_CLOSE); lexer.yybegin(ActionScriptLexer.XMLOPENTAG); @@ -1160,7 +1240,7 @@ public class ActionScript3Parser { case XML_INSTRATTRNAMEVAR_BEGIN: //add usesVars.setVal(true); addS(rets, sb); - rets.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + rets.add(expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.CURLY_CLOSE); expectedType(SymbolType.ASSIGN); sb.append("="); @@ -1170,7 +1250,7 @@ public class ActionScript3Parser { usesVars.setVal(true); sb.append("\""); addS(rets, sb); - rets.add(new EscapeXAttrAVM2Item(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables))); + rets.add(new EscapeXAttrAVM2Item(null, expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables))); sb.append("\""); expectedType(SymbolType.CURLY_CLOSE); lexer.yybegin(ActionScriptLexer.XMLOPENTAG); @@ -1178,7 +1258,7 @@ public class ActionScript3Parser { case XML_VAR_BEGIN: //esc_xelem usesVars.setVal(true); addS(rets, sb); - rets.add(new EscapeXElemAVM2Item(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables))); + rets.add(new EscapeXElemAVM2Item(null, expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables))); expectedType(SymbolType.CURLY_CLOSE); lexer.yybegin(ActionScriptLexer.XML); break; @@ -1188,7 +1268,7 @@ public class ActionScript3Parser { sb.append(""); @@ -1199,14 +1279,14 @@ public class ActionScript3Parser { //openedTags.add("*"); //ret = add(ret, ); - GraphTargetItem ex = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem ex = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); expectedType(SymbolType.CURLY_CLOSE); lexer.yybegin(ActionScriptLexer.XMLOPENTAG); sub.add("*"); sb.append("<"); addS(rets, sb); rets.add(ex); - rets.addAll(xmltag(thisType, pkg, subusesvars, sub, subclose, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); + rets.addAll(xmltag(allOpenedNamespaces, thisType, pkg, subusesvars, sub, subclose, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); closedVarTags.setVal(subclose.getVal() + subclose.getVal()); break; case XML_INSTRVARTAG_BEGIN: //add @@ -1214,13 +1294,13 @@ public class ActionScript3Parser { addS(rets, sb); sb.append(" st = xmltag(thisType, pkg, subusesvars, sub, closedVarTags, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables); + List st = xmltag(allOpenedNamespaces, thisType, pkg, subusesvars, sub, closedVarTags, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables); sb.append(s.value.toString()); addS(rets, sb); rets.addAll(st); @@ -1256,18 +1336,18 @@ public class ActionScript3Parser { return rets; } - private GraphTargetItem xml(TypeItem thisType, DottedChain pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem xml(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { List openedTags = new ArrayList<>(); int closedVarTags = 0; - GraphTargetItem ret = add(xmltag(thisType, pkg, new Reference<>(false), openedTags, new Reference<>(closedVarTags), needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); + GraphTargetItem ret = add(xmltag(allOpenedNamespaces, thisType, pkg, new Reference<>(false), openedTags, new Reference<>(closedVarTags), needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); ret = new XMLAVM2Item(ret); lexer.yybegin(ActionScriptLexer.YYINITIAL); //TODO: Order of additions as in official compiler return ret; } - private GraphTargetItem command(TypeItem thisType, DottedChain pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, boolean mustBeCommand, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem command(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, boolean mustBeCommand, List variables) throws IOException, AVM2ParseException { LexBufferer buf = new LexBufferer(); lexer.addListener(buf); GraphTargetItem ret = null; @@ -1300,7 +1380,7 @@ public class ActionScript3Parser { } else { expectedType(SymbolType.NAMESPACE); expectedType(SymbolType.ASSIGN); - GraphTargetItem ns = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem ns = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); ret = new DefaultXMLNamespace(null, ns); //TODO: use dxns for attribute namespaces instead of dxnslate } @@ -1310,20 +1390,20 @@ public class ActionScript3Parser { switch (s.type) { case USE: expectedType(SymbolType.NAMESPACE); - GraphTargetItem ns = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); - openedNamespaces.add(abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PACKAGE /*FIXME?*/, ns.toString(), 0, true)); + GraphTargetItem ns = type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); + openedNamespaces.add(new NamespaceItem(ns.toString(), Namespace.KIND_PACKAGE /*FIXME?*/)); break; case WITH: needsActivation.setVal(true); expectedType(SymbolType.PARENT_OPEN); - GraphTargetItem wvar = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//(name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables)); + GraphTargetItem wvar = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//(name(allOpenedNamespaces, thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables)); if (!isNameOrProp(wvar)) { throw new AVM2ParseException("Not a property or name", lexer.yyline()); } expectedType(SymbolType.PARENT_CLOSE); expectedType(SymbolType.CURLY_OPEN); List withVars = new ArrayList<>(); - List wcmd = commands(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, withVars); + List wcmd = commands(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, withVars); variables.addAll(withVars); for (AssignableAVM2Item a : withVars) { if (a instanceof UnresolvedAVM2Item) { @@ -1336,7 +1416,7 @@ public class ActionScript3Parser { ((WithAVM2Item) ret).subvariables = withVars; break; /*case DELETE: - GraphTargetItem varDel = expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); + GraphTargetItem varDel = expression(allOpenedNamespaces, thisType,pkg,needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(allOpenedNamespaces, thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); if(!isNameOrProp(varDel)){ throw new ParseException("Not a property or name", lexer.yyline()); } @@ -1354,7 +1434,7 @@ public class ActionScript3Parser { s = lexer.lex(); expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); needsActivation.setVal(true); - ret = (function(new ArrayList<>(), pkg, false, needsActivation, importedClasses, 0/*?*/, thisType, openedNamespaces, s.value.toString(), false, variables)); + ret = (function(allOpenedNamespaces, new ArrayList<>(), pkg, false, needsActivation, importedClasses, thisType, openedNamespaces, s.value.toString(), false, variables)); break; case VAR: s = lex(); @@ -1363,14 +1443,14 @@ public class ActionScript3Parser { s = lex(); GraphTargetItem type; if (s.type == SymbolType.COLON) { - type = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); + type = type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); s = lex(); } else { type = new UnboundedTypeItem(); } if (s.type == SymbolType.ASSIGN) { - GraphTargetItem varval = (expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + GraphTargetItem varval = (expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); ret = new NameAVM2Item(type, lexer.yyline(), varIdentifier, varval, true, openedNamespaces); variables.add((NameAVM2Item) ret); } else { @@ -1380,12 +1460,12 @@ public class ActionScript3Parser { } break; case CURLY_OPEN: - ret = new BlockItem(null, commands(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); + ret = new BlockItem(null, commands(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); expectedType(SymbolType.CURLY_CLOSE); break; /*case INCREMENT: //preincrement case DECREMENT: //predecrement - GraphTargetItem varincdec = expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); + GraphTargetItem varincdec = expression(allOpenedNamespaces, thisType,pkg,needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(allOpenedNamespaces, thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); if(!isNameOrProp(varincdec)){ throw new ParseException("Not a property or name", lexer.yyline()); } @@ -1398,7 +1478,7 @@ public class ActionScript3Parser { case SUPER: //constructor call ParsedSymbol ss2 = lex(); if (ss2.type == SymbolType.PARENT_OPEN) { - List args = call(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables); + List args = call(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables); ret = new ConstructSuperAVM2Item(null, new LocalRegAVM2Item(null, 0, null), args); } else {//no costructor call, but it could be calling parent methods... => handle in expression lexer.pushback(ss2); @@ -1407,16 +1487,16 @@ public class ActionScript3Parser { break; case IF: expectedType(SymbolType.PARENT_OPEN); - GraphTargetItem ifExpr = (expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + GraphTargetItem ifExpr = (expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.PARENT_CLOSE); - GraphTargetItem onTrue = command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); + GraphTargetItem onTrue = command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); List onTrueList = new ArrayList<>(); onTrueList.add(onTrue); s = lex(); List onFalseList = null; if (s.type == SymbolType.ELSE) { onFalseList = new ArrayList<>(); - onFalseList.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + onFalseList.add(command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); } else { lexer.pushback(s); } @@ -1425,7 +1505,7 @@ public class ActionScript3Parser { case WHILE: expectedType(SymbolType.PARENT_OPEN); List whileExpr = new ArrayList<>(); - whileExpr.add(commaExpression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); + whileExpr.add(commaExpression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); expectedType(SymbolType.PARENT_CLOSE); List whileBody = new ArrayList<>(); Loop wloop = new Loop(uniqId(), null, null); @@ -1433,7 +1513,7 @@ public class ActionScript3Parser { loopLabels.put(wloop, loopLabel); } loops.push(wloop); - whileBody.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + whileBody.add(command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); ret = new WhileItem(null, wloop, whileExpr, whileBody); break; case DO: @@ -1443,11 +1523,11 @@ public class ActionScript3Parser { if (loopLabel != null) { loopLabels.put(dloop, loopLabel); } - doBody.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + doBody.add(command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); expectedType(SymbolType.WHILE); expectedType(SymbolType.PARENT_OPEN); List doExpr = new ArrayList<>(); - doExpr.add(commaExpression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); + doExpr.add(commaExpression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); expectedType(SymbolType.PARENT_CLOSE); ret = new DoWhileItem(null, dloop, doBody, doExpr); break; @@ -1462,11 +1542,11 @@ public class ActionScript3Parser { s = lex(); } expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); - GraphTargetItem firstCommand = command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, false, variables); + GraphTargetItem firstCommand = command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, false, variables); if (firstCommand instanceof NameAVM2Item) { NameAVM2Item nai = (NameAVM2Item) firstCommand; if (nai.isDefinition() && nai.getAssignedValue() == null) { //Declared value in for..in - firstCommand = expression1(firstCommand, GraphTargetItem.NOPRECEDENCE, thisType, pkg, needsActivation, importedClasses, openedNamespaces, true, registerVars, inFunction, inMethod, true, variables); + firstCommand = expression1(allOpenedNamespaces, firstCommand, GraphTargetItem.NOPRECEDENCE, thisType, pkg, needsActivation, importedClasses, openedNamespaces, true, registerVars, inFunction, inMethod, true, variables); } } InAVM2Item inexpr = null; @@ -1493,21 +1573,21 @@ public class ActionScript3Parser { forFirstCommands.add(firstCommand); } while (s.isType(SymbolType.COMMA)) { - forFirstCommands.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, false, variables)); + forFirstCommands.add(command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, false, variables)); s = lex(); } lexer.pushback(s); //GraphTargetItem firstCommand = command(thisType,pkg,needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); - forExpr = (expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + forExpr = (expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.SEMICOLON); - GraphTargetItem fcom = command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); + GraphTargetItem fcom = command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); if (fcom != null) { forFinalCommands.add(fcom); } } expectedType(SymbolType.PARENT_CLOSE); List forBody = new ArrayList<>(); - forBody.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forin ? forinlevel + 1 : forinlevel, true, variables)); + forBody.add(command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forin ? forinlevel + 1 : forinlevel, true, variables)); if (forin) { if (each) { ret = new ForEachInAVM2Item(null, floop, inexpr, forBody); @@ -1526,7 +1606,7 @@ public class ActionScript3Parser { loopLabels.put(sloop, loopLabel); } expectedType(SymbolType.PARENT_OPEN); - GraphTargetItem switchExpr = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem switchExpr = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); expectedType(SymbolType.PARENT_CLOSE); expectedType(SymbolType.CURLY_OPEN); s = lex(); @@ -1546,7 +1626,7 @@ public class ActionScript3Parser { int pos = 0; while (s.type == SymbolType.CASE) { while (s.type == SymbolType.CASE) { - GraphTargetItem curCaseExpr = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem curCaseExpr = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); expectedType(SymbolType.COLON); s = lex(); caseExprsAll.add(curCaseExpr); @@ -1554,14 +1634,14 @@ public class ActionScript3Parser { } pos++; lexer.pushback(s); - List caseCmd = commands(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables); + List caseCmd = commands(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables); caseCmds.add(caseCmd); s = lex(); } List defCmd = new ArrayList<>(); if (s.type == SymbolType.DEFAULT) { expectedType(SymbolType.COLON); - defCmd = commands(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables); + defCmd = commands(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables); s = lexer.lex(); } expected(s, lexer.yyline(), SymbolType.CURLY_CLOSE); @@ -1626,7 +1706,7 @@ public class ActionScript3Parser { ret = new ContinueItem(null, cloopId); break; case RETURN: - GraphTargetItem retexpr = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, true, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem retexpr = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, true, registerVars, inFunction, inMethod, true, variables); if (retexpr == null) { ret = new ReturnVoidAVM2Item(null); } else { @@ -1636,7 +1716,7 @@ public class ActionScript3Parser { case TRY: needsActivation.setVal(true); List tryCommands = new ArrayList<>(); - tryCommands.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + tryCommands.add(command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); s = lex(); boolean found = false; List> catchCommands = new ArrayList<>(); @@ -1650,7 +1730,7 @@ public class ActionScript3Parser { String enamestr = s.value.toString(); expectedType(SymbolType.COLON); - GraphTargetItem etype = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); + GraphTargetItem etype = type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); NameAVM2Item e = new NameAVM2Item(etype, lexer.yyline(), enamestr, new ExceptionAVM2Item(null)/*?*/, true/*?*/, openedNamespaces); variables.add(e); catchExceptions.add(e); @@ -1659,7 +1739,7 @@ public class ActionScript3Parser { expectedType(SymbolType.PARENT_CLOSE); List cc = new ArrayList<>(); List catchVars = new ArrayList<>(); - cc.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, catchVars)); + cc.add(command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, catchVars)); catchesVars.add(catchVars); variables.addAll(catchVars); @@ -1705,7 +1785,7 @@ public class ActionScript3Parser { List finallyCommands = null; if (s.type == SymbolType.FINALLY) { finallyCommands = new ArrayList<>(); - finallyCommands.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + finallyCommands.add(command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); found = true; s = lex(); } @@ -1719,7 +1799,7 @@ public class ActionScript3Parser { ret = tai; break; case THROW: - ret = new ThrowAVM2Item(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + ret = new ThrowAVM2Item(null, expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); break; default: GraphTargetItem valcmd = expressionCommands(s, registerVars, inFunction, inMethod, forinlevel, variables); @@ -1731,7 +1811,7 @@ public class ActionScript3Parser { return null; } lexer.pushback(s); - ret = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + ret = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); if (debugMode) { System.out.println("/command"); } @@ -1743,7 +1823,7 @@ public class ActionScript3Parser { lexer.removeListener(buf); if (ret == null) { //can be popped expression buf.pushAllBack(lexer); - ret = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + ret = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); } s = lex(); if ((s != null) && (s.type != SymbolType.SEMICOLON)) { @@ -1754,11 +1834,11 @@ public class ActionScript3Parser { } - private GraphTargetItem expression(TypeItem thisType, DottedChain pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { - return expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, allowRemainder, variables); + private GraphTargetItem expression(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { + return expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, allowRemainder, variables); } - /*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 { + /*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(); @@ -1788,7 +1868,7 @@ public class ActionScript3Parser { return (item instanceof NameAVM2Item); } - private int brackets(TypeItem thisType, DottedChain pkg, Reference needsActivation, List importedClasses, List openedNamespaces, List ret, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + private int brackets(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, List ret, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { ParsedSymbol s = lex(); int arrCnt = 0; if (s.type == SymbolType.BRACKET_OPEN) { @@ -1799,7 +1879,7 @@ public class ActionScript3Parser { lexer.pushback(s); } arrCnt++; - ret.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + ret.add(expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); s = lex(); if (!s.isType(SymbolType.COMMA, SymbolType.BRACKET_CLOSE)) { expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.BRACKET_CLOSE); @@ -1812,12 +1892,12 @@ public class ActionScript3Parser { return arrCnt; } - private GraphTargetItem commaExpression(TypeItem thisType, DottedChain pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forInLevel, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem commaExpression(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forInLevel, List variables) throws IOException, AVM2ParseException { GraphTargetItem cmd = null; List expr = new ArrayList<>(); ParsedSymbol s; do { - cmd = command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forInLevel, false, variables); + cmd = command(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forInLevel, false, variables); if (cmd != null) { expr.add(cmd); } @@ -1825,7 +1905,7 @@ public class ActionScript3Parser { } while (s.type == SymbolType.COMMA && cmd != null); lexer.pushback(s); if (cmd == null) { - expr.add(expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + expr.add(expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); } else { if (!cmd.hasReturnValue()) { throw new AVM2ParseException("Expression expected", lexer.yyline()); @@ -1834,12 +1914,12 @@ public class ActionScript3Parser { return new CommaExpressionItem(null, expr); } - private GraphTargetItem expression(TypeItem thisType, DottedChain pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { - GraphTargetItem prim = expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); + private GraphTargetItem expression(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { + GraphTargetItem prim = expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); if (prim == null) { return null; } - return expression1(prim, GraphTargetItem.NOPRECEDENCE, thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); + return expression1(allOpenedNamespaces, prim, GraphTargetItem.NOPRECEDENCE, thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); } /** @@ -1864,7 +1944,7 @@ public class ActionScript3Parser { return lookahead; } - private GraphTargetItem expression1(GraphTargetItem lhs, int min_precedence, TypeItem thisType, DottedChain pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem expression1(List> allOpenedNamespaces, GraphTargetItem lhs, int min_precedence, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { if (debugMode) { System.out.println("expression1:"); } @@ -1886,14 +1966,14 @@ public class ActionScript3Parser { if (debugMode) { System.out.println("ternar-middle:"); } - mhs = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); + mhs = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); expectedType(SymbolType.COLON); if (debugMode) { System.out.println("/ternar-middle"); } } - rhs = expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); + rhs = expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); if (rhs == null) { lexer.pushback(op); break; @@ -1902,13 +1982,13 @@ public class ActionScript3Parser { lookahead = peekExprToken(); while ((lookahead.type.isBinary() && lookahead.type.getPrecedence() < /* > on wiki */ op.type.getPrecedence()) || (lookahead.type.isRightAssociative() && lookahead.type.getPrecedence() == op.type.getPrecedence())) { - rhs = expression1(rhs, lookahead.type.getPrecedence(), thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); + rhs = expression1(allOpenedNamespaces, rhs, lookahead.type.getPrecedence(), thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables); lookahead = peekExprToken(); } switch (op.type) { case AS: - //GraphTargetItem type = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); + //GraphTargetItem type = type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); lhs = new AsTypeAVM2Item(null, lhs, rhs); //??? allowRemainder = false; @@ -1988,7 +2068,7 @@ public class ActionScript3Parser { lhs = new InstanceOfAVM2Item(null, lhs, rhs); break; case IS: - GraphTargetItem istype = rhs;//type(thisType,pkg,needsActivation, importedClasses, openedNamespaces, variables); + GraphTargetItem istype = rhs;//type(allOpenedNamespaces, thisType,pkg,needsActivation, importedClasses, openedNamespaces, variables); lhs = new IsTypeAVM2Item(null, lhs, istype); break; case ASSIGN: @@ -2065,7 +2145,7 @@ public class ActionScript3Parser { } } if (lhs instanceof ParenthesisItem) { - GraphTargetItem coerced = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); + GraphTargetItem coerced = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); if (coerced != null && isType(((ParenthesisItem) lhs).value)) { lhs = new CoerceAVM2Item(null, ((ParenthesisItem) lhs).value, coerced); } @@ -2077,7 +2157,7 @@ public class ActionScript3Parser { return lhs; } - private GraphTargetItem expressionPrimary(TypeItem thisType, DottedChain pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem expressionPrimary(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { if (debugMode) { System.out.println("primary:"); } @@ -2087,14 +2167,14 @@ public class ActionScript3Parser { switch (s.type) { case XML_STARTTAG_BEGIN: lexer.pushback(s); - ret = xml(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables); + ret = xml(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables); break; case STRING: ret = new StringAVM2Item(null, s.value.toString()); allowMemberOrCall = true; break; case NEGATE: - ret = expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables); + ret = expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables); ret = new NegAVM2Item(null, ret); break; @@ -2108,7 +2188,7 @@ public class ActionScript3Parser { } else { lexer.pushback(s); - GraphTargetItem num = expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem num = expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, true, variables); if (num instanceof IntegerValueAVM2Item) { ((IntegerValueAVM2Item) num).value = -((IntegerValueAVM2Item) num).value; ret = num; @@ -2126,7 +2206,7 @@ public class ActionScript3Parser { } break; case TYPEOF: - ret = new TypeOfAVM2Item(null, expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables)); + ret = new TypeOfAVM2Item(null, expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables)); break; case TRUE: ret = new BooleanAVM2Item(null, true); @@ -2155,9 +2235,9 @@ public class ActionScript3Parser { expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.STRING, SymbolType.INTEGER, SymbolType.DOUBLE); GraphTargetItem n = new StringAVM2Item(null, s.value.toString()); -//expression(thisType,pkg,needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); +//expression(allOpenedNamespaces, thisType,pkg,needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); expectedType(SymbolType.COLON); - GraphTargetItem v = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); + GraphTargetItem v = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); NameValuePair nv = new NameValuePair(n, v); nvs.add(nv); @@ -2172,7 +2252,7 @@ public class ActionScript3Parser { case BRACKET_OPEN: //Array literal or just brackets lexer.pushback(s); List inBrackets = new ArrayList<>(); - int arrCnt = brackets(thisType, pkg, needsActivation, importedClasses, openedNamespaces, inBrackets, registerVars, inFunction, inMethod, variables); + int arrCnt = brackets(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, inBrackets, registerVars, inFunction, inMethod, variables); ret = new NewArrayAVM2Item(null, inBrackets); allowMemberOrCall = true; @@ -2186,7 +2266,7 @@ public class ActionScript3Parser { lexer.pushback(s); } needsActivation.setVal(true); - ret = function(new ArrayList<>(), pkg, false, needsActivation, importedClasses, 0/*?*/, thisType, openedNamespaces, fname, false, variables); + ret = function(allOpenedNamespaces, new ArrayList<>(), pkg, false, needsActivation, importedClasses, thisType, openedNamespaces, fname, false, variables); allowMemberOrCall = true; break; case NAN: @@ -2206,7 +2286,7 @@ public class ActionScript3Parser { break; case DELETE: - GraphTargetItem varDel = expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, true, variables);//name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); + GraphTargetItem varDel = expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, true, variables);//name(allOpenedNamespaces, thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); if (!isNameOrProp(varDel)) { throw new AVM2ParseException("Not a property or name", lexer.yyline()); } @@ -2214,7 +2294,7 @@ public class ActionScript3Parser { break; case INCREMENT: case DECREMENT: //preincrement - GraphTargetItem varincdec = expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false/*?*/, variables);//name(thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); + GraphTargetItem varincdec = expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false/*?*/, variables);//name(allOpenedNamespaces, thisType,false, openedNamespaces, registerVars, inFunction, inMethod, variables); if (!isNameOrProp(varincdec)) { throw new AVM2ParseException("Not a property or name", lexer.yyline()); } @@ -2227,11 +2307,11 @@ public class ActionScript3Parser { break; case NOT: - ret = new NotItem(null, expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables)); + ret = new NotItem(null, expressionPrimary(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables)); break; case PARENT_OPEN: - ret = new ParenthesisItem(null, expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + ret = new ParenthesisItem(null, expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.PARENT_CLOSE); if (ret.value == null) { throw new AVM2ParseException("Expression in parenthesis expected", lexer.yyline()); @@ -2253,29 +2333,29 @@ public class ActionScript3Parser { lexer.pushback(s); } needsActivation.setVal(true); - ret = function(new ArrayList<>(), pkg, false, needsActivation, importedClasses, 0/*?*/, thisType, openedNamespaces, ffname, false, variables); + ret = function(allOpenedNamespaces, new ArrayList<>(), pkg, false, needsActivation, importedClasses, thisType, openedNamespaces, ffname, false, variables); } else if (s.type == SymbolType.LOWER_THAN) { - GraphTargetItem subtype = type(thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); + GraphTargetItem subtype = type(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, variables); expectedType(SymbolType.GREATER_THAN); s = lex(); expected(s, lexer.yyline(), SymbolType.BRACKET_OPEN); lexer.pushback(s); List params = new ArrayList<>(); - brackets(thisType, pkg, needsActivation, importedClasses, openedNamespaces, params, registerVars, inFunction, inMethod, variables); + brackets(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, params, registerVars, inFunction, inMethod, variables); ret = new InitVectorAVM2Item(subtype, params, openedNamespaces); } else if (s.type == SymbolType.PARENT_OPEN) { - GraphTargetItem newvar = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); - newvar = applyType(thisType, pkg, needsActivation, importedClasses, openedNamespaces, newvar, registerVars, inFunction, inMethod, variables); + GraphTargetItem newvar = expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + newvar = applyType(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, newvar, registerVars, inFunction, inMethod, variables); expectedType(SymbolType.PARENT_CLOSE); expectedType(SymbolType.PARENT_OPEN); - ret = new ConstructSomethingAVM2Item(lexer.yyline(), openedNamespaces, newvar, call(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); + ret = new ConstructSomethingAVM2Item(lexer.yyline(), openedNamespaces, newvar, call(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); } else { lexer.pushback(s); - GraphTargetItem newvar = name(thisType, pkg, needsActivation, false /*?*/, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses); - newvar = applyType(thisType, pkg, needsActivation, importedClasses, openedNamespaces, newvar, registerVars, inFunction, inMethod, variables); + GraphTargetItem newvar = name(allOpenedNamespaces, thisType, pkg, needsActivation, false /*?*/, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses); + newvar = applyType(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, newvar, registerVars, inFunction, inMethod, variables); expectedType(SymbolType.PARENT_OPEN); - ret = new ConstructSomethingAVM2Item(lexer.yyline(), openedNamespaces, newvar, call(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); + ret = new ConstructSomethingAVM2Item(lexer.yyline(), openedNamespaces, newvar, call(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); } allowMemberOrCall = true; break; @@ -2284,10 +2364,10 @@ public class ActionScript3Parser { case SUPER: case ATTRIBUTE: lexer.pushback(s); - ret = name(thisType, pkg, needsActivation, false, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses); + ret = name(allOpenedNamespaces, thisType, pkg, needsActivation, false, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses); allowMemberOrCall = true; - //var = memberOrCall(thisType, pkg, needsActivation, importedClasses, openedNamespaces, var, registerVars, inFunction, inMethod, variables); + //var = memberOrCall(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, var, registerVars, inFunction, inMethod, variables); //ret = var; break; default: @@ -2301,7 +2381,7 @@ public class ActionScript3Parser { lexer.pushback(s); } if (allowMemberOrCall && ret != null) { - ret = memberOrCall(thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); + ret = memberOrCall(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); } if (debugMode) { System.out.println("/primary"); @@ -2313,7 +2393,7 @@ public class ActionScript3Parser { private List constantPool; - private List parseImports(List openedNamespaces) throws IOException, AVM2ParseException { + private List parseImports(List openedNamespaces) throws IOException, AVM2ParseException { ParsedSymbol s; List importedClasses = new ArrayList<>(); @@ -2341,7 +2421,7 @@ public class ActionScript3Parser { } if (isStar) { - openedNamespaces.add(abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PACKAGE, imp.toString(), 0, true)); + openedNamespaces.add(new NamespaceItem(imp, Namespace.KIND_PACKAGE)); } else { importedClasses.add(imp); } @@ -2353,37 +2433,9 @@ public class ActionScript3Parser { return importedClasses; } - private PackageAVM2Item parsePackage(List openedNamespaces) throws IOException, AVM2ParseException, CompilationException { - List items = new ArrayList<>(); - expectedType(SymbolType.PACKAGE); - DottedChain name = DottedChain.TOPLEVEL; - ParsedSymbol s = lex(); - if (s.type != SymbolType.CURLY_OPEN) { - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - name = name.add(s.value.toString()); - s = lex(); - } - while (s.type != SymbolType.CURLY_OPEN) { - expected(s, lexer.yyline(), SymbolType.DOT); - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - name = name.add(s.value.toString()); - s = lex(); - } - - List importedClasses = parseImports(openedNamespaces); - - //traits(false, new ArrayList(), new Reference(false), new ArrayList(), importedClasses, privateNs, 0, publicNs, packageInternalNs, 0, openedNamespaces, name, null, false, items); - //expectedType(SymbolType.CURLY_CLOSE); - return new PackageAVM2Item(importedClasses, name, items); - } - - private List parseScript(String fileName) throws IOException, AVM2ParseException, CompilationException { - - List openedNamespaces = new ArrayList<>(); - - int scriptPrivateNs; + private List parseScript(int scriptIndex, String fileName) throws IOException, AVM2ParseException, CompilationException { + //int scriptPrivateNs; if (fileName.contains("/")) { fileName = fileName.substring(fileName.lastIndexOf('/') + 1); } @@ -2394,20 +2446,21 @@ public class ActionScript3Parser { if (className.endsWith(".as")) { className = className.substring(0, className.length() - 3); }*/ - openedNamespaces.add(scriptPrivateNs = abcIndex.getSelectedAbc().constants.addNamespace(Namespace.KIND_PRIVATE, 0)); //abc.getLastAbc().constants.getStringId(name + ":" + className, true) - - int publicNs; - openedNamespaces.add(publicNs = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PACKAGE, "", 0, true)); + /*openedNamespaces.add(scriptPrivateNs = abcIndex.getSelectedAbc().constants.addNamespace(Namespace.KIND_PRIVATE, 0)); //abc.getLastAbc().constants.getStringId(name + ":" + className, true) + int publicNs; + openedNamespaces.add(publicNs = abcIndex.getSelectedAbc().constants.getNamespaceId(Namespace.KIND_PACKAGE, "", 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); + scriptTraits(scriptIndex, fileName, items); + //FIXME traits(fileName, true, new ArrayList<>(), new Reference<>(false), new ArrayList<>(), new ArrayList<>(), scriptPrivateNs, 0, publicNs, 0, 0, openedNamespaces, null, null, false, items); return items; } - public List scriptTraitsFromString(String str, String fileName) throws AVM2ParseException, IOException, CompilationException { + public List scriptTraitsFromString(String str, String fileName, int scriptIndex) throws AVM2ParseException, IOException, CompilationException { lexer = new ActionScriptLexer(str); - List ret = parseScript(fileName); + List ret = parseScript(scriptIndex, fileName); if (lexer.lex().type != SymbolType.EOF) { throw new AVM2ParseException("Parsing finisned before end of the file", lexer.yyline()); } @@ -2422,8 +2475,8 @@ public class ActionScript3Parser { 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 { - List traits = scriptTraitsFromString(s, fileName); + public void addScript(String s, boolean documentClass, String fileName, int classPos, int scriptIndex) throws AVM2ParseException, IOException, CompilationException { + List traits = scriptTraitsFromString(s, fileName, scriptIndex); addScriptFromTree(traits, documentClass, classPos); } @@ -2451,14 +2504,14 @@ public class ActionScript3Parser { } } - public static void compile(String src, ABC abc, List otherABCs, boolean documentClass, String fileName, int classPos) throws AVM2ParseException, IOException, InterruptedException, CompilationException { + public static void compile(String src, ABC abc, List otherABCs, boolean documentClass, String fileName, int classPos, int scriptIndex) throws AVM2ParseException, IOException, InterruptedException, CompilationException { //List parABCs = new ArrayList<>(); initPlayer(); ActionScript3Parser parser = new ActionScript3Parser(abc, otherABCs); boolean success = false; ABC originalAbc = ((ABCContainerTag) ((Tag) abc.parentTag).cloneTag()).getABC(); try { - parser.addScript(src, documentClass, fileName, classPos); + parser.addScript(src, documentClass, fileName, classPos, scriptIndex); success = true; } finally { if (!success) { @@ -2475,18 +2528,20 @@ public class ActionScript3Parser { } } - public static void compile(SWF swf, String src, String dst, int classPos) { + public static void compile(SWF swf, String src, String dst, int classPos, int scriptIndex) { System.err.println("WARNING: AS3 compiler is not finished yet. This is only used for debuggging!"); try { initPlayer(); ABC abc = new ABC(null); ActionScript3Parser parser = new ActionScript3Parser(abc, new ArrayList<>()); - parser.addScript(new String(Helper.readFile(src), Utf8Helper.charset), true, src, classPos); + parser.addScript(new String(Helper.readFile(src), Utf8Helper.charset), true, src, classPos, scriptIndex); try (OutputStream fos = new BufferedOutputStream(new FileOutputStream(new File(dst)))) { abc.saveToStream(fos); + } } catch (Exception ex) { - Logger.getLogger(ActionScript3Parser.class.getName()).log(Level.SEVERE, null, ex); + Logger.getLogger(ActionScript3Parser.class + .getName()).log(Level.SEVERE, null, ex); } System.exit(0); } 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 67d69c75e..a3d4c0f97 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 @@ -119,7 +119,7 @@ public class CallAVM2Item extends AVM2Item { Reference outPropValue = new Reference<>(null); Reference outPropValueAbc = new Reference<>(null); - if (cname != null && AVM2SourceGenerator.searchPrototypeChain(localData.privateNs, localData.protectedNs, true, g.abcIndex, pkgName, cname, prop.propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue, outPropValueAbc) && (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, outPropValueAbc) && (localData.getFullClass().equals(outNs.getVal().add(outName.getVal()).toRawString()))) { 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 b7825052f..514c87ec1 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 @@ -38,28 +38,27 @@ public class ClassAVM2Item extends AVM2Item implements Block { public String className; - public GraphTargetItem constructor; - - public int namespace; - - public int protectedNs; - public int privateNs; + public GraphTargetItem iinit; public boolean isDynamic; public boolean isFinal; - public List openedNamespaces; + public List openedNamespaces; public List staticInit; - public boolean staticInitActivation; + public boolean cinitActivation; - public List sinitVariables; + public boolean iinitActivation; + + public List cinitVariables; public List importedClasses; - public DottedChain pkg; + public NamespaceItem pkg; + + public List iinitVariables; public List>> metadata; @@ -72,25 +71,24 @@ public class ClassAVM2Item extends AVM2Item implements Block { return ret; } - 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) { + public ClassAVM2Item(List>> metadata, List importedClasses, NamespaceItem pkg, List openedNamespaces, boolean isFinal, boolean isDynamic, String className, GraphTargetItem extendsOp, List implementsOp, List cinit, boolean staticInitActivation, List cinitVariables, GraphTargetItem iinit, List iinitVariables, List traits, boolean iinitActivation) { super(null, NOPRECEDENCE); this.metadata = metadata; this.importedClasses = importedClasses; this.pkg = pkg; - this.privateNs = privateNs; - this.protectedNs = protectedNs; this.className = className; this.traits = traits; this.extendsOp = extendsOp; this.implementsOp = implementsOp; - this.constructor = constructor; - this.namespace = namespace; + this.iinitActivation = iinitActivation; + this.iinit = iinit; this.isDynamic = isDynamic; this.isFinal = isFinal; this.openedNamespaces = openedNamespaces; - this.staticInit = staticInit; - this.staticInitActivation = staticInitActivation; - this.sinitVariables = sinitVariables; + this.staticInit = cinit; + this.cinitActivation = staticInitActivation; + this.cinitVariables = cinitVariables; + this.iinitVariables = iinitVariables; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstAVM2Item.java index dacfaab40..5c90938fb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstAVM2Item.java @@ -30,8 +30,6 @@ import java.util.Map; */ public class ConstAVM2Item extends AVM2Item { - private final int namespace; - private final boolean isStatic; public String var; @@ -44,23 +42,18 @@ public class ConstAVM2Item extends AVM2Item { public int line; - public DottedChain pkg; - - public int getNamespace() { - return namespace; - } + public NamespaceItem pkg; public boolean isStatic() { return isStatic; } - public ConstAVM2Item(List>> metadata, DottedChain pkg, String customNamespace, boolean isStatic, int namespace, String var, GraphTargetItem type, GraphTargetItem value, int line) { + public ConstAVM2Item(List>> metadata, NamespaceItem pkg, String customNamespace, boolean isStatic, String var, GraphTargetItem type, GraphTargetItem value, int line) { super(null, NOPRECEDENCE, value); this.metadata = metadata; this.pkg = pkg; this.line = line; - this.namespace = namespace; this.isStatic = isStatic; this.var = var; this.type = type; 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 dcc71bdc0..68ff85910 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 @@ -34,9 +34,9 @@ import java.util.List; */ public class ConstructSomethingAVM2Item extends CallAVM2Item { - public List openedNamespaces; + public List openedNamespaces; - public ConstructSomethingAVM2Item(int line, List openedNamespaces, GraphTargetItem name, List arguments) { + public ConstructSomethingAVM2Item(int line, List openedNamespaces, GraphTargetItem name, List arguments) { super(line, name, arguments); this.openedNamespaces = openedNamespaces; } @@ -49,7 +49,7 @@ public class ConstructSomethingAVM2Item extends CallAVM2Item { private int allNsSetWithVec(ABC abc) { int[] nssa = new int[openedNamespaces.size() + 1]; for (int i = 0; i < openedNamespaces.size(); i++) { - nssa[i] = openedNamespaces.get(i); + nssa[i] = openedNamespaces.get(i).getCpoolIndex(abc.constants); } nssa[nssa.length - 1] = abc.constants.getNamespaceId(Namespace.KIND_PACKAGE, "__AS3__.vec", 0, true); return abc.constants.getNamespaceSetId(nssa, true); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/FunctionAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/FunctionAVM2Item.java index 66e4e1028..35d9678da 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/FunctionAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/FunctionAVM2Item.java @@ -39,8 +39,6 @@ public class FunctionAVM2Item extends AVM2Item { public String functionName; - public int namespace; - public List paramNames; public List body; @@ -61,17 +59,16 @@ public class FunctionAVM2Item extends AVM2Item { public boolean isInterface; - public DottedChain pkg; + public NamespaceItem pkg; public List>> metadata; - public FunctionAVM2Item(List>> metadata, DottedChain pkg, boolean isInterface, boolean needsActivation, int namespace, boolean hasRest, int line, String functionName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { + public FunctionAVM2Item(List>> metadata, NamespaceItem pkg, boolean isInterface, boolean needsActivation, boolean hasRest, int line, String functionName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { super(null, NOPRECEDENCE); this.metadata = metadata; this.pkg = pkg; this.needsActivation = needsActivation; - this.namespace = namespace; this.paramNames = paramNames; this.body = body; this.functionName = functionName; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/GetterAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/GetterAVM2Item.java index 521880a36..d3b6b6790 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/GetterAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/GetterAVM2Item.java @@ -27,7 +27,7 @@ import java.util.Map; */ public class GetterAVM2Item extends MethodAVM2Item { - public GetterAVM2Item(boolean isPrivate, List>> metadata, DottedChain pkg, boolean isInterface, String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { - super(isPrivate, metadata, pkg, isInterface, customNamespace, needsActivation, hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); + public GetterAVM2Item(boolean outsidePackage, boolean isPrivate, List>> metadata, NamespaceItem pkg, boolean isInterface, String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { + super(outsidePackage, isPrivate, metadata, pkg, isInterface, customNamespace, needsActivation, hasRest, line, override, isFinal, isStatic, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); } } 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 cf7f24bc9..1e1d692d6 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 @@ -38,7 +38,7 @@ import java.util.List; */ public class IndexAVM2Item extends AssignableAVM2Item { - private final List openedNamespaces; + private final List openedNamespaces; public GraphTargetItem object; @@ -46,7 +46,7 @@ public class IndexAVM2Item extends AssignableAVM2Item { public boolean attr; - public IndexAVM2Item(boolean attr, GraphTargetItem object, GraphTargetItem index, GraphTargetItem storeValue, List openedNamespaces) { + public IndexAVM2Item(boolean attr, GraphTargetItem object, GraphTargetItem index, GraphTargetItem storeValue, List openedNamespaces) { super(storeValue); this.object = object; this.index = index; @@ -55,7 +55,10 @@ public class IndexAVM2Item extends AssignableAVM2Item { } private int allNsSet(ABC abc) { - int[] nssa = Helper.toIntArray(openedNamespaces); + int[] nssa = new int[openedNamespaces.size()]; + for (int i = 0; i < nssa.length; i++) { + nssa[i] = openedNamespaces.get(i).getCpoolIndex(abc.constants); + } return abc.constants.getNamespaceSetId(nssa, true); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/InterfaceAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/InterfaceAVM2Item.java index 7b06f6520..760a4e9e9 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/InterfaceAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/InterfaceAVM2Item.java @@ -37,19 +37,17 @@ public class InterfaceAVM2Item extends AVM2Item { public List methods; - public int namespace; - public boolean isFinal; - public List openedNamespaces; + public List openedNamespaces; - public DottedChain pkg; + public NamespaceItem pkg; public List importedClasses; public List>> metadata; - public InterfaceAVM2Item(List>> metadata, List importedClasses, DottedChain pkg, List openedNamespaces, boolean isFinal, int namespace, String name, List superInterfaces, List traits) { + public InterfaceAVM2Item(List>> metadata, List importedClasses, NamespaceItem pkg, List openedNamespaces, boolean isFinal, String name, List superInterfaces, List traits) { super(null, NOPRECEDENCE); this.metadata = metadata; this.importedClasses = importedClasses; @@ -57,7 +55,6 @@ public class InterfaceAVM2Item extends AVM2Item { this.name = name; this.superInterfaces = superInterfaces; this.methods = traits; - this.namespace = namespace; this.isFinal = isFinal; this.openedNamespaces = openedNamespaces; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java index e36606bfe..90a986aba 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java @@ -37,6 +37,8 @@ public class MethodAVM2Item extends FunctionAVM2Item { private final boolean isPrivate; + public final boolean outsidePackage; + public boolean isPrivate() { return isPrivate; } @@ -44,8 +46,9 @@ public class MethodAVM2Item extends FunctionAVM2Item { public String customNamespace; //public boolean isInterface; - public MethodAVM2Item(boolean isPrivate, List>> metadata, DottedChain pkg, boolean isInterface, String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { - super(metadata, pkg, isInterface, needsActivation, namespace, hasRest, line, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); + public MethodAVM2Item(boolean outsidePackage, boolean isPrivate, List>> metadata, NamespaceItem pkg, boolean isInterface, String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { + super(metadata, pkg, isInterface, needsActivation, hasRest, line, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); + this.outsidePackage = outsidePackage; this.isStatic = isStatic; this.override = override; this.isFinal = isFinal; 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 201850ac6..9a6736dd5 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 @@ -47,7 +47,7 @@ public class NameAVM2Item extends AssignableAVM2Item { private int nsKind = -1; - public List openedNamespaces; + public List openedNamespaces; public int line; @@ -127,7 +127,7 @@ public class NameAVM2Item extends AssignableAVM2Item { return variableName; } - public NameAVM2Item(GraphTargetItem type, int line, String variableName, GraphTargetItem storeValue, boolean definition, List openedNamespaces) { + public NameAVM2Item(GraphTargetItem type, int line, String variableName, GraphTargetItem storeValue, boolean definition, List openedNamespaces) { super(storeValue); this.variableName = variableName; this.assignedValue = storeValue; @@ -206,7 +206,7 @@ public class NameAVM2Item extends AssignableAVM2Item { String name = variableName; boolean attr = false; if (name != null && name.startsWith("@")) { - name = name.substring(1); + //name = name.substring(1); attr = true; } AVM2SourceGenerator g = (AVM2SourceGenerator) generator; @@ -255,18 +255,12 @@ public class NameAVM2Item extends AssignableAVM2Item { @Override public boolean hasReturnValue() { - if (definition) { - return false; - } - return true; + return !definition; } @Override public boolean needsSemicolon() { - if (definition) { - return true; - } - return false; + return definition; } @Override diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespaceItem.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespaceItem.java new file mode 100644 index 000000000..10c9bf92f --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespaceItem.java @@ -0,0 +1,83 @@ +/* + * 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.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.types.Namespace; +import com.jpexs.decompiler.graph.DottedChain; +import java.util.List; +import java.util.Objects; + +/** + * + * @author JPEXS + */ +public class NamespaceItem { + + public DottedChain name; + public int kind; + + public NamespaceItem(DottedChain name, int kind) { + this.name = name; + this.kind = kind; + } + + public NamespaceItem(String name, int kind) { + this.name = DottedChain.parse(name); + this.kind = kind; + } + + @Override + public String toString() { + return Namespace.kindToStr(kind) + " " + name.toRawString(); + } + + @Override + public int hashCode() { + int hash = 7; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final NamespaceItem other = (NamespaceItem) obj; + if (!Objects.equals(this.name, other.name)) { + return false; + } + return (this.kind == other.kind); + } + + public int getCpoolIndex(AVM2ConstantPool cpool) { + return cpool.getNamespaceId(kind, name, 0, true); + } + + public static int getCpoolSetIndex(AVM2ConstantPool cpool, List namespaces) { + int[] nssa = new int[namespaces.size()]; + for (int i = 0; i < nssa.length; i++) { + nssa[i] = namespaces.get(i).getCpoolIndex(cpool); + } + + return cpool.getNamespaceSetId(nssa, true); + } + +} 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 11efea864..236be1173 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 @@ -50,9 +50,9 @@ public class NamespacedAVM2Item extends AssignableAVM2Item { public boolean attr; - public List openedNamespaces; + public List openedNamespaces; - public NamespacedAVM2Item(GraphTargetItem ns, String name, GraphTargetItem nameItem, GraphTargetItem obj, boolean attr, List openedNamespaces, GraphTargetItem storeValue) { + public NamespacedAVM2Item(GraphTargetItem ns, String name, GraphTargetItem nameItem, GraphTargetItem obj, boolean attr, List openedNamespaces, GraphTargetItem storeValue) { super(storeValue); this.ns = ns; this.nameItem = nameItem; @@ -63,7 +63,10 @@ public class NamespacedAVM2Item extends AssignableAVM2Item { } private int allNsSet(ABC abc) { - int[] nssa = Helper.toIntArray(openedNamespaces); + int[] nssa = new int[openedNamespaces.size()]; + for (int i = 0; i < nssa.length; i++) { + nssa[i] = openedNamespaces.get(i).getCpoolIndex(abc.constants); + } return abc.constants.getNamespaceSetId(nssa, true); } 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 3a85525b7..daa86f0dc 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 @@ -58,7 +58,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item { public AbcIndexing abcIndex; - private final List openedNamespaces; + private final List openedNamespaces; private final List callStack; @@ -70,7 +70,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item { return p; } - public PropertyAVM2Item(GraphTargetItem object, String propertyName, AbcIndexing abcIndex, List openedNamespaces, List callStack) { + public PropertyAVM2Item(GraphTargetItem object, String propertyName, AbcIndexing abcIndex, List openedNamespaces, List callStack) { this.propertyName = propertyName; this.object = object; this.abcIndex = abcIndex; @@ -84,7 +84,11 @@ public class PropertyAVM2Item extends AssignableAVM2Item { } private int allNsSet(ABC abc) { - int[] nssa = Helper.toIntArray(openedNamespaces); + int[] nssa = new int[openedNamespaces.size()]; + for (int i = 0; i < nssa.length; i++) { + nssa[i] = openedNamespaces.get(i).getCpoolIndex(abc.constants); + } + return abc.constants.getNamespaceSetId(nssa, true); } @@ -249,10 +253,10 @@ public class PropertyAVM2Item extends AssignableAVM2Item { if (objType == null) { loopobjType: for (int i = 0; i < openedNamespaces.size(); i++) { - int nsindex = openedNamespaces.get(i); + int nsindex = openedNamespaces.get(i).getCpoolIndex(constants); - int nsKind = constants.getNamespace(openedNamespaces.get(i)).kind; - DottedChain nsname = constants.getNamespace(openedNamespaces.get(i)).getName(constants); + int nsKind = openedNamespaces.get(i).kind; + DottedChain nsname = openedNamespaces.get(i).name; int name_index = 0; for (int m = 1; m < constants.getMultinameCount(); m++) { Multiname mname = constants.getMultiname(m); @@ -314,7 +318,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item { } } if (nsKind == Namespace.KIND_PACKAGE && propertyName != null) { - AbcIndexing.TraitIndex p = abcIndex.findNsProperty(new AbcIndexing.PropertyNsDef(propertyName, nsname, abc, openedNamespaces.get(i)), true, true); + AbcIndexing.TraitIndex p = abcIndex.findNsProperty(new AbcIndexing.PropertyNsDef(propertyName, nsname, abc, openedNamespaces.get(i).getCpoolIndex(constants)), true, true); Reference outName = new Reference<>(""); Reference outNs = new Reference<>(DottedChain.EMPTY); @@ -577,7 +581,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item { GraphTargetItem targetType = propType.getVal(); String srcType = assignedValue.returnType().toString(); GraphTargetItem coerced = assignedValue; - if (!targetType.equals(srcType) && !propertyName.startsWith("@")) { + if (!targetType.toString().equals(srcType) && !propertyName.startsWith("@")) { coerced = new CoerceAVM2Item(null, assignedValue, targetType); } return toSourceMerge(localData, generator, obj, coerced, @@ -635,7 +639,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item { /*List abcs = new ArrayList<>(); abcs.add(abc); abcs.addAll(otherABCs);*/ - if (!localData.subMethod && cname != null && AVM2SourceGenerator.searchPrototypeChain(localData.privateNs, localData.protectedNs, true, abcIndex, pkgName, cname, propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue, outPropValueAbc) && (localData.currentClass.equals(outNs.getVal().add(outName.getVal())))) { + if (!localData.subMethod && cname != null && AVM2SourceGenerator.searchPrototypeChain(localData.privateNs, localData.protectedNs, true, abcIndex, pkgName, cname, propertyName, outName, outNs, outPropNs, outPropNsKind, outPropNsIndex, outPropType, outPropValue, outPropValueAbc) && (localData.getFullClass().equals(outNs.getVal().add(outName.getVal()).toRawString()))) { NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.getFullClass()), 0, "this", null, false, openedNamespaces); nobj.setRegNumber(0); obj = nobj; @@ -670,7 +674,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item { Reference ret_temp = new Reference<>(-1); Reference obj_temp = new Reference<>(-1); - boolean isInteger = propType.getVal().equals("int"); + boolean isInteger = propType.getVal().toString().equals("int"); List ret = toSourceMerge(localData, generator, obj, dupSetTemp(localData, generator, obj_temp), //Start get original diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SetterAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SetterAVM2Item.java index 4ac4e318a..f9afe49c3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SetterAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SetterAVM2Item.java @@ -27,7 +27,7 @@ import java.util.Map; */ public class SetterAVM2Item extends MethodAVM2Item { - public SetterAVM2Item(boolean isPrivate, List>> metadata, DottedChain pkg, boolean isInterface, String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { - super(isPrivate, metadata, pkg, isInterface, customNamespace, needsActivation, hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); + public SetterAVM2Item(boolean outsidePackage, boolean isPrivate, List>> metadata, NamespaceItem pkg, boolean isInterface, String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { + super(outsidePackage, isPrivate, metadata, pkg, isInterface, customNamespace, needsActivation, hasRest, line, override, isFinal, isStatic, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SlotAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SlotAVM2Item.java index b18e583e2..1a5b7e28e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SlotAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SlotAVM2Item.java @@ -30,8 +30,6 @@ import java.util.Map; */ public class SlotAVM2Item extends AVM2Item { - private final int namespace; - private final boolean isStatic; public String var; @@ -44,22 +42,17 @@ public class SlotAVM2Item extends AVM2Item { public List>> metadata; - public DottedChain pkg; - - public int getNamespace() { - return namespace; - } + public NamespaceItem pkg; public boolean isStatic() { return isStatic; } - public SlotAVM2Item(List>> metadata, DottedChain pkg, String customNamespace, boolean isStatic, int namespace, String var, GraphTargetItem type, GraphTargetItem value, int line) { + public SlotAVM2Item(List>> metadata, NamespaceItem pkg, String customNamespace, boolean isStatic, String var, GraphTargetItem type, GraphTargetItem value, int line) { super(null, NOPRECEDENCE, value); this.metadata = metadata; this.pkg = pkg; this.line = line; - this.namespace = namespace; this.isStatic = isStatic; this.var = var; this.type = type; 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 8aaa6e4cb..6e3238ddc 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 @@ -47,7 +47,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { private int nsKind = -1; - public List openedNamespaces; + public List openedNamespaces; public int line; @@ -153,7 +153,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { this.name = name; } - public UnresolvedAVM2Item(List subtypes, List importedClasses, boolean mustBeType, GraphTargetItem type, int line, DottedChain name, GraphTargetItem storeValue, List openedNamespaces) { + public UnresolvedAVM2Item(List subtypes, List importedClasses, boolean mustBeType, GraphTargetItem type, int line, DottedChain name, GraphTargetItem storeValue, List openedNamespaces) { super(storeValue); this.name = name; this.assignedValue = storeValue; @@ -352,8 +352,8 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { } //Search for types in opened namespaces - for (int ni : openedNamespaces) { - Namespace ons = abc.getSelectedAbc().constants.getNamespace(ni); + for (NamespaceItem n : openedNamespaces) { + Namespace ons = abc.getSelectedAbc().constants.getNamespace(n.getCpoolIndex(abc.getSelectedAbc().constants)); TypeItem ti = new TypeItem(ons.getName(abc.getSelectedAbc().constants).add(name.get(0))); AbcIndexing.ClassIndex ci = abc.findClass(ti); if (ci != null) { @@ -381,7 +381,23 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { 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); + + boolean isSuper = name.get(0).equals("super"); + GraphTargetItem ntype = thisType; + if (isSuper) { + AbcIndexing.ClassIndex ci = abc.findClass(thisType); + if (ci == null) { + throw new CompilationException("This class not found", line); + } + ci = ci.parent; + if (ci == null) { + ntype = new TypeItem("Object"); + } else { + ntype = new TypeItem(ci.abc.instance_info.get(ci.index).getName(ci.abc.constants).getNameWithNamespace(ci.abc.constants)); + } + } + + NameAVM2Item ret = new NameAVM2Item(ntype, 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, openedNamespaces, new ArrayList<>()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/XMLFilterAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/XMLFilterAVM2Item.java index e3a240292..202de0b77 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/XMLFilterAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/XMLFilterAVM2Item.java @@ -34,11 +34,11 @@ import java.util.List; */ public class XMLFilterAVM2Item extends AVM2Item { - public List openedNamespaces; + public List openedNamespaces; public GraphTargetItem object; - public XMLFilterAVM2Item(GraphTargetItem object, GraphTargetItem value, List openedNamespaces) { + public XMLFilterAVM2Item(GraphTargetItem object, GraphTargetItem value, List openedNamespaces) { super(null, NOPRECEDENCE, value); this.openedNamespaces = openedNamespaces; this.object = object; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java index 5dc7ff79c..f32f4ad3f 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/TraitSlotConst.java @@ -18,6 +18,8 @@ package com.jpexs.decompiler.flash.abc.types.traits; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool; +import com.jpexs.decompiler.flash.abc.avm2.model.NewFunctionAVM2Item; +import com.jpexs.decompiler.flash.abc.avm2.parser.script.FunctionAVM2Item; import com.jpexs.decompiler.flash.abc.types.AssignedValue; import com.jpexs.decompiler.flash.abc.types.ConvertData; import com.jpexs.decompiler.flash.abc.types.Multiname; @@ -29,6 +31,7 @@ import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.flash.helpers.NulWriter; import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType; import com.jpexs.decompiler.graph.DottedChain; +import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.helpers.Helper; import java.util.HashMap; @@ -146,6 +149,12 @@ public class TraitSlotConst extends Trait implements TraitWithSlot { if (showModifier) { getModifiers(abc, isStatic, writer); } + if (convertData.assignedValues.containsKey(this)) { + GraphTargetItem val = convertData.assignedValues.get(this).value; + if (val instanceof NewFunctionAVM2Item) { + return val.toString(writer, LocalData.create(abc.constants, new HashMap<>(), fullyQualifiedNames)); + } + } getNameStr(writer, abc, fullyQualifiedNames); if (value_kind != 0 || convertData.assignedValues.containsKey(this)) { writer.appendNoHilight(" = "); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/FILLSTYLE.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/FILLSTYLE.java index 22c928fb9..3b80599ba 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/FILLSTYLE.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/FILLSTYLE.java @@ -22,6 +22,7 @@ import com.jpexs.decompiler.flash.types.annotations.Conditional; import com.jpexs.decompiler.flash.types.annotations.ConditionalType; import com.jpexs.decompiler.flash.types.annotations.Internal; import com.jpexs.decompiler.flash.types.annotations.SWFType; +import com.jpexs.decompiler.flash.types.annotations.SWFVersion; import java.io.Serializable; import java.util.Set; @@ -40,14 +41,17 @@ public class FILLSTYLE implements NeedsCharacters, Serializable { public static final int RADIAL_GRADIENT = 0x12; + @SWFVersion(from = 8) public static final int FOCAL_RADIAL_GRADIENT = 0x13; public static final int REPEATING_BITMAP = 0x40; public static final int CLIPPED_BITMAP = 0x41; + @SWFVersion(from = 7) public static final int NON_SMOOTHED_REPEATING_BITMAP = 0x42; + @SWFVersion(from = 7) public static final int NON_SMOOTHED_CLIPPED_BITMAP = 0x43; @Internal