diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c6c9e86d..df57ed47a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -35,6 +35,7 @@ All notable changes to this project will be documented in this file. - [#1938] AS3 Direct editation - implied this instead of findprop - [#1938] AS3 Direct editation - local registers coerce/convert - [#1938] AS3 Direct editation - setting default values for slots +- AS3 Direct editation - using local classes as types ## [18.3.2] - 2023-01-10 ### Removed 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 25e04a2c8..86bc28986 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SourceGeneratorLocalData.java @@ -69,6 +69,8 @@ public class SourceGeneratorLocalData implements Serializable { public List scopeStack = new ArrayList<>(); public ScriptInfo currentScript; + + public int scriptIndex; public boolean subMethod = false; 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 3f8dae9ce..442d0c7eb 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 @@ -1387,8 +1387,8 @@ public class AVM2SourceGenerator implements SourceGenerator { generateTraitsPhase2(importedClasses, pkg, traitItems, it, openedNamespaces, localData); generateTraitsPhase2(importedClasses, pkg, traitItems, st, openedNamespaces, localData); abcIndex.refreshSelected(); - generateTraitsPhase3(importedClasses, initScope, isInterface, name, superName, false, localData, traitItems, instanceInfo.instance_traits, it, new HashMap<>(), class_index); - generateTraitsPhase3(importedClasses, initScope, isInterface, name, superName, true, localData, traitItems, classInfo.static_traits, st, new HashMap<>(), class_index); + generateTraitsPhase4(importedClasses, initScope, isInterface, name, superName, false, localData, traitItems, instanceInfo.instance_traits, it, new HashMap<>(), class_index); + generateTraitsPhase4(importedClasses, initScope, isInterface, name, superName, true, localData, traitItems, classInfo.static_traits, st, new HashMap<>(), class_index); int init; if (iinit == null || isInterface) { instanceInfo.iinit_index = init = method(false, 0, false, isInterface, new ArrayList<>(), pkg, false, new ArrayList<>(), initScope + 1, false, 0, isInterface ? null : name, extendsVal != null ? extendsVal.toString() : null, true, localData, new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), TypeItem.UNBOUNDED/*?? FIXME*/); @@ -1606,6 +1606,7 @@ public class AVM2SourceGenerator implements SourceGenerator { newlocalData.callStack.addAll(localData.callStack); newlocalData.traitUsages = localData.traitUsages; newlocalData.currentScript = localData.currentScript; + newlocalData.scriptIndex = localData.scriptIndex; newlocalData.privateNs = localData.privateNs; newlocalData.protectedNs = localData.protectedNs; newlocalData.isStatic = isStatic; @@ -2148,6 +2149,30 @@ public class AVM2SourceGenerator implements SourceGenerator { abcIndex.getSelectedAbc().constants.getStringId(((ClassAVM2Item) item).className, true), ((ClassAVM2Item) item).pkg.getCpoolIndex(abcIndex)), true); + localData.currentClass = null; + } + if (item instanceof InterfaceAVM2Item) { + localData.currentClass = ((InterfaceAVM2Item) item).pkg.name.addWithSuffix(((InterfaceAVM2Item) item).name).toRawString(); + ABC abc = abcIndex.getSelectedAbc(); + AVM2ConstantPool constants = abc.constants; + InstanceInfo instanceInfo = abc.instance_info.get(((TraitClass) traits[k]).class_info); + instanceInfo.name_index = constants.getMultinameId(Multiname.createQName(false, constants.getStringId(((InterfaceAVM2Item) item).name, true), + ((InterfaceAVM2Item) item).pkg.getCpoolIndex(abcIndex)), true); + + localData.currentClass = null; + } + } + } + + public void generateTraitsPhase3(List items, Trait[] traits, SourceGeneratorLocalData localData) throws CompilationException { + for (int k = 0; k < items.size(); k++) { + GraphTargetItem item = items.get(k); + if (traits[k] == null) { + continue; + } + if (item instanceof ClassAVM2Item) { + localData.currentClass = ((ClassAVM2Item) item).pkg.name.addWithSuffix(((ClassAVM2Item) item).className).toRawString(); + InstanceInfo instanceInfo = abcIndex.getSelectedAbc().instance_info.get(((TraitClass) traits[k]).class_info); if (((ClassAVM2Item) item).extendsOp != null) { instanceInfo.super_index = typeName(localData, ((ClassAVM2Item) item).extendsOp); } else { @@ -2162,11 +2187,7 @@ public class AVM2SourceGenerator implements SourceGenerator { if (item instanceof InterfaceAVM2Item) { localData.currentClass = ((InterfaceAVM2Item) item).pkg.name.addWithSuffix(((InterfaceAVM2Item) item).name).toRawString(); ABC abc = abcIndex.getSelectedAbc(); - AVM2ConstantPool constants = abc.constants; - InstanceInfo instanceInfo = abc.instance_info.get(((TraitClass) traits[k]).class_info); - instanceInfo.name_index = constants.getMultinameId(Multiname.createQName(false, constants.getStringId(((InterfaceAVM2Item) item).name, true), - ((InterfaceAVM2Item) item).pkg.getCpoolIndex(abcIndex)), true); - + InstanceInfo instanceInfo = abc.instance_info.get(((TraitClass) traits[k]).class_info); instanceInfo.interfaces = new int[((InterfaceAVM2Item) item).superInterfaces.size()]; for (int i = 0; i < ((InterfaceAVM2Item) item).superInterfaces.size(); i++) { GraphTargetItem un = ((InterfaceAVM2Item) item).superInterfaces.get(i); @@ -2211,7 +2232,7 @@ public class AVM2SourceGenerator implements SourceGenerator { return ret; } - public void generateTraitsPhase3(List importedClasses, int methodInitScope, boolean isInterface, String className, String superName, boolean generateStatic, SourceGeneratorLocalData localData, List items, Traits ts, Trait[] traits, Map initScopes, Reference class_index) throws AVM2ParseException, CompilationException { + public void generateTraitsPhase4(List importedClasses, int methodInitScope, boolean isInterface, String className, String superName, boolean generateStatic, SourceGeneratorLocalData localData, List items, Traits ts, Trait[] traits, Map initScopes, Reference class_index) throws AVM2ParseException, CompilationException { //Note: Names must be generated first before accesed in inner subs for (int k = 0; k < items.size(); k++) { @@ -2446,12 +2467,14 @@ public class AVM2SourceGenerator implements SourceGenerator { return traits; } - public void generateScriptInfo(ScriptInfo scriptInfo, List> allOpenedNamespaces, SourceGeneratorLocalData localData, List commands, int classPos) throws AVM2ParseException, CompilationException { + public void generateScriptInfo(int scriptIndex, ScriptInfo scriptInfo, List> allOpenedNamespaces, SourceGeneratorLocalData localData, List commands, int classPos) throws AVM2ParseException, CompilationException { Reference class_index = new Reference<>(classPos); localData.currentScript = scriptInfo; + localData.scriptIndex = scriptIndex; Trait[] traitArr = generateTraitsPhase1(new ArrayList<>(), new ArrayList<>(), null, null, true, localData, commands, scriptInfo.traits, class_index); generateTraitsPhase2(new ArrayList<>(), null/*FIXME*/, commands, traitArr, new ArrayList<>(), localData); - + abcIndex.refreshSelected(); + generateTraitsPhase3(commands, traitArr, localData); abcIndex.refreshSelected(); ABC abc = abcIndex.getSelectedAbc(); @@ -2520,7 +2543,7 @@ public class AVM2SourceGenerator implements SourceGenerator { abc.addMethodBody(mb); scriptInfo.init_index = mb.method_info; localData.pkg = DottedChain.EMPTY; - generateTraitsPhase3(new ArrayList<>(), 1/*??*/, false, null, null, true, localData, commands, scriptInfo.traits, traitArr, initScopes, class_index); + generateTraitsPhase4(new ArrayList<>(), 1/*??*/, false, null, null, true, localData, commands, scriptInfo.traits, traitArr, initScopes, class_index); int maxSlotId = 0; for (int k = 0; k < scriptInfo.traits.traits.size(); k++) { 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 220de7778..0906df45b 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 @@ -321,6 +321,13 @@ public final class AbcIndexing { public GraphTargetItem type; public DottedChain pkg; + private GraphTargetItem noNsType(GraphTargetItem type) { + TypeItem ti = (TypeItem)type; + ti = (TypeItem)ti.clone(); + ti.ns = null; + return ti; + } + public ClassDef(GraphTargetItem type, ABC abc, Integer scriptIndex) { this.type = type; if (scriptIndex != null) { @@ -336,7 +343,7 @@ public final class AbcIndexing { @Override public int hashCode() { int hash = 3; - hash = 17 * hash + Objects.hashCode(this.type); + hash = 17 * hash + Objects.hashCode(noNsType(this.type)); hash = 17 * hash + Objects.hashCode(this.pkg); return hash; } @@ -353,7 +360,7 @@ public final class AbcIndexing { return false; } final ClassDef other = (ClassDef) obj; - if (!Objects.equals(this.type, other.type)) { + if (!Objects.equals(noNsType(this.type), noNsType(other.type))) { return false; } return Objects.equals(this.pkg, other.pkg); 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 690f2cf79..6b41398ea 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 @@ -2592,9 +2592,10 @@ public class ActionScript3Parser { SourceGeneratorLocalData localData = new SourceGeneratorLocalData( new HashMap<>(), 0, Boolean.FALSE, 0); ScriptInfo si = new ScriptInfo(); + int scriptIndex = abcIndex.getSelectedAbc().script_info.size(); abcIndex.getSelectedAbc().script_info.add(si); try { - gen.generateScriptInfo(si, allOpenedNamespaces, localData, items, classPos); + gen.generateScriptInfo(scriptIndex, si, allOpenedNamespaces, localData, items, classPos); } catch (Exception ex) { abcIndex.getSelectedAbc().script_info.remove(si); throw ex; 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 1adf743c1..a9089c75b 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 @@ -412,7 +412,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item { if (!isProperty) { for (int i = 0; i < name.size(); i++) { DottedChain fname = name.subChain(i + 1); - AbcIndexing.ClassIndex ci = abc.findClass(new TypeItem(fname), null, null/*FIXME?*/); + AbcIndexing.ClassIndex ci = abc.findClass(new TypeItem(fname), abc.getSelectedAbc(), localData.scriptIndex); if (ci != null) { if (!subtypes.isEmpty() && name.size() > i + 1) { continue;