From 7057a0bdcb26cf1a3f9863227ed6dd557b50646f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Sun, 8 Nov 2015 11:15:18 +0100 Subject: [PATCH] various fixes for AS3 direct editation, decompilation, etc. to make FP ABC verifier happy --- .gitignore | 1 + .../flash/SourceGeneratorLocalData.java | 2 +- .../com/jpexs/decompiler/flash/abc/ABC.java | 30 ++--- .../decompiler/flash/abc/avm2/AVM2Code.java | 3 +- .../flash/abc/avm2/graph/AVM2Graph.java | 6 + .../flash/abc/avm2/model/ConvertAVM2Item.java | 2 +- .../abc/avm2/model/NewFunctionAVM2Item.java | 7 +- .../flash/abc/avm2/model/SetSlotAVM2Item.java | 4 + .../parser/script/AVM2SourceGenerator.java | 53 +++++--- .../abc/avm2/parser/script/AbcIndexing.java | 19 ++- .../parser/script/ActionScript3Parser.java | 127 ++++++++++++------ .../avm2/parser/script/GetterAVM2Item.java | 4 +- .../avm2/parser/script/MethodAVM2Item.java | 9 +- .../avm2/parser/script/SetterAVM2Item.java | 4 +- .../flash/abc/types/traits/Trait.java | 4 +- .../src/com/jpexs/decompiler/graph/Graph.java | 22 ++- .../decompiler/flash/DirectEditingTest.java | 14 +- libsrc/ffdec_lib/testdata/as3/as3.swf | Bin 107342 -> 107631 bytes .../testdata/as3/classes/MoreClass.as | 19 +++ libsrc/ffdec_lib/testdata/as3/classes/Test.as | 3 +- 20 files changed, 230 insertions(+), 103 deletions(-) create mode 100644 libsrc/ffdec_lib/testdata/as3/classes/MoreClass.as diff --git a/.gitignore b/.gitignore index 95ea29573..35c466825 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ hs_err_pid*.log /libsrc/ffdec_lib/dist/ /libsrc/ffdec_lib/testdata/decompile/ /libsrc/ffdec_lib/testdata/recompile/ +/libsrc/ffdec_lib/testdata/directediting/ /libsrc/ffdec_lib/coverage.ec /libsrc/ffdec_lib/revision.txt /libsrc/gif/nbproject/private/ diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java index 260d379d8..769a7e3ba 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java @@ -74,7 +74,7 @@ public class SourceGeneratorLocalData implements Serializable { public boolean isStatic = false; public String getFullClass() { - return pkg.add(currentClass).toRawString(); + return pkg == null ? currentClass : pkg.add(currentClass).toRawString(); } public SourceGeneratorLocalData(HashMap registerVars, Integer inFunction, Boolean inMethod, Integer forInLevel) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java index 9588969b0..ae9410467 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/ABC.java @@ -400,9 +400,9 @@ public class ABC { // constant double int constant_double_pool_count = ais.readU30("double_count"); constants.constant_double = new ArrayList<>(constant_double_pool_count); - if (constant_double_pool_count > 0) { - constants.addDouble(0); - } + //if (constant_double_pool_count > 0) { + constants.addDouble(0); + //} if (constant_double_pool_count > 1) { ais.newDumpLevel("doubles", "double[]"); for (int i = 1; i < constant_double_pool_count; i++) { // index 0 not used. Values 1..n-1 @@ -433,9 +433,9 @@ public class ABC { int constant_string_pool_count = ais.readU30("string_count"); constants.constant_string = new ArrayList<>(constant_string_pool_count); stringOffsets = new long[constant_string_pool_count]; - if (constant_string_pool_count > 0) { - constants.addString(""); - } + //if (constant_string_pool_count > 0) { + constants.addString(null); + //} if (constant_string_pool_count > 1) { ais.newDumpLevel("strings", "string[]"); for (int i = 1; i < constant_string_pool_count; i++) { // index 0 not used. Values 1..n-1 @@ -449,9 +449,9 @@ public class ABC { // constant namespace int constant_namespace_pool_count = ais.readU30("namespace_count"); constants.constant_namespace = new ArrayList<>(constant_namespace_pool_count); - if (constant_namespace_pool_count > 0) { - constants.addNamespace(null); - } + //if (constant_namespace_pool_count > 0) { + constants.addNamespace(null); + //} if (constant_namespace_pool_count > 1) { ais.newDumpLevel("namespaces", "namespace[]"); for (int i = 1; i < constant_namespace_pool_count; i++) { // index 0 not used. Values 1..n-1 @@ -463,9 +463,9 @@ public class ABC { // constant namespace set int constant_namespace_set_pool_count = ais.readU30("ns_set_count"); constants.constant_namespace_set = new ArrayList<>(constant_namespace_set_pool_count); - if (constant_namespace_set_pool_count > 0) { - constants.addNamespaceSet(null); - } + //if (constant_namespace_set_pool_count > 0) { + constants.addNamespaceSet(null); + //} if (constant_namespace_set_pool_count > 1) { ais.newDumpLevel("ns_sets", "ns_set[]"); for (int i = 1; i < constant_namespace_set_pool_count; i++) { // index 0 not used. Values 1..n-1 @@ -484,9 +484,9 @@ public class ABC { // constant multiname int constant_multiname_pool_count = ais.readU30("multiname_count"); constants.constant_multiname = new ArrayList<>(constant_multiname_pool_count); - if (constant_multiname_pool_count > 0) { - constants.addMultiname(null); - } + //if (constant_multiname_pool_count > 0) { + constants.addMultiname(null); + //} if (constant_multiname_pool_count > 1) { ais.newDumpLevel("multiname", "multinames[]"); for (int i = 1; i < constant_multiname_pool_count; i++) { // index 0 not used. Values 1..n-1 diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java index b8a16368a..98f591b08 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/AVM2Code.java @@ -1434,7 +1434,8 @@ public class AVM2Code implements Cloneable { } } - public List clearTemporaryRegisters(List output) { + public List clearTemporaryRegisters(List input) { + List output = new ArrayList<>(input); for (int i = 0; i < output.size(); i++) { if (output.get(i) instanceof SetLocalAVM2Item) { if (isKilled(((SetLocalAVM2Item) output.get(i)).regIndex, 0, code.size() - 1)) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java index 81bbe5bea..aeac300a5 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/graph/AVM2Graph.java @@ -939,4 +939,10 @@ public class AVM2Graph extends Graph { ret.scopeStack = copyScopeStack; return ret; } + + @Override + protected List filter(List list) { + return avm2code.clearTemporaryRegisters(list); + } + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java index fe1b11eaa..f485795ca 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/ConvertAVM2Item.java @@ -29,7 +29,7 @@ public class ConvertAVM2Item extends AVM2Item { public GraphTargetItem type; public ConvertAVM2Item(AVM2Instruction instruction, GraphTargetItem value, GraphTargetItem type) { - super(instruction, NOPRECEDENCE, value); + super(instruction, value.getPrecedence(), value); this.type = type; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java index 8866a4284..27cd39b57 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/NewFunctionAVM2Item.java @@ -78,11 +78,8 @@ public class NewFunctionAVM2Item extends AVM2Item { abc.method_info.get(methodIndex).getReturnTypeStr(writer, abc.constants, fullyQualifiedNames); writer.startBlock(); if (body != null) { - if (writer instanceof NulWriter) { - body.convert(new ConvertData(), path + "/inner", ScriptExportMode.AS, isStatic, methodIndex, scriptIndex, classIndex, abc, null, new ScopeStack(), 0, (NulWriter) writer, fullyQualifiedNames, null, false); - } else { - body.toString(path + "/inner", ScriptExportMode.AS, abc, null, writer, fullyQualifiedNames); - } + body.convert(new ConvertData(), path + "/inner", ScriptExportMode.AS, isStatic, methodIndex, scriptIndex, classIndex, abc, null, new ScopeStack(), 0, new NulWriter(), fullyQualifiedNames, null, false); + body.toString(path + "/inner", ScriptExportMode.AS, abc, null, writer, fullyQualifiedNames); } writer.endBlock(); writer.endMethod(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSlotAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSlotAVM2Item.java index 905c523ea..eb28be78d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSlotAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/model/SetSlotAVM2Item.java @@ -46,6 +46,10 @@ public class SetSlotAVM2Item extends AVM2Item implements SetTypeAVM2Item, Assign @Override public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException { getSrcData().localName = slotName == null ? "/*UnknownSlot*/" : slotName.getName(localData.constantsAvm2, localData.fullyQualifiedNames, false); + if (getSrcData().localName.equals(value.toString(localData))) { + //assigning parameters to activation reg + return writer; + } getName(writer, localData); writer.append(" = "); return value.toString(writer, localData); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java index f217d9d2b..b77d7a276 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AVM2SourceGenerator.java @@ -98,7 +98,6 @@ import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Matcher; @@ -1178,11 +1177,11 @@ public class AVM2SourceGenerator implements SourceGenerator { instanceInfo.iinit_index = init = method(false, 0, false, isInterface, new ArrayList<>(), pkg, false, new ArrayList<>(), initScope + 1, false, 0, isInterface ? null : name, extendsVal != null ? extendsVal.toString() : null, true, localData, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), TypeItem.UNBOUNDED/*?? FIXME*/); } else { MethodAVM2Item m = (MethodAVM2Item) constructor; - instanceInfo.iinit_index = init = method(false, 0, false, false, new ArrayList<>(), pkg, m.needsActivation, m.subvariables, initScope + 1, m.hasRest, m.line, name, extendsVal != null ? extendsVal.toString() : null, true, localData, m.paramTypes, m.paramNames, m.paramValues, m.body, TypeItem.UNBOUNDED/*?? FIXME*/); + instanceInfo.iinit_index = init = method(false, str(pkg.toRawString() + ":" + name + "/" + name), false, false, new ArrayList<>(), pkg, m.needsActivation, m.subvariables, initScope + 1, m.hasRest, m.line, name, extendsVal != null ? extendsVal.toString() : null, true, localData, m.paramTypes, m.paramNames, m.paramValues, m.body, TypeItem.UNBOUNDED/*?? FIXME*/); } //Class initializer - int staticMi = method(true, 0, false, false, new ArrayList<>(), pkg, staticNeedsActivation, sinitVariables, initScope + (implementsStr.isEmpty() ? 0 : 1), false, 0, isInterface ? null : name, superName, false, localData, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), staticInit, TypeItem.UNBOUNDED); + int staticMi = method(true, str(""), false, false, new ArrayList<>(), pkg, staticNeedsActivation, sinitVariables, initScope + (implementsStr.isEmpty() ? 0 : 1), false, 0, isInterface ? null : name, superName, false, localData, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), staticInit, TypeItem.UNBOUNDED); MethodBody sinitBody = abcIndex.getSelectedAbc().findBody(staticMi); List sinitcode = new ArrayList<>(); @@ -1475,7 +1474,7 @@ public class AVM2SourceGenerator implements SourceGenerator { for (AssignableAVM2Item an : subvariables) { if (an instanceof NameAVM2Item) { NameAVM2Item n = (NameAVM2Item) an; - if (n.isDefinition()) { + if (n.isDefinition() && !registerNames.contains(n.getVariableName())) { if (!needsActivation || (n.getSlotScope() <= 0)) { String varName = n.getVariableName(); Matcher m = pat.matcher(varName); @@ -1500,6 +1499,7 @@ public class AVM2SourceGenerator implements SourceGenerator { registerTypes.add(n.type.toString()); slotNames.add(n.getVariableName()); slotTypes.add(n.type.toString()); + } } } @@ -1908,7 +1908,8 @@ public class AVM2SourceGenerator implements SourceGenerator { new Multiname( Multiname.QNAME, abcIndex.getSelectedAbc().constants.getStringId(((ClassAVM2Item) item).className, true), - abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId(((ClassAVM2Item) item).pkg, true)), 0, true), 0, 0, new ArrayList<>()), true); + //abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId(((ClassAVM2Item) item).pkg, true)), 0, true) + ((ClassAVM2Item) item).namespace, 0, 0, new ArrayList<>()), true); if (((ClassAVM2Item) item).extendsOp != null) { instanceInfo.super_index = typeName(localData, ((ClassAVM2Item) item).extendsOp); @@ -1987,7 +1988,7 @@ public class AVM2SourceGenerator implements SourceGenerator { if (mai.isStatic() != generateStatic) { continue; } - ((TraitMethodGetterSetter) traits[k]).method_info = method(mai.isStatic(), abcIndex.getSelectedAbc().constants.getStringId(mai.functionName, true), false, isInterface, new ArrayList<>(), mai.pkg, mai.needsActivation, mai.subvariables, methodInitScope + (mai.isStatic() ? 0 : 1), mai.hasRest, mai.line, className, superName, false, localData, mai.paramTypes, mai.paramNames, mai.paramValues, mai.body, mai.retType); + ((TraitMethodGetterSetter) traits[k]).method_info = method(mai.isStatic(), abcIndex.getSelectedAbc().constants.getStringId(localData.pkg.toRawString() + ":" + localData.currentClass + "/" + (mai.isPrivate() ? "private:" : "") + mai.functionName, true), false, isInterface, new ArrayList<>(), mai.pkg, mai.needsActivation, mai.subvariables, methodInitScope + (mai.isStatic() ? 0 : 1), mai.hasRest, mai.line, className, superName, false, localData, mai.paramTypes, mai.paramNames, mai.paramValues, mai.body, mai.retType); } else if (item instanceof FunctionAVM2Item) { FunctionAVM2Item fai = (FunctionAVM2Item) item; ((TraitFunction) traits[k]).method_info = method(false, abcIndex.getSelectedAbc().constants.getStringId(fai.functionName, true), false, isInterface, new ArrayList<>(), fai.pkg, fai.needsActivation, fai.subvariables, methodInitScope, fai.hasRest, fai.line, className, superName, false, localData, fai.paramTypes, fai.paramNames, fai.paramValues, fai.body, fai.retType); @@ -2144,7 +2145,7 @@ public class AVM2SourceGenerator implements SourceGenerator { abcIndex.refreshSelected(); - MethodInfo mi = new MethodInfo(new int[0], 0, 0, 0, new ValueKind[0], new int[0]); + MethodInfo mi = new MethodInfo(new int[0], 0, abcIndex.getSelectedAbc().constants.getStringId("", true), 0, new ValueKind[0], new int[0]); MethodBody mb = new MethodBody(abcIndex.getSelectedAbc(), new Traits(), new byte[0], new ABCException[0]); mb.method_info = abcIndex.getSelectedAbc().addMethodInfo(mi); mb.setCode(new AVM2Code()); @@ -2209,7 +2210,7 @@ public class AVM2SourceGenerator implements SourceGenerator { mb.autoFillStats(abcIndex.getSelectedAbc(), 1, false); abcIndex.getSelectedAbc().addMethodBody(mb); si.init_index = mb.method_info; - localData.pkg = null; //FIXME: pkg.packageName; + localData.pkg = DottedChain.EMPTY; //FIXME: pkg.packageName; generateTraitsPhase3(1/*??*/, false, null, null, true, localData, commands, si.traits, traitArr, initScopes, class_index); return si; } @@ -2291,7 +2292,8 @@ public class AVM2SourceGenerator implements SourceGenerator { } outPropNs.setVal(sp.trait.getName(sp.abc).getNamespace(sp.abc.constants).getName(sp.abc.constants)); outPropNsKind.setVal(sp.trait.getName(sp.abc).getNamespace(sp.abc.constants).kind); - outPropNsIndex.setVal(selectedNs == 0 ? 0 : sp.abc.constants.getNamespaceSubIndex(selectedNs)); + int nsi = sp.trait.getName(sp.abc).namespace_index; + outPropNsIndex.setVal(sp.abc == abc.getSelectedAbc() ? sp.abc.constants.getNamespaceSubIndex(nsi) : 0); outPropType.setVal(sp.returnType); outPropValue.setVal(sp.value); outPropValueAbc.setVal(sp.abc); @@ -2306,8 +2308,8 @@ public class AVM2SourceGenerator implements SourceGenerator { int ni = ci.abc.instance_info.get(ci.index).name_index; indices.add(ni); outABCs.add(ci.abc); - names.add(abc.getSelectedAbc().constants.constant_multiname.get(ni).getName(abc.getSelectedAbc().constants, null, true)); - namespaces.add(abc.getSelectedAbc().constants.constant_multiname.get(ni).getNamespace(abc.getSelectedAbc().constants).getName(abc.getSelectedAbc().constants).toRawString()); + names.add(ci.abc.constants.constant_multiname.get(ni).getName(ci.abc.constants, null, true)); + namespaces.add(ci.abc.constants.constant_multiname.get(ni).getNamespace(ci.abc.constants).getName(ci.abc.constants).toRawString()); ci = ci.parent; } } @@ -2384,15 +2386,30 @@ public class AVM2SourceGenerator implements SourceGenerator { DottedChain dname = type.fullTypeName; String pkg = dname.getWithoutLast().toRawString(); String name = dname.getLast(); - for (InstanceInfo ii : abc.getSelectedAbc().instance_info) { - Multiname mname = abc.getSelectedAbc().constants.constant_multiname.get(ii.name_index); - if (mname != null && name.equals(mname.getName(abc.getSelectedAbc().constants, null, true))) { - if (mname.getNamespace(abc.getSelectedAbc().constants).hasName(pkg, abc.getSelectedAbc().constants)) { - name_index = ii.name_index; - break; - } + /*for (InstanceInfo ii : abc.getSelectedAbc().instance_info) { + Multiname mname = abc.getSelectedAbc().constants.constant_multiname.get(ii.name_index); + if (mname != null && name.equals(mname.getName(abc.getSelectedAbc().constants, null, true))) { + Namespace ns = mname.getNamespace(abc.getSelectedAbc().constants); + if (ns != null && ns.hasName(pkg, abc.getSelectedAbc().constants)) { + name_index = ii.name_index; + break; + } + } + }*/ + AbcIndexing.ClassIndex ci = abc.findClass(new TypeItem(dname)); + if (ci != null) { + Multiname m = ci.abc.instance_info.get(ci.index).getName(ci.abc.constants); + if (m != null) { + Namespace ns = ci.abc.instance_info.get(ci.index).getName(ci.abc.constants).getNamespace(ci.abc.constants); + String n = m.getName(ci.abc.constants, new ArrayList(), true); + String nsn = ns == null ? null : ns.getName(ci.abc.constants).toRawString(); + name_index = abc.getSelectedAbc().constants.getQnameId( + n, + ns == null ? Namespace.KIND_PACKAGE : ns.kind, + nsn, true); } } + for (int i = 1; i < abc.getSelectedAbc().constants.constant_multiname.size(); i++) { Multiname mname = abc.getSelectedAbc().constants.constant_multiname.get(i); if (mname != null && name.equals(mname.getName(abc.getSelectedAbc().constants, null, true))) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java index 8b06e8c07..d87b5a4ef 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/AbcIndexing.java @@ -195,6 +195,11 @@ public class AbcIndexing { return propName; } + @Override + public String toString() { + return ns.toString() + ":" + propName + (propNsIndex > 0 ? "[ns:" + propNsIndex + "]" : ""); + } + public PropertyNsDef(String propName, DottedChain ns, ABC abc, int nsIndex) { this.propName = propName; this.ns = ns; @@ -302,7 +307,14 @@ public class AbcIndexing { } public TraitIndex findScriptProperty(String propName, DottedChain ns) { - return scriptProperties.get(new PropertyNsDef(propName, ns, null, 0)); + PropertyNsDef nsd = new PropertyNsDef(propName, ns, null, 0); + if (!scriptProperties.containsKey(nsd)) { + if (parent != null) { + return parent.findScriptProperty(propName, ns); + } + return null; + } + return scriptProperties.get(nsd); } public TraitIndex findNsProperty(PropertyNsDef prop, boolean findStatic, boolean findInstance) { @@ -366,7 +378,7 @@ public class AbcIndexing { //now search parent class AbcIndexing.ClassIndex ci = findClass(prop.parent); - if (ci != null && ci.parent != null) { + if (ci != null && ci.parent != null && (prop.abc == null || prop.propNsIndex == 0)) { ci = ci.parent; //parent protected DottedChain parentClass = ci.abc.instance_info.get(ci.index).getName(ci.abc.constants).getNameWithNamespace(ci.abc.constants); @@ -437,7 +449,8 @@ public class AbcIndexing { map.put(dp, new TraitIndex(t, abc, getTraitReturnType(abc, t), propValue, multinameToType(name_index, abc.constants))); } if (mapNs != null) { - PropertyNsDef ndp = new PropertyNsDef(t.getName(abc).getName(abc.constants, new ArrayList<>() /*?*/, true), abc.constants.getMultiname(t.name_index).getNameWithNamespace(abc.constants), abc, abc.constants.getMultiname(t.name_index).namespace_index); + Multiname m = abc.constants.getMultiname(t.name_index); + PropertyNsDef ndp = new PropertyNsDef(t.getName(abc).getName(abc.constants, new ArrayList<>() /*?*/, true), m == null || m.namespace_index == 0 ? DottedChain.EMPTY : m.getNamespace(abc.constants).getName(abc.constants), abc, m.namespace_index); TraitIndex ti = new TraitIndex(t, abc, getTraitReturnType(abc, t), propValue, multinameToType(name_index, abc.constants)); if (!mapNs.containsKey(ndp)) { mapNs.put(ndp, ti); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java index 43fc76db1..7cfe7bda2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java @@ -90,7 +90,6 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.Loop; import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.AndItem; -import com.jpexs.decompiler.graph.model.BinaryOp; import com.jpexs.decompiler.graph.model.BlockItem; import com.jpexs.decompiler.graph.model.BreakItem; import com.jpexs.decompiler.graph.model.CommaExpressionItem; @@ -181,7 +180,7 @@ public class ActionScript3Parser { } ParsedSymbol s = lex(); GraphTargetItem ret = newcmds; - while (s.isType(SymbolType.DOT, SymbolType.PARENT_OPEN, SymbolType.BRACKET_OPEN, SymbolType.TYPENAME, SymbolType.FILTER)) { + while (s.isType(SymbolType.DOT, SymbolType.PARENT_OPEN, SymbolType.BRACKET_OPEN, SymbolType.TYPENAME, SymbolType.FILTER, SymbolType.DESCENDANTS)) { switch (s.type) { case BRACKET_OPEN: case DOT: @@ -197,6 +196,11 @@ public class ActionScript3Parser { case PARENT_OPEN: ret = new CallAVM2Item(lexer.yyline(), ret, call(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, variables)); break; + case DESCENDANTS: + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.MULTIPLY); + ret = new GetDescendantsAVM2Item(ret, s.type == SymbolType.MULTIPLY ? null : s.value.toString(), openedNamespaces); + break; } s = lex(); @@ -230,8 +234,13 @@ public class ActionScript3Parser { if (s.type == SymbolType.TYPENAME) { List params = new ArrayList<>(); do { - params.add(expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables) - ); + s = lex(); + if (s.isType(SymbolType.MULTIPLY)) { + params.add(new NullAVM2Item(null)); + } else { + lexer.pushback(s); + params.add(expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, false, variables)); + } s = lex(); } while (s.type == SymbolType.COMMA); if (s.type == SymbolType.USHIFT_RIGHT) { @@ -281,8 +290,8 @@ public class ActionScript3Parser { s = lex(); } else { s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - String propName = s.value.toString(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.MULTIPLY); + String propName = s.value.toString(); //Can be * GraphTargetItem propItem = null; s = lex(); GraphTargetItem ns = null; @@ -351,7 +360,7 @@ public class ActionScript3Parser { continue; } } else { - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE, SymbolType.MULTIPLY); name2 += s.value.toString(); } name = name.add(name2); @@ -455,9 +464,9 @@ public class ActionScript3Parser { return ret; } - private MethodAVM2Item method(List>> metadata, DottedChain pkg, boolean isInterface, String customAccess, Reference needsActivation, List importedClasses, boolean override, boolean isFinal, TypeItem thisType, List openedNamespaces, boolean isStatic, int namespace, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException { + private MethodAVM2Item method(boolean isPrivate, List>> metadata, DottedChain pkg, boolean isInterface, String customAccess, Reference needsActivation, List importedClasses, boolean override, boolean isFinal, TypeItem thisType, List openedNamespaces, boolean isStatic, int namespace, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException { FunctionAVM2Item f = function(metadata, pkg, isInterface, needsActivation, importedClasses, namespace, thisType, openedNamespaces, functionName, isMethod, variables); - return new MethodAVM2Item(f.metadata, f.pkg, f.isInterface, customAccess, f.needsActivation, f.hasRest, f.line, override, isFinal, isStatic, f.namespace, functionName, f.paramTypes, f.paramNames, f.paramValues, f.body, f.subvariables, f.retType); + return new MethodAVM2Item(isPrivate, f.metadata, f.pkg, f.isInterface, customAccess, f.needsActivation, f.hasRest, f.line, override, isFinal, isStatic, f.namespace, functionName, f.paramTypes, f.paramNames, f.paramValues, f.body, f.subvariables, f.retType); } private FunctionAVM2Item function(List>> metadata, DottedChain pkg, boolean isInterface, Reference needsActivation, List importedClasses, int namespace, TypeItem thisType, List openedNamespaces, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException { @@ -550,6 +559,7 @@ public class ActionScript3Parser { List originalOpenedNamespaces = openedNamespaces; int originalPrivateNs = privateNs; boolean inPkg = pkg != null; + int cpos = 0; looptrait: while (true) { s = lex(); @@ -561,6 +571,7 @@ public class ActionScript3Parser { boolean isFinal = false; boolean isDynamic = false; String customAccess = null; + boolean isPrivate = false; if (scriptTraits && s.type == SymbolType.PACKAGE) { if (inPkg) { @@ -664,6 +675,7 @@ public class ActionScript3Parser { } break; case PRIVATE: + isPrivate = true; namespace = privateNs; if (isInterface) { throw new AVM2ParseException("Interface cannot have public, private or protected modifier", lexer.yyline()); @@ -685,6 +697,9 @@ public class ActionScript3Parser { if (isInterface) { namespace = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_NAMESPACE, abcIndex.getSelectedAbc().constants.getStringId(pkg == null || pkg.isEmpty() ? classNameStr : pkg + ":" + classNameStr, true)), 0, true); } else { + if (packageInternalNs == 0) { + packageInternalNs = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abcIndex.getSelectedAbc().constants.getStringId(pkg.toRawString(), true)), 0, true); + } namespace = packageInternalNs; } } @@ -785,8 +800,22 @@ public class ActionScript3Parser { s = lex(); } - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - String fname = s.value.toString(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.PARENT_OPEN); + String fname = null; + if (s.isType(SymbolType.PARENT_OPEN)) { + lexer.pushback(s); + if (isGetter) { + fname = "get"; + isGetter = false; + } else if (isSetter) { + fname = "set"; + isSetter = false; + } else { + throw new AVM2ParseException("Missing method name", lexer.yyline()); + } + } else { + fname = s.value.toString(); + } if (classNameStr != null && fname.equals(classNameStr)) { //constructor if (isStatic) { throw new AVM2ParseException("Constructor cannot be static", lexer.yyline()); @@ -803,9 +832,9 @@ public class ActionScript3Parser { if (isInterface) { throw new AVM2ParseException("Interface cannot have constructor", lexer.yyline()); } - constr = (method(metadata, pkg, false, customAccess, new Reference<>(false), importedClasses, false, false, thisType, openedNamespaces, false, namespace, "", true, constrVariables)); + constr = (method(isPrivate, metadata, pkg, false, customAccess, new Reference<>(false), importedClasses, false, false, thisType, openedNamespaces, false, namespace, "", true, constrVariables)); } else { - MethodAVM2Item ft = method(metadata, pkg, isInterface, customAccess, new Reference<>(false), importedClasses, isOverride, isFinal, thisType, openedNamespaces, isStatic, namespace, fname, true, new ArrayList<>()); + MethodAVM2Item ft = method(isPrivate, metadata, pkg, isInterface, customAccess, new Reference<>(false), importedClasses, isOverride, isFinal, thisType, openedNamespaces, isStatic, namespace, fname, true, new ArrayList<>()); if (isGetter) { if (!ft.paramTypes.isEmpty()) { @@ -826,10 +855,10 @@ public class ActionScript3Parser { } GraphTargetItem t; if (isGetter) { - GetterAVM2Item g = new GetterAVM2Item(ft.metadata, ft.pkg, isInterface, customAccess, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); + GetterAVM2Item g = new GetterAVM2Item(ft.isPrivate(), ft.metadata, ft.pkg, isInterface, customAccess, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); t = g; } else if (isSetter) { - SetterAVM2Item st = new SetterAVM2Item(ft.metadata, ft.pkg, isInterface, customAccess, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); + SetterAVM2Item st = new SetterAVM2Item(ft.isPrivate(), ft.metadata, ft.pkg, isInterface, customAccess, ft.needsActivation, ft.hasRest, ft.line, ft.isOverride(), ft.isFinal(), isStatic, ft.namespace, ft.functionName, ft.paramTypes, ft.paramNames, ft.paramValues, ft.body, ft.subvariables, ft.retType); t = st; } else { t = ft; @@ -911,10 +940,15 @@ public class ActionScript3Parser { break; default: if (s.type == SymbolType.CURLY_CLOSE && inPkg && classNameStr == null) { - inPkg = false; - pkg = null; - openedNamespaces = originalOpenedNamespaces; + inPkg = true; + openedNamespaces = new ArrayList<>(); privateNs = originalPrivateNs; + packageInternalNs = originalPrivateNs; + publicNs = privateNs; + //publicNs = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId("")), 0); + List newOpenedNs = new ArrayList<>(); + importedClasses = parseImports(newOpenedNs); + pkg = DottedChain.TOPLEVEL; } else { lexer.pushback(s); break looptrait; @@ -939,8 +973,10 @@ public class ActionScript3Parser { int publicNs = 0; int privateNs = 0; int packageInternalNs = 0; - if (pkg != null) { + if (pkg != null && !pkg.isEmpty()) { openedNamespaces.add(packageInternalNs = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abcIndex.getSelectedAbc().constants.getStringId(pkg, true)), 0, true)); + } else { + openedNamespaces.add(packageInternalNs = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE_INTERNAL, abcIndex.getSelectedAbc().constants.getStringId("", true)), 0, true)); } if (pkg != null && !pkg.isEmpty()) { openedNamespaces.add(publicNs = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId("", true)), 0, true)); @@ -948,7 +984,7 @@ public class ActionScript3Parser { publicNs = gpublicNs; } - openedNamespaces.add(privateNs = abcIndex.getSelectedAbc().constants.addNamespace(new Namespace(Namespace.KIND_PRIVATE, 0))); //abc.getLastAbc().constants.getStringId(fileName + "$", true) + openedNamespaces.add(privateNs = abcIndex.getSelectedAbc().constants.addNamespace(new Namespace(Namespace.KIND_PRIVATE, abcIndex.getSelectedAbc().constants.getStringId(pkg.toRawString() + ":" + nameStr)))); openedNamespaces.add(abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_NAMESPACE, abcIndex.getSelectedAbc().constants.getStringId(AS3_NAMESPACE, true)), 0, true)); @@ -967,7 +1003,7 @@ public class ActionScript3Parser { //FIXME for Private classes in script!!! AVM2SourceGenerator.parentNamesAddNames(abcIndex, AVM2SourceGenerator.resolveType(new SourceGeneratorLocalData(new HashMap<>(), 0, false, 0), ((TypeItem) ((UnresolvedAVM2Item) extendsStr).resolve(null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), new ArrayList<>())), abcIndex), indices, names, namespaces); for (int i = 0; i < names.size(); i++) { - if (namespaces.get(i).isEmpty()) { + if (namespaces.get(i) == null || namespaces.get(i).isEmpty()) { continue; } openedNamespaces.add(abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_STATIC_PROTECTED, abcIndex.getSelectedAbc().constants.getStringId(namespaces.get(i) + ":" + names.get(i), true)), 0, true)); @@ -1444,10 +1480,16 @@ public class ActionScript3Parser { GraphTargetItem forExpr = null; List forFirstCommands = new ArrayList<>(); if (!forin) { - //GraphTargetItem firstCommand = command(thisType,pkg,needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); + s = lex(); if (firstCommand != null) { //can be empty command forFirstCommands.add(firstCommand); } + while (s.isType(SymbolType.COMMA)) { + forFirstCommands.add(command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, false, variables)); + s = lex(); + } + lexer.pushback(s); + //GraphTargetItem firstCommand = command(thisType,pkg,needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); forExpr = (expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables)); expectedType(SymbolType.SEMICOLON); GraphTargetItem fcom = command(thisType, pkg, needsActivation, importedClasses, openedNamespaces, loops, loopLabels, registerVars, inFunction, inMethod, forinlevel, true, variables); @@ -2132,6 +2174,7 @@ public class ActionScript3Parser { List inBrackets = new ArrayList<>(); int arrCnt = brackets(thisType, pkg, needsActivation, importedClasses, openedNamespaces, inBrackets, registerVars, inFunction, inMethod, variables); ret = new NewArrayAVM2Item(null, inBrackets); + allowMemberOrCall = true; break; case FUNCTION: @@ -2270,24 +2313,9 @@ public class ActionScript3Parser { private List constantPool; - private PackageAVM2Item parsePackage(List openedNamespaces) throws IOException, AVM2ParseException, CompilationException { - List items = new ArrayList<>(); - expectedType(SymbolType.PACKAGE); - DottedChain name = DottedChain.TOPLEVEL; - ParsedSymbol s = lex(); - if (s.type != SymbolType.CURLY_OPEN) { - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - name = name.add(s.value.toString()); - s = lex(); - } - while (s.type != SymbolType.CURLY_OPEN) { - expected(s, lexer.yyline(), SymbolType.DOT); - s = lex(); - expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); - name = name.add(s.value.toString()); - s = lex(); - } + private List parseImports(List openedNamespaces) throws IOException, AVM2ParseException { + ParsedSymbol s; List importedClasses = new ArrayList<>(); s = lex(); @@ -2322,7 +2350,28 @@ public class ActionScript3Parser { s = lex(); } lexer.pushback(s); + return importedClasses; + } + private PackageAVM2Item parsePackage(List openedNamespaces) throws IOException, AVM2ParseException, CompilationException { + List items = new ArrayList<>(); + expectedType(SymbolType.PACKAGE); + DottedChain name = DottedChain.TOPLEVEL; + ParsedSymbol s = lex(); + if (s.type != SymbolType.CURLY_OPEN) { + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + name = name.add(s.value.toString()); + s = lex(); + } + while (s.type != SymbolType.CURLY_OPEN) { + expected(s, lexer.yyline(), SymbolType.DOT); + s = lex(); + expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER); + name = name.add(s.value.toString()); + s = lex(); + } + + List importedClasses = parseImports(openedNamespaces); int publicNs; openedNamespaces.add(publicNs = abcIndex.getSelectedAbc().constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abcIndex.getSelectedAbc().constants.getStringId(name, true)), 0, true)); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/GetterAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/GetterAVM2Item.java index 7d9836edf..521880a36 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/GetterAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/GetterAVM2Item.java @@ -27,7 +27,7 @@ import java.util.Map; */ public class GetterAVM2Item extends MethodAVM2Item { - public GetterAVM2Item(List>> metadata, DottedChain pkg, boolean isInterface, String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { - super(metadata, pkg, isInterface, customNamespace, needsActivation, hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); + public GetterAVM2Item(boolean isPrivate, List>> metadata, DottedChain pkg, boolean isInterface, String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { + super(isPrivate, metadata, pkg, isInterface, customNamespace, needsActivation, hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java index 51a1e11bc..e36606bfe 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/MethodAVM2Item.java @@ -35,14 +35,21 @@ public class MethodAVM2Item extends FunctionAVM2Item { private final boolean override; + private final boolean isPrivate; + + public boolean isPrivate() { + return isPrivate; + } + public String customNamespace; //public boolean isInterface; - public MethodAVM2Item(List>> metadata, DottedChain pkg, boolean isInterface, String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { + public MethodAVM2Item(boolean isPrivate, List>> metadata, DottedChain pkg, boolean isInterface, String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { super(metadata, pkg, isInterface, needsActivation, namespace, hasRest, line, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); this.isStatic = isStatic; this.override = override; this.isFinal = isFinal; + this.isPrivate = isPrivate; this.customNamespace = customNamespace; //this.isInterface = this.isInterface; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SetterAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SetterAVM2Item.java index 37e208a4b..4ac4e318a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SetterAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/SetterAVM2Item.java @@ -27,7 +27,7 @@ import java.util.Map; */ public class SetterAVM2Item extends MethodAVM2Item { - public SetterAVM2Item(List>> metadata, DottedChain pkg, boolean isInterface, String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { - super(metadata, pkg, isInterface, customNamespace, needsActivation, hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); + public SetterAVM2Item(boolean isPrivate, List>> metadata, DottedChain pkg, boolean isInterface, String customNamespace, boolean needsActivation, boolean hasRest, int line, boolean override, boolean isFinal, boolean isStatic, int namespace, String methodName, List paramTypes, List paramNames, List paramValues, List body, List subvariables, GraphTargetItem retType) { + super(isPrivate, metadata, pkg, isInterface, customNamespace, needsActivation, hasRest, line, override, isFinal, isStatic, namespace, methodName, paramTypes, paramNames, paramValues, body, subvariables, retType); } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java index 9ddb85841..3aa160382 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/types/traits/Trait.java @@ -110,7 +110,7 @@ public abstract class Trait implements Cloneable, Serializable { writer.append(","); } first = false; - if (!key.isEmpty()) { + if (key != null && !key.isEmpty()) { writer.append(IdentifiersDeobfuscation.printIdentifier(true, key)).append("="); } writer.append("\""); @@ -248,7 +248,7 @@ public abstract class Trait implements Cloneable, Serializable { public final ClassPath getPath(ABC abc) { Multiname name = getName(abc); Namespace ns = name.getNamespace(abc.constants); - DottedChain packageName = ns.getName(abc.constants); + DottedChain packageName = ns == null ? DottedChain.EMPTY : ns.getName(abc.constants); String objectName = name.getName(abc.constants, null, true); return new ClassPath(packageName, objectName); //assume not null name } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java index ee7485dec..d092d45a7 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/graph/Graph.java @@ -157,6 +157,10 @@ public class Graph { cur1.iloop_header = cur2; } + protected List filter(List list) { + return new ArrayList<>(list); + } + /** * Traverse loops deep first search * @@ -1989,20 +1993,26 @@ public class Graph { makeAllCommands(onTrue, trueStack); makeAllCommands(onFalse, falseStack); - if (!isEmpty(onTrue) && !isEmpty(onFalse) && onTrue.size() == 1 && onFalse.size() == 1 && (onTrue.get(0) instanceof PushItem) && (onFalse.get(0) instanceof PushItem)) { - stack.push(new TernarOpItem(null, expr.invert(null), ((PushItem) onTrue.get(0)).value, ((PushItem) onFalse.get(0)).value)); + List filteredOnTrue = filter(onTrue); + List filteredOnFalse = filter(onFalse); + + if (!isEmpty(filteredOnTrue) && !isEmpty(filteredOnFalse) && filteredOnTrue.size() == 1 && filteredOnFalse.size() == 1 && (filteredOnTrue.get(0) instanceof PushItem) && (filteredOnFalse.get(0) instanceof PushItem)) { + stack.push(new TernarOpItem(null, expr.invert(null), ((PushItem) filteredOnTrue.get(0)).value, ((PushItem) filteredOnFalse.get(0)).value)); } else { boolean isIf = true; //If the ontrue is empty, switch ontrue and onfalse - if (onTrue.isEmpty() && !onFalse.isEmpty()) { + if (filteredOnTrue.isEmpty() && !filteredOnFalse.isEmpty()) { expr = expr.invert(null); List tmp = onTrue; onTrue = onFalse; onFalse = tmp; + tmp = filteredOnTrue; + filteredOnTrue = filteredOnFalse; + filteredOnFalse = tmp; } - if (!stack.isEmpty() && onFalse.isEmpty() && ((onTrue.size() == 1 && (onTrue.get(0) instanceof PopItem)) || ((onTrue.size() == 2) && (onTrue.get(0) instanceof PopItem) && (onTrue.get(1) instanceof PushItem)))) { - if (onTrue.size() == 2) { - GraphTargetItem rightSide = ((PushItem) onTrue.get(1)).value; + if (!stack.isEmpty() && ((filteredOnTrue.size() == 1 && (filteredOnTrue.get(0) instanceof PopItem)) || ((filteredOnTrue.size() >= 2) && (filteredOnTrue.get(0) instanceof PopItem) && (filteredOnTrue.get(filteredOnTrue.size() - 1) instanceof PushItem)))) { + if (filteredOnTrue.size() > 1) { + GraphTargetItem rightSide = ((PushItem) filteredOnTrue.get(filteredOnTrue.size() - 1)).value; GraphTargetItem prevExpr = stack.pop(); GraphTargetItem leftSide = expr.getNotCoercedNoDup(); diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/DirectEditingTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/DirectEditingTest.java index 8dde60a3b..fb9d7b028 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/DirectEditingTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/DirectEditingTest.java @@ -19,9 +19,7 @@ package com.jpexs.decompiler.flash; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.ScriptPack; import com.jpexs.decompiler.flash.abc.avm2.parser.AVM2ParseException; -import com.jpexs.decompiler.flash.abc.avm2.parser.script.ActionScript3Parser; import com.jpexs.decompiler.flash.abc.types.ConvertData; -import com.jpexs.decompiler.flash.abc.types.ScriptInfo; import com.jpexs.decompiler.flash.action.Action; import com.jpexs.decompiler.flash.action.parser.ActionParseException; import com.jpexs.decompiler.flash.action.parser.script.ActionScript2Parser; @@ -30,7 +28,6 @@ import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode; import com.jpexs.decompiler.flash.helpers.CodeFormatting; import com.jpexs.decompiler.flash.helpers.HighlightedTextWriter; import com.jpexs.decompiler.flash.tags.ABCContainerTag; -import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.base.ASMSource; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.decompiler.graph.TranslateException; @@ -89,9 +86,14 @@ public class DirectEditingTest extends FileTestBase { } System.out.println("Recompiling:" + classPathString + "..."); - en.toSource(htw, abc.script_info.get(s).traits.traits, new ConvertData(), ScriptExportMode.AS, false); - String original = htw.toString(); - abc.replaceScriptPack(en, original); + try { + en.toSource(htw, abc.script_info.get(s).traits.traits, new ConvertData(), ScriptExportMode.AS, false); + String original = htw.toString(); + abc.replaceScriptPack(en, original); + } catch (Exception ex) { + fail("Exception during decompilation - file: " + filePath + " class: " + classPathString, ex); + throw ex; + } } } } else { diff --git a/libsrc/ffdec_lib/testdata/as3/as3.swf b/libsrc/ffdec_lib/testdata/as3/as3.swf index f8c158460f5fa5667168fc64541123d6dcb9e8c7..dfa4d810a0840bf745b90c76d667823f2489a0ad 100644 GIT binary patch delta 28254 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 delta 27947 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�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