diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java b/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java index 59f2207c4..cee75e157 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/ABC.java @@ -94,10 +94,10 @@ public class ABC { constants.constant_double.add(null); constants.constant_int.add(null); constants.constant_uint.add(null); - constants.constant_string.add(""); + constants.constant_string.add(""); constants.constant_multiname.add(null); constants.constant_namespace.add(null); - constants.constant_namespace_set.add(null); + constants.constant_namespace_set.add(null); } public int addMethodBody(MethodBody body) { @@ -895,7 +895,6 @@ public class ABC { return ret; } - public int findMethodInfoByName(int classId, String methodName) { if (classId > -1) { for (Trait t : instance_info.get(classId).instance_traits.traits) { diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/ABCOutputStream.java b/trunk/src/com/jpexs/decompiler/flash/abc/ABCOutputStream.java index 0cb74ea55..10af35cc9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/ABCOutputStream.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/ABCOutputStream.java @@ -161,12 +161,17 @@ public class ABCOutputStream extends OutputStream { public void writeNamespace(Namespace ns) throws IOException { write(ns.kind); + boolean found = false; for (int k = 0; k < Namespace.nameSpaceKinds.length; k++) { if (Namespace.nameSpaceKinds[k] == ns.kind) { writeU30(ns.name_index); + found = true; break; } } + if (!found) { + throw new RuntimeException("Invalid ns kind:" + ns.kind); + } } public void writeMultiname(Multiname m) throws IOException { diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index 7a4969fd1..2a8108c16 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -1857,18 +1857,21 @@ public class AVM2Code implements Serializable { stats.instructionStats[pos].scopepos = scope; AVM2Instruction ins = code.get(pos); int stackDelta = ins.definition.getStackDelta(ins, abc); + int scopeDelta = ins.definition.getScopeStackDelta(ins, abc); + int oldStack = stack; + + //+" deltaScope:"+(scopeDelta>0?"+"+scopeDelta:scopeDelta)+" stack:"+stack+" scope:"+scope); stack += stackDelta; - int scopeDelta = ins.definition.getScopeStackDelta(ins, abc); scope += scopeDelta; - + if (stack > stats.maxstack) { stats.maxstack = stack; } if (scope > stats.maxscope) { stats.maxscope = scope; } - //System.out.println(""+ins+" deltaStack:"+(stackDelta>0?"+"+stackDelta:stackDelta)+" deltaScope:"+(scopeDelta>0?"+"+scopeDelta:scopeDelta)+" stack:"+stack+" scope:"+scope); - + + //System.out.println("stack "+oldStack+(stackDelta>=0?"+"+stackDelta:stackDelta)+" max:"+stats.maxstack+" "+ins); if ((ins.definition instanceof DXNSIns) || (ins.definition instanceof DXNSLateIns)) { stats.has_set_dxns = true; } @@ -1885,7 +1888,7 @@ public class AVM2Code implements Serializable { handleRegister(stats, ins.operands[i]); } } - } + } if (ins.definition instanceof ReturnValueIns) { //check stack=1 return true; @@ -1927,7 +1930,7 @@ public class AVM2Code implements Serializable { } public CodeStats getStats(ABC abc, MethodBody body, int initScope) { - CodeStats stats = new CodeStats(this); + CodeStats stats = new CodeStats(this); if (!walkCode(stats, 0, 0, initScope, abc)) { return null; } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/ConstantPool.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/ConstantPool.java index 2f3dbb864..37b40c825 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/ConstantPool.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/ConstantPool.java @@ -221,6 +221,9 @@ public class ConstantPool { } public int getStringId(String val) { + if (val == null) { + return 0; + } for (int i = 1; i < constant_string.size(); i++) { if (constant_string.get(i).equals(val)) { return i; @@ -262,6 +265,9 @@ public class ConstantPool { } public int getStringId(String val, boolean add) { + if (val == null) { + return 0; + } int id = getStringId(val); if (add && id == 0) { id = addString(val); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyIns.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyIns.java index 76598d5b7..fcb9e0a20 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyIns.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyIns.java @@ -56,14 +56,13 @@ public class FindPropertyIns extends InstructionDefinition { @Override public int getStackDelta(AVM2Instruction ins, ABC abc) { int ret = 1; - //FLEX does not calculate following: - /*int multinameIndex = ins.operands[0]; + int multinameIndex = ins.operands[0]; if (abc.constants.getMultiname(multinameIndex).needsName()) { ret--; } if (abc.constants.getMultiname(multinameIndex).needsNs()) { ret--; - }*/ + } return ret; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyStrictIns.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyStrictIns.java index 8f8fdb64d..3da8ee078 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyStrictIns.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/FindPropertyStrictIns.java @@ -55,14 +55,13 @@ public class FindPropertyStrictIns extends InstructionDefinition { @Override public int getStackDelta(AVM2Instruction ins, ABC abc) { int ret = 1; - //FLEX does not calculate following: - /*int multinameIndex = ins.operands[0]; + int multinameIndex = ins.operands[0]; if (abc.constants.getMultiname(multinameIndex).needsName()) { ret--; } if (abc.constants.getMultiname(multinameIndex).needsNs()) { ret--; - }*/ + } return ret; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java index 8217fa0cf..4f1e8080b 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/GetPropertyIns.java @@ -25,6 +25,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.FullMultinameAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.GetPropertyAVM2Item; import com.jpexs.decompiler.flash.abc.types.MethodBody; import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.abc.types.Multiname; import com.jpexs.decompiler.graph.GraphTargetItem; import java.util.HashMap; import java.util.List; @@ -48,8 +49,11 @@ public class GetPropertyIns extends InstructionDefinition { public int getStackDelta(AVM2Instruction ins, ABC abc) { int ret = -1 + 1; int multinameIndex = ins.operands[0]; - if (abc.constants.getMultiname(multinameIndex).needsName()) { - ret--; + int kind=abc.constants.getMultiname(multinameIndex).kind; + if(kind != Multiname.MULTINAMEL && kind!= Multiname.MULTINAMELA){ + if (abc.constants.getMultiname(multinameIndex).needsName()) { + ret--; + } } if (abc.constants.getMultiname(multinameIndex).needsNs()) { ret--; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java index c72b14b31..40ded5a9b 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/instructions/other/SetPropertyIns.java @@ -35,6 +35,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreDecrementAVM2Item import com.jpexs.decompiler.flash.abc.avm2.model.operations.PreIncrementAVM2Item; import com.jpexs.decompiler.flash.abc.types.MethodBody; import com.jpexs.decompiler.flash.abc.types.MethodInfo; +import com.jpexs.decompiler.flash.abc.types.Multiname; import com.jpexs.decompiler.graph.GraphTargetItem; import java.util.HashMap; import java.util.List; @@ -133,6 +134,10 @@ public class SetPropertyIns extends InstructionDefinition implements SetTypeIns public int getStackDelta(AVM2Instruction ins, ABC abc) { int ret = -2; int multinameIndex = ins.operands[0]; + int multinameKind = abc.constants.getMultiname(multinameIndex).kind; + if(multinameKind == Multiname.MULTINAMEL || multinameKind == Multiname.MULTINAMELA){ + return 0; + } if (abc.constants.getMultiname(multinameIndex).needsName()) { ret--; } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/PostDecrementAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/PostDecrementAVM2Item.java index 0658737dc..a3586bde2 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/PostDecrementAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/PostDecrementAVM2Item.java @@ -18,8 +18,6 @@ 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.instructions.arithmetic.DecrementIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIns; import com.jpexs.decompiler.flash.abc.avm2.model.clauses.AssignmentAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/PostIncrementAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/PostIncrementAVM2Item.java index 9f06957f5..58ac3ed7f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/PostIncrementAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/PostIncrementAVM2Item.java @@ -18,19 +18,8 @@ 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.instructions.arithmetic.IncrementIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.DupIns; import com.jpexs.decompiler.flash.abc.avm2.model.clauses.AssignmentAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.parser.script.AVM2SourceGenerator; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.parser.script.NameAVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.parser.script.PropertyAVM2Item; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/UndefinedAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/UndefinedAVM2Item.java index fcdfaf09f..129e48d53 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/UndefinedAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/UndefinedAVM2Item.java @@ -18,7 +18,6 @@ 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.instructions.stack.PushNullIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PushUndefinedIns; import com.jpexs.decompiler.flash.ecma.Undefined; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreDecrementAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreDecrementAVM2Item.java index 715cb68fd..7ebf87de4 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreDecrementAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreDecrementAVM2Item.java @@ -18,8 +18,6 @@ package com.jpexs.decompiler.flash.abc.avm2.model.operations; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.DecrementIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIns; import com.jpexs.decompiler.flash.abc.avm2.model.clauses.AssignmentAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item; import com.jpexs.decompiler.graph.GraphSourceItem; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreIncrementAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreIncrementAVM2Item.java index 421696853..25090bb54 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreIncrementAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/model/operations/PreIncrementAVM2Item.java @@ -18,7 +18,6 @@ package com.jpexs.decompiler.flash.abc.avm2.model.operations; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; -import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIns; import com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java index 4a57e4dc0..c3be4b07d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java @@ -32,7 +32,6 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetScopeObjectIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.InitPropertyIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ReturnValueIns; @@ -80,7 +79,6 @@ import com.jpexs.decompiler.graph.model.DoWhileItem; import com.jpexs.decompiler.graph.model.DuplicateItem; import com.jpexs.decompiler.graph.model.ForItem; import com.jpexs.decompiler.graph.model.IfItem; -import com.jpexs.decompiler.graph.model.LocalData; import com.jpexs.decompiler.graph.model.NotItem; import com.jpexs.decompiler.graph.model.OrItem; import com.jpexs.decompiler.graph.model.SwitchItem; @@ -564,7 +562,7 @@ public class AVM2SourceGenerator implements SourceGenerator { return abc; } - public void generateClass(int initScope, PackageAVM2Item pkg, ClassInfo classInfo, InstanceInfo instanceInfo, SourceGeneratorLocalData localData, boolean isInterface, String name, String superName, GraphTargetItem extendsVal, List implementsStr, GraphTargetItem constructor, List traitItems) throws ParseException { + public void generateClass(int namespace, int initScope, PackageAVM2Item pkg, ClassInfo classInfo, InstanceInfo instanceInfo, SourceGeneratorLocalData localData, boolean isInterface, String name, String superName, GraphTargetItem extendsVal, List implementsStr, GraphTargetItem constructor, List traitItems) throws ParseException { localData.currentClass = pkg.packageName.equals("") ? name : pkg.packageName + "." + name; List ret = new ArrayList<>(); if (extendsVal == null && !isInterface) { @@ -597,11 +595,11 @@ public class AVM2SourceGenerator implements SourceGenerator { if (ti instanceof SlotAVM2Item) { SlotAVM2Item si = (SlotAVM2Item) ti; if (si.isStatic()) { - mb.code.code.add(ins(new FindPropertyStrictIns(), traitName(pkg.packageName, name, si.getNsKind(), si.var))); + mb.code.code.add(ins(new FindPropertyStrictIns(), traitName(namespace, si.var))); List tis = new ArrayList<>(); tis.add(si.value); mb.code.code.addAll(toInsList(generate(localData, tis))); - mb.code.code.add(ins(new InitPropertyIns(), traitName(pkg.packageName, name, si.getNsKind(), si.var))); + mb.code.code.add(ins(new InitPropertyIns(), traitName(namespace, si.var))); } } } @@ -634,7 +632,7 @@ public class AVM2SourceGenerator implements SourceGenerator { return ret; } - public int generateClass(ClassInfo ci, InstanceInfo ii, int initScope, PackageAVM2Item pkg, SourceGeneratorLocalData localData, AVM2Item cls) throws ParseException { + public int generateClass(int namespace, ClassInfo ci, InstanceInfo ii, int initScope, PackageAVM2Item pkg, SourceGeneratorLocalData localData, AVM2Item cls) throws ParseException { /*ClassInfo ci = new ClassInfo(); InstanceInfo ii = new InstanceInfo(); abc.class_info.add(ci); @@ -642,7 +640,7 @@ public class AVM2SourceGenerator implements SourceGenerator { */ if (cls instanceof ClassAVM2Item) { ClassAVM2Item cai = (ClassAVM2Item) cls; - generateClass(initScope, pkg, ci, ii, localData, false, cai.className, cai.extendsOp.toString(), cai.extendsOp, cai.implementsOp, cai.constructor, cai.traits); + generateClass(namespace, initScope, pkg, ci, ii, localData, false, cai.className, cai.extendsOp.toString(), cai.extendsOp, cai.implementsOp, cai.constructor, cai.traits); if (!cai.isDynamic) { ii.flags |= InstanceInfo.CLASS_SEALED; } @@ -650,19 +648,19 @@ public class AVM2SourceGenerator implements SourceGenerator { ii.flags |= InstanceInfo.CLASS_FINAL; } ii.flags |= InstanceInfo.CLASS_PROTECTEDNS; - ii.protectedNS = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PROTECTED, abc.constants.getStringId(pkg.packageName + ":" + cai.className, true)), 0, true); + ii.protectedNS = cai.protectedNs; } if (cls instanceof InterfaceAVM2Item) { InterfaceAVM2Item iai = (InterfaceAVM2Item) cls; - generateClass(initScope, pkg, ci, ii, localData, true, iai.name, null, null, iai.superInterfaces, null, iai.methods); + generateClass(namespace, initScope, pkg, ci, ii, localData, true, iai.name, null, null, iai.superInterfaces, null, iai.methods); ii.flags |= InstanceInfo.CLASS_INTERFACE; } return abc.instance_info.size() - 1; } - public int traitName(String pkg, String className, int nsKind, String var) { - return abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(var), namespace(nsKind, nsKind != Namespace.KIND_PACKAGE && className != null ? (pkg + ":" + className) : ""), 0, 0, new ArrayList()), true); + public int traitName(int namespace, String var) { + return abc.constants.getMultinameId(new Multiname(Multiname.QNAME, str(var), namespace, 0, 0, new ArrayList()), true); } public int typeName(SourceGeneratorLocalData localData, GraphTargetItem type) { @@ -900,11 +898,11 @@ public class AVM2SourceGenerator implements SourceGenerator { continue; } if (item instanceof InterfaceAVM2Item) { - generateClass(abc.class_info.get(((TraitClass) traits[k]).class_info), abc.instance_info.get(((TraitClass) traits[k]).class_info), initScope, pkg, localData, (InterfaceAVM2Item) item); + generateClass(((InterfaceAVM2Item) item).namespace, abc.class_info.get(((TraitClass) traits[k]).class_info), abc.instance_info.get(((TraitClass) traits[k]).class_info), initScope, pkg, localData, (InterfaceAVM2Item) item); } if (item instanceof ClassAVM2Item) { - generateClass(abc.class_info.get(((TraitClass) traits[k]).class_info), abc.instance_info.get(((TraitClass) traits[k]).class_info), initScope, pkg, localData, (ClassAVM2Item) item); + generateClass(((ClassAVM2Item) item).namespace, abc.class_info.get(((TraitClass) traits[k]).class_info), abc.instance_info.get(((TraitClass) traits[k]).class_info), initScope, pkg, localData, (ClassAVM2Item) item); } if ((item instanceof MethodAVM2Item) || (item instanceof GetterAVM2Item) || (item instanceof SetterAVM2Item)) { MethodAVM2Item mai = (MethodAVM2Item) item; @@ -912,7 +910,6 @@ public class AVM2SourceGenerator implements SourceGenerator { continue; } Reference hasArgs = new Reference<>(Boolean.FALSE); - calcRegisters(localData, mai, hasArgs); ((TraitMethodGetterSetter) traits[k]).method_info = method(initScope + 1/*class scope*/, mai.hasRest, hasArgs.getVal(), mai.line, className, superName, false, localData, mai.paramTypes, mai.paramNames, mai.paramValues, mai.body, mai.retType); } else if (item instanceof FunctionAVM2Item) { @@ -937,7 +934,7 @@ public class AVM2SourceGenerator implements SourceGenerator { abc.instance_info.add(ii); tc.class_info = abc.instance_info.size() - 1; tc.kindType = Trait.TRAIT_CLASS; - tc.name_index = traitName(pkg.packageName, className, ((InterfaceAVM2Item) item).namespaceKind, ((InterfaceAVM2Item) item).name); + tc.name_index = traitName(((InterfaceAVM2Item) item).namespace, ((InterfaceAVM2Item) item).name); tc.slot_id = slot_id++; ts.traits.add(tc); traits[k] = tc; @@ -961,7 +958,7 @@ public class AVM2SourceGenerator implements SourceGenerator { } tc.kindType = Trait.TRAIT_CLASS; - tc.name_index = traitName(pkg.packageName, className, ((ClassAVM2Item) item).namespaceKind, ((ClassAVM2Item) item).className); + tc.name_index = traitName(((ClassAVM2Item) item).namespace, ((ClassAVM2Item) item).className); tc.slot_id = slot_id++; ts.traits.add(tc); traits[k] = tc; @@ -974,7 +971,8 @@ public class AVM2SourceGenerator implements SourceGenerator { GraphTargetItem val = null; GraphTargetItem type = null; boolean isNamespace = false; - int nsKind = 0; + int namespace = 0; + boolean isStatic = false; if (item instanceof SlotAVM2Item) { SlotAVM2Item sai = (SlotAVM2Item) item; if (sai.isStatic() != generateStatic) { @@ -983,7 +981,8 @@ public class AVM2SourceGenerator implements SourceGenerator { var = sai.var; val = sai.value; type = sai.type; - nsKind = sai.getNsKind(); + isStatic = sai.isStatic(); + namespace = sai.getNamespace(); } if (item instanceof ConstAVM2Item) { ConstAVM2Item cai = (ConstAVM2Item) item; @@ -993,20 +992,21 @@ public class AVM2SourceGenerator implements SourceGenerator { var = cai.var; val = cai.value; type = cai.type; - nsKind = cai.getNsKind(); + namespace = cai.getNamespace(); isNamespace = type.toString().equals("Namespace"); + isStatic = cai.isStatic(); } - tsc.name_index = traitName(pkg.packageName, className, nsKind, var); + tsc.name_index = traitName(namespace, var); tsc.type_index = isNamespace ? 0 : typeName(localData, type); - ValueKind vk = getValueKind(nsKind, type, val); + ValueKind vk = getValueKind(abc.constants.constant_namespace.get(namespace).kind, type, val); if (vk == null) { tsc.value_kind = ValueKind.CONSTANT_Undefined; } else { tsc.value_kind = vk.value_kind; tsc.value_index = vk.value_index; } - tsc.slot_id = slot_id++; + tsc.slot_id = isStatic ? slot_id++ : 0; ts.traits.add(tsc); traits[k] = tsc; } @@ -1017,7 +1017,7 @@ public class AVM2SourceGenerator implements SourceGenerator { } TraitMethodGetterSetter tmgs = new TraitMethodGetterSetter(); tmgs.kindType = (item instanceof MethodAVM2Item) ? Trait.TRAIT_METHOD : ((item instanceof GetterAVM2Item) ? Trait.TRAIT_GETTER : Trait.TRAIT_SETTER); - tmgs.name_index = traitName(pkg.packageName, className, ((MethodAVM2Item) item).namespaceKind, ((MethodAVM2Item) item).functionName); + tmgs.name_index = traitName(((MethodAVM2Item) item).namespace, ((MethodAVM2Item) item).functionName); tmgs.disp_id = 0; //0 = disable override optimization; TODO: handle this if (mai.isFinal()) { tmgs.kindFlags |= Trait.ATTR_Final; @@ -1032,7 +1032,7 @@ public class AVM2SourceGenerator implements SourceGenerator { TraitFunction tf = new TraitFunction(); tf.slot_id = slot_id++; tf.kindType = Trait.TRAIT_FUNCTION; - tf.name_index = traitName(pkg.packageName, className, Namespace.KIND_PACKAGE, ((FunctionAVM2Item) item).functionName); + tf.name_index = traitName(((FunctionAVM2Item) item).namespace, ((FunctionAVM2Item) item).functionName); ts.traits.add(tf); traits[k] = tf; } @@ -1110,17 +1110,44 @@ public class AVM2SourceGenerator implements SourceGenerator { } } - public static boolean searchProperty(List abcs, String pkg, String obj, String propertyName, Reference outName, Reference outNs, Reference outPropNs, Reference outPropNsKind) { + public static GraphTargetItem getTraitReturnType(ABC abc, Trait t) { + if (t instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) t; + if (tsc.type_index == 0) { + return TypeItem.UNBOUNDED; + } + return new TypeItem(abc.constants.constant_multiname.get(tsc.type_index).getNameWithNamespace(abc.constants)); + } + if (t instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t; + if (tmgs.kindType == Trait.TRAIT_GETTER) { + return new TypeItem(abc.constants.constant_multiname.get(abc.method_info.get(tmgs.method_info).ret_type).getNameWithNamespace(abc.constants)); + } + if (tmgs.kindType == Trait.TRAIT_SETTER) { + return new TypeItem(abc.constants.constant_multiname.get(abc.method_info.get(tmgs.method_info).param_types[0]).getNameWithNamespace(abc.constants)); + } + } + if (t instanceof TraitFunction) { + return new TypeItem("Function"); + } + return TypeItem.UNBOUNDED; + } + + public static boolean searchPrototypeChain(boolean instanceOnly, List abcs, String pkg, String obj, String propertyName, Reference outName, Reference outNs, Reference outPropNs, Reference outPropNsKind, Reference outPropType) { + for (ABC abc : abcs) { - for (ScriptInfo ii : abc.script_info) { - for (Trait t : ii.traits.traits) { - if (pkg.equals(t.getName(abc).getNamespace(abc.constants).getName(abc.constants))) { - if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList()))) { - outName.setVal(obj); - outNs.setVal(pkg); - outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants)); - outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind); - return true; + if (!instanceOnly) { + for (ScriptInfo ii : abc.script_info) { + for (Trait t : ii.traits.traits) { + if (pkg.equals(t.getName(abc).getNamespace(abc.constants).getName(abc.constants))) { + if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList()))) { + outName.setVal(obj); + outNs.setVal(pkg); + outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants)); + outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind); + outPropType.setVal(getTraitReturnType(abc, t).toString()); + return true; + } } } } @@ -1138,23 +1165,27 @@ public class AVM2SourceGenerator implements SourceGenerator { outNs.setVal(pkg); outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants)); outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind); + outPropType.setVal(getTraitReturnType(abc, t).toString()); return true; } } - for (Trait t : abc.class_info.get(i).static_traits.traits) { - if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList()))) { - outName.setVal(obj); - outNs.setVal(pkg); - outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants)); - outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind); - return true; + if (!instanceOnly) { + for (Trait t : abc.class_info.get(i).static_traits.traits) { + if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList()))) { + outName.setVal(obj); + outNs.setVal(pkg); + outPropNs.setVal(t.getName(abc).getNamespace(abc.constants).getName(abc.constants)); + outPropNsKind.setVal(t.getName(abc).getNamespace(abc.constants).kind); + outPropType.setVal(getTraitReturnType(abc, t).toString()); + return true; + } } } Multiname superName = abc.constants.constant_multiname.get(ii.super_index); if (superName != null) { - return searchProperty(abcs, superName.getNamespace(abc.constants).getName(abc.constants), superName.getName(abc.constants, new ArrayList()), propertyName, outName, outNs, outPropNs, outPropNsKind); + return searchPrototypeChain(instanceOnly, abcs, superName.getNamespace(abc.constants).getName(abc.constants), superName.getName(abc.constants, new ArrayList()), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropType); } else { return false; } @@ -1221,36 +1252,30 @@ public class AVM2SourceGenerator implements SourceGenerator { List abcs = new ArrayList<>(); abcs.add(abc); abcs.addAll(allABCs); - String parts[] = new String[]{n.getVariableName()}; - if (n.getVariableName().contains(".")) { - parts = n.getVariableName().split("\\."); - } - loopi: + for (int i = 0; i < n.openedNamespaces.size(); i++) { - String ns = n.openedNamespaces.get(i); - String nspkg = ns; - String nsclass = null; - int nsKind = n.openedNamespacesKind.get(i); - if (nspkg.contains(":") && nsKind != Namespace.KIND_NAMESPACE) { - nsclass = nspkg.substring(nspkg.indexOf(":") + 1); - nspkg = nspkg.substring(0, nspkg.indexOf(":")); - } - for (int h = 0; h < abc.instance_info.size(); h++) { - InstanceInfo ii = abc.instance_info.get(h); - Multiname mn = abc.constants.constant_multiname.get(ii.name_index); - if (mn.getNamespace(abc.constants).getName(abc.constants).equals(nspkg) && (nsclass == null || (mn.getName(abc.constants, new ArrayList()).equals(nsclass)))) { - //found opened class - Reference outName = new Reference<>(""); - Reference outNs = new Reference<>(""); - Reference outPropNs = new Reference<>(""); - Reference outPropNsKind = new Reference<>(1); - if (AVM2SourceGenerator.searchProperty(abcs, nspkg, mn.getName(abc.constants, new ArrayList()), parts[0], outName, outNs, outPropNs, outPropNsKind)) { - resolved = new PropertyAVM2Item(null, parts[0], n.getIndex(), abcs, n.openedNamespaces, n.openedNamespacesKind); - break loopi; + int nsIndex = n.openedNamespaces.get(i); + Namespace ns = abc.constants.constant_namespace.get(nsIndex); + int nsKind = ns.kind; + loopabc: + for (ABC a : abcs) { + for (int h = 0; h < a.instance_info.size(); h++) { + InstanceInfo ii = a.instance_info.get(h); + Multiname nm = a.constants.constant_multiname.get(ii.name_index); + if (nm.getNamespace(a.constants).getName(a.constants).equals(ns.getName(abc.constants)) && nm.getNamespace(a.constants).kind == nsKind) { + + //found opened class + Reference outName = new Reference<>(""); + Reference outNs = new Reference<>(""); + Reference outPropNs = new Reference<>(""); + Reference outPropNsKind = new Reference<>(1); + Reference outPropType = new Reference<>(""); + if (AVM2SourceGenerator.searchPrototypeChain(false, abcs, nm.getNamespace(a.constants).getName(a.constants), nm.getName(a.constants, new ArrayList()), n.getVariableName(), outName, outNs, outPropNs, outPropNsKind, outPropType)) { + resolved = new PropertyAVM2Item(null, n.getVariableName(), n.getIndex(), abc, allABCs, n.openedNamespaces); + } } } } - } n.redirect = resolved; if (resolved == null) { diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java index 9d3bfdaf8..783e1fc96 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptLexer.java @@ -19,9 +19,9 @@ package com.jpexs.decompiler.flash.abc.avm2.parser.script; import com.jpexs.decompiler.flash.abc.avm2.parser.ParseException; -import java.util.Stack; -import java.util.List; import java.util.ArrayList; +import java.util.List; +import java.util.Stack; /** * This class is a scanner generated by diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java index 72deaaff7..7e3256145 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScriptParser.java @@ -129,13 +129,13 @@ public class ActionScriptParser { return uniqLast; } - private List commands(List openedNamespaces, List openedNamespacesKinds, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, List variables) throws IOException, ParseException { + private List commands(List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, List variables) throws IOException, ParseException { List ret = new ArrayList<>(); if (debugMode) { System.out.println("commands:"); } GraphTargetItem cmd = null; - while ((cmd = command(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)) != null) { + while ((cmd = command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)) != null) { ret.add(cmd); } if (debugMode) { @@ -144,7 +144,7 @@ public class ActionScriptParser { return ret; } - private GraphTargetItem type(List openedNamespaces, List openedNamespacesKinds, List variables) throws IOException, ParseException { + private GraphTargetItem type(List importedClasses, List openedNamespaces, List variables) throws IOException, ParseException { ParsedSymbol s = lex(); if (s.type == SymbolType.MULTIPLY) { return new UnboundedTypeItem(); @@ -153,20 +153,20 @@ public class ActionScriptParser { } else { lexer.pushback(s); } - return name(true, openedNamespaces, openedNamespacesKinds, null, false, false, variables); + return name(true, openedNamespaces, null, false, false, variables, importedClasses); } - private GraphTargetItem memberOrCall(List openedNamespaces, List openedNamespacesKinds, GraphTargetItem newcmds, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, ParseException { + private GraphTargetItem memberOrCall(List importedClasses, List openedNamespaces, GraphTargetItem newcmds, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, ParseException { ParsedSymbol s = lex(); GraphTargetItem ret = newcmds; while (s.isType(SymbolType.DOT, SymbolType.PARENT_OPEN)) { switch (s.type) { case DOT: lexer.pushback(s); - ret = member(openedNamespaces, openedNamespacesKinds, ret, registerVars, inFunction, inMethod, variables); + ret = member(importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); break; case PARENT_OPEN: - ret = new CallAVM2Item(ret, call(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, variables)); + ret = new CallAVM2Item(ret, call(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); break; } s = lex(); @@ -175,7 +175,7 @@ public class ActionScriptParser { return ret; } - private GraphTargetItem member(List openedNamespaces, List openedNamespacesKinds, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, ParseException { + private GraphTargetItem member(List importedClasses, List openedNamespaces, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, ParseException { GraphTargetItem ret = obj; ParsedSymbol s = lex(); while (s.isType(SymbolType.DOT)) { @@ -185,21 +185,18 @@ public class ActionScriptParser { s = lex(); GraphTargetItem index = null; if (s.type == SymbolType.BRACKET_OPEN) { - index = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables); + index = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); expectedType(SymbolType.BRACKET_CLOSE); } else { lexer.pushback(s); } - List allAbcs = new ArrayList<>(); - allAbcs.add(abc); - allAbcs.addAll(otherABCs); - ret = new PropertyAVM2Item(ret, propName, index, allAbcs, openedNamespaces, openedNamespacesKinds); + ret = new PropertyAVM2Item(ret, propName, index, abc, otherABCs, openedNamespaces); } lexer.pushback(s); return ret; } - private GraphTargetItem name(boolean typeOnly, List openedNamespaces, List openedNamespacesKinds, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, ParseException { + private GraphTargetItem name(boolean typeOnly, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, List importedClasses) throws IOException, ParseException { ParsedSymbol s = lex(); expected(s, lexer.yyline(), SymbolType.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolType.STRING_OP); List parts = new ArrayList<>(); @@ -213,56 +210,53 @@ public class ActionScriptParser { } GraphTargetItem index = null; if (s.type == SymbolType.BRACKET_OPEN) { - index = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables); + index = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); expectedType(SymbolType.BRACKET_CLOSE); } else { lexer.pushback(s); } - List allAbcs = new ArrayList<>(); - allAbcs.add(abc); - allAbcs.addAll(otherABCs); if (!typeOnly) { for (NameAVM2Item n : variables) { if (n.getVariableName().equals(parts.get(0))) { - NameAVM2Item ni = new NameAVM2Item(n.type, lexer.yyline(), n.getVariableName(), null, false, openedNamespaces, openedNamespacesKinds); + NameAVM2Item ni = new NameAVM2Item(n.type, lexer.yyline(), n.getVariableName(), null, false, openedNamespaces); variables.add(ni); GraphTargetItem ret = ni; if (parts.size() == 1) { ((NameAVM2Item) ret).setIndex(index); } for (int i = 1; i < parts.size(); i++) { - ret = new PropertyAVM2Item(ret, parts.get(i), i == parts.size() - 1 ? index : null, allAbcs, openedNamespaces, openedNamespacesKinds); + ret = new PropertyAVM2Item(ret, parts.get(i), i == parts.size() - 1 ? index : null, abc, otherABCs, openedNamespaces); } return ret; } } } + + List allAbcs = new ArrayList<>(); + allAbcs.add(abc); + allAbcs.addAll(otherABCs); //search for variable in openedNamespaces if (!typeOnly) { for (int i = 0; i < openedNamespaces.size(); i++) { - String ns = openedNamespaces.get(i); - String nspkg = ns; - String nsclass = null; - int nsKind = openedNamespacesKinds.get(i); - if (nspkg.contains(":") && nsKind != Namespace.KIND_NAMESPACE) { - nsclass = nspkg.substring(nspkg.indexOf(":") + 1); - nspkg = nspkg.substring(0, nspkg.indexOf(":")); - } + int nsIndex = openedNamespaces.get(i); + Namespace ns = abc.constants.constant_namespace.get(nsIndex); + int nsKind = ns.kind; loopabc: for (ABC a : allAbcs) { for (int h = 0; h < a.instance_info.size(); h++) { InstanceInfo ii = a.instance_info.get(h); Multiname n = a.constants.constant_multiname.get(ii.name_index); - if (n.getNamespace(a.constants).getName(a.constants).equals(nspkg) && (nsclass == null || (n.getName(a.constants, new ArrayList()).equals(nsclass)))) { + if (n.getNamespace(a.constants).getName(a.constants).equals(ns.getName(abc.constants)) && n.getNamespace(a.constants).kind == nsKind) { //found opened class Reference outName = new Reference<>(""); Reference outNs = new Reference<>(""); Reference outPropNs = new Reference<>(""); Reference outPropNsKind = new Reference<>(1); - if (AVM2SourceGenerator.searchProperty(allAbcs, nspkg, n.getName(a.constants, new ArrayList()), parts.get(0), outName, outNs, outPropNs, outPropNsKind)) { - return new PropertyAVM2Item(null, parts.get(0), index, allAbcs, openedNamespaces, openedNamespacesKinds); + Reference outPropType = new Reference<>(""); + if (AVM2SourceGenerator.searchPrototypeChain(false, allAbcs, n.getNamespace(a.constants).getName(a.constants), n.getName(a.constants, new ArrayList()), parts.get(0), outName, outNs, outPropNs, outPropNsKind, outPropType)) { + return new PropertyAVM2Item(null, parts.get(0), index, abc, otherABCs, openedNamespaces); } } } @@ -270,6 +264,7 @@ public class ActionScriptParser { } } + //variable not found, gonna search types String pkg = ""; String name = null; @@ -277,10 +272,28 @@ public class ActionScriptParser { int k; loopk: for (k = parts.size() - 1; k >= 0; k--) { + if (typeOnly) { if (k < parts.size() - 1) { k = -1; - break; + break loopk; + } + } + if (k == 0 || typeOnly) { + for (int i = 0; i < importedClasses.size(); i++) { + String iname = importedClasses.get(i); + String ipkg = ""; + if (iname.contains(".")) { + ipkg = iname.substring(0, iname.lastIndexOf(".")); + iname = iname.substring(iname.lastIndexOf(".") + 1); + } + if (iname.equals(parts.get(0))) { + k = 0; + pkg = ipkg; + name = iname; + break loopk; + } + } } pkg = ""; @@ -292,39 +305,34 @@ public class ActionScriptParser { } name = parts.get(k); - for (int i = 0; i < openedNamespaces.size(); i++) { - String ns = openedNamespaces.get(i); - String nspkg = ns; - String nsclass = null; - int nsKind = openedNamespacesKinds.get(i); - if (nspkg.contains(":") && nsKind != Namespace.KIND_NAMESPACE) { - nsclass = nspkg.substring(nspkg.indexOf(":") + 1); - nspkg = nspkg.substring(0, nspkg.indexOf(":")); + String fname = pkg.equals("") ? name : pkg + "." + name; + + for (ABC a : allAbcs) { + int c = a.findClassByName(fname); + if (c != -1) { + break loopk; } - if (nspkg.equals(pkg) || pkg.equals("")) { - if (nsclass == null) { - loopabc: - for (ABC a : allAbcs) { - for (InstanceInfo ii : a.instance_info) { - Multiname n = a.constants.constant_multiname.get(ii.name_index); - if (n.getNamespace(a.constants).kind == nsKind && n.getNamespace(a.constants).getName(a.constants).equals(nspkg) && n.getName(a.constants, new ArrayList()).equals(name)) { - foundNsKind = n.getNamespace(a.constants).kind; - pkg = nspkg; - break loopk; - } - } + } + + for (int i = 0; i < openedNamespaces.size(); i++) { + int nsIndex = openedNamespaces.get(i); + Namespace ns = abc.constants.constant_namespace.get(nsIndex); + int nsKind = ns.kind; + String nsname = ns.getName(abc.constants); + if (nsKind == Namespace.KIND_PACKAGE) { + for (ABC a : allAbcs) { + int c = a.findClassByName(nsname.equals("") ? fname : nsname + "." + fname); + if (c != -1) { + pkg = nsname; + break loopk; } - } else if (name.equals(nsclass)) { - pkg = nspkg; - foundNsKind = openedNamespacesKinds.get(i); - break loopk; } } } } if (k == -1) { - NameAVM2Item ret = new NameAVM2Item(null, lexer.yyline(), Helper.joinStrings(parts, "."), null, false, openedNamespaces, openedNamespacesKinds); + NameAVM2Item ret = new NameAVM2Item(null, lexer.yyline(), Helper.joinStrings(parts, "."), null, false, openedNamespaces); ret.unresolved = true; ret.setIndex(index); variables.add(ret); @@ -333,7 +341,7 @@ public class ActionScriptParser { } GraphTargetItem ret = new TypeItem("".equals(pkg) ? name : pkg + "." + name); for (int i = 1; i < parts.size(); i++) { - ret = new PropertyAVM2Item(ret, parts.get(i), i == parts.size() - 1 ? index : null, allAbcs, openedNamespaces, openedNamespacesKinds); + ret = new PropertyAVM2Item(ret, parts.get(i), i == parts.size() - 1 ? index : null, abc, otherABCs, openedNamespaces); } return ret; } @@ -376,7 +384,7 @@ public class ActionScriptParser { return ret; } - private List call(List openedNamespaces, List openedNamespacesKinds, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, ParseException { + private List call(List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, ParseException { List ret = new ArrayList<>(); //expected(SymbolType.PARENT_OPEN); //MUST BE HANDLED BY CALLER ParsedSymbol s = lex(); @@ -384,19 +392,19 @@ public class ActionScriptParser { if (s.type != SymbolType.COMMA) { lexer.pushback(s); } - ret.add(expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables)); + ret.add(expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); s = lex(); expected(s, lexer.yyline(), SymbolType.COMMA, SymbolType.PARENT_CLOSE); } return ret; } - private MethodAVM2Item method(boolean override, boolean isFinal, GraphTargetItem thisType, List openedNamespaces, List openedNamespacesKinds, boolean isStatic, int namespaceKind, boolean withBody, String functionName, boolean isMethod, List variables) throws IOException, ParseException { - FunctionAVM2Item f = function(thisType, openedNamespaces, openedNamespacesKinds, withBody, functionName, isMethod, variables); - return new MethodAVM2Item(f.hasRest, f.line, override, isFinal, isStatic, namespaceKind, functionName, f.paramTypes, f.paramNames, f.paramValues, f.body, f.subvariables, f.retType); + private MethodAVM2Item method(List importedClasses, boolean override, boolean isFinal, GraphTargetItem thisType, List openedNamespaces, boolean isStatic, int namespace, boolean withBody, String functionName, boolean isMethod, List variables) throws IOException, ParseException { + FunctionAVM2Item f = function(importedClasses, namespace, thisType, openedNamespaces, withBody, functionName, isMethod, variables); + return new MethodAVM2Item(f.hasRest, f.line, override, isFinal, isStatic, f.namespace, functionName, f.paramTypes, f.paramNames, f.paramValues, f.body, f.subvariables, f.retType); } - private FunctionAVM2Item function(GraphTargetItem thisType, List openedNamespaces, List openedNamespacesKinds, boolean withBody, String functionName, boolean isMethod, List variables) throws IOException, ParseException { + private FunctionAVM2Item function(List importedClasses, int namespace, GraphTargetItem thisType, List openedNamespaces, boolean withBody, String functionName, boolean isMethod, List variables) throws IOException, ParseException { int line = lexer.yyline(); ParsedSymbol s; expectedType(SymbolType.PARENT_OPEN); @@ -420,13 +428,13 @@ public class ActionScriptParser { s = lex(); if (!hasRest) { if (s.type == SymbolType.COLON) { - paramTypes.add(type(openedNamespaces, openedNamespacesKinds, variables)); + paramTypes.add(type(importedClasses, openedNamespaces, variables)); s = lex(); } else { paramTypes.add(new UnboundedTypeItem()); } if (s.type == SymbolType.ASSIGN) { - paramValues.add(expression(openedNamespaces, openedNamespacesKinds, null, isMethod, isMethod, isMethod, variables)); + paramValues.add(expression(importedClasses, openedNamespaces, null, isMethod, isMethod, isMethod, variables)); } else { if (!paramValues.isEmpty()) { throw new ParseException("Some of parameters do not have default values", lexer.yyline()); @@ -444,33 +452,33 @@ public class ActionScriptParser { s = lex(); GraphTargetItem retType; if (s.type == SymbolType.COLON) { - retType = type(openedNamespaces, openedNamespacesKinds, variables); + retType = type(importedClasses, openedNamespaces, variables); } else { retType = new UnboundedTypeItem(); lexer.pushback(s); } List body = null; List subvariables = new ArrayList<>(); - subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), "this", null, true, openedNamespaces, openedNamespacesKinds)); + subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), "this", null, true, openedNamespaces)); for (int i = 0; i < paramNames.size(); i++) { - subvariables.add(new NameAVM2Item(paramTypes.get(i), lexer.yyline(), paramNames.get(i), null, true, openedNamespaces, openedNamespacesKinds)); + subvariables.add(new NameAVM2Item(paramTypes.get(i), lexer.yyline(), paramNames.get(i), null, true, openedNamespaces)); } - subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), "arguments", null, true, openedNamespaces, openedNamespacesKinds)); + subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), "arguments", null, true, openedNamespaces)); int parCnt = subvariables.size(); if (withBody) { expectedType(SymbolType.CURLY_OPEN); - body = commands(openedNamespaces, openedNamespacesKinds, new Stack(), new HashMap(), new HashMap(), true, isMethod, 0, subvariables); + body = commands(importedClasses, openedNamespaces, new Stack(), new HashMap(), new HashMap(), true, isMethod, 0, subvariables); expectedType(SymbolType.CURLY_CLOSE); } for (int i = 0; i < parCnt; i++) { subvariables.remove(0); } - return new FunctionAVM2Item(hasRest, line, functionName, paramTypes, paramNames, paramValues, body, subvariables, retType); + return new FunctionAVM2Item(namespace, hasRest, line, functionName, paramTypes, paramNames, paramValues, body, subvariables, retType); } - private GraphTargetItem traits(List openedNamespaces, List openedNamespacesKinds, String packageName, String classNameStr, boolean isInterface, List traits) throws ParseException, IOException { + private GraphTargetItem traits(List importedClasses, int privateNs, int protectedNs, int publicNs, int packageInternalNs, int protectedStaticNs, List openedNamespaces, String packageName, String classNameStr, boolean isInterface, List traits) throws ParseException, IOException { ParsedSymbol s; GraphTargetItem constr = null; List variables = new ArrayList<>(); @@ -479,7 +487,7 @@ public class ActionScriptParser { while (true) { s = lex(); boolean isStatic = false; - int nsKind = -1; + int namespace = -1; boolean isGetter = false; boolean isSetter = false; boolean isOverride = false; @@ -518,28 +526,28 @@ public class ActionScriptParser { } isStatic = true; } else { - if (nsKind != -1) { + if (namespace != -1) { throw new ParseException("Only one access identifier allowed", lexer.yyline()); } } switch (s.type) { case PUBLIC: - nsKind = Namespace.KIND_PACKAGE; + namespace = publicNs; break; case PRIVATE: - nsKind = Namespace.KIND_PRIVATE; + namespace = privateNs; break; case PROTECTED: - nsKind = Namespace.KIND_PROTECTED; + namespace = protectedNs; break; } s = lex(); } - if (nsKind == -1) { - nsKind = Namespace.KIND_PACKAGE_INTERNAL; + if (namespace == -1) { + namespace = packageInternalNs; } - if (nsKind == Namespace.KIND_PROTECTED && isStatic) { - nsKind = Namespace.KIND_STATIC_PROTECTED; + if (namespace == protectedNs && isStatic) { + namespace = protectedStaticNs; } switch (s.type) { case CLASS: @@ -550,26 +558,26 @@ public class ActionScriptParser { throw new ParseException("Override flag not allowed for classes", lexer.yyline()); } - //GraphTargetItem classTypeStr = type(openedNamespaces, openedNamespacesKinds, variables); + //GraphTargetItem classTypeStr = type(importedClasses, openedNamespaces, variables); s = lex(); expected(s, lexer.yyline(), SymbolType.IDENTIFIER); String classTypeStr = s.value.toString(); GraphTargetItem extendsTypeStr = null; s = lex(); if (s.type == SymbolType.EXTENDS) { - extendsTypeStr = type(openedNamespaces, openedNamespacesKinds, variables); + extendsTypeStr = type(importedClasses, openedNamespaces, variables); s = lex(); } List implementsTypeStrs = new ArrayList<>(); if (s.type == SymbolType.IMPLEMENTS) { do { - GraphTargetItem implementsTypeStr = type(openedNamespaces, openedNamespacesKinds, variables); + GraphTargetItem implementsTypeStr = type(importedClasses, openedNamespaces, variables); implementsTypeStrs.add(implementsTypeStr); s = lex(); } while (s.type == SymbolType.COMMA); } expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); - traits.add((classTraits(isDynamic, isFinal, openedNamespaces, openedNamespacesKinds, packageName, nsKind, false, classTypeStr, extendsTypeStr, implementsTypeStrs, variables))); + traits.add((classTraits(packageInternalNs, importedClasses, privateNs, isDynamic, isFinal, openedNamespaces, packageName, namespace, false, classTypeStr, extendsTypeStr, implementsTypeStrs, variables))); expectedType(SymbolType.CURLY_CLOSE); break; case INTERFACE: @@ -585,7 +593,7 @@ public class ActionScriptParser { if (isDynamic) { throw new ParseException("Dynamic flag not allowed for interfaces", lexer.yyline()); } - //GraphTargetItem interfaceTypeStr = type(openedNamespaces, openedNamespacesKinds, variables); + //GraphTargetItem interfaceTypeStr = type(importedClasses, openedNamespaces, variables); s = lex(); expected(s, lexer.yyline(), SymbolType.IDENTIFIER); String intTypeStr = s.value.toString(); @@ -594,13 +602,13 @@ public class ActionScriptParser { if (s.type == SymbolType.EXTENDS) { do { - GraphTargetItem intExtendsTypeStr = type(openedNamespaces, openedNamespacesKinds, variables); + GraphTargetItem intExtendsTypeStr = type(importedClasses, openedNamespaces, variables); intExtendsTypeStrs.add(intExtendsTypeStr); s = lex(); } while (s.type == SymbolType.COMMA); } expected(s, lexer.yyline(), SymbolType.CURLY_OPEN); - traits.add((classTraits(false, isFinal, openedNamespaces, openedNamespacesKinds, packageName, nsKind, true, intTypeStr, null, intExtendsTypeStrs, variables))); + traits.add((classTraits(packageInternalNs, importedClasses, privateNs, false, isFinal, openedNamespaces, packageName, namespace, true, intTypeStr, null, intExtendsTypeStrs, variables))); expectedType(SymbolType.CURLY_CLOSE); break; @@ -639,29 +647,29 @@ public class ActionScriptParser { if (isFinal) { throw new ParseException("Final flag not allowed for constructor", lexer.yyline()); } - constr = (method(false, false, thisType, openedNamespaces, openedNamespacesKinds, false, nsKind, !isInterface, "", true, variables)); + constr = (method(importedClasses, false, false, thisType, openedNamespaces, false, namespace, !isInterface, "", true, variables)); } else { if (isStatic) { GraphTargetItem t; - MethodAVM2Item ft = method(isOverride, isFinal, thisType, openedNamespaces, openedNamespacesKinds, isStatic, nsKind, !isInterface, fname, true, variables); + MethodAVM2Item ft = method(importedClasses, isOverride, isFinal, thisType, openedNamespaces, isStatic, namespace, !isInterface, fname, true, variables); traits.add(ft); if (isGetter || isSetter) { throw new ParseException("Getter or Setter cannot be static", lexer.yyline()); } } else { - MethodAVM2Item ft = method(isOverride, isFinal, thisType, openedNamespaces, openedNamespacesKinds, isStatic, nsKind, !isInterface, fname, true, variables); + MethodAVM2Item ft = method(importedClasses, isOverride, isFinal, thisType, openedNamespaces, isStatic, namespace, !isInterface, fname, true, variables); GraphTargetItem t; if (isGetter) { if (!ft.paramTypes.isEmpty()) { throw new ParseException("Getter can't have any parameters", lexer.yyline()); } - GetterAVM2Item g = new GetterAVM2Item(ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespaceKind, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); + GetterAVM2Item g = new GetterAVM2Item(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); t = g; } else if (isSetter) { if (ft.paramTypes.size() != 1) { throw new ParseException("Getter must have exactly one parameter", lexer.yyline()); } - SetterAVM2Item st = new SetterAVM2Item(ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespaceKind, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); + SetterAVM2Item st = new SetterAVM2Item(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); t = st; } else { t = ft; @@ -691,7 +699,7 @@ public class ActionScriptParser { lexer.pushback(s); } - ConstAVM2Item ns = new ConstAVM2Item(true, nsKind, nname, new TypeItem("Namespace"), new StringAVM2Item(null, nval)); + ConstAVM2Item ns = new ConstAVM2Item(true, namespace, nname, new TypeItem("Namespace"), new StringAVM2Item(null, nval)); traits.add(ns); break; case CONST: @@ -713,21 +721,21 @@ public class ActionScriptParser { s = lex(); GraphTargetItem type = null; if (s.type == SymbolType.COLON) { - type = type(openedNamespaces, openedNamespacesKinds, variables); + type = type(importedClasses, openedNamespaces, variables); s = lex(); } GraphTargetItem value = null; if (s.type == SymbolType.ASSIGN) { - value = expression(openedNamespaces, openedNamespacesKinds, new HashMap(), false, false, true, variables); + value = expression(importedClasses, openedNamespaces, new HashMap(), false, false, true, variables); s = lex(); } GraphTargetItem tar; if (isConst) { - tar = new ConstAVM2Item(isStatic, nsKind, vcname, type, value); + tar = new ConstAVM2Item(isStatic, namespace, vcname, type, value); } else { - tar = new SlotAVM2Item(isStatic, nsKind, vcname, type, value); + tar = new SlotAVM2Item(isStatic, namespace, vcname, type, value); } traits.add(tar); if (s.type != SymbolType.SEMICOLON) { @@ -743,7 +751,7 @@ public class ActionScriptParser { return constr; } - private GraphTargetItem classTraits(boolean isDynamic, boolean isFinal, List openedNamespaces, List openedNamespacesKinds, String packageName, int namespaceKind, boolean isInterface, String nameStr, GraphTargetItem extendsStr, List implementsStr, List variables) throws IOException, ParseException { + private GraphTargetItem classTraits(int packageInternalNs, List importedClasses, int privateNs, boolean isDynamic, boolean isFinal, List openedNamespaces, String packageName, int namespace, boolean isInterface, String nameStr, GraphTargetItem extendsStr, List implementsStr, List variables) throws IOException, ParseException { GraphTargetItem ret = null; @@ -753,26 +761,16 @@ public class ActionScriptParser { String classNameStr = nameStr; openedNamespaces = new ArrayList<>(openedNamespaces); - openedNamespacesKinds = new ArrayList<>(openedNamespacesKinds); + //openedNamespacesKinds = new ArrayList<>(openedNamespacesKinds); + + //int privateNs = 0; + int protectedNs = 0; + int publicNs = namespace; + int protectedStaticNs = 0; + + openedNamespaces.add(protectedNs = abc.constants.addNamespace(new Namespace(Namespace.KIND_PROTECTED, abc.constants.getStringId(packageName.equals("") ? classNameStr : packageName + ":" + classNameStr, true)))); + openedNamespaces.add(protectedStaticNs = abc.constants.addNamespace(new Namespace(Namespace.KIND_STATIC_PROTECTED, abc.constants.getStringId(packageName.equals("") ? classNameStr : packageName + ":" + classNameStr, true)))); - openedNamespacesKinds.add(Namespace.KIND_PRIVATE); - openedNamespaces.add(packageName + ":" + classNameStr); - openedNamespacesKinds.add(Namespace.KIND_PACKAGE); - openedNamespaces.add(""); - openedNamespacesKinds.add(Namespace.KIND_PRIVATE); - openedNamespaces.add(classNameStr + ".as$"); - if (!packageName.equals("")) { - openedNamespacesKinds.add(Namespace.KIND_PACKAGE); - openedNamespaces.add(packageName); - } - openedNamespacesKinds.add(Namespace.KIND_PACKAGE_INTERNAL); - openedNamespaces.add(packageName); - openedNamespacesKinds.add(Namespace.KIND_NAMESPACE); - openedNamespaces.add(AS3_NAMESPACE); - openedNamespacesKinds.add(Namespace.KIND_PROTECTED); - openedNamespaces.add(packageName + ":" + classNameStr); - openedNamespacesKinds.add(Namespace.KIND_STATIC_PROTECTED); - openedNamespaces.add(packageName + ":" + classNameStr); List indices = new ArrayList<>(); List names = new ArrayList<>(); List namespaces = new ArrayList<>(); @@ -781,17 +779,15 @@ public class ActionScriptParser { if (namespaces.get(i).equals("")) { continue; } - openedNamespacesKinds.add(Namespace.KIND_STATIC_PROTECTED); - - openedNamespaces.add(namespaces.get(i) + ":" + names.get(i)); + openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_STATIC_PROTECTED, abc.constants.getStringId(namespaces.get(i) + ":" + names.get(i), true)), 0, true)); } - GraphTargetItem constr = traits(openedNamespaces, openedNamespacesKinds, packageName, classNameStr, isInterface, traits); + GraphTargetItem constr = traits(importedClasses, privateNs, protectedNs, publicNs, packageInternalNs, protectedStaticNs, openedNamespaces, packageName, classNameStr, isInterface, traits); if (isInterface) { - return new InterfaceAVM2Item(isFinal, namespaceKind, classNameStr, implementsStr, traits); + return new InterfaceAVM2Item(isFinal, namespace, classNameStr, implementsStr, traits); } else { - return new ClassAVM2Item(isDynamic, isFinal, namespaceKind, classNameStr, extendsStr, implementsStr, constr, traits); + return new ClassAVM2Item(protectedNs, isDynamic, isFinal, namespace, classNameStr, extendsStr, implementsStr, constr, traits); } } @@ -800,7 +796,7 @@ public class ActionScriptParser { switch (s.type) { /*case INT: expectedType(SymbolType.PARENT_OPEN); - ret = new ToIntegerAVM2Item(null, expression(openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); + ret = new ToIntegerAVM2Item(null, expression(importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.PARENT_CLOSE); break; case NUMBER_OP: @@ -811,7 +807,7 @@ public class ActionScriptParser { ret = memberOrCall(vi, registerVars, inFunction, inMethod, variables); } else { expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); - ret = new ToNumberAVM2Item(null, expression(openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); + ret = new ToNumberAVM2Item(null, expression(importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.PARENT_CLOSE); } break; @@ -825,7 +821,7 @@ public class ActionScriptParser { ret = memberOrCall(vi2, registerVars, inFunction, inMethod, variables); } else { expected(s, lexer.yyline(), SymbolType.PARENT_OPEN); - ret = new ToStringAVM2Item(null, expression(openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); + ret = new ToStringAVM2Item(null, expression(importedClasses, openedNamespaces,openedNamespacesKinds,registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.PARENT_CLOSE); ret = memberOrCall(ret, registerVars, inFunction, inMethod, variables); } @@ -836,7 +832,7 @@ public class ActionScriptParser { //return ret; } - private GraphTargetItem command(List openedNamespaces, List openedNamespacesKinds, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, boolean mustBeCommand, List variables) throws IOException, ParseException { + private GraphTargetItem command(List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, boolean mustBeCommand, List variables) throws IOException, ParseException { LexBufferer buf = new LexBufferer(); lexer.addListener(buf); GraphTargetItem ret = null; @@ -862,24 +858,23 @@ public class ActionScriptParser { switch (s.type) { case USE: expectedType(SymbolType.NAMESPACE); - GraphTargetItem ns=type(openedNamespaces, openedNamespacesKinds, variables); - openedNamespaces.add(ns.toString()); - openedNamespacesKinds.add(Namespace.KIND_NAMESPACE); + GraphTargetItem ns = type(importedClasses, openedNamespaces, variables); + openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE /*FIXME?*/, abc.constants.getStringId(ns.toString(), true)), 0, true)); break; case WITH: expectedType(SymbolType.PARENT_OPEN); - GraphTargetItem wvar = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables);//(name(false, openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, variables)); + GraphTargetItem wvar = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//(name(false, openedNamespaces, registerVars, inFunction, inMethod, variables)); if (!isNameOrProp(wvar)) { throw new ParseException("Not a property or name", lexer.yyline()); } expectedType(SymbolType.PARENT_CLOSE); expectedType(SymbolType.CURLY_OPEN); - List wcmd = commands(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables); + List wcmd = commands(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables); expectedType(SymbolType.CURLY_CLOSE); ret = new WithAVM2Item(null, wvar, wcmd); break; /*case DELETE: - GraphTargetItem varDel = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables);//name(false, openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, variables); + GraphTargetItem varDel = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(false, openedNamespaces, registerVars, inFunction, inMethod, variables); if(!isNameOrProp(varDel)){ throw new ParseException("Not a property or name", lexer.yyline()); } @@ -896,7 +891,7 @@ public class ActionScriptParser { case FUNCTION: s = lexer.lex(); expected(s, lexer.yyline(), SymbolType.IDENTIFIER); - ret = (function(TypeItem.UNBOUNDED, openedNamespaces, openedNamespacesKinds, true, s.value.toString(), false, variables)); + ret = (function(importedClasses, 0/*?*/, TypeItem.UNBOUNDED, openedNamespaces, true, s.value.toString(), false, variables)); break; case VAR: s = lex(); @@ -905,29 +900,29 @@ public class ActionScriptParser { s = lex(); GraphTargetItem type; if (s.type == SymbolType.COLON) { - type = type(openedNamespaces, openedNamespacesKinds, variables); + type = type(importedClasses, openedNamespaces, variables); s = lex(); } else { type = new UnboundedTypeItem(); } if (s.type == SymbolType.ASSIGN) { - GraphTargetItem varval = (expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables)); - ret = new NameAVM2Item(type, lexer.yyline(), varIdentifier, varval, true, openedNamespaces, openedNamespacesKinds); + GraphTargetItem varval = (expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); + ret = new NameAVM2Item(type, lexer.yyline(), varIdentifier, varval, true, openedNamespaces); variables.add((NameAVM2Item) ret); } else { - ret = new NameAVM2Item(type, lexer.yyline(), varIdentifier, null, true, openedNamespaces, openedNamespacesKinds); + ret = new NameAVM2Item(type, lexer.yyline(), varIdentifier, null, true, openedNamespaces); variables.add((NameAVM2Item) ret); lexer.pushback(s); } break; case CURLY_OPEN: - ret = new BlockItem(null, commands(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); + ret = new BlockItem(null, commands(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); expectedType(SymbolType.CURLY_CLOSE); break; /*case INCREMENT: //preincrement case DECREMENT: //predecrement - GraphTargetItem varincdec = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables);//name(false, openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, variables); + GraphTargetItem varincdec = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(false, openedNamespaces, registerVars, inFunction, inMethod, variables); if(!isNameOrProp(varincdec)){ throw new ParseException("Not a property or name", lexer.yyline()); } @@ -940,7 +935,7 @@ public class ActionScriptParser { case SUPER: //constructor call ParsedSymbol ss2 = lex(); if (ss2.type == SymbolType.PARENT_OPEN) { - List args = call(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, variables); + List args = call(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); @@ -949,16 +944,16 @@ public class ActionScriptParser { break; case IF: expectedType(SymbolType.PARENT_OPEN); - GraphTargetItem ifExpr = (expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables)); + GraphTargetItem ifExpr = (expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.PARENT_CLOSE); - GraphTargetItem onTrue = command(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); + GraphTargetItem onTrue = command(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(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + onFalseList.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); } else { lexer.pushback(s); } @@ -967,7 +962,7 @@ public class ActionScriptParser { case WHILE: expectedType(SymbolType.PARENT_OPEN); List whileExpr = new ArrayList<>(); - whileExpr.add(commaExpression(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); + whileExpr.add(commaExpression(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); expectedType(SymbolType.PARENT_CLOSE); List whileBody = new ArrayList<>(); Loop wloop = new Loop(uniqId(), null, null); @@ -975,7 +970,7 @@ public class ActionScriptParser { loopLabels.put(wloop, loopLabel); } loops.push(wloop); - whileBody.add(command(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + whileBody.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); ret = new WhileItem(null, wloop, whileExpr, whileBody); break; case DO: @@ -985,11 +980,11 @@ public class ActionScriptParser { if (loopLabel != null) { loopLabels.put(dloop, loopLabel); } - doBody.add(command(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + doBody.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); expectedType(SymbolType.WHILE); expectedType(SymbolType.PARENT_OPEN); List doExpr = new ArrayList<>(); - doExpr.add(commaExpression(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); + doExpr.add(commaExpression(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables)); expectedType(SymbolType.PARENT_CLOSE); ret = new DoWhileItem(null, dloop, doBody, doExpr); break; @@ -1031,7 +1026,7 @@ public class ActionScriptParser { } } } - collection = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables); + collection = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); forin = true; } else { lexer.pushback(s3); @@ -1058,20 +1053,20 @@ public class ActionScriptParser { GraphTargetItem forExpr = null; List forFirstCommands = new ArrayList<>(); if (!forin) { - GraphTargetItem fc = command(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); + GraphTargetItem fc = command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); if (fc != null) { //can be empty command forFirstCommands.add(fc); } - forExpr = (expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables)); + forExpr = (expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.SEMICOLON); - forFinalCommands.add(command(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + forFinalCommands.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); } expectedType(SymbolType.PARENT_CLOSE); List forBody = new ArrayList<>(); - forBody.add(command(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forin ? forinlevel + 1 : forinlevel, true, variables)); + forBody.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forin ? forinlevel + 1 : forinlevel, true, variables)); if (forin) { - NameAVM2Item obj = new NameAVM2Item(new UnboundedTypeItem(), lexer.yyline(), objIdent, null, false, openedNamespaces, openedNamespacesKinds); + NameAVM2Item obj = new NameAVM2Item(new UnboundedTypeItem(), lexer.yyline(), objIdent, null, false, openedNamespaces); variables.add(obj); if (each) { ret = new ForEachInAVM2Item(null, floop, new InAVM2Item(null, obj, collection), forBody); @@ -1090,7 +1085,7 @@ public class ActionScriptParser { loopLabels.put(sloop, loopLabel); } expectedType(SymbolType.PARENT_OPEN); - GraphTargetItem switchExpr = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem switchExpr = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); expectedType(SymbolType.PARENT_CLOSE); expectedType(SymbolType.CURLY_OPEN); s = lex(); @@ -1111,7 +1106,7 @@ public class ActionScriptParser { while (s.type == SymbolType.CASE) { List caseExprs = new ArrayList<>(); while (s.type == SymbolType.CASE) { - GraphTargetItem curCaseExpr = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem curCaseExpr = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); caseExprs.add(curCaseExpr); expectedType(SymbolType.COLON); s = lex(); @@ -1120,14 +1115,14 @@ public class ActionScriptParser { } pos++; lexer.pushback(s); - List caseCmd = commands(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables); + List caseCmd = commands(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(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables); + defCmd = commands(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, variables); s = lexer.lex(); } expected(s, lexer.yyline(), SymbolType.CURLY_CLOSE); @@ -1192,7 +1187,7 @@ public class ActionScriptParser { ret = new ContinueItem(null, cloopId); break; case RETURN: - GraphTargetItem retexpr = expression(openedNamespaces, openedNamespacesKinds, true, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem retexpr = expression(importedClasses, openedNamespaces, true, registerVars, inFunction, inMethod, true, variables); if (retexpr == null) { ret = new ReturnVoidAVM2Item(null); } else { @@ -1201,7 +1196,7 @@ public class ActionScriptParser { break; case TRY: List tryCommands = new ArrayList<>(); - tryCommands.add(command(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + tryCommands.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); s = lex(); boolean found = false; List> catchCommands = null; @@ -1213,13 +1208,13 @@ public class ActionScriptParser { String enamestr = s.value.toString(); expectedType(SymbolType.COLON); - GraphTargetItem etype = type(openedNamespaces, openedNamespacesKinds, variables); - NameAVM2Item e = new NameAVM2Item(etype, lexer.yyline(), enamestr, null, false/*?*/, openedNamespaces, openedNamespacesKinds); + GraphTargetItem etype = type(importedClasses, openedNamespaces, variables); + NameAVM2Item e = new NameAVM2Item(etype, lexer.yyline(), enamestr, null, false/*?*/, openedNamespaces); catchExceptions.add(e); expectedType(SymbolType.PARENT_CLOSE); catchCommands = new ArrayList<>(); List cc = new ArrayList<>(); - cc.add(command(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + cc.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); catchCommands.add(cc); s = lex(); found = true; @@ -1227,7 +1222,7 @@ public class ActionScriptParser { List finallyCommands = null; if (s.type == SymbolType.FINALLY) { finallyCommands = new ArrayList<>(); - finallyCommands.add(command(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); + finallyCommands.add(command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables)); found = true; s = lex(); } @@ -1240,7 +1235,7 @@ public class ActionScriptParser { ret = tai; break; case THROW: - ret = new ThrowAVM2Item(null, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables)); + ret = new ThrowAVM2Item(null, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); break; default: GraphTargetItem valcmd = expressionCommands(s, registerVars, inFunction, inMethod, forinlevel, variables); @@ -1252,7 +1247,7 @@ public class ActionScriptParser { return null; } lexer.pushback(s); - ret = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables); + ret = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); if (debugMode) { System.out.println("/command"); } @@ -1263,7 +1258,7 @@ public class ActionScriptParser { lexer.removeListener(buf); if (ret == null) { //can be popped expression buf.pushAllBack(lexer); - ret = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables); + ret = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); } s = lex(); if ((s != null) && (s.type != SymbolType.SEMICOLON)) { @@ -1274,8 +1269,8 @@ public class ActionScriptParser { } - private GraphTargetItem expression(List openedNamespaces, List openedNamespacesKinds, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, ParseException { - return expression(openedNamespaces, openedNamespacesKinds, false, registerVars, inFunction, inMethod, allowRemainder, variables); + private GraphTargetItem expression(List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, ParseException { + return expression(importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, allowRemainder, variables); } private GraphTargetItem fixPrecedence(GraphTargetItem expr) { @@ -1296,22 +1291,22 @@ public class ActionScriptParser { return ret; } - private GraphTargetItem expressionRemainder(List openedNamespaces, List openedNamespacesKinds, GraphTargetItem expr, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, ParseException { + private GraphTargetItem expressionRemainder(List openedNamespaces, GraphTargetItem expr, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables, List importedClasses) throws IOException, ParseException { GraphTargetItem ret = null; ParsedSymbol s = lex(); switch (s.type) { case NAMESPACE_OP: s = lex(); if (s.type == SymbolType.BRACKET_OPEN) { - GraphTargetItem index = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables); - NameAVM2Item name = new NameAVM2Item(new UnboundedTypeItem(), lexer.yyline(), null, null, false, openedNamespaces, openedNamespacesKinds); + GraphTargetItem index = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + NameAVM2Item name = new NameAVM2Item(new UnboundedTypeItem(), lexer.yyline(), null, null, false, openedNamespaces); name.setIndex(index); name.setNs(expr); ret = name; expectedType(SymbolType.BRACKET_CLOSE); } else { lexer.pushback(s); - GraphTargetItem name = name(false, openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, variables); + GraphTargetItem name = name(false, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses); if (name instanceof NameAVM2Item) { ((NameAVM2Item) name).setNs(expr); ((NameAVM2Item) name).unresolved = false; @@ -1322,79 +1317,79 @@ public class ActionScriptParser { } break; case TERNAR: - GraphTargetItem terOnTrue = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem terOnTrue = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); expectedType(SymbolType.COLON); - GraphTargetItem terOnFalse = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem terOnFalse = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); ret = new TernarOpItem(null, expr, terOnTrue, terOnFalse); break; case SHIFT_LEFT: - ret = new LShiftAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new LShiftAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case SHIFT_RIGHT: - ret = new RShiftAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new RShiftAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case USHIFT_RIGHT: - ret = new URShiftAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new URShiftAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case BITAND: - ret = new BitAndAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new BitAndAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case BITOR: - ret = new BitOrAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new BitOrAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case DIVIDE: - ret = new DivideAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new DivideAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case MODULO: - ret = new ModuloAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new ModuloAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case EQUALS: - ret = new EqAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new EqAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case STRICT_EQUALS: - ret = new StrictEqAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new StrictEqAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case NOT_EQUAL: - ret = new NeqAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new NeqAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case STRICT_NOT_EQUAL: - ret = new StrictNeqAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new StrictNeqAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case LOWER_THAN: - ret = new LtAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new LtAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case LOWER_EQUAL: - ret = new LeAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new LeAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case GREATER_THAN: - ret = new GtAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new GtAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case GREATER_EQUAL: - ret = new GeAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new GeAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case AND: - ret = new AndItem(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new AndItem(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case OR: - ret = new OrItem(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new OrItem(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case MINUS: - ret = new SubtractAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new SubtractAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case MULTIPLY: - ret = new MultiplyAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new MultiplyAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case PLUS: - ret = new AddAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new AddAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case XOR: - ret = new BitXorAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new BitXorAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case AS: //TODO break; case INSTANCEOF: - ret = new InstanceOfAVM2Item(null, expr, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, false, variables)); + ret = new InstanceOfAVM2Item(null, expr, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, false, variables)); break; case IS: @@ -1412,7 +1407,7 @@ public class ActionScriptParser { case ASSIGN_SHIFT_RIGHT: case ASSIGN_USHIFT_RIGHT: case ASSIGN_XOR: - GraphTargetItem assigned = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem assigned = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); switch (s.type) { case ASSIGN: //assigned = assigned; @@ -1478,14 +1473,14 @@ public class ActionScriptParser { case BRACKET_OPEN: //member case PARENT_OPEN: //function call lexer.pushback(s); - ret = memberOrCall(openedNamespaces, openedNamespacesKinds, expr, registerVars, inFunction, inMethod, variables); + ret = memberOrCall(importedClasses, openedNamespaces, expr, registerVars, inFunction, inMethod, variables); break; default: lexer.pushback(s); if (expr instanceof ParenthesisItem) { if (isType(((ParenthesisItem) expr).value)) { - GraphTargetItem expr2 = expression(openedNamespaces, openedNamespacesKinds, false, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem expr2 = expression(importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, true, variables); if (expr2 != null) { ret = new CoerceAVM2Item(null, ((ParenthesisItem) expr).value, expr2); } @@ -1520,7 +1515,7 @@ public class ActionScriptParser { return false; } - private int brackets(List openedNamespaces, List openedNamespacesKinds, List ret, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, ParseException { + private int brackets(List importedClasses, List openedNamespaces, List ret, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, ParseException { ParsedSymbol s = lex(); int arrCnt = 0; if (s.type == SymbolType.BRACKET_OPEN) { @@ -1531,7 +1526,7 @@ public class ActionScriptParser { lexer.pushback(s); } arrCnt++; - ret.add(expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables)); + ret.add(expression(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); @@ -1544,12 +1539,12 @@ public class ActionScriptParser { return arrCnt; } - private GraphTargetItem commaExpression(List openedNamespaces, List openedNamespacesKinds, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forInLevel, List variables) throws IOException, ParseException { + private GraphTargetItem commaExpression(List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forInLevel, List variables) throws IOException, ParseException { GraphTargetItem cmd = null; List expr = new ArrayList<>(); ParsedSymbol s; do { - cmd = command(openedNamespaces, openedNamespacesKinds, loops, loopLabels, registerVars, inFunction, inMethod, forInLevel, false, variables); + cmd = command(importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forInLevel, false, variables); if (cmd != null) { expr.add(cmd); } @@ -1557,7 +1552,7 @@ public class ActionScriptParser { } while (s.type == SymbolType.COMMA && cmd != null); lexer.pushback(s); if (cmd == null) { - expr.add(expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables)); + expr.add(expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); } else { if (!cmd.hasReturnValue()) { throw new ParseException("Expression expected", lexer.yyline()); @@ -1566,7 +1561,7 @@ public class ActionScriptParser { return new CommaExpressionItem(null, expr); } - private GraphTargetItem expression(List openedNamespaces, List openedNamespacesKinds, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, ParseException { + private GraphTargetItem expression(List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, ParseException { if (debugMode) { System.out.println("expression:"); } @@ -1589,7 +1584,7 @@ public class ActionScriptParser { existsRemainder = true; } else { lexer.pushback(s); - GraphTargetItem num = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables); + GraphTargetItem num = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); if (num instanceof IntegerValueAVM2Item) { ((IntegerValueAVM2Item) num).value = -(Long) ((IntegerValueAVM2Item) num).value; ret = num; @@ -1608,7 +1603,7 @@ public class ActionScriptParser { break; case TYPEOF: expectedType(SymbolType.PARENT_OPEN); - ret = new TypeOfAVM2Item(null, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables)); + ret = new TypeOfAVM2Item(null, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.PARENT_CLOSE); existsRemainder = true; break; @@ -1639,9 +1634,9 @@ public class ActionScriptParser { expected(s, lexer.yyline(), SymbolType.IDENTIFIER, SymbolType.STRING); GraphTargetItem n = new StringAVM2Item(null, s.value.toString()); -//expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, allowRemainder, variables); +//expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); expectedType(SymbolType.COLON); - GraphTargetItem v = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, allowRemainder, variables); + GraphTargetItem v = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, allowRemainder, variables); NameValuePair nv = new NameValuePair(n, v); nvs.add(nv); @@ -1655,7 +1650,7 @@ public class ActionScriptParser { case BRACKET_OPEN: //Array literal or just brackets lexer.pushback(s); List inBrackets = new ArrayList<>(); - int arrCnt = brackets(openedNamespaces, openedNamespacesKinds, inBrackets, registerVars, inFunction, inMethod, variables); + int arrCnt = brackets(importedClasses, openedNamespaces, inBrackets, registerVars, inFunction, inMethod, variables); ret = new NewArrayAVM2Item(null, inBrackets); break; case FUNCTION: @@ -1666,7 +1661,7 @@ public class ActionScriptParser { } else { lexer.pushback(s); } - ret = function(TypeItem.UNBOUNDED, openedNamespaces, openedNamespacesKinds, true, fname, false, variables); + ret = function(importedClasses, 0/*?*/, TypeItem.UNBOUNDED, openedNamespaces, true, fname, false, variables); //TODO break; case NAN: @@ -1686,7 +1681,7 @@ public class ActionScriptParser { existsRemainder = true; break; case DELETE: - GraphTargetItem varDel = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables);//name(false, openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, variables); + GraphTargetItem varDel = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(false, openedNamespaces, registerVars, inFunction, inMethod, variables); if (!isNameOrProp(varDel)) { throw new ParseException("Not a property or name", lexer.yyline()); } @@ -1699,7 +1694,7 @@ public class ActionScriptParser { break; case INCREMENT: case DECREMENT: //preincrement - GraphTargetItem varincdec = expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables);//name(false, openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, variables); + GraphTargetItem varincdec = expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);//name(false, openedNamespaces, registerVars, inFunction, inMethod, variables); if (!isNameOrProp(varincdec)) { throw new ParseException("Not a property or name", lexer.yyline()); } @@ -1712,27 +1707,27 @@ public class ActionScriptParser { existsRemainder = true; break; case NOT: - ret = new NotItem(null, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables)); + ret = new NotItem(null, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); existsRemainder = true; break; case PARENT_OPEN: - ret = new ParenthesisItem(null, expression(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, true, variables)); + ret = new ParenthesisItem(null, expression(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.PARENT_CLOSE); - ret = memberOrCall(openedNamespaces, openedNamespacesKinds, ret, registerVars, inFunction, inMethod, variables); + ret = memberOrCall(importedClasses, openedNamespaces, ret, registerVars, inFunction, inMethod, variables); existsRemainder = true; break; case NEW: - GraphTargetItem newvar = name(true, openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, variables); + GraphTargetItem newvar = name(true, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses); expectedType(SymbolType.PARENT_OPEN); - ret = new ConstructSomethingAVM2Item(newvar, call(openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, variables)); + ret = new ConstructSomethingAVM2Item(newvar, call(importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); existsRemainder = true; break; case IDENTIFIER: case THIS: case SUPER: lexer.pushback(s); - GraphTargetItem var = name(false, openedNamespaces, openedNamespacesKinds, registerVars, inFunction, inMethod, variables); - var = memberOrCall(openedNamespaces, openedNamespacesKinds, var, registerVars, inFunction, inMethod, variables); + GraphTargetItem var = name(false, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses); + var = memberOrCall(importedClasses, openedNamespaces, var, registerVars, inFunction, inMethod, variables); ret = var; existsRemainder = true; break; @@ -1748,7 +1743,7 @@ public class ActionScriptParser { if (allowRemainder && existsRemainder) { GraphTargetItem rem = ret; do { - rem = expressionRemainder(openedNamespaces, openedNamespacesKinds, rem, registerVars, inFunction, inMethod, assocRight, variables); + rem = expressionRemainder(openedNamespaces, rem, registerVars, inFunction, inMethod, assocRight, variables, importedClasses); if (rem != null) { ret = rem; } @@ -1763,7 +1758,7 @@ public class ActionScriptParser { private ActionScriptLexer lexer = null; private List constantPool; - private PackageAVM2Item parsePackage() throws IOException, ParseException { + private PackageAVM2Item parsePackage(String fileName) throws IOException, ParseException { ParsedSymbol s = lex(); expected(s, lexer.yyline(), SymbolType.PACKAGE); String name = ""; @@ -1779,8 +1774,34 @@ public class ActionScriptParser { name += "." + s.value.toString(); } List items = new ArrayList<>(); - List openedNamespacesKinds = new ArrayList<>(); - List openedNamespaces = new ArrayList<>(); + List openedNamespaces = new ArrayList<>(); + + int privateNs = 0; + int publicNs = 0; + if (fileName.contains("/")) { + fileName = fileName.substring(fileName.lastIndexOf("/") + 1); + } + if (fileName.contains("\\")) { + fileName = fileName.substring(fileName.lastIndexOf("\\") + 1); + } + String className = fileName; + if (className.endsWith(".as")) { + className = className.substring(0, className.length() - 3); + } + openedNamespaces.add(privateNs = abc.constants.addNamespace(new Namespace(Namespace.KIND_PRIVATE, 0))); //abc.constants.getStringId(name + ":" + className, true) + int packageInternalNs = 0; + openedNamespaces.add(packageInternalNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abc.constants.getStringId(name, true)), 0, true)); + openedNamespaces.add(publicNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true)); + + openedNamespaces.add(abc.constants.addNamespace(new Namespace(Namespace.KIND_PRIVATE, 0))); //abc.constants.getStringId(fileName + "$", true) + if (!name.equals("")) { + openedNamespaces.add(publicNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(name, true)), 0, true)); + } + + openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_NAMESPACE, abc.constants.getStringId(AS3_NAMESPACE, true)), 0, true)); + + List importedClasses = new ArrayList<>(); + s = lex(); while (s.type == SymbolType.IMPORT) { String impPackage = ""; @@ -1808,25 +1829,27 @@ public class ActionScriptParser { s = lex(); } - String fullImp = impName == null ? impPackage : impPackage + ":" + impName; - openedNamespaces.add(fullImp); - openedNamespacesKinds.add(Namespace.KIND_PACKAGE); + if (impName == null) { + openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(impPackage, true)), 0, true)); + } else { + importedClasses.add(impPackage + "." + impName); + } expected(s, lexer.yyline(), SymbolType.SEMICOLON); s = lex(); } lexer.pushback(s); - traits(openedNamespaces, openedNamespacesKinds, name, null, false, items); + traits(importedClasses, privateNs, 0, publicNs, packageInternalNs, 0, openedNamespaces, name, null, false, items); expectedType(SymbolType.CURLY_CLOSE); return new PackageAVM2Item(name, items); } - public PackageAVM2Item packageFromString(String str) throws ParseException, IOException { + public PackageAVM2Item packageFromString(String str, String fileName) throws ParseException, IOException { this.constantPool = constantPool; lexer = new ActionScriptLexer(new StringReader(str)); - PackageAVM2Item ret = parsePackage(); + PackageAVM2Item ret = parsePackage(fileName); if (lexer.lex().type != SymbolType.EOF) { throw new ParseException("Parsing finisned before end of the file", lexer.yyline()); } @@ -1847,8 +1870,8 @@ public class ActionScriptParser { abc.script_info.add(gen.generateScriptInfo(pkg, localData, pkg.items, documentClass)); } - public void addScript(String s, boolean documentClass) throws ParseException, IOException { - PackageAVM2Item pkg = packageFromString(s); + public void addScript(String s, boolean documentClass, String fileName) throws ParseException, IOException { + PackageAVM2Item pkg = packageFromString(s, fileName); addScriptFromTree(pkg, documentClass); } @@ -1875,7 +1898,7 @@ public class ActionScriptParser { } ABC abc = new ABC(swf); ActionScriptParser parser = new ActionScriptParser(abc, playerABCs); - parser.addScript(new String(Helper.readFile(src), "UTF-8"), true); + parser.addScript(new String(Helper.readFile(src), "UTF-8"), true, src); abc.saveToStream(new FileOutputStream(new File(dst))); } catch (Exception ex) { Logger.getLogger(ActionScriptParser.class.getName()).log(Level.SEVERE, null, ex); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AssignableAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AssignableAVM2Item.java index eff0a0b09..7d7252350 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AssignableAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AssignableAVM2Item.java @@ -54,7 +54,7 @@ public abstract class AssignableAVM2Item extends AVM2Item { this.assignedValue = storeValue; } - public abstract List toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post,boolean decrement, boolean needsReturn); + public abstract List toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post, boolean decrement, boolean needsReturn); public GraphTargetItem getAssignedValue() { return assignedValue; @@ -71,7 +71,7 @@ public abstract class AssignableAVM2Item extends AVM2Item { ret.add(generateSetLoc(register.getVal())); return ret; } - + protected List setTemp(SourceGeneratorLocalData localData, SourceGenerator generator, Reference register) { register.setVal(getFreeRegister(localData, generator)); List ret = new ArrayList<>(); @@ -89,13 +89,12 @@ public abstract class AssignableAVM2Item extends AVM2Item { } /*protected List getAndKillTemp(SourceGeneratorLocalData localData, SourceGenerator generator, Reference register) { - killRegister(localData, generator, register.getVal()); - List ret = new ArrayList<>(); - ret.add(generateGetLoc(register.getVal())); - ret.add(ins(new KillIns(), register.getVal())); - return ret; - }*/ - + killRegister(localData, generator, register.getVal()); + List ret = new ArrayList<>(); + ret.add(generateGetLoc(register.getVal())); + ret.add(ins(new KillIns(), register.getVal())); + return ret; + }*/ @SuppressWarnings("unchecked") protected List killTemp(SourceGeneratorLocalData localData, SourceGenerator generator, List> registers) { List ret = new ArrayList<>(); diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/CallAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/CallAVM2Item.java index 0a76e7d17..955922d71 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/CallAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/CallAVM2Item.java @@ -23,9 +23,6 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallPropVoidIn import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallPropertyIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; -import com.jpexs.decompiler.flash.abc.avm2.model.LocalRegAVM2Item; -import com.jpexs.decompiler.flash.abc.types.InstanceInfo; -import com.jpexs.decompiler.flash.abc.types.Multiname; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; @@ -33,7 +30,6 @@ import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.TypeFunctionItem; import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.LocalData; -import java.util.AbstractList; import java.util.ArrayList; import java.util.List; @@ -80,12 +76,13 @@ public class CallAVM2Item extends AVM2Item { Reference outNs = new Reference<>(""); Reference outPropNs = new Reference<>(""); Reference outPropNsKind = new Reference<>(1); - if (AVM2SourceGenerator.searchProperty(allAbcs, pkgName, cname, n.getVariableName(), outName, outNs, outPropNs, outPropNsKind)) { - NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.currentClass), n.line, "this", null, false, n.openedNamespaces, n.openedNamespacesKind); + Reference outPropType = new Reference<>(""); + if (AVM2SourceGenerator.searchPrototypeChain(true, allAbcs, pkgName, cname, n.getVariableName(), outName, outNs, outPropNs, outPropNsKind, outPropType)) { + NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.currentClass), n.line, "this", null, false, n.openedNamespaces); nobj.setRegNumber(0); obj = nobj; } - PropertyAVM2Item p = new PropertyAVM2Item(obj, n.getVariableName(), n.getIndex(), allAbcs, n.openedNamespaces, n.openedNamespacesKind); + PropertyAVM2Item p = new PropertyAVM2Item(obj, n.getVariableName(), n.getIndex(), g.abc, g.allABCs, n.openedNamespaces); p.setAssignedValue(n.getAssignedValue()); callable = p; } @@ -111,10 +108,7 @@ public class CallAVM2Item extends AVM2Item { GraphTargetItem callable = name; if (callable instanceof NameAVM2Item) { NameAVM2Item n = (NameAVM2Item) callable; - List allAbcs = new ArrayList<>(); - allAbcs.add(g.abc); - allAbcs.addAll(g.allABCs); - PropertyAVM2Item p = new PropertyAVM2Item(null, n.getVariableName(), n.getIndex(), allAbcs, n.openedNamespaces, n.openedNamespacesKind); + PropertyAVM2Item p = new PropertyAVM2Item(null, n.getVariableName(), n.getIndex(), g.abc, g.allABCs, n.openedNamespaces); p.setAssignedValue(n.getAssignedValue()); callable = p; } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java index 66b9e3fbc..be3b72331 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ClassAVM2Item.java @@ -33,7 +33,8 @@ public class ClassAVM2Item extends AVM2Item implements Block { public List implementsOp; public String className; public GraphTargetItem constructor; - public int namespaceKind; + public int namespace; + public int protectedNs; public boolean isDynamic; public boolean isFinal; @@ -46,14 +47,15 @@ public class ClassAVM2Item extends AVM2Item implements Block { return ret; } - public ClassAVM2Item(boolean isDynamic, boolean isFinal, int namespaceKind, String className, GraphTargetItem extendsOp, List implementsOp, GraphTargetItem constructor, List traits) { + public ClassAVM2Item(int protectedNs, boolean isDynamic, boolean isFinal, int namespace, String className, GraphTargetItem extendsOp, List implementsOp, GraphTargetItem constructor, List traits) { super(null, NOPRECEDENCE); + this.protectedNs = protectedNs; this.className = className; this.traits = traits; this.extendsOp = extendsOp; this.implementsOp = implementsOp; this.constructor = constructor; - this.namespaceKind = namespaceKind; + this.namespace = namespace; this.isDynamic = isDynamic; this.isFinal = isFinal; } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstAVM2Item.java index 650687957..051fbb73f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstAVM2Item.java @@ -27,22 +27,22 @@ import com.jpexs.decompiler.graph.model.LocalData; */ public class ConstAVM2Item extends AVM2Item { - private final int nsKind; + private final int namespace; private boolean isStatic; public String var; public GraphTargetItem type; - public int getNsKind() { - return nsKind; + public int getNamespace() { + return namespace; } public boolean isStatic() { return isStatic; } - public ConstAVM2Item(boolean isStatic, int nsKind, String var, GraphTargetItem type, GraphTargetItem value) { + public ConstAVM2Item(boolean isStatic, int namespace, String var, GraphTargetItem type, GraphTargetItem value) { super(null, NOPRECEDENCE); - this.nsKind = nsKind; + this.namespace = namespace; this.value = value; this.isStatic = isStatic; this.var = var; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstructSomethingAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstructSomethingAVM2Item.java index 3516b1336..4cebd125d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstructSomethingAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ConstructSomethingAVM2Item.java @@ -19,7 +19,6 @@ package com.jpexs.decompiler.flash.abc.avm2.parser.script; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.ConstructPropIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.executing.CallPropertyIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/FunctionAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/FunctionAVM2Item.java index 2e7bb11a5..039771278 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/FunctionAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/FunctionAVM2Item.java @@ -30,6 +30,7 @@ public class FunctionAVM2Item extends AVM2Item { public String calculatedFunctionName; public String functionName; + public int namespace; public List paramNames; public List body; public List subvariables; @@ -39,8 +40,9 @@ public class FunctionAVM2Item extends AVM2Item { public int line; public boolean hasRest; - public FunctionAVM2Item(boolean hasRest, int line, String functionName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { + public FunctionAVM2Item(int namespace, boolean hasRest, int line, String functionName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { super(null, NOPRECEDENCE); + this.namespace = namespace; this.paramNames = paramNames; this.body = body; this.functionName = functionName; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/GetterAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/GetterAVM2Item.java index 01294ec3f..bd7bb445f 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/GetterAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/GetterAVM2Item.java @@ -25,8 +25,8 @@ import java.util.List; */ public class GetterAVM2Item extends MethodAVM2Item { - public GetterAVM2Item(boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespaceKind, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { - super(hasRest, line, override, isFinal, isStatic, namespaceKind, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); + public GetterAVM2Item(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(hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/InterfaceAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/InterfaceAVM2Item.java index b1c623724..53782051e 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/InterfaceAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/InterfaceAVM2Item.java @@ -32,15 +32,15 @@ public class InterfaceAVM2Item extends AVM2Item { public String name; public List superInterfaces; public List methods; - public int namespaceKind; + public int namespace; public boolean isFinal; - public InterfaceAVM2Item(boolean isFinal, int namespaceKind, String name, List superInterfaces, List traits) { + public InterfaceAVM2Item(boolean isFinal, int namespace, String name, List superInterfaces, List traits) { super(null, NOPRECEDENCE); this.name = name; this.superInterfaces = superInterfaces; this.methods = traits; - this.namespaceKind = namespaceKind; + this.namespace = namespace; this.isFinal = isFinal; } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java index be8d529ed..f040db2cd 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java @@ -27,14 +27,12 @@ import java.util.List; */ public class MethodAVM2Item extends FunctionAVM2Item { - public int namespaceKind; private boolean isStatic; private boolean isFinal; private boolean override; - public MethodAVM2Item(boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespaceKind, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { - super(hasRest, line, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); - this.namespaceKind = namespaceKind; + public MethodAVM2Item(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(namespace, hasRest, line, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); this.isStatic = isStatic; this.override = override; this.isFinal = isFinal; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java index 37d14c4fb..5be25ebb2 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NameAVM2Item.java @@ -34,7 +34,6 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceSIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertDIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertSIns; import com.jpexs.decompiler.flash.abc.types.Multiname; -import com.jpexs.decompiler.flash.abc.types.Namespace; import com.jpexs.decompiler.flash.abc.types.NamespaceSet; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphSourceItem; @@ -57,8 +56,7 @@ public class NameAVM2Item extends AssignableAVM2Item { private boolean definition; private GraphTargetItem index; private int nsKind = -1; - public List openedNamespaces; - public List openedNamespacesKind; + public List openedNamespaces; public int line; public GraphTargetItem type; private GraphTargetItem ns = null; @@ -116,7 +114,7 @@ public class NameAVM2Item extends AssignableAVM2Item { return variableName; } - public NameAVM2Item(GraphTargetItem type, int line, String variableName, GraphTargetItem storeValue, boolean definition, List openedNamespaces, List openedNamespacesKind) { + public NameAVM2Item(GraphTargetItem type, int line, String variableName, GraphTargetItem storeValue, boolean definition, List openedNamespaces) { super(storeValue); this.variableName = variableName; this.assignedValue = storeValue; @@ -124,7 +122,6 @@ public class NameAVM2Item extends AssignableAVM2Item { this.line = line; this.type = type; this.openedNamespaces = openedNamespaces; - this.openedNamespacesKind = openedNamespacesKind; } public boolean isDefinition() { @@ -143,7 +140,7 @@ public class NameAVM2Item extends AssignableAVM2Item { private int allNsSet(ABC abc) { int nssa[] = new int[openedNamespaces.size()]; for (int i = 0; i < openedNamespaces.size(); i++) { - nssa[i] = (abc.constants.getNamespaceId(new Namespace(openedNamespacesKind.get(i), abc.constants.getStringId(openedNamespaces.get(i), true)), 0, true)); + nssa[i] = openedNamespaces.get(i); } return abc.constants.getNamespaceSetId(new NamespaceSet(nssa), true); } @@ -235,7 +232,7 @@ public class NameAVM2Item extends AssignableAVM2Item { } if (assignedValue != null) { - return toSourceMerge(localData, generator, assignedValue, (!(assignedValue.returnType().toString().equals("int")&&type.toString().equals("int")))?generateCoerce(generator, type.toString()):null, needsReturn + return toSourceMerge(localData, generator, assignedValue, (!("int".equals("" + assignedValue.returnType()) && "int".equals("" + type))) ? generateCoerce(generator, "" + type) : null, needsReturn ? ins(new DupIns()) : null, generateSetLoc(regNumber)); } else { return toSourceMerge(localData, generator, generateGetLoc(regNumber), @@ -286,7 +283,7 @@ public class NameAVM2Item extends AssignableAVM2Item { if (index != null) { return TypeItem.UNBOUNDED; } - if(type == null){ + if (type == null) { return TypeItem.UNBOUNDED; } return type; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java index 605c736bf..eccab7ac7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/PropertyAVM2Item.java @@ -23,32 +23,23 @@ import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.DecrementIIns import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.DecrementIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.arithmetic.IncrementIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.GetLocalIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.KillIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.localregs.SetLocalIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns; +import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns; -import com.jpexs.decompiler.flash.abc.avm2.instructions.other.ThrowIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.DupIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.stack.PopIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertDIns; -import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.CoerceAVM2Item; import com.jpexs.decompiler.flash.abc.types.InstanceInfo; import com.jpexs.decompiler.flash.abc.types.Multiname; import com.jpexs.decompiler.flash.abc.types.Namespace; import com.jpexs.decompiler.flash.abc.types.NamespaceSet; -import com.jpexs.decompiler.flash.abc.types.ScriptInfo; import com.jpexs.decompiler.flash.abc.types.traits.Trait; -import com.jpexs.decompiler.flash.abc.types.traits.TraitFunction; -import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter; -import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.GraphSourceItem; import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; -import com.jpexs.decompiler.graph.TypeFunctionItem; import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.LocalData; import java.util.ArrayList; @@ -63,18 +54,18 @@ public class PropertyAVM2Item extends AssignableAVM2Item { public String propertyName; public GraphTargetItem object; - public List abcs; + public ABC abc; + public List otherABCs; public GraphTargetItem index; - private List openedNamespaces; - private List openedNamespacesKind; + private List openedNamespaces; - public PropertyAVM2Item(GraphTargetItem object, String propertyName, GraphTargetItem index, List abcs, List openedNamespaces, List openedNamespacesKind) { + public PropertyAVM2Item(GraphTargetItem object, String propertyName, GraphTargetItem index, ABC abc, List otherABCs, List openedNamespaces) { this.propertyName = propertyName; this.object = object; - this.abcs = abcs; + this.otherABCs = otherABCs; + this.abc = abc; this.index = index; this.openedNamespaces = openedNamespaces; - this.openedNamespacesKind = openedNamespacesKind; } @Override @@ -85,199 +76,329 @@ public class PropertyAVM2Item extends AssignableAVM2Item { private int allNsSet() { int nssa[] = new int[openedNamespaces.size()]; for (int i = 0; i < openedNamespaces.size(); i++) { - nssa[i] = (abcs.get(0).constants.getNamespaceId(new Namespace(openedNamespacesKind.get(i), abcs.get(0).constants.getStringId(openedNamespaces.get(i), true)), 0, true)); + nssa[i] = openedNamespaces.get(i); } - return abcs.get(0).constants.getNamespaceSetId(new NamespaceSet(nssa), true); + return abc.constants.getNamespaceSetId(new NamespaceSet(nssa), true); } - private String resolveObjectType() { + private void resolve(Reference objectType, Reference propertyType, Reference propertyIndex) { String objType = object == null ? null : object.returnType().toString(); + String propType = ""; + int propIndex = 0; if (objType == null) { - loopo: + loopobjType: for (int i = 0; i < openedNamespaces.size(); i++) { - String ns = openedNamespaces.get(i); - String nspkg = ns; - String nsclass = null; - int nsKind = openedNamespacesKind.get(i); - if (nspkg.contains(":") && nsKind != Namespace.KIND_NAMESPACE) { - nsclass = nspkg.substring(nspkg.indexOf(":") + 1); - nspkg = nspkg.substring(0, nspkg.indexOf(":")); + int nsindex = openedNamespaces.get(i); + int nsKind = abc.constants.constant_namespace.get(openedNamespaces.get(i)).kind; + String nsname = abc.constants.constant_namespace.get(openedNamespaces.get(i)).getName(abc.constants); + int name_index = 0; + for (int m = 1; m < abc.constants.constant_multiname.size(); m++) { + Multiname mname = abc.constants.constant_multiname.get(m); + if (mname.kind == Multiname.QNAME && mname.getName(abc.constants, new ArrayList()).equals(propertyName) && mname.namespace_index == nsindex) { + name_index = m; + break; + } } - loopabc: - for (ABC a : abcs) { - for (int h = 0; h < a.instance_info.size(); h++) { - InstanceInfo ii = a.instance_info.get(h); - Multiname n = a.constants.constant_multiname.get(ii.name_index); - if (n.getNamespace(a.constants).getName(a.constants).equals(nspkg) && (nsclass == null || (n.getName(a.constants, new ArrayList()).equals(nsclass)))) { - Reference outName = new Reference<>(""); - Reference outNs = new Reference<>(""); - Reference outPropNs = new Reference<>(""); - Reference outPropNsKind = new Reference<>(1); - if (AVM2SourceGenerator.searchProperty(abcs, nspkg, n.getName(a.constants, new ArrayList()), propertyName, outName, outNs, outPropNs, outPropNsKind)) { - objType = "".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal(); - break loopo; + if (name_index > 0) { + for (int c = 0; c < abc.instance_info.size(); c++) { + for (Trait t : abc.instance_info.get(c).instance_traits.traits) { + if (t.name_index == name_index) { + objType = abc.instance_info.get(c).getName(abc.constants).getNameWithNamespace(abc.constants); + propType = AVM2SourceGenerator.getTraitReturnType(abc, t).toString(); + propIndex = t.name_index; + break loopobjType; + } + } + for (Trait t : abc.class_info.get(c).static_traits.traits) { + if (t.name_index == name_index) { + objType = abc.instance_info.get(c).getName(abc.constants).getNameWithNamespace(abc.constants); + propType = AVM2SourceGenerator.getTraitReturnType(abc, t).toString(); + propIndex = t.name_index; + break loopobjType; + } + } + } + } + if (nsKind == Namespace.KIND_PACKAGE) { + List abcs = new ArrayList<>(); + abcs.add(abc); + abcs.addAll(otherABCs); + loopabc: + for (ABC a : otherABCs) { + for (int h = 0; h < a.instance_info.size(); h++) { + InstanceInfo ii = a.instance_info.get(h); + Multiname n = a.constants.constant_multiname.get(ii.name_index); + if (n.getNamespace(a.constants).kind == Namespace.KIND_PACKAGE && n.getNamespace(a.constants).getName(a.constants).equals(nsname)) { + Reference outName = new Reference<>(""); + Reference outNs = new Reference<>(""); + Reference outPropNs = new Reference<>(""); + Reference outPropNsKind = new Reference<>(1); + Reference outPropType = new Reference<>(""); + if (AVM2SourceGenerator.searchPrototypeChain(false, abcs, nsname, n.getName(a.constants, new ArrayList()), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropType)) { + objType = "".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal(); + propType = outPropType.getVal(); + propIndex = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, + abc.constants.getStringId(propertyName, true), + abc.constants.getNamespaceId(new Namespace(outPropNsKind.getVal(), abc.constants.getStringId(outPropNs.getVal(), true)), 0, true), 0, 0, new ArrayList()), true + ); + + break loopobjType; + } } } } } } - } - if (objType == null) { - throw new RuntimeException("Unresolved object type"); - } - return objType; - } + } else { + List abcs = new ArrayList<>(); + abcs.add(abc); + abcs.addAll(otherABCs); + loopa: + for (ABC a : abcs) { + for (InstanceInfo ii : a.instance_info) { + Multiname m = ii.getName(a.constants); + if (m.getNameWithNamespace(a.constants).equals(objType)) { + Reference outName = new Reference<>(""); + Reference outNs = new Reference<>(""); + Reference outPropNs = new Reference<>(""); + Reference outPropNsKind = new Reference<>(1); + Reference outPropType = new Reference<>(""); + if (AVM2SourceGenerator.searchPrototypeChain(false, abcs, m.getNamespace(a.constants).getName(a.constants), m.getName(a.constants, new ArrayList()), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropType)) { + objType = "".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal(); + propType = outPropType.getVal(); + propIndex = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, + abc.constants.getStringId(propertyName, true), + abc.constants.getNamespaceId(new Namespace(outPropNsKind.getVal(), abc.constants.getStringId(outPropNs.getVal(), true)), 0, true), 0, 0, new ArrayList()), true + ); - public GraphTargetItem resolvePropertyType() { - if (index != null) { - return TypeItem.UNBOUNDED; - } - - String objType = resolveObjectType(); - for (ABC a : abcs) { - int ci = a.findClassByName(objType); - if (ci != -1) { - for (Trait t : a.instance_info.get(ci).instance_traits.traits) { - String tnames = t.getName(a).getName(a.constants, new ArrayList()); - if (tnames.equals(propertyName)) { - if (t instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) t; - if (tsc.type_index == 0) { - return TypeItem.UNBOUNDED; - } - return new TypeItem(a.constants.constant_multiname.get(tsc.type_index).getNameWithNamespace(a.constants)); + break loopa; } - if (t instanceof TraitMethodGetterSetter) { - TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t; - if (tmgs.kindType == Trait.TRAIT_GETTER) { - return new TypeItem(a.constants.constant_multiname.get(a.method_info.get(tmgs.method_info).ret_type).getNameWithNamespace(a.constants)); - } - if (tmgs.kindType == Trait.TRAIT_SETTER) { - return new TypeItem(a.constants.constant_multiname.get(a.method_info.get(tmgs.method_info).param_types[0]).getNameWithNamespace(a.constants)); - } - } - if (t instanceof TraitFunction) { - return new TypeItem("Function"); - } - return TypeItem.UNBOUNDED; } } - break; } } - return TypeItem.UNBOUNDED; + + if (propIndex == 0) { + propIndex = abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, + abc.constants.getStringId(propertyName, true), 0, + allNsSet(), 0, new ArrayList()), true); + propType = "*"; + objType = "*"; + + } + propertyIndex.setVal(propIndex); + propertyType.setVal(propType); + objectType.setVal(objType); } public int resolveProperty() { - if (index != null) { - return abcs.get(0).constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, - abcs.get(0).constants.getStringId(propertyName, true), 0, - allNsSet(), 0, new ArrayList()), true); - } - - String objType = resolveObjectType(); - for (ABC a : abcs) { - int ci = a.findClassByName(objType); - if (ci != -1) { - for (Trait t : a.instance_info.get(ci).instance_traits.traits) { - Multiname tname = t.getName(a); - String tnames = t.getName(a).getName(a.constants, new ArrayList()); - if (tnames.equals(propertyName)) { - return abcs.get(0).constants.getMultinameId(new Multiname(tname.kind, - abcs.get(0).constants.getStringId(tnames, true), - abcs.get(0).constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abcs.get(0).constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList()), true); - } - } - for (Trait t : a.class_info.get(ci).static_traits.traits) { - Multiname tname = t.getName(a); - String tnames = t.getName(a).getName(a.constants, new ArrayList()); - if (tnames.equals(propertyName)) { - return abcs.get(0).constants.getMultinameId(new Multiname(tname.kind, - abcs.get(0).constants.getStringId(tnames, true), - abcs.get(0).constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abcs.get(0).constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList()), true); - } - } - break; - } - } - - for (ABC a : abcs) { - for (ScriptInfo si : a.script_info) { - for (Trait t : si.traits.traits) { - Multiname tname = t.getName(a); - String tnames = t.getName(a).getName(a.constants, new ArrayList()); - if (tnames.equals(propertyName)) { - return abcs.get(0).constants.getMultinameId(new Multiname(tname.kind, - abcs.get(0).constants.getStringId(tnames, true), - abcs.get(0).constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abcs.get(0).constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList()), true); - } - } - } - } - - return abcs.get(0).constants.getMultinameId(new Multiname(Multiname.MULTINAME, - abcs.get(0).constants.getStringId(propertyName, true), 0, - allNsSet(), 0, new ArrayList()), true); + Reference objType = new Reference<>(""); + Reference propType = new Reference<>(""); + Reference propIndex = new Reference<>(0); + resolve(objType, propType, propIndex); + return propIndex.getVal(); } + /* + private String resolveObjectType() { + String objType = object == null ? null : object.returnType().toString(); + if (objType == null) { + loopo: + for (int i = 0; i < openedNamespaces.size(); i++) { + int nsindex = openedNamespaces.get(i); + int nsKind = abc.constants.constant_namespace.get(openedNamespaces.get(i)).kind; + String nsname = abc.constants.constant_namespace.get(openedNamespaces.get(i)).getName(abc.constants); + int name_index = 0; + for (int m = 1; m < abc.constants.constant_multiname.size(); m++) { + Multiname mname = abc.constants.constant_multiname.get(m); + if (mname.kind == Multiname.QNAME && mname.getName(abc.constants, new ArrayList()).equals(propertyName) && mname.namespace_index == nsindex) { + name_index = m; + break; + } + } + if (name_index > 0) { + for (int s = 0; s < abc.script_info.size(); s++) { + for (Trait t : abc.script_info.get(s).traits.traits) { + if (t.name_index == name_index) { + return getTraitReturnType(abc, t).toString(); + } + } + } + for (int c = 0; c < abc.instance_info.size(); c++) { + for (Trait t : abc.instance_info.get(c).instance_traits.traits) { + if (t.name_index == name_index) { + return getTraitReturnType(abc, t).toString(); + } + } + for (Trait t : abc.class_info.get(c).static_traits.traits) { + if (t.name_index == name_index) { + return getTraitReturnType(abc, t).toString(); + } + } + } + } + if (nsKind == Namespace.KIND_PACKAGE) { + List abcs = new ArrayList<>(); + abcs.add(abc); + abcs.addAll(otherABCs); + loopabc: + for (ABC a : otherABCs) { + for (int h = 0; h < a.instance_info.size(); h++) { + InstanceInfo ii = a.instance_info.get(h); + Multiname n = a.constants.constant_multiname.get(ii.name_index); + if (n.getNamespace(a.constants).kind == Namespace.KIND_PACKAGE && n.getNamespace(a.constants).getName(a.constants).equals(nsname)) { + Reference outName = new Reference<>(""); + Reference outNs = new Reference<>(""); + Reference outPropNs = new Reference<>(""); + Reference outPropNsKind = new Reference<>(1); + if (AVM2SourceGenerator.searchPrototypeChain(abcs, nsname, n.getName(a.constants, new ArrayList()), propertyName, outName, outNs, outPropNs, outPropNsKind)) { + return "".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal(); + } + } + } + } + } + } + } + if (objType == null) { + throw new RuntimeException("Unresolved object type"); + } + return objType; + }*/ + + /* + public GraphTargetItem resolvePropertyType() { + if (index != null) { + return TypeItem.UNBOUNDED; + } + + String objType = resolveObjectType(); + for (ABC a : abcs) { + int ci = a.findClassByName(objType); + if (ci != -1) { + for (Trait t : a.instance_info.get(ci).instance_traits.traits) { + String tnames = t.getName(a).getName(a.constants, new ArrayList()); + if (tnames.equals(propertyName)) { + if (t instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) t; + if (tsc.type_index == 0) { + return TypeItem.UNBOUNDED; + } + return new TypeItem(a.constants.constant_multiname.get(tsc.type_index).getNameWithNamespace(a.constants)); + } + if (t instanceof TraitMethodGetterSetter) { + TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t; + if (tmgs.kindType == Trait.TRAIT_GETTER) { + return new TypeItem(a.constants.constant_multiname.get(a.method_info.get(tmgs.method_info).ret_type).getNameWithNamespace(a.constants)); + } + if (tmgs.kindType == Trait.TRAIT_SETTER) { + return new TypeItem(a.constants.constant_multiname.get(a.method_info.get(tmgs.method_info).param_types[0]).getNameWithNamespace(a.constants)); + } + } + if (t instanceof TraitFunction) { + return new TypeItem("Function"); + } + return TypeItem.UNBOUNDED; + } + } + break; + } + } + return TypeItem.UNBOUNDED; + } + */ + /* public int resolveProperty() { + if (index != null) { + return abc.constants.getMultinameId(new Multiname(Multiname.MULTINAMEL, + abc.constants.getStringId(propertyName, true), 0, + allNsSet(), 0, new ArrayList()), true); + } + + String objType = resolveObjectType(); + for (ABC a : abcs) { + int ci = a.findClassByName(objType); + if (ci != -1) { + for (Trait t : a.instance_info.get(ci).instance_traits.traits) { + Multiname tname = t.getName(a); + String tnames = t.getName(a).getName(a.constants, new ArrayList()); + if (tnames.equals(propertyName)) { + return abc.constants.getMultinameId(new Multiname(tname.kind, + abc.constants.getStringId(tnames, true), + abc.constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abc.constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList()), true); + } + } + for (Trait t : a.class_info.get(ci).static_traits.traits) { + Multiname tname = t.getName(a); + String tnames = t.getName(a).getName(a.constants, new ArrayList()); + if (tnames.equals(propertyName)) { + return abc.constants.getMultinameId(new Multiname(tname.kind, + abc.constants.getStringId(tnames, true), + abc.constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abc.constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList()), true); + } + } + break; + } + } + + for (ABC a : abcs) { + for (ScriptInfo si : a.script_info) { + for (Trait t : si.traits.traits) { + Multiname tname = t.getName(a); + String tnames = t.getName(a).getName(a.constants, new ArrayList()); + if (tnames.equals(propertyName)) { + return abc.constants.getMultinameId(new Multiname(tname.kind, + abc.constants.getStringId(tnames, true), + abc.constants.getNamespaceId(new Namespace(tname.getNamespace(a.constants).kind, abc.constants.getStringId(tname.getNamespace(a.constants).getName(a.constants), true)), 0, true), 0, 0, new ArrayList()), true); + } + } + } + } + + return abc.constants.getMultinameId(new Multiname(Multiname.MULTINAME, + abc.constants.getStringId(propertyName, true), 0, + allNsSet(), 0, new ArrayList()), true); + }*/ @Override public GraphTargetItem returnType() { if (index != null) { return TypeItem.UNBOUNDED; } - String objType = resolveObjectType(); + Reference objType = new Reference<>(""); + Reference propType = new Reference<>(""); + Reference propIndex = new Reference<>(0); + resolve(objType, propType, propIndex); - if (objType == null) { - return TypeItem.UNBOUNDED; - } - for (ABC a : abcs) { - int ci = a.findClassByName(objType); - if (ci != -1) { - for (Trait t : a.instance_info.get(ci).instance_traits.traits) { - String tname = t.getName(a).getName(a.constants, new ArrayList()); - if (tname.equals(propertyName)) { - if (t instanceof TraitSlotConst) { - TraitSlotConst tsc = (TraitSlotConst) t; - if (tsc.type_index == 0) { - return TypeItem.UNBOUNDED; - } - return new TypeItem(a.constants.constant_multiname.get(tsc.type_index).getNameWithNamespace(a.constants)); - } - if (t instanceof TraitMethodGetterSetter) { - TraitMethodGetterSetter tmgs = (TraitMethodGetterSetter) t; - return new TypeFunctionItem(a.constants.constant_multiname.get(a.method_info.get(tmgs.method_info).ret_type).getNameWithNamespace(a.constants)); - } - if (t instanceof TraitFunction) { - TraitFunction tf = (TraitFunction) t; - return new TypeFunctionItem(a.constants.constant_multiname.get(a.method_info.get(tf.method_info).ret_type).getNameWithNamespace(a.constants)); - } - } - } - break; - } - } - - return TypeItem.UNBOUNDED; + return new TypeItem(propType.getVal()); } public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator, boolean needsReturn) { - int propertyId = resolveProperty(); + Reference objType = new Reference<>(""); + Reference propType = new Reference<>(""); + Reference propIndex = new Reference<>(0); + resolve(objType, propType, propIndex); + + int propertyId = propIndex.getVal(); Object obj = resolveObject(localData, generator); - Reference ret_temp=new Reference<>(0); + Reference ret_temp = new Reference<>(-1); if (assignedValue != null) { - String targetType = resolvePropertyType().toString(); + String targetType = propType.getVal(); String srcType = assignedValue.returnType().toString(); GraphTargetItem st = assignedValue; if (!targetType.equals(srcType)) { st = new CoerceAVM2Item(null, assignedValue, targetType); } return toSourceMerge(localData, generator, obj, index, st, - needsReturn?dupSetTemp(localData, generator, ret_temp):null, + needsReturn ? dupSetTemp(localData, generator, ret_temp) : null, ins(new SetPropertyIns(), propertyId), - needsReturn?getTemp(localData, generator, ret_temp):null, - killTemp(localData, generator, Arrays.asList(ret_temp))); + needsReturn ? getTemp(localData, generator, ret_temp) : null, + killTemp(localData, generator, Arrays.asList(ret_temp))); } else { + if (obj instanceof AVM2Instruction && (((AVM2Instruction) obj).definition instanceof FindPropertyStrictIns) && index == null) { + return toSourceMerge(localData, generator, ins(new GetLexIns(), propertyId), + needsReturn ? null : ins(new PopIns()) + ); + } return toSourceMerge(localData, generator, obj, index, ins(new GetPropertyIns(), propertyId), needsReturn ? null : ins(new PopIns()) @@ -300,12 +421,11 @@ public class PropertyAVM2Item extends AssignableAVM2Item { return true; } - - private Object resolveObject(SourceGeneratorLocalData localData, SourceGenerator generator){ + private Object resolveObject(SourceGeneratorLocalData localData, SourceGenerator generator) { Object obj = object; - int propertyId = resolveProperty(); - if(obj==null){ - String cname; + + if (obj == null) { + String cname; String pkgName = ""; cname = localData.currentClass; if (cname.contains(".")) { @@ -316,46 +436,59 @@ public class PropertyAVM2Item extends AssignableAVM2Item { Reference outNs = new Reference<>(""); Reference outPropNs = new Reference<>(""); Reference outPropNsKind = new Reference<>(1); - if (AVM2SourceGenerator.searchProperty(abcs, pkgName, cname, propertyName, outName, outNs, outPropNs, outPropNsKind)) { - NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.currentClass), 0/*?*/, "this", null, false, openedNamespaces, openedNamespacesKind); + Reference outPropType = new Reference<>(""); + List abcs = new ArrayList<>(); + abcs.add(abc); + abcs.addAll(otherABCs); + if (AVM2SourceGenerator.searchPrototypeChain(true, abcs, pkgName, cname, propertyName, outName, outNs, outPropNs, outPropNsKind, outPropType)) { + NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.currentClass), 0, "this", null, false, openedNamespaces); nobj.setRegNumber(0); obj = nobj; } else { - obj = ins(new FindPropertyStrictIns(), propertyId); + Reference objType = new Reference<>(""); + Reference propType = new Reference<>(""); + Reference propIndex = new Reference<>(0); + resolve(objType, propType, propIndex); + obj = ins(new FindPropertyStrictIns(), propIndex.getVal()); } } return obj; } - + @Override - public List toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post,boolean decrement, boolean needsReturn) { - int propertyId = resolveProperty(); + public List toSourceChange(SourceGeneratorLocalData localData, SourceGenerator generator, boolean post, boolean decrement, boolean needsReturn) { + + Reference objType = new Reference<>(""); + Reference propType = new Reference<>(""); + Reference propIndex = new Reference<>(0); + resolve(objType, propType, propIndex); + + int propertyId = propIndex.getVal(); Object obj = resolveObject(localData, generator); Reference ret_temp = new Reference<>(-1); Reference obj_temp = new Reference<>(-1); Reference index_temp = new Reference<>(-1); - - boolean isInteger = resolvePropertyType().toString().equals("int"); - - - List ret= toSourceMerge(localData, generator, obj, dupSetTemp(localData, generator, obj_temp), index,index!=null?dupSetTemp(localData, generator, index_temp):null, + + boolean isInteger = propType.getVal().equals("int"); + + List ret = toSourceMerge(localData, generator, obj, dupSetTemp(localData, generator, obj_temp), index, index != null ? dupSetTemp(localData, generator, index_temp) : null, //Start get original //getTemp(localData, generator, obj_temp), //index!=null?getTemp(localData, generator, index_temp):null, ins(new GetPropertyIns(), propertyId), - !isInteger?ins(new ConvertDIns()):null, + !isInteger ? ins(new ConvertDIns()) : null, //End get original - (!post)?(decrement?ins(isInteger?new DecrementIIns():new DecrementIns()):ins(isInteger?new IncrementIIns():new IncrementIns())):null, - needsReturn?ins(new DupIns()):null, - (post)?(decrement?ins(isInteger?new DecrementIIns():new DecrementIns()):ins(isInteger?new IncrementIIns():new IncrementIns())):null, + (!post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null, + needsReturn ? ins(new DupIns()) : null, + (post) ? (decrement ? ins(isInteger ? new DecrementIIns() : new DecrementIns()) : ins(isInteger ? new IncrementIIns() : new IncrementIns())) : null, setTemp(localData, generator, ret_temp), getTemp(localData, generator, obj_temp), - index!=null?getTemp(localData, generator, index_temp):null, + index != null ? getTemp(localData, generator, index_temp) : null, getTemp(localData, generator, ret_temp), ins(new SetPropertyIns(), propertyId), //needsReturn?getTemp(localData, generator, ret_temp):null, - killTemp(localData, generator, Arrays.asList(ret_temp,obj_temp,index_temp))); + killTemp(localData, generator, Arrays.asList(ret_temp, obj_temp, index_temp))); return ret; } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SetterAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SetterAVM2Item.java index de0cd3964..211b11076 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SetterAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SetterAVM2Item.java @@ -25,8 +25,8 @@ import java.util.List; */ public class SetterAVM2Item extends MethodAVM2Item { - public SetterAVM2Item(boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespaceKind, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { - super(hasRest, line, override, isFinal, isStatic, namespaceKind, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); + public SetterAVM2Item(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(hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SlotAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SlotAVM2Item.java index 193df7a2e..33a51f4ff 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SlotAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SlotAVM2Item.java @@ -27,22 +27,22 @@ import com.jpexs.decompiler.graph.model.LocalData; */ public class SlotAVM2Item extends AVM2Item { - private final int nsKind; + private final int namespace; private boolean isStatic; public String var; public GraphTargetItem type; - public int getNsKind() { - return nsKind; + public int getNamespace() { + return namespace; } public boolean isStatic() { return isStatic; } - public SlotAVM2Item(boolean isStatic, int nsKind, String var, GraphTargetItem type, GraphTargetItem value) { + public SlotAVM2Item(boolean isStatic, int namespace, String var, GraphTargetItem type, GraphTargetItem value) { super(null, NOPRECEDENCE); - this.nsKind = nsKind; + this.namespace = namespace; this.value = value; this.isStatic = isStatic; this.var = var; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/todo.txt b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/todo.txt index 6b205382f..5bd2fa6f3 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/todo.txt +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/todo.txt @@ -9,4 +9,4 @@ TODO List for AS3 parser/compiler: - with - delete property - default xml namespace -- better private namespaces handling \ No newline at end of file +- custom namespace modifiers \ No newline at end of file diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/types/Multiname.java b/trunk/src/com/jpexs/decompiler/flash/abc/types/Multiname.java index 76a69eb3b..6d3c9f6b8 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/types/Multiname.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/types/Multiname.java @@ -42,6 +42,16 @@ public class Multiname { public int qname_index = -1; //for TypeName public List params; //for TypeName + public boolean validType() { + boolean cnt = false; + for (int i = 0; i < multinameKinds.length; i++) { + if (multinameKinds[i] == kind) { + cnt = true; + } + } + return cnt; + } + public Multiname(int kind, int name_index, int namespace_index, int namespace_set_index, int qname_index, List params) { this.kind = kind; this.name_index = name_index; @@ -49,6 +59,9 @@ public class Multiname { this.namespace_set_index = namespace_set_index; this.qname_index = qname_index; this.params = params; + if (!validType()) { + throw new RuntimeException("Invalid multiname kind:" + kind); + } } public boolean isAttribute() { diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/types/Namespace.java b/trunk/src/com/jpexs/decompiler/flash/abc/types/Namespace.java index dd763676b..79869c300 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/types/Namespace.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/types/Namespace.java @@ -97,7 +97,7 @@ public class Namespace { public String getName(ConstantPool constants) { if (name_index == 0) { - return "-"; + return null; } return constants.getString(name_index); }