diff --git a/trunk/src/com/jpexs/decompiler/flash/SWF.java b/trunk/src/com/jpexs/decompiler/flash/SWF.java index a1481b2b8..e0c0b5cd7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWF.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWF.java @@ -601,6 +601,7 @@ public final class SWF implements TreeItem, Timelined { assignExportNamesToSymbols(); assignClassesToSymbols(); findFileAttributes(); + findABCTags(); } else { boolean hasNonUnknownTag = false; for (Tag tag : tags) { @@ -682,6 +683,27 @@ public final class SWF implements TreeItem, Timelined { return new File(title).getName(); } + private void findABCTags(){ + List objs = new ArrayList<>(); + objs.addAll(tags); + + ArrayList newAbcList = new ArrayList<>(); + getABCTags(objs, newAbcList); + this.abcList = newAbcList; + } + + + private static void getABCTags(List list, List actionScripts) { + for (ContainerItem t : list) { + if (t instanceof Container) { + getABCTags(((Container) t).getSubItems(), actionScripts); + } + if (t instanceof ABCContainerTag) { + actionScripts.add((ABCContainerTag) t); + } + } + } + private void findFileAttributes() { for (Tag t : tags) { if (t instanceof FileAttributesTag) { diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/ABCInputStream.java b/trunk/src/com/jpexs/decompiler/flash/abc/ABCInputStream.java index ecde8dbf8..3e0a7c388 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/ABCInputStream.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/ABCInputStream.java @@ -214,26 +214,25 @@ public class ABCInputStream extends InputStream { public Multiname readMultiname() throws IOException { int kind = readU8(); - int namespace_index = -1; - int name_index = -1; - int namespace_set_index = -1; - int qname_index = -1; + int namespace_index = 0; + int name_index = 0; + int namespace_set_index = 0; + int qname_index = 0; List params = new ArrayList<>(); - if ((kind == 7) || (kind == 0xd)) { // CONSTANT_QName and CONSTANT_QNameA. + if ((kind == Multiname.QNAME) || (kind == Multiname.QNAMEA)) { namespace_index = readU30(); name_index = readU30(); - } else if ((kind == 0xf) || (kind == 0x10)) { //CONSTANT_RTQName and CONSTANT_RTQNameA + } else if ((kind == Multiname.RTQNAME) || (kind == Multiname.RTQNAMEA)) { name_index = readU30(); - } else if ((kind == 0x11) || (kind == 0x12))//kind==0x11,0x12 nothing CONSTANT_RTQNameL and CONSTANT_RTQNameLA. - { - } else if ((kind == 9) || (kind == 0xe)) { // CONSTANT_Multiname and CONSTANT_MultinameA. + } else if ((kind == Multiname.RTQNAMEL) || (kind == Multiname.RTQNAMELA)) { + + } else if ((kind == Multiname.MULTINAME) || (kind == Multiname.MULTINAMEA)) { name_index = readU30(); namespace_set_index = readU30(); - } else if ((kind == 0x1B) || (kind == 0x1C)) { //CONSTANT_MultinameL and CONSTANT_MultinameLA + } else if ((kind == Multiname.MULTINAMEL) || (kind == Multiname.MULTINAMELA)) { namespace_set_index = readU30(); - } else if (kind == 0x1D) { - //Constant_TypeName + } else if (kind == Multiname.TYPENAME) { qname_index = readU30(); //Multiname index!!! int paramsLength = readU30(); for (int i = 0; i < paramsLength; i++) { 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 4a9d9e3f1..e7293ac7c 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -1990,18 +1990,20 @@ public class AVM2Code implements Serializable { if (code.get(maxIp).definition instanceof JumpIns) { nextIp = adr2pos(pos2adr(nextIp) + code.get(maxIp).operands[0]); } - int origScopePos = stats.instructionStats[nextIp].scopepos; - int origStackPos = stats.instructionStats[nextIp].stackpos; + if(nextIp ops=new ArrayList<>(); + for(Integer o:operands){ + if(o!=null){ + ops.add(o); + } + } + int opArr[]=new int[ops.size()]; + for(int i=0;i openedNamespaces, SourceGeneratorLocalData localData) { + private int genNs(String pkg,String custom, int namespace, List openedNamespaces, SourceGeneratorLocalData localData,int line) throws CompilationException { if (custom != null) { PropertyAVM2Item prop = new PropertyAVM2Item(null, custom, abc, allABCs, openedNamespaces, new ArrayList()); Reference value = new Reference<>(null); prop.resolve(localData, new Reference(""), new Reference(""), new Reference(0), value); + boolean resolved = true; + if(value.getVal() == null){ + resolved = false; + + } + if(!resolved){ + throw new CompilationException("Namespace not defined", line); + } namespace = value.getVal().value_index; } return namespace; @@ -1811,13 +1819,13 @@ public class AVM2SourceGenerator implements SourceGenerator { } else if (item instanceof ClassAVM2Item) { traits[k].name_index = traitName(((ClassAVM2Item) item).namespace, ((ClassAVM2Item) item).className); } else if ((item instanceof MethodAVM2Item) || (item instanceof GetterAVM2Item) || (item instanceof SetterAVM2Item)) { - traits[k].name_index = traitName(genNs(((MethodAVM2Item) item).customNamespace, ((MethodAVM2Item) item).namespace, openedNamespaces, localData), ((MethodAVM2Item) item).functionName); + traits[k].name_index = traitName(genNs(pkg,((MethodAVM2Item) item).customNamespace, ((MethodAVM2Item) item).namespace, openedNamespaces, localData,((MethodAVM2Item)item).line), ((MethodAVM2Item) item).functionName); } else if (item instanceof FunctionAVM2Item) { traits[k].name_index = traitName(((FunctionAVM2Item) item).namespace, ((FunctionAVM2Item) item).functionName); } else if (item instanceof ConstAVM2Item) { - traits[k].name_index = traitName(genNs(((ConstAVM2Item) item).customNamespace, ((ConstAVM2Item) item).getNamespace(), openedNamespaces, localData), ((ConstAVM2Item) item).var); + traits[k].name_index = traitName(genNs(pkg,((ConstAVM2Item) item).customNamespace, ((ConstAVM2Item) item).getNamespace(), openedNamespaces, localData,((ConstAVM2Item)item).line), ((ConstAVM2Item) item).var); } else if (item instanceof SlotAVM2Item) { - traits[k].name_index = traitName(genNs(((SlotAVM2Item) item).customNamespace, ((SlotAVM2Item) item).getNamespace(), openedNamespaces, localData), ((SlotAVM2Item) item).var); + traits[k].name_index = traitName(genNs(pkg,((SlotAVM2Item) item).customNamespace, ((SlotAVM2Item) item).getNamespace(), openedNamespaces, localData,((SlotAVM2Item)item).line), ((SlotAVM2Item) item).var); } } @@ -2152,7 +2160,10 @@ public class AVM2SourceGenerator implements SourceGenerator { if (pkg.equals(clsName.getNamespace(abc.constants).getName(abc.constants))) { //class found - for (Trait t : ii.instance_traits.traits) { + for (Trait t : ii.instance_traits.traits) { + if(t.getName(abc) == null){ //in traits phase 2 + continue; + } if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList()))) { outName.setVal(obj); outNs.setVal(pkg); @@ -2169,6 +2180,9 @@ public class AVM2SourceGenerator implements SourceGenerator { if (!instanceOnly) { for (Trait t : abc.class_info.get(i).static_traits.traits) { + if(t.getName(abc) == null){ //in traits phase 2 + continue; + } if (propertyName.equals(t.getName(abc).getName(abc.constants, new ArrayList()))) { outName.setVal(obj); outNs.setVal(pkg); @@ -2294,7 +2308,7 @@ public class AVM2SourceGenerator implements SourceGenerator { for (int i = 1; i < abc.constants.constant_multiname.size(); i++) { Multiname mname = abc.constants.constant_multiname.get(i); if (name.equals(mname.getName(abc.constants, new ArrayList()))) { - if (pkg.equals(mname.getNamespace(abc.constants).getName(abc.constants))) { + if (mname.getNamespace(abc.constants)!=null && pkg.equals(mname.getNamespace(abc.constants).getName(abc.constants))) { name_index = i; break; } 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 85cc0a758..d613bf5a6 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 @@ -175,9 +175,25 @@ public class ActionScriptParser { case PARENT_OPEN: ret = new CallAVM2Item(lexer.yyline(), ret, call(needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); break; + } s = lex(); } + if (s.type == SymbolType.INCREMENT) { + if (!isNameOrProp(ret)) { + throw new ParseException("Invalid assignment", lexer.yyline()); + } + ret = new PostIncrementAVM2Item(null, ret); + s = lex(); + + } else if (s.type == SymbolType.DECREMENT) { + if (!isNameOrProp(ret)) { + throw new ParseException("Invalid assignment", lexer.yyline()); + } + ret = new PostDecrementAVM2Item(null, ret); + s = lex(); + } + lexer.pushback(s); return ret; } @@ -208,19 +224,27 @@ public class ActionScriptParser { s = lex(); expected(s, lexer.yyline(), SymbolType.IDENTIFIER); String propName = s.value.toString(); + GraphTargetItem propItem = null; s = lex(); GraphTargetItem ns = null; if (s.type == SymbolType.NAMESPACE_OP) { - s = lex(); - expected(s, lexer.yyline(), SymbolType.IDENTIFIER); ns = new UnresolvedAVM2Item(new ArrayList(), importedClasses, false, null, lexer.yyline(), propName, null, openedNamespaces); variables.add((UnresolvedAVM2Item) ns); - propName = s.value.toString(); + s = lex(); + if(s.type == SymbolType.BRACKET_OPEN){ + propItem = expression(needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + expectedType(SymbolType.BRACKET_CLOSE); + propName = null; + }else{ + expected(s, lexer.yyline(), SymbolType.IDENTIFIER); + propName = s.value.toString(); + propItem = null; + } } else { lexer.pushback(s); } if (ns != null) { - ret = new NamespacedAVM2Item(ns, propName, ret, attr, openedNamespaces, null); + ret = new NamespacedAVM2Item(ns, propName,propItem, ret, attr, openedNamespaces, null); } else { ret = new PropertyAVM2Item(ret, (attr ? "@" : "") + propName, abc, otherABCs, openedNamespaces, new ArrayList()); } @@ -249,7 +273,9 @@ public class ActionScriptParser { if (s.type == SymbolType.ATTRIBUTE) { name += "@"; s = lex(); - if (s.type == SymbolType.IDENTIFIER) { + if(s.type == SymbolType.MULTIPLY){ + name += s.value.toString(); + } else if (s.type == SymbolType.IDENTIFIER) { name += s.value.toString(); } else { if (s.type != SymbolType.BRACKET_OPEN) { @@ -266,6 +292,7 @@ public class ActionScriptParser { } String nsname = null; String nsprop = null; + GraphTargetItem nspropItem = null; if (s.type == SymbolType.NAMESPACE_OP) { if (name.contains(".")) { nsname = name.substring(name.lastIndexOf('.') + 1); @@ -275,9 +302,9 @@ public class ActionScriptParser { s = lex(); if (s.type == SymbolType.IDENTIFIER) { nsprop = s.value.toString(); - } else { - nsprop = null; - lexer.pushback(s); + } else if(s.type == SymbolType.BRACKET_OPEN){ + nspropItem = expression(needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables); + expectedType(SymbolType.BRACKET_CLOSE); } if (name.contains(".")) { name = name.substring(0, name.lastIndexOf('.')); @@ -332,7 +359,7 @@ public class ActionScriptParser { } UnresolvedAVM2Item ns = new UnresolvedAVM2Item(params, importedClasses, typeOnly, null, lexer.yyline(), nsname, null, openedNamespaces); variables.add(ns); - ret = new NamespacedAVM2Item(ns, nsprop, ret, attr, openedNamespaces, null); + ret = new NamespacedAVM2Item(ns, nsprop, nspropItem, ret, attr, openedNamespaces, null); } if (s.type == SymbolType.BRACKET_OPEN) { lexer.pushback(s); @@ -463,9 +490,12 @@ public class ActionScriptParser { List body = null; List subvariables = new ArrayList<>(); subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), "this", null, true, openedNamespaces)); - for (int i = 0; i < paramNames.size(); i++) { + for (int i = 0; i < paramNames.size() - (hasRest ? 1 : 0); i++) { subvariables.add(new NameAVM2Item(paramTypes.get(i), lexer.yyline(), paramNames.get(i), null, true, openedNamespaces)); } + if (hasRest) { + subvariables.add(new NameAVM2Item(TypeItem.UNBOUNDED, lexer.yyline(), paramNames.get(paramNames.size() - 1), null, true, openedNamespaces)); + } subvariables.add(new NameAVM2Item(thisType, lexer.yyline(), "arguments", null, true, openedNamespaces)); int parCnt = subvariables.size(); Reference needsActivation2 = new Reference<>(false); @@ -682,29 +712,29 @@ public class ActionScriptParser { constr = (method(false, customAccess, new Reference(false), importedClasses, false, false, thisType, openedNamespaces, false, namespace, "", true, constrVariables)); } else { MethodAVM2Item ft = method(false, customAccess, new Reference(false), importedClasses, isOverride, isFinal, thisType, openedNamespaces, isStatic, namespace, fname, true, new ArrayList()); - - if(isGetter){ + + if (isGetter) { if (!ft.paramTypes.isEmpty()) { throw new ParseException("Getter can't have any parameters", lexer.yyline()); } } - - if(isSetter){ + + if (isSetter) { if (ft.paramTypes.size() != 1) { throw new ParseException("Getter must have exactly one parameter", lexer.yyline()); } } - + if (isStatic && isInterface) { if (isInterface) { throw new ParseException("Interface cannot have static fields", lexer.yyline()); } } GraphTargetItem t; - if (isGetter) { + if (isGetter) { GetterAVM2Item g = new GetterAVM2Item(isInterface, customAccess, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); t = g; - } else if (isSetter) { + } else if (isSetter) { SetterAVM2Item st = new SetterAVM2Item(isInterface, customAccess, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); t = st; } else { @@ -737,7 +767,7 @@ public class ActionScriptParser { lexer.pushback(s); } - ConstAVM2Item ns = new ConstAVM2Item(customAccess, true, namespace, nname, new TypeItem("Namespace"), new StringAVM2Item(null, nval)); + ConstAVM2Item ns = new ConstAVM2Item(customAccess, true, namespace, nname, new TypeItem("Namespace"), new StringAVM2Item(null, nval),lexer.yyline()); traits.add(ns); break; case CONST: @@ -776,9 +806,9 @@ public class ActionScriptParser { } GraphTargetItem tar; if (isConst) { - tar = new ConstAVM2Item(customAccess, isStatic, namespace, vcname, type, value); + tar = new ConstAVM2Item(customAccess, isStatic, namespace, vcname, type, value,lexer.yyline()); } else { - tar = new SlotAVM2Item(customAccess, isStatic, namespace, vcname, type, value); + tar = new SlotAVM2Item(customAccess, isStatic, namespace, vcname, type, value,lexer.yyline()); } traits.add(tar); if (s.type != SymbolType.SEMICOLON) { @@ -1772,18 +1802,6 @@ public class ActionScriptParser { } ret = as; break; - case INCREMENT: //postincrement - if (!(expr instanceof AssignableAVM2Item)) { - throw new ParseException("Invalid assignment", lexer.yyline()); - } - ret = new PostIncrementAVM2Item(null, expr); - break; - case DECREMENT: //postdecrement - if (!(expr instanceof AssignableAVM2Item)) { - throw new ParseException("Invalid assignment", lexer.yyline()); - } - ret = new PostDecrementAVM2Item(null, expr); - break; case DOT: //member case BRACKET_OPEN: //member case PARENT_OPEN: //function call @@ -1817,6 +1835,9 @@ public class ActionScriptParser { if (item instanceof PropertyAVM2Item) { return true; } + if (item instanceof IndexAVM2Item) { + return true; + } return false; } @@ -2035,9 +2056,23 @@ public class ActionScriptParser { existsRemainder = true; break; case NEW: - GraphTargetItem newvar = name(needsActivation, true, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses); - expectedType(SymbolType.PARENT_OPEN); - ret = new ConstructSomethingAVM2Item(lexer.yyline(), openedNamespaces, newvar, call(needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); + s = lex(); + if(s.type == SymbolType.FUNCTION){ + s = lexer.lex(); + String ffname = ""; + if (s.isType(SymbolType.IDENTIFIER)) { + ffname = s.value.toString(); + } else { + lexer.pushback(s); + } + needsActivation.setVal(true); + ret = function(false, needsActivation, importedClasses, 0/*?*/, TypeItem.UNBOUNDED, openedNamespaces, ffname, false, variables); + }else{ + lexer.pushback(s); + GraphTargetItem newvar = name(needsActivation, true, openedNamespaces, registerVars, inFunction, inMethod, variables, importedClasses); + expectedType(SymbolType.PARENT_OPEN); + ret = new ConstructSomethingAVM2Item(lexer.yyline(), openedNamespaces, newvar, call(needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); + } existsRemainder = true; break; case IDENTIFIER: @@ -2201,7 +2236,7 @@ public class ActionScriptParser { this.otherABCs = otherABCs; } - public static void compile(String src, ABC abc, boolean documentClass, String fileName) throws ParseException, IOException, InterruptedException, CompilationException { + public static void compile(String src, ABC abc, List otherABCs,boolean documentClass, String fileName) throws ParseException, IOException, InterruptedException, CompilationException { SWC swc = new SWC(new FileInputStream(Configuration.getPlayerSWC())); SWF swf = new SWF(swc.getSWF("library.swf"), true); List playerABCs = new ArrayList<>(); @@ -2210,7 +2245,10 @@ public class ActionScriptParser { playerABCs.add(((ABCContainerTag) t).getABC()); } } - ActionScriptParser parser = new ActionScriptParser(abc, playerABCs); + List parABCs=new ArrayList<>(); + parABCs.addAll(playerABCs); + parABCs.addAll(otherABCs); + ActionScriptParser parser = new ActionScriptParser(abc, parABCs); parser.addScript(src, documentClass, fileName); } 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 96417b47f..52d08ae0e 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 @@ -58,8 +58,8 @@ public class CallAVM2Item extends AVM2Item { return writer; } - @Override - public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator, boolean needsReturn) throws CompilationException { AVM2SourceGenerator g = (AVM2SourceGenerator) generator; @@ -75,7 +75,7 @@ public class CallAVM2Item extends AVM2Item { String cname; String pkgName = ""; cname = localData.currentClass; - if (cname.contains(".")) { + if (cname!=null && cname.contains(".")) { pkgName = cname.substring(0, cname.lastIndexOf('.')); cname = cname.substring(cname.lastIndexOf('.') + 1); } @@ -86,7 +86,7 @@ public class CallAVM2Item extends AVM2Item { Reference outPropNsKind = new Reference<>(1); Reference outPropType = new Reference<>(""); Reference outPropValue = new Reference<>(null); - if (AVM2SourceGenerator.searchPrototypeChain(true, allAbcs, pkgName, cname, n.getVariableName(), outName, outNs, outPropNs, outPropNsKind, outPropType, outPropValue)) { + if (cname!=null && AVM2SourceGenerator.searchPrototypeChain(true, allAbcs, pkgName, cname, n.getVariableName(), outName, outNs, outPropNs, outPropNsKind, outPropType, outPropValue)) { NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.currentClass), n.line, "this", null, false, n.openedNamespaces); nobj.setRegNumber(0); obj = nobj; @@ -114,7 +114,7 @@ public class CallAVM2Item extends AVM2Item { String cname; String pkgName = ""; cname = localData.currentClass; - if (cname.contains(".")) { + if (cname!=null && cname.contains(".")) { pkgName = cname.substring(0, cname.lastIndexOf('.')); cname = cname.substring(cname.lastIndexOf('.') + 1); } @@ -124,7 +124,7 @@ public class CallAVM2Item extends AVM2Item { Reference outPropNsKind = new Reference<>(1); Reference outPropType = new Reference<>(""); Reference outPropValue = new Reference<>(null); - if (AVM2SourceGenerator.searchPrototypeChain(true, allAbcs, pkgName, cname, prop.propertyName, outName, outNs, outPropNs, outPropNsKind, outPropType, outPropValue) && (localData.currentClass.equals("".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal()))) { + if (cname!=null && AVM2SourceGenerator.searchPrototypeChain(true, allAbcs, pkgName, cname, prop.propertyName, outName, outNs, outPropNs, outPropNsKind, outPropType, outPropValue) && (localData.currentClass.equals("".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal()))) { NameAVM2Item nobj = new NameAVM2Item(new TypeItem(localData.currentClass), 0, "this", null, false, new ArrayList()); nobj.setRegNumber(0); obj = nobj; @@ -138,42 +138,30 @@ public class CallAVM2Item extends AVM2Item { obj = new AVM2Instruction(0, new FindPropertyStrictIns(), new int[]{propIndex}, new byte[0]); } return toSourceMerge(localData, generator, obj, arguments, - ins(new CallPropertyIns(), propIndex, arguments.size()) + ins(needsReturn?new CallPropertyIns():new CallPropVoidIns(), propIndex, arguments.size()) ); } + if(callable instanceof IndexAVM2Item){ + return ((IndexAVM2Item)callable).toSource(localData, generator, needsReturn, true, arguments); + } + if(callable instanceof NamespacedAVM2Item){ + return ((NamespacedAVM2Item)callable).toSource(localData, generator, needsReturn, true, arguments); + } + throw new CompilationException("Not a callable", line); } + @Override + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { + return toSource(localData, generator, true); + } + + + @Override public List toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - - AVM2SourceGenerator g = (AVM2SourceGenerator) generator; - - GraphTargetItem callable = name; - if (callable instanceof UnresolvedAVM2Item) { - callable = ((UnresolvedAVM2Item) callable).resolved; - } - - if (callable instanceof NameAVM2Item) { - NameAVM2Item n = (NameAVM2Item) callable; - PropertyAVM2Item p = new PropertyAVM2Item(null, n.getVariableName(), g.abc, g.allABCs, n.openedNamespaces, new ArrayList()); - p.setAssignedValue(n.getAssignedValue()); - callable = p; - } - - if (callable instanceof PropertyAVM2Item) { - PropertyAVM2Item prop = (PropertyAVM2Item) callable; - Object obj = prop.object; - if (obj == null) { - obj = new AVM2Instruction(0, new FindPropertyStrictIns(), new int[]{prop.resolveProperty(localData)}, new byte[0]); - } - return toSourceMerge(localData, generator, obj, arguments, - new AVM2Instruction(0, new CallPropVoidIns(), new int[]{prop.resolveProperty(localData), arguments.size()}, new byte[0]) - ); - } - - return new ArrayList<>(); + return toSource(localData, generator, false); } @Override 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 8c1abe180..1387746f6 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 @@ -32,6 +32,7 @@ public class ConstAVM2Item extends AVM2Item { public String var; public GraphTargetItem type; public String customNamespace; + public int line; public int getNamespace() { return namespace; @@ -41,8 +42,9 @@ public class ConstAVM2Item extends AVM2Item { return isStatic; } - public ConstAVM2Item(String customNamespace, boolean isStatic, int namespace, String var, GraphTargetItem type, GraphTargetItem value) { + public ConstAVM2Item(String customNamespace, boolean isStatic, int namespace, String var, GraphTargetItem type, GraphTargetItem value, int line) { super(null, NOPRECEDENCE); + this.line = line; this.namespace = namespace; this.value = value; this.isStatic = isStatic; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java index 8c959ac04..6194eb23a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/IndexAVM2Item.java @@ -20,9 +20,11 @@ import com.jpexs.decompiler.flash.SourceGeneratorLocalData; import com.jpexs.decompiler.flash.abc.ABC; 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.instructions.executing.CallIns; 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.instructions.stack.PopIns; import com.jpexs.decompiler.flash.abc.avm2.instructions.types.ConvertDIns; import static com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item.ins; import static com.jpexs.decompiler.flash.abc.avm2.parser.script.AssignableAVM2Item.dupSetTemp; @@ -115,7 +117,7 @@ public class IndexAVM2Item extends AssignableAVM2Item { } - public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator, boolean needsReturn) throws CompilationException { + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator, boolean needsReturn, boolean call, List callargs) throws CompilationException { AVM2SourceGenerator g = (AVM2SourceGenerator) generator; int indexPropIndex = g.abc.constants.getMultinameId(new Multiname(attr ? Multiname.MULTINAMELA : Multiname.MULTINAMEL, 0, 0, allNsSet(g.abc), 0, new ArrayList()), true); Reference ret_temp = new Reference<>(-1); @@ -132,20 +134,24 @@ public class IndexAVM2Item extends AssignableAVM2Item { } else { return toSourceMerge(localData, generator, object, + call?ins(new DupIns()):null, index, - ins(new GetPropertyIns(), indexPropIndex)); + ins(new GetPropertyIns(), indexPropIndex), + call?callargs:null, + call?ins(new CallIns(),callargs.size()):null, + needsReturn ? null : ins(new PopIns())); } } @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - return toSource(localData, generator, true); + return toSource(localData, generator, true, false, new ArrayList()); } @Override public List toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - return toSource(localData, generator, false); + return toSource(localData, generator, false, false, new ArrayList()); } } diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespacedAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespacedAVM2Item.java index 350b2b677..9a92771ae 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespacedAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/NamespacedAVM2Item.java @@ -22,6 +22,7 @@ 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.executing.CallIns; 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; @@ -57,13 +58,15 @@ public class NamespacedAVM2Item extends AssignableAVM2Item { public GraphTargetItem ns; public String name; + public GraphTargetItem nameItem; public GraphTargetItem obj; public boolean attr; public List openedNamespaces; - public NamespacedAVM2Item(GraphTargetItem ns, String name, GraphTargetItem obj, boolean attr, List openedNamespaces, GraphTargetItem storeValue) { + public NamespacedAVM2Item(GraphTargetItem ns, String name, GraphTargetItem nameItem, GraphTargetItem obj, boolean attr, List openedNamespaces, GraphTargetItem storeValue) { super(storeValue); this.ns = ns; + this.nameItem = nameItem; this.name = name; this.obj = obj; this.attr = attr; @@ -80,7 +83,7 @@ public class NamespacedAVM2Item extends AssignableAVM2Item { @Override public AssignableAVM2Item copy() { - return new NamespacedAVM2Item(ns, name, obj, attr, openedNamespaces, assignedValue); + return new NamespacedAVM2Item(ns, name, nameItem, obj, attr, openedNamespaces, assignedValue); } @Override @@ -154,16 +157,19 @@ public class NamespacedAVM2Item extends AssignableAVM2Item { return TypeItem.UNBOUNDED; } - public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator, boolean needsReturn) throws CompilationException { + public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator, boolean needsReturn, boolean call, List callargs) throws CompilationException { AVM2SourceGenerator g = (AVM2SourceGenerator) generator; Reference ns_temp = new Reference<>(-1); Reference index_temp = new Reference<>(-1); Reference ret_temp = new Reference<>(-1); + + Reference obj_temp = new Reference<>(-1); + if (name == null) { if (assignedValue != null) { return toSourceMerge(localData, generator, - obj == null ? ns : null, obj == null ? generateCoerce(generator, new TypeItem("Namespace")) : null, ins(new ConvertSIns()), obj != null ? obj : ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList()), true)), - ns, generateCoerce(generator, new TypeItem("Namespace")), ins(new ConvertSIns()), assignedValue, + obj == null ? ns : null, obj == null ? generateCoerce(generator, new TypeItem("Namespace")) : null, nameItem, ins(new ConvertSIns()), obj != null ? obj : ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList()), true)), + ns, generateCoerce(generator, new TypeItem("Namespace")), nameItem, ins(new ConvertSIns()), assignedValue, needsReturn ? dupSetTemp(localData, generator, ret_temp) : null, ins(new SetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList()), true)), needsReturn ? getTemp(localData, generator, ret_temp) : null, @@ -171,10 +177,14 @@ public class NamespacedAVM2Item extends AssignableAVM2Item { ); } else { return toSourceMerge(localData, generator, - obj == null ? ns : null, obj == null ? generateCoerce(generator, new TypeItem("Namespace")) : null, ins(new ConvertSIns()), obj != null ? obj : ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList()), true)), - ns, generateCoerce(generator, new TypeItem("Namespace")), ins(new ConvertSIns()), ins(new GetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList()), true)), + obj == null ? ns : null, obj == null ? generateCoerce(generator, new TypeItem("Namespace")) : null, nameItem, ins(new ConvertSIns()), obj != null ? obj : ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList()), true)), + call ? dupSetTemp(localData, generator, obj_temp) : null, + ns, generateCoerce(generator, new TypeItem("Namespace")), nameItem, ins(new ConvertSIns()), ins(new GetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(Multiname.RTQNAMEL, 0, 0, 0, 0, new ArrayList()), true)), + call ? getTemp(localData, generator, obj_temp) : null, + call ? callargs : null, + call ? ins(new CallIns(), callargs.size()) : null, needsReturn ? null : ins(new PopIns()), - killTemp(localData, generator, Arrays.asList(ns_temp, index_temp, ret_temp)) + killTemp(localData, generator, Arrays.asList(obj_temp)) ); } } else { @@ -190,9 +200,13 @@ public class NamespacedAVM2Item extends AssignableAVM2Item { } else { return toSourceMerge(localData, generator, obj == null ? ns : null, obj == null ? generateCoerce(generator, new TypeItem("Namespace")) : null, obj != null ? obj : ins(new FindPropertyStrictIns(), g.abc.constants.getMultinameId(new Multiname(attr ? Multiname.RTQNAMEA : Multiname.RTQNAME, g.abc.constants.getStringId(name, true), 0, 0, 0, new ArrayList()), true)), + call ? dupSetTemp(localData, generator, obj_temp) : null, ns, generateCoerce(generator, new TypeItem("Namespace")), ins(new GetPropertyIns(), g.abc.constants.getMultinameId(new Multiname(attr ? Multiname.RTQNAMEA : Multiname.RTQNAME, g.abc.constants.getStringId(name, true), 0, 0, 0, new ArrayList()), true)), + call ? getTemp(localData, generator, obj_temp) : null, + call ? callargs : null, + call ? ins(new CallIns(), callargs.size()) : null, needsReturn ? null : ins(new PopIns()), - killTemp(localData, generator, Arrays.asList(ns_temp, index_temp, ret_temp)) + killTemp(localData, generator, Arrays.asList(obj_temp)) ); } } @@ -200,12 +214,12 @@ public class NamespacedAVM2Item extends AssignableAVM2Item { @Override public List toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - return toSource(localData, generator, true); + return toSource(localData, generator, true, false, new ArrayList()); } @Override public List toSourceIgnoreReturnValue(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException { - return toSource(localData, generator, false); + return toSource(localData, generator, false, false, new ArrayList()); } } 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 4db70ee96..b8949de22 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 @@ -36,6 +36,7 @@ import com.jpexs.decompiler.flash.abc.types.MethodBody; import com.jpexs.decompiler.flash.abc.types.Multiname; import com.jpexs.decompiler.flash.abc.types.Namespace; import com.jpexs.decompiler.flash.abc.types.NamespaceSet; +import com.jpexs.decompiler.flash.abc.types.ScriptInfo; import com.jpexs.decompiler.flash.abc.types.ValueKind; import com.jpexs.decompiler.flash.abc.types.traits.Trait; import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; @@ -214,6 +215,21 @@ public class PropertyAVM2Item extends AssignableAVM2Item { } break loopobjType; } + } + } + + for(ScriptInfo si:abc.script_info){ + for (Trait t :si.traits.traits) { + if (t.name_index == name_index) { + objType = "Object"; + propType = AVM2SourceGenerator.getTraitReturnType(abc, t).toString(); + propIndex = t.name_index; + if (t instanceof TraitSlotConst) { + TraitSlotConst tsc = (TraitSlotConst) t; + propValue = new ValueKind(tsc.value_index, tsc.value_kind); + } + break loopobjType; + } } } } @@ -233,7 +249,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item { Reference outPropNsKind = new Reference<>(1); Reference outPropType = new Reference<>(""); Reference outPropValue = new Reference<>(null); - if (AVM2SourceGenerator.searchPrototypeChain(false, abcs, nsname, n.getName(a.constants, new ArrayList()), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropType, outPropValue)) { + if (propertyName!=null && AVM2SourceGenerator.searchPrototypeChain(false, abcs, nsname, n.getName(a.constants, new ArrayList()), propertyName, outName, outNs, outPropNs, outPropNsKind, outPropType, outPropValue)) { objType = "".equals(outNs.getVal()) ? outName.getVal() : outNs.getVal() + "." + outName.getVal(); propType = outPropType.getVal(); propIndex = abc.constants.getMultinameId(new Multiname(Multiname.QNAME, @@ -300,7 +316,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item { pname = pname.substring(1); } propIndex = abc.constants.getMultinameId(new Multiname(attr ? (pname.isEmpty() ? Multiname.MULTINAMELA : Multiname.MULTINAMEA) : Multiname.MULTINAME, - abc.constants.getStringId(pname, true), 0, + abc.constants.getStringId("*".equals(pname)?null:pname, true), 0, //Note: name = * is for .@* attribute attr && pname.isEmpty() ? abc.constants.getNamespaceSetId(new NamespaceSet(new int[]{abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abc.constants.getStringId(localData.pkg, true)), 0, true)}), true) : allNsSet(), 0, new ArrayList()), true); propType = "*"; objType = "*"; 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 aaa63cf6b..37d211d97 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 @@ -32,6 +32,7 @@ public class SlotAVM2Item extends AVM2Item { public String var; public GraphTargetItem type; public String customNamespace; + public int line; public int getNamespace() { return namespace; @@ -41,8 +42,9 @@ public class SlotAVM2Item extends AVM2Item { return isStatic; } - public SlotAVM2Item(String customNamespace, boolean isStatic, int namespace, String var, GraphTargetItem type, GraphTargetItem value) { + public SlotAVM2Item(String customNamespace, boolean isStatic, int namespace, String var, GraphTargetItem type, GraphTargetItem value, int line) { super(null, NOPRECEDENCE); + this.line = line; this.namespace = namespace; this.value = value; this.isStatic = isStatic; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java index 4e02e62c8..b8641bfcc 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java @@ -57,6 +57,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { public GraphTargetItem type; //private GraphTargetItem ns = null; public GraphTargetItem resolved; + public GraphTargetItem resolvedRoot; private boolean mustBeType; public List importedClasses; public List scopeStack = new ArrayList(); @@ -311,7 +312,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { ret.setAssignedValue(assignedValue); } ret.setNs(n.getNs()); - return ret; + return resolvedRoot=ret; } } } @@ -348,7 +349,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { if (parts.size() == 1 && assignedValue != null) { throw new CompilationException("Cannot assign type", line); } - return ret; + return resolvedRoot=ret; } } @@ -385,7 +386,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { throw new CompilationException("Cannot assign type", line); } - return ret; + return resolvedRoot=ret; } } } @@ -423,7 +424,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { throw new CompilationException("Cannot assign type", line); } - return ret; + return resolvedRoot=ret; } } } @@ -445,13 +446,19 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { if (parts.size() == 1) { ((NameAVM2Item) ret).setAssignedValue(assignedValue); } - return ret; + return resolvedRoot=ret; } if (paramNames.contains(parts.get(0)) || parts.get(0).equals("arguments")) { int ind = paramNames.indexOf(parts.get(0)); + GraphTargetItem t = TypeItem.UNBOUNDED; + if(ind == -1){ + + }else if(ind < paramTypes.size()){ + t = paramTypes.get(ind); + } //else rest parameter - GraphTargetItem ret = new NameAVM2Item(ind == -1 ? TypeItem.UNBOUNDED : paramTypes.get(ind), line, parts.get(0), null, false, openedNamespaces); + GraphTargetItem ret = new NameAVM2Item(t, line, parts.get(0), null, false, openedNamespaces); resolved = ret; for (int i = 1; i < parts.size(); i++) { resolved = new PropertyAVM2Item(resolved, parts.get(i), abc, otherAbcs, openedNamespaces, new ArrayList()); @@ -462,7 +469,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { if (parts.size() == 1) { ((NameAVM2Item) ret).setAssignedValue(assignedValue); } - return ret; + return resolvedRoot=ret; } if (!subtypes.isEmpty() && parts.size() == 1 && parts.get(0).equals("Vector")) { @@ -477,10 +484,10 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { ret.subtypes.add(st.fullTypeName); } resolved = ret; - return ret; + return resolvedRoot=ret; } - if (mustBeType) { + if (mustBeType) { throw new CompilationException("Not a type", line); } resolved = null; @@ -495,7 +502,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { ((PropertyAVM2Item) resolved).setAssignedValue(assignedValue); } } - return ret; + return resolvedRoot=ret; } } 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 56fcc0584..f8ea7b1c9 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/types/Multiname.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/types/Multiname.java @@ -196,16 +196,16 @@ public class Multiname { switch (kind) { case QNAME: case QNAMEA: - return getKindStr() + "(" + namespaceToString(constants, namespace_index) + "," + "\"" + Helper.escapeString(constants.getString(name_index)) + "\"" + ")"; + return getKindStr() + "(" + namespaceToString(constants, namespace_index) + "," + (name_index==0?"null":"\"" + Helper.escapeString(constants.getString(name_index)) + "\"") + ")"; case RTQNAME: case RTQNAMEA: - return getKindStr() + "(" + "\"" + Helper.escapeString(constants.getString(name_index)) + "\"" + ")"; + return getKindStr() + "(" + (name_index==0?"null":"\"" + Helper.escapeString(constants.getString(name_index))) + "\"" + ")"; case RTQNAMEL: case RTQNAMELA: return getKindStr() + "()"; case MULTINAME: case MULTINAMEA: - return getKindStr() + "(" + "\"" + Helper.escapeString(constants.getString(name_index)) + "\"" + "," + namespaceSetToString(constants, namespace_set_index) + ")"; + return getKindStr() + "(" + (name_index==0?"null":"\"" + Helper.escapeString(constants.getString(name_index)) + "\"") + "," + namespaceSetToString(constants, namespace_set_index) + ")"; case MULTINAMEL: case MULTINAMELA: return getKindStr() + "(" + namespaceSetToString(constants, namespace_set_index) + ")"; diff --git a/trunk/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java b/trunk/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java index cc19cc6db..8444d4d1d 100644 --- a/trunk/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java +++ b/trunk/src/com/jpexs/decompiler/flash/abc/types/traits/TraitClass.java @@ -125,9 +125,9 @@ public class TraitClass extends Trait implements TraitWithSlot { } if (ns.kind == Namespace.KIND_NAMESPACE) { if (!usname.equals("*")) { - if (!uses.contains(usname)) { + /*if (!uses.contains(usname)) { uses.add(usname); - } + }*/ if (!pkg.equals(ignorePackage)) { imports.add(newimport); } diff --git a/trunk/src/com/jpexs/decompiler/flash/exporters/morphshape/CanvasMorphShapeExporter.java b/trunk/src/com/jpexs/decompiler/flash/exporters/morphshape/CanvasMorphShapeExporter.java index 39471feb4..d083fe6c7 100644 --- a/trunk/src/com/jpexs/decompiler/flash/exporters/morphshape/CanvasMorphShapeExporter.java +++ b/trunk/src/com/jpexs/decompiler/flash/exporters/morphshape/CanvasMorphShapeExporter.java @@ -33,11 +33,6 @@ import com.jpexs.decompiler.flash.types.RGBA; import com.jpexs.decompiler.flash.types.SHAPE; import com.jpexs.helpers.Helper; import com.jpexs.helpers.SerializableImage; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.Locale; -import javax.imageio.ImageIO; /** * diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java b/trunk/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java index 3be10420e..9447b16dd 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/AdvancedSettingsDialog.java @@ -30,7 +30,6 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; -import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Arrays; @@ -47,11 +46,9 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; -import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.SpringLayout; import javax.swing.table.DefaultTableModel; -import javax.swing.table.TableModel; /** * diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 1da9998ab..1a512a03a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -684,15 +684,9 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec swfs.add(newSwfs); for (SWF swf : newSwfs) { - List objs = new ArrayList<>(); - objs.addAll(swf.tags); + - ArrayList abcList = new ArrayList<>(); - getActionScript3(objs, abcList); - - swf.abcList = abcList; - - boolean hasAbc = !abcList.isEmpty(); + boolean hasAbc = !swf.abcList.isEmpty(); swf.isAS3 = hasAbc; tagTree.setModel(new TagTreeModel(mainFrame, swfs)); @@ -933,16 +927,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec } } - public static void getActionScript3(List list, List actionScripts) { - for (ContainerItem t : list) { - if (t instanceof Container) { - getActionScript3(((Container) t).getSubItems(), actionScripts); - } - if (t instanceof ABCContainerTag) { - actionScripts.add((ABCContainerTag) t); - } - } - } + public static void getMorphShapes(List list, List morphShapes) { for (ContainerItem t : list) { diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/MyCommandButtonUI.java b/trunk/src/com/jpexs/decompiler/flash/gui/MyCommandButtonUI.java index bfd81f533..3e6835635 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/MyCommandButtonUI.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/MyCommandButtonUI.java @@ -26,9 +26,7 @@ import org.pushingpixels.flamingo.api.common.JCommandButton; import org.pushingpixels.flamingo.api.common.popup.JCommandPopupMenu; import org.pushingpixels.flamingo.api.common.popup.JPopupPanel; import org.pushingpixels.flamingo.api.common.popup.PopupPanelManager; -import org.pushingpixels.flamingo.internal.ui.common.BasicCommandButtonUI; import org.pushingpixels.substance.flamingo.common.ui.SubstanceCommandButtonUI; -import org.pushingpixels.substance.internal.utils.SubstanceCoreUtilities; /** * diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index 2322c0d96..b1fb4300a 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -684,7 +684,7 @@ public class ABCPanel extends JPanel implements ItemListener, ActionListener, Se boolean isDocumentClass = documentClass.equals(pack.getPath().toString()); try { - ActionScriptParser.compile(decompiledTextArea.getText(), abc, isDocumentClass, scriptName); + ActionScriptParser.compile(decompiledTextArea.getText(), abc,new ArrayList(), isDocumentClass, scriptName); //Move newly added script to its position abc.script_info.set(oldIndex, abc.script_info.get(newIndex)); abc.script_info.remove(newIndex); diff --git a/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodCodePanel.java b/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodCodePanel.java index 350f1b599..0df5d6733 100644 --- a/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodCodePanel.java +++ b/trunk/src/com/jpexs/decompiler/flash/gui/abc/MethodCodePanel.java @@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.AppStrings; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.avm2.ConstantPool; import com.jpexs.decompiler.flash.abc.types.traits.Trait; -import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.gui.Main; import com.jpexs.decompiler.flash.gui.View; diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/base/FontTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/base/FontTag.java index 1d19c1d63..bf04f5b88 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/base/FontTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/base/FontTag.java @@ -30,7 +30,6 @@ import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.GLYPHENTRY; import com.jpexs.decompiler.flash.types.RECT; -import com.jpexs.decompiler.flash.types.RGBA; import com.jpexs.decompiler.flash.types.SHAPE; import com.jpexs.decompiler.flash.types.TEXTRECORD; import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD; diff --git a/trunk/src/com/jpexs/decompiler/graph/model/SwitchItem.java b/trunk/src/com/jpexs/decompiler/graph/model/SwitchItem.java index f8e7f631a..96fa3f3c9 100644 --- a/trunk/src/com/jpexs/decompiler/graph/model/SwitchItem.java +++ b/trunk/src/com/jpexs/decompiler/graph/model/SwitchItem.java @@ -69,7 +69,7 @@ public class SwitchItem extends LoopItem implements Block { ((NulWriter) writer).startLoop(loop.id, LoopWithType.LOOP_TYPE_SWITCH); } if (labelUsed) { - writer.append("loopswitch" + loop.id + ":").newLine(); + writer.append("loop" + loop.id + ":").newLine(); } writer.append("switch"); if (writer.getFormatting().spaceBeforeParenthesesSwitchParentheses) { diff --git a/trunk/test/com/jpexs/decompiler/flash/ActionScript3Test.java b/trunk/test/com/jpexs/decompiler/flash/ActionScript3Test.java index 05b412470..c2690acfc 100644 --- a/trunk/test/com/jpexs/decompiler/flash/ActionScript3Test.java +++ b/trunk/test/com/jpexs/decompiler/flash/ActionScript3Test.java @@ -209,14 +209,13 @@ public class ActionScript3Test { + "trace(\"new line \\r\\n hello!\");\r\n", false); } - @Test public void testContinueLevels() { decompileMethod("testContinueLevels", "var b:* = undefined;\r\n" + "var c:* = undefined;\r\n" + "var d:* = undefined;\r\n" + "var e:* = undefined;\r\n" + "var a:* = 5;\r\n" - + "loopswitch3:\r\n" + + "loop3:\r\n" + "switch(a)\r\n" + "{\r\n" + "case 57 * a:\r\n" diff --git a/trunk/test/com/jpexs/decompiler/flash/RecompileTest.java b/trunk/test/com/jpexs/decompiler/flash/RecompileTest.java index 4a53ab7a2..ed611afb3 100644 --- a/trunk/test/com/jpexs/decompiler/flash/RecompileTest.java +++ b/trunk/test/com/jpexs/decompiler/flash/RecompileTest.java @@ -16,15 +16,20 @@ */ package com.jpexs.decompiler.flash; -import static com.jpexs.decompiler.flash.SWF.createASTagList; +import com.jpexs.decompiler.flash.abc.ABC; +import com.jpexs.decompiler.flash.abc.ClassPath; import com.jpexs.decompiler.flash.abc.NotSameException; +import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.parser.ParseException; import com.jpexs.decompiler.flash.action.parser.script.ActionScriptParser; import com.jpexs.decompiler.flash.configuration.Configuration; +import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.gui.Main; import com.jpexs.decompiler.flash.helpers.CodeFormatting; import com.jpexs.decompiler.flash.helpers.HilightedTextWriter; +import com.jpexs.decompiler.flash.helpers.collections.MyEntry; +import com.jpexs.decompiler.flash.tags.ABCContainerTag; import com.jpexs.decompiler.flash.tags.base.ASMSource; import com.jpexs.decompiler.flash.tags.base.ContainerItem; import com.jpexs.decompiler.flash.treeitems.TreeItem; @@ -42,6 +47,7 @@ import java.util.ArrayList; import java.util.List; import static org.testng.Assert.fail; import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; /** @@ -51,13 +57,14 @@ import org.testng.annotations.Test; public class RecompileTest { @BeforeClass - public void init(){ + public void init() { Main.initLogging(false); } - + public static final String TESTDATADIR = "testdata/recompile"; - private void testRecompileOne(String filename) { + @Test(dataProvider = "provideFiles") + public void testRecompile(String filename) { try { SWF swf = new SWF(new BufferedInputStream(new FileInputStream(TESTDATADIR + File.separator + filename)), false); Configuration.debugCopy.set(true); @@ -69,23 +76,6 @@ public class RecompileTest { } } - @Test - public void testRecompile() { - File dir = new File(TESTDATADIR); - if (!dir.exists()) { - return; - } - File[] files = dir.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return name.toLowerCase().endsWith(".swf"); - } - }); - for (File f : files) { - testRecompileOne(f.getName()); - } - } - private void testAS2DirectEditingOneRecursive(List nodeList) { for (TreeNode node : nodeList) { if (node.subNodes.isEmpty()) { @@ -117,7 +107,7 @@ public class RecompileTest { String as3 = writer.toString(); as3 = asm.removePrefixAndSuffix(as3); if (!as3.equals(as2)) { - fail("ActionScript is diffrent: " + item.getSwf().getShortFileName() + "/" + item.toString()); + fail("ActionScript is different: " + item.getSwf().getShortFileName() + "/" + item.toString()); } } catch (InterruptedException | IOException | OutOfMemoryError | TranslateException | StackOverflowError ex) { } @@ -128,25 +118,45 @@ public class RecompileTest { } } - private void testAS2DirectEditingOne(String filename) { - try { - SWF swf = new SWF(new BufferedInputStream(new FileInputStream(TESTDATADIR + File.separator + filename)), false); + @Test(dataProvider = "provideFiles") + public void testDirectEditing(String filename) throws IOException, InterruptedException, com.jpexs.decompiler.flash.abc.avm2.parser.ParseException, CompilationException { + try{SWF swf = new SWF(new BufferedInputStream(new FileInputStream(TESTDATADIR + File.separator + filename)), false); + if (swf.fileAttributes.actionScript3) { + List allAbcs = new ArrayList<>(); + for (ABCContainerTag ct : swf.abcList) { + allAbcs.add(ct.getABC()); + } + for (ABC abc : allAbcs) { + for (int s = 0; s < abc.script_info.size(); s++) { + HilightedTextWriter htw = new HilightedTextWriter(new CodeFormatting(), false); + MyEntry en = abc.script_info.get(s).getPacks(abc, s).get(0); + System.out.print("Recompiling:"+en.key.toString()+"..."); + en.value.toSource(htw, swf.abcList, abc.script_info.get(s).traits.traits, ScriptExportMode.AS, false); + String original = htw.toString(); + ABC nabc = new ABC(swf); + com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScriptParser.compile(original, nabc,allAbcs, false, en.key.className + ".as"); + System.out.println("OK"); + } + } + } else { List list2 = new ArrayList<>(); list2.addAll(swf.tags); - List list = createASTagList(list2, null); + List list = SWF.createASTagList(list2, null); TagNode.setExport(list, true); testAS2DirectEditingOneRecursive(list); - } catch (IOException | InterruptedException ex) { - fail(); + } + }catch(Exception ex){ + System.out.println("FAIL"); + throw ex; } } - @Test - public void testAS2DirectEditing() { + @DataProvider(name = "provideFiles") + public Object[][] provideFiles() { File dir = new File(TESTDATADIR); if (!dir.exists()) { - return; + return new Object[0][]; } File[] files = dir.listFiles(new FilenameFilter() { @Override @@ -154,8 +164,10 @@ public class RecompileTest { return name.toLowerCase().endsWith(".swf"); } }); - for (File f : files) { - testAS2DirectEditingOne(f.getName()); + Object[][] ret = new Object[files.length][1]; + for (int f = 0; f < files.length; f++) { + ret[f][0] = files[f].getName(); } + return ret; } }