Fixed: #2329 AS3 - imports for standalone functions

This commit is contained in:
Jindra Petřík
2024-09-27 18:29:45 +02:00
parent ce2ac52ba1
commit c9dfe10a60
7 changed files with 93 additions and 83 deletions

View File

@@ -35,6 +35,7 @@ import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.abc.types.ScriptInfo;
import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.TraitClass;
import com.jpexs.decompiler.flash.abc.types.traits.TraitMethodGetterSetter;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
@@ -321,33 +322,41 @@ public class ScriptPack extends AS3ClassTreeItem {
}
DottedChain pkg = getPathPackage();
List<Trait> traitList = new ArrayList<>();
List<Integer> traitIndicesList = new ArrayList<>(traitIndices);
for (int t : traitIndices) {
Trait trait = traits.get(t);
traitList.add(trait);
}
List<DottedChain> fullyQualifiedNames = new ArrayList<>();
if (trait instanceof TraitSlotConst) {
for (int t = 0; t < traitList.size(); t++) {
Trait trait = traitList.get(t);
int nskind = trait.getName(abc).getSimpleNamespaceKind(abc.constants);
if ((nskind != Namespace.KIND_PACKAGE) && (nskind != Namespace.KIND_PACKAGE_INTERNAL)) {
continue;
}
if (!first) {
writer.newLine();
}
writer.startTrait(t);
Multiname name = trait.getName(abc);
int nskind = name.getSimpleNamespaceKind(abc.constants);
if ((nskind == Namespace.KIND_PACKAGE) || (nskind == Namespace.KIND_PACKAGE_INTERNAL)) {
trait.toStringPackaged(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, false);
} else {
trait.toString(abcIndex, pkg, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, false);
}
writer.startTrait(traitIndicesList.get(t));
trait.toStringPackaged(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, fullyQualifiedNames, parallel, false);
if (!(trait instanceof TraitClass)) {
writer.endTrait();
}
first = false;
traitList.remove(t);
traitIndicesList.remove(t);
t--;
}
List<DottedChain> fullyQualifiedNames = new ArrayList<>();
if (!first) {
writer.newLine();
}
@@ -355,22 +364,33 @@ public class ScriptPack extends AS3ClassTreeItem {
if (isSimple) {
ignorePackage = getPathPackage();
}
List<Trait> importTraits = new ArrayList<>();
for (int t : traitIndices) {
Trait trait = traits.get(t);
if (!(trait instanceof TraitSlotConst)) {
continue;
}
importTraits.add(trait);
}
Trait.writeImports(importTraits, script_init, abcIndex, scriptIndex, -1, true, abc, writer, ignorePackage, fullyQualifiedNames);
Trait.writeImports(traitList, script_init, abcIndex, scriptIndex, -1, true, abc, writer, ignorePackage, fullyQualifiedNames);
first = true;
//Slot const last
for (int t : traitIndices) {
for (int t = 0; t < traitList.size(); t++) {
Trait trait = traitList.get(t);
if (trait instanceof TraitSlotConst) {
continue;
}
if (!first) {
writer.newLine();
}
writer.startTrait(traitIndicesList.get(t));
trait.toString(abcIndex, pkg, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, false);
Trait trait = traits.get(t);
if (!(trait instanceof TraitClass)) {
writer.endTrait();
}
first = false;
traitList.remove(t);
traitIndicesList.remove(t);
t--;
}
//Slot const last
for (int t = 0; t < traitList.size(); t++) {
Trait trait = traitList.get(t);
if (!(trait instanceof TraitSlotConst)) {
continue;
@@ -383,17 +403,15 @@ public class ScriptPack extends AS3ClassTreeItem {
if (!first) {
writer.newLine();
}
writer.startTrait(t);
writer.startTrait(traitIndicesList.get(t));
Multiname name = trait.getName(abc);
int nskind = name.getSimpleNamespaceKind(abc.constants);
if ((nskind == Namespace.KIND_PACKAGE) || (nskind == Namespace.KIND_PACKAGE_INTERNAL)) {
trait.toStringPackaged(abcIndex, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, false);
} else {
trait.toString(abcIndex, pkg, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, false);
}
if (!(trait instanceof TraitClass)) {
writer.endTrait();
trait.toString(abcIndex, pkg, null, convertData, "", abc, false, exportMode, scriptIndex, -1, writer, new ArrayList<>(), parallel, false);
}
writer.endTrait();
first = false;
}

View File

@@ -2706,6 +2706,15 @@ public class AVM2Code implements Cloneable {
if (commandToAssigned.containsKey(ti)) {
AssignedValue asv = commandToAssigned.get(ti);
TraitSlotConst tsc = commandToTrait.get(ti);
int nsKind = tsc.getName(abc).getSimpleNamespaceKind(abc.constants);
if (classIndex == -1 && (nsKind == Namespace.KIND_PACKAGE || nsKind == Namespace.KIND_PACKAGE_INTERNAL)) {
list.remove(i);
i--;
continue;
}
TraitSlotConstAVM2Item item = new TraitSlotConstAVM2Item(
ti.getSrc(),
ti.getLineStartItem(),

View File

@@ -391,17 +391,16 @@ public abstract class Trait implements Cloneable, Serializable {
traitNamesInThisScript.add(st.getName(abc).getName(abc.constants, new ArrayList<>(), true, true));
}
}
Set<String> traitNamesInThisScriptSet = new LinkedHashSet<>(traitNamesInThisScript);
traitNamesInThisScript = new ArrayList<>(traitNamesInThisScriptSet);
//imports
List<Dependency> dependencies = new ArrayList<>();
String customNs = null;
List<String> uses = new ArrayList<>();
Reference<Integer> numberContextRef = new Reference<>(null);
for (Trait trait : traits) {
Multiname multiname = trait.getName(abc);
int nskind = multiname.getSimpleNamespaceKind(abc.constants);
@@ -419,16 +418,13 @@ public abstract class Trait implements Cloneable, Serializable {
imports.add(d.getId());
}
}
List<String> importedNames = new ArrayList<>();
importedNames.addAll(Arrays.asList(builtInClasses));
importedNames.addAll(Arrays.asList(builtInClasses));
importedNames.addAll(namesInThisPackage);
importedNames.addAll(traitNamesInThisScript);
for (DottedChain imp : imports) {
if (imp.getLast().equals("*")) {
if (imp.getWithoutLast().equals(ignorePackage)) {
@@ -451,7 +447,7 @@ public abstract class Trait implements Cloneable, Serializable {
i--;
}
}
for (int i = 0; i < imports.size(); i++) {
DottedChain ipath = imports.get(i);
DottedChain pkg = ipath.getWithoutLast();
@@ -465,9 +461,9 @@ public abstract class Trait implements Cloneable, Serializable {
for (int i = 0; i < imports.size(); i++) {
DottedChain ipath = imports.get(i);
String name = ipath.getLast();
importedNames.add(name);
importedNames.add(name);
}
List<String> uniqueImportedNames = new ArrayList<>();
for (int i = 0; i < importedNames.size(); i++) {
String name = importedNames.get(i);
@@ -497,7 +493,6 @@ public abstract class Trait implements Cloneable, Serializable {
hasImport = true;
}
}
boolean hasUse = false;
if (!uses.isEmpty()) {
@@ -653,24 +648,28 @@ public abstract class Trait implements Cloneable, Serializable {
}
Set<Integer> namespaceIdsClass = new HashSet<>();
Multiname mc = abc.instance_info.get(classIndex).getName(abc.constants);
if (mc.isApiVersioned(abc.constants)) {
NamespaceSet nss = mc.getNamespaceSet(abc.constants);
for (int n : nss.namespaces) {
namespaceIdsClass.add(n);
}
if (classIndex == -1) {
nskind = Namespace.KIND_PACKAGE_INTERNAL;
} else {
namespaceIdsClass.add(mc.namespace_index);
}
Multiname mc = abc.instance_info.get(classIndex).getName(abc.constants);
if (mc.isApiVersioned(abc.constants)) {
NamespaceSet nss = mc.getNamespaceSet(abc.constants);
for (int n : nss.namespaces) {
namespaceIdsClass.add(n);
}
} else {
namespaceIdsClass.add(mc.namespace_index);
}
for (int ns : namespaceIdsThis) {
if (namespaceIdsClass.contains(ns)) {
nskind = Namespace.KIND_PACKAGE_INTERNAL;
break;
for (int ns : namespaceIdsThis) {
if (namespaceIdsClass.contains(ns)) {
nskind = Namespace.KIND_PACKAGE_INTERNAL;
break;
}
}
}
}
if (!(classIndex == -1 && nskind == Namespace.KIND_PACKAGE_INTERNAL)) {
String nsPrefix = Namespace.getPrefix(nskind);
if (nsPrefix != null && !nsPrefix.isEmpty()) {
@@ -876,6 +875,9 @@ public abstract class Trait implements Cloneable, Serializable {
writer.appendNoHilight(" " + nsname); //assume not null name
}
writer.startBlock();
List<Trait> traits = new ArrayList<>();
traits.add(this);
writeImports(traits, -1, abcIndex, scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
toString(abcIndex, name.getNameWithNamespace(abc.constants, true).getWithoutLast(), parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, insideInterface);
writer.endBlock();
writer.newLine();

View File

@@ -211,17 +211,9 @@ public class TraitClass extends Trait implements TraitWithSlot {
Multiname instanceInfoMultiname = instanceInfo.getName(abc.constants);
//DottedChain packageName = instanceInfoMultiname.getNamespace(abc.constants).getName(abc.constants); //assume not null name
fullyQualifiedNames = new ArrayList<>();
Reference<Boolean> first = new Reference<>(true);
if (getName(abc).getNamespace(abc.constants).kind != Namespace.KIND_PACKAGE_INTERNAL) {
List<Trait> traits = new ArrayList<>();
traits.add(this);
first.setVal(!writeImports(traits, -1, abcIndex, scriptIndex, classIndex, false, abc, writer, packageName, fullyQualifiedNames));
}
Reference<Boolean> first = new Reference<>(true);
String instanceInfoName = instanceInfoMultiname.getName(abc.constants, fullyQualifiedNames, false, true);
getMetaData(this, convertData, abc, writer);

View File

@@ -20,6 +20,7 @@ import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.parser.script.AbcIndexing;
import com.jpexs.decompiler.flash.abc.types.ConvertData;
import com.jpexs.decompiler.flash.abc.types.MethodBody;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.exporters.script.Dependency;
import com.jpexs.decompiler.flash.exporters.script.DependencyParser;
@@ -125,9 +126,6 @@ public class TraitFunction extends Trait implements TraitWithSlot {
@Override
public GraphTextWriter toString(AbcIndexing abcIndex, DottedChain packageName, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel, boolean insideInterface) throws InterruptedException {
List<Trait> traits = new ArrayList<>();
traits.add(this);
writeImports(traits, -1, abcIndex, scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames);
getMetaData(this, convertData, abc, writer);
writer.startMethod(method_info, getName(abc).getName(abc.constants, new ArrayList<>(), true, false));
toStringHeader(parent, packageName, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel, insideInterface);
@@ -168,9 +166,6 @@ public class TraitFunction extends Trait implements TraitWithSlot {
@Override
public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException {
fullyQualifiedNames = new ArrayList<>();
List<Trait> traits = new ArrayList<>();
traits.add(this);
writeImports(traits, -1, abcIndex, scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames);
writer.startMethod(method_info, getName(abc).getName(abc.constants, new ArrayList<>(), true, false));
convertHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
int bodyIndex = abc.findBodyIndex(method_info);

View File

@@ -167,11 +167,7 @@ public class TraitMethodGetterSetter extends Trait {
*/
@Override
public void convert(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel, ScopeStack scopeStack) throws InterruptedException {
if (classIndex < 0) {
List<Trait> traits = new ArrayList<>();
traits.add(this);
writeImports(traits, -1, abcIndex, scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
}
int nsKind = getName(abc).getSimpleNamespaceKind(abc.constants);
writer.startMethod(method_info, getName(abc).getName(abc.constants, new ArrayList<>(), true, false));
path = path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames, false, true);
convertHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
@@ -202,10 +198,6 @@ public class TraitMethodGetterSetter extends Trait {
@Override
public GraphTextWriter toString(AbcIndexing abcIndex, DottedChain packageName, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel, boolean insideInterface) throws InterruptedException {
if (classIndex < 0) {
//writeImports(this, -1, abcIndex, scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
}
getMetaData(this, convertData, abc, writer);
writer.startMethod(method_info, getName(abc).getName(abc.constants, new ArrayList<>(), true, false));
path = path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames, false, true);