diff --git a/CHANGELOG.md b/CHANGELOG.md index 976fbae27..1c4619e24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file. - AS3 - direct editation - arguments object on method with activation - AS3 - direct editation - bit not - AS3 - direct editation - call on local register +- AS3 - direct editation - resolve properties and local regs before types ## [15.0.0] - 2021-11-29 ### Added 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 cdb4385bd..596d9d9fa 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 @@ -1621,7 +1621,7 @@ public class AVM2SourceGenerator implements SourceGenerator { UnresolvedAVM2Item n = (UnresolvedAVM2Item) an; if (n.resolved == null) { String fullClass = localData.getFullClass(); - GraphTargetItem res = n.resolve(localData.currentClass, new TypeItem(fullClass), paramTypes, paramNames, abcIndex, callStack, subvariables); + GraphTargetItem res = n.resolve(localData, localData.currentClass, new TypeItem(fullClass), paramTypes, paramNames, abcIndex, callStack, subvariables); if (res instanceof AssignableAVM2Item) { subvariables.set(i, (AssignableAVM2Item) res); } else { @@ -1638,7 +1638,7 @@ public class AVM2SourceGenerator implements SourceGenerator { UnresolvedAVM2Item n = (UnresolvedAVM2Item) an; if (n.resolved == null) { String fullClass = localData.getFullClass(); - GraphTargetItem res = n.resolve(localData.currentClass, new TypeItem(fullClass), paramTypes, paramNames, abcIndex, callStack, subvariables); + GraphTargetItem res = n.resolve(localData, localData.currentClass, new TypeItem(fullClass), paramTypes, paramNames, abcIndex, callStack, subvariables); paramTypes.set(t, res); } } @@ -2178,7 +2178,7 @@ public class AVM2SourceGenerator implements SourceGenerator { public int superIntName(SourceGeneratorLocalData localData, GraphTargetItem un) throws CompilationException { if (un instanceof UnresolvedAVM2Item) { - ((UnresolvedAVM2Item) un).resolve(localData.currentClass, null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), new ArrayList<>()); + ((UnresolvedAVM2Item) un).resolve(localData, localData.currentClass, null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), new ArrayList<>()); un = ((UnresolvedAVM2Item) un).resolved; } if (!(un instanceof TypeItem)) { //not applyType @@ -2718,7 +2718,7 @@ public class AVM2SourceGenerator implements SourceGenerator { if (item instanceof UnresolvedAVM2Item) { String fullClass = localData.getFullClass(); - item = ((UnresolvedAVM2Item) item).resolve(localData.currentClass, new TypeItem(fullClass), new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), new ArrayList<>()); + item = ((UnresolvedAVM2Item) item).resolve(localData, localData.currentClass, new TypeItem(fullClass), new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), new ArrayList<>()); } if (item instanceof TypeItem) { typeItem = item; @@ -2731,7 +2731,7 @@ public class AVM2SourceGenerator implements SourceGenerator { } if (typeItem instanceof UnresolvedAVM2Item) { String fullClass = localData.getFullClass(); - typeItem = ((UnresolvedAVM2Item) typeItem).resolve(localData.currentClass, new TypeItem(fullClass), new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), new ArrayList<>()); + typeItem = ((UnresolvedAVM2Item) typeItem).resolve(localData, localData.currentClass, new TypeItem(fullClass), new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), new ArrayList<>()); } if (!(typeItem instanceof TypeItem)) { 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 84c3da297..85ba4c53b 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 @@ -1011,7 +1011,8 @@ public class ActionScript3Parser { List names = new ArrayList<>(); List namespaces = new ArrayList<>(); //FIXME for Private classes in script (?) - AVM2SourceGenerator.parentNamesAddNames(abcIndex, AVM2SourceGenerator.resolveType(new SourceGeneratorLocalData(new HashMap<>(), 0, false, 0), ((TypeItem) ((UnresolvedAVM2Item) extendsTypeStr).resolve(pkgName.addWithSuffix(subNameStr).toRawString(), null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), new ArrayList<>())), abcIndex), indices, names, namespaces); + AVM2SourceGenerator.parentNamesAddNames(abcIndex, AVM2SourceGenerator.resolveType(new SourceGeneratorLocalData(new HashMap<>(), 0, false, 0), ((TypeItem) ((UnresolvedAVM2Item) extendsTypeStr) + .resolve(null, pkgName.addWithSuffix(subNameStr).toRawString(), null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), new ArrayList<>())), abcIndex), indices, names, namespaces); for (int i = 0; i < names.size(); i++) { if (namespaces.get(i) == null || namespaces.get(i).isEmpty()) { continue; @@ -1750,7 +1751,7 @@ public class ActionScript3Parser { UnresolvedAVM2Item ui = (UnresolvedAVM2Item) a; if (ui.getVariableName().equals(DottedChain.parseWithSuffix(e.getVariableName()))) { try { - ui.resolve(null, null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), variables); + ui.resolve(null, null, null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), variables); } catch (CompilationException ex) { // ignore } @@ -1773,7 +1774,7 @@ public class ActionScript3Parser { for (NameAVM2Item e : catchExceptions) { if (ui.getVariableName().equals(DottedChain.parseWithSuffix(e.getVariableName()))) { try { - ui.resolve(null, null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), variables); + ui.resolve(null, null, null, new ArrayList<>(), new ArrayList<>(), abcIndex, new ArrayList<>(), variables); } catch (CompilationException ex) { // ignore } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java index d6037fb7a..34dd19027 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/UnresolvedAVM2Item.java @@ -17,6 +17,7 @@ package com.jpexs.decompiler.flash.abc.avm2.parser.script; import com.jpexs.decompiler.flash.SourceGeneratorLocalData; +import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction; import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instructions; import com.jpexs.decompiler.flash.abc.avm2.model.BooleanAVM2Item; @@ -27,6 +28,7 @@ import com.jpexs.decompiler.flash.abc.avm2.model.NullAVM2Item; import com.jpexs.decompiler.flash.abc.avm2.model.UndefinedAVM2Item; import com.jpexs.decompiler.flash.abc.types.MethodBody; import com.jpexs.decompiler.flash.abc.types.Namespace; +import com.jpexs.decompiler.flash.abc.types.ValueKind; import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; import com.jpexs.decompiler.flash.helpers.GraphTextWriter; import com.jpexs.decompiler.graph.CompilationException; @@ -36,6 +38,7 @@ import com.jpexs.decompiler.graph.GraphTargetItem; import com.jpexs.decompiler.graph.SourceGenerator; import com.jpexs.decompiler.graph.TypeItem; import com.jpexs.decompiler.graph.model.LocalData; +import com.jpexs.helpers.Reference; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -284,7 +287,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { throw new RuntimeException("Cannot assign"); } - public GraphTargetItem resolve(String currentClass, GraphTargetItem thisType, List paramTypes, List paramNames, AbcIndexing abc, List callStack, List variables) throws CompilationException { + public GraphTargetItem resolve(SourceGeneratorLocalData localData /*can be null!!!*/, String currentClass, GraphTargetItem thisType, List paramTypes, List paramNames, AbcIndexing abc, List callStack, List variables) throws CompilationException { if (scopeStack.isEmpty()) { //Everything is multiname property in with command //search for variable @@ -313,7 +316,48 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { } } - if (currentClass != null) { + if ((paramNames.contains(name.get(0)) || name.get(0).equals("arguments"))) { + int ind = paramNames.indexOf(name.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(t, line, name.get(0), null, false, openedNamespaces, abcIndex); + resolved = ret; + for (int i = 1; i < name.size(); i++) { + resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>()); + if (i == name.size() - 1) { + ((PropertyAVM2Item) resolved).assignedValue = assignedValue; + } + } + if (name.size() == 1) { + ((NameAVM2Item) ret).setAssignedValue(assignedValue); + } + return resolvedRoot = ret; + } + + boolean isProperty = false; + if (localData != null) { //resolve can be called without localData + PropertyAVM2Item resolvedx = new PropertyAVM2Item(null, name.get(0), abc, openedNamespaces, callStack); + ((PropertyAVM2Item) resolvedx).scopeStack = scopeStack; + ((PropertyAVM2Item) resolvedx).setAssignedValue(assignedValue); + Reference objectType = new Reference<>(null); + Reference propertyType = new Reference<>(null); + Reference propertyIndex = new Reference<>(null); + Reference propertyValue = new Reference<>(null); + Reference propertyValueABC = new Reference<>(null); + + resolvedx.resolve(true, localData, objectType, propertyType, propertyIndex, propertyValue, propertyValueABC); + + if (objectType.getVal() != null && !((objectType.getVal() instanceof TypeItem) && ("".equals(((TypeItem) objectType.getVal()).fullTypeName.toRawString())))) { + isProperty = true; + } + } + + if (currentClass != null && !isProperty) { DottedChain classChain = DottedChain.parseWithSuffix(currentClass); DottedChain pkg = classChain.getWithoutLast(); @@ -334,87 +378,87 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { } //Search for types in imported classes - for (DottedChain imp : importedClasses) { - String impName = imp.getLast(); + if (!isProperty) { + for (DottedChain imp : importedClasses) { + String impName = imp.getLast(); - if (impName.equals(name.get(0))) { - TypeItem ret = new TypeItem(imp); - resolved = ret; - for (int i = 1; i < name.size(); i++) { - resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>()); - if (i == name.size() - 1) { - ((PropertyAVM2Item) resolved).assignedValue = assignedValue; - } - } - - if (name.size() == 1) { - AbcIndexing.TraitIndex ti = abc.findScriptProperty(imp); - if (ti != null && (ti.trait instanceof TraitSlotConst)) { - resolved = new ImportedSlotConstItem(ret); - if (assignedValue != null) { - ((ImportedSlotConstItem) resolved).assignedValue = assignedValue; + if (impName.equals(name.get(0))) { + TypeItem ret = new TypeItem(imp); + resolved = ret; + for (int i = 1; i < name.size(); i++) { + resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>()); + if (i == name.size() - 1) { + ((PropertyAVM2Item) resolved).assignedValue = assignedValue; } } - } - return resolvedRoot = ret; + if (name.size() == 1) { + AbcIndexing.TraitIndex ti = abc.findScriptProperty(imp); + if (ti != null && (ti.trait instanceof TraitSlotConst)) { + resolved = new ImportedSlotConstItem(ret); + if (assignedValue != null) { + ((ImportedSlotConstItem) resolved).assignedValue = assignedValue; + } + } + } + + return resolvedRoot = ret; + } } } //Search all fully qualitfied types - /*List allAbcs = new ArrayList<>(); - allAbcs.add(abc); - allAbcs.addAll(otherAbcs);*/ - for (int i = 0; i < name.size(); i++) { - DottedChain fname = name.subChain(i + 1); - AbcIndexing.ClassIndex ci = abc.findClass(new TypeItem(fname)); - if (ci != null) { - if (!subtypes.isEmpty() && name.size() > i + 1) { - continue; - } - TypeItem ret = new TypeItem(fname); - resolved = ret; - for (int j = i + 1; j < name.size(); j++) { - resolved = new PropertyAVM2Item(resolved, name.get(j), abc, openedNamespaces, new ArrayList<>()); - if (j == name.size() - 1) { - ((PropertyAVM2Item) resolved).assignedValue = assignedValue; + if (!isProperty) { + for (int i = 0; i < name.size(); i++) { + DottedChain fname = name.subChain(i + 1); + AbcIndexing.ClassIndex ci = abc.findClass(new TypeItem(fname)); + if (ci != null) { + if (!subtypes.isEmpty() && name.size() > i + 1) { + continue; + } + TypeItem ret = new TypeItem(fname); + resolved = ret; + for (int j = i + 1; j < name.size(); j++) { + resolved = new PropertyAVM2Item(resolved, name.get(j), abc, openedNamespaces, new ArrayList<>()); + if (j == name.size() - 1) { + ((PropertyAVM2Item) resolved).assignedValue = assignedValue; + } + } + if (name.size() == i + 1 && assignedValue != null) { + throw new CompilationException("Cannot assign type", line); } - } - if (name.size() == i + 1 && assignedValue != null) { - throw new CompilationException("Cannot assign type", line); - } - return resolvedRoot = ret; + return resolvedRoot = ret; + } + } + + //Search for types in opened namespaces + for (NamespaceItem n : openedNamespaces) { + Namespace ons = abc.getSelectedAbc().constants.getNamespace(n.getCpoolIndex(abc)); + TypeItem ti = new TypeItem(ons.getName(abc.getSelectedAbc().constants).addWithSuffix(name.get(0))); + AbcIndexing.ClassIndex ci = abc.findClass(ti); + if (ci != null) { + if (!subtypes.isEmpty() && name.size() > 1) { + continue; + } + TypeItem ret = ti; + resolved = ret; + for (int i = 1; i < name.size(); i++) { + resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>()); + if (i == name.size() - 1) { + ((PropertyAVM2Item) resolved).assignedValue = assignedValue; + } + } + if (name.size() == 1 && assignedValue != null) { + throw new CompilationException("Cannot assign type", line); + } + + return resolvedRoot = ret; + } } } - //Search for types in opened namespaces - for (NamespaceItem n : openedNamespaces) { - Namespace ons = abc.getSelectedAbc().constants.getNamespace(n.getCpoolIndex(abc)); - TypeItem ti = new TypeItem(ons.getName(abc.getSelectedAbc().constants).addWithSuffix(name.get(0))); - AbcIndexing.ClassIndex ci = abc.findClass(ti); - if (ci != null) { - if (!subtypes.isEmpty() && name.size() > 1) { - continue; - } - TypeItem ret = ti; - resolved = ret; - for (int i = 1; i < name.size(); i++) { - resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>()); - if (i == name.size() - 1) { - ((PropertyAVM2Item) resolved).assignedValue = assignedValue; - } - } - if (name.size() == 1 && assignedValue != null) { - throw new CompilationException("Cannot assign type", line); - } - - return resolvedRoot = ret; - } - } - - if (name.get( - 0).equals("this") || name.get(0).equals("super")) { + if (!isProperty && (name.get(0).equals("this") || name.get(0).equals("super"))) { if (thisType == null) { throw new CompilationException("Cannot use this in that context", line); } @@ -448,41 +492,9 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { return resolvedRoot = ret; } - if (paramNames.contains(name.get(0)) || name.get(0).equals("arguments")) { - int ind = paramNames.indexOf(name.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(t, line, name.get(0), null, false, openedNamespaces, abcIndex); - resolved = ret; - for (int i = 1; i < name.size(); i++) { - resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, new ArrayList<>()); - if (i == name.size() - 1) { - ((PropertyAVM2Item) resolved).assignedValue = assignedValue; - } - } - if (name.size() == 1) { - ((NameAVM2Item) ret).setAssignedValue(assignedValue); - } - return resolvedRoot = ret; - } - - if (/*!subtypes.isEmpty() && */name.size() - == 1 && name.get(0).equals("Vector")) { + if (!isProperty && (name.size() == 1 && name.get(0).equals("Vector"))) { TypeItem ret = new TypeItem(InitVectorAVM2Item.VECTOR_FQN); - /*for (String s : subtypes) { - UnresolvedAVM2Item su = new UnresolvedAVM2Item(new ArrayList<>(), importedClasses, true, null, line, s, null, openedNamespaces); - su.resolve(thisType, paramTypes, paramNames, abc, otherAbcs, callStack, variables); - if (!(su.resolved instanceof TypeItem)) { - throw new CompilationException("Not a type", line); - } - TypeItem st = (TypeItem) su.resolved; - ret.subtypes.add(st.fullTypeName); - }*/ resolved = ret; return resolvedRoot = ret; } @@ -492,9 +504,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { } resolved = null; GraphTargetItem ret = null; - for (int i = 0; - i < name.size(); - i++) { + for (int i = 0; i < name.size(); i++) { resolved = new PropertyAVM2Item(resolved, name.get(i), abc, openedNamespaces, callStack); if (ret == null) { ((PropertyAVM2Item) resolved).scopeStack = scopeStack;