mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-14 23:11:53 +00:00
Fixed #1981 AS3 star import collisions
This commit is contained in:
@@ -456,6 +456,7 @@ public final class SWF implements SWFContainerItem, Timelined, Openable {
|
||||
abcIndex.addAbc(((ABCContainerTag) tag).getABC());
|
||||
}
|
||||
}
|
||||
abcIndex.rebuildPkgToObjectsNameMap();
|
||||
return abcIndex;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,8 @@ import com.jpexs.helpers.Reference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
@@ -83,6 +85,7 @@ public final class AbcIndexing {
|
||||
for (ABCContainerTag at : swf.getAbcList()) {
|
||||
addAbc(at.getABC());
|
||||
}
|
||||
rebuildPkgToObjectsNameMap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -425,6 +428,8 @@ public final class AbcIndexing {
|
||||
}
|
||||
}
|
||||
|
||||
private Map<DottedChain, Set<String>> pkgToObjectsName = new LinkedHashMap<>();
|
||||
|
||||
private final Map<ClassDef, ClassIndex> classes = new HashMap<>();
|
||||
|
||||
private final Map<PropertyDef, TraitIndex> instanceProperties = new HashMap<>();
|
||||
@@ -436,6 +441,36 @@ public final class AbcIndexing {
|
||||
private final Map<PropertyNsDef, TraitIndex> classNsProperties = new HashMap<>();
|
||||
|
||||
private final Map<PropertyNsDef, TraitIndex> scriptProperties = new HashMap<>();
|
||||
|
||||
public void rebuildPkgToObjectsNameMap() {
|
||||
pkgToObjectsName.clear();
|
||||
for (ClassDef cd:classes.keySet()) {
|
||||
if (!(cd.type instanceof TypeItem)) {
|
||||
continue;
|
||||
}
|
||||
if (!pkgToObjectsName.containsKey(cd.pkg)) {
|
||||
pkgToObjectsName.put(cd.pkg, new LinkedHashSet<>());
|
||||
}
|
||||
pkgToObjectsName.get(cd.pkg).add(((TypeItem)cd.type).fullTypeName.getLast());
|
||||
}
|
||||
for (PropertyNsDef nsdef:scriptProperties.keySet()) {
|
||||
if (!pkgToObjectsName.containsKey(nsdef.ns)) {
|
||||
pkgToObjectsName.put(nsdef.ns, new LinkedHashSet<>());
|
||||
}
|
||||
pkgToObjectsName.get(nsdef.ns).add(nsdef.propName);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<String> getPackageObjects(DottedChain pkg) {
|
||||
Set<String> classNames = new LinkedHashSet<>();
|
||||
if (pkgToObjectsName.containsKey(pkg)) {
|
||||
classNames.addAll(pkgToObjectsName.get(pkg));
|
||||
}
|
||||
if (parent != null) {
|
||||
classNames.addAll(parent.getPackageObjects(pkg));
|
||||
}
|
||||
return classNames;
|
||||
}
|
||||
|
||||
public ClassIndex findClass(GraphTargetItem cls, ABC abc, Integer scriptIndex) {
|
||||
ClassDef keyWithScriptIndex = new ClassDef(cls, abc, scriptIndex);
|
||||
@@ -717,6 +752,7 @@ public final class AbcIndexing {
|
||||
}
|
||||
removeAbc(abc);
|
||||
addAbc(abc);
|
||||
rebuildPkgToObjectsNameMap();
|
||||
}
|
||||
|
||||
public void removeAbc(ABC abc) {
|
||||
@@ -808,7 +844,7 @@ public final class AbcIndexing {
|
||||
}
|
||||
}
|
||||
abcs.add(abc);
|
||||
selectedAbc = abc;
|
||||
selectedAbc = abc;
|
||||
}
|
||||
|
||||
public void selectAbc(ABC abc) {
|
||||
@@ -816,6 +852,7 @@ public final class AbcIndexing {
|
||||
selectedAbc = abc;
|
||||
} else {
|
||||
addAbc(abc);
|
||||
rebuildPkgToObjectsNameMap();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -170,14 +171,15 @@ public abstract class Trait implements Cloneable, Serializable {
|
||||
return getName(abc).getNamespace(abc.constants).getName(abc.constants);
|
||||
}
|
||||
|
||||
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String ignoredCustom, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String ignoredCustom, ABC abc, List<Dependency> dependencies, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
if (ignoredCustom == null) {
|
||||
Namespace n = getName(abc).getNamespace(abc.constants);
|
||||
if (n.kind == Namespace.KIND_NAMESPACE) {
|
||||
ignoredCustom = n.getName(abc.constants).toRawString();
|
||||
}
|
||||
}
|
||||
DependencyParser.parseUsagesFromMultiname(ignoredCustom, abc, dependencies, uses, getName(abc), ignorePackage, fullyQualifiedNames, DependencyType.NAMESPACE);
|
||||
DependencyParser.parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, getName(abc), ignorePackage, fullyQualifiedNames, DependencyType.NAMESPACE);
|
||||
//DependencyParser.parseUsagesFromMultiname(ignoredCustom, abc, dependencies, getName(abc), ignorePackage, fullyQualifiedNames, DependencyType.NAMESPACE);
|
||||
}
|
||||
|
||||
private static final String[] builtInClasses = {"ArgumentError", "arguments", "Array", "Boolean", "Class", "Date", "DefinitionError", "Error", "EvalError", "Function", "int", "JSON", "Math", "Namespace", "Number", "Object", "QName", "RangeError", "ReferenceError", "RegExp", "SecurityError", "String", "SyntaxError", "TypeError", "uint", "URIError", "VerifyError", "XML", "XMLList"};
|
||||
@@ -190,23 +192,8 @@ public abstract class Trait implements Cloneable, Serializable {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public void writeUses(int scriptIndex, int classIndex, boolean isStatic, ABC abc, GraphTextWriter writer) throws InterruptedException {
|
||||
List<Dependency> dependencies = new ArrayList<>();
|
||||
List<String> uses = new ArrayList<>();
|
||||
String customNs = null;
|
||||
Namespace ns = getName(abc).getNamespace(abc.constants);
|
||||
if (ns.kind == Namespace.KIND_NAMESPACE) {
|
||||
customNs = ns.getName(abc.constants).toRawString();
|
||||
}
|
||||
getDependencies(scriptIndex, classIndex, isStatic, customNs, abc, dependencies, uses, null, new ArrayList<>());
|
||||
for (String us : uses) {
|
||||
writer.appendNoHilight("use namespace " + us + ";").newLine();
|
||||
}
|
||||
}
|
||||
|
||||
public void writeImportsUsages(int scriptIndex, int classIndex, boolean isStatic, ABC abc, GraphTextWriter writer, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
|
||||
public void writeImports(AbcIndexing abcIndex, int scriptIndex, int classIndex, boolean isStatic, ABC abc, GraphTextWriter writer, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
|
||||
List<String> namesInThisPackage = new ArrayList<>();
|
||||
for (ABCContainerTag tag : abc.getAbcTags()) {
|
||||
@@ -222,13 +209,12 @@ public abstract class Trait implements Cloneable, Serializable {
|
||||
|
||||
//imports
|
||||
List<Dependency> dependencies = new ArrayList<>();
|
||||
List<String> uses = new ArrayList<>();
|
||||
String customNs = null;
|
||||
Namespace ns = getName(abc).getNamespace(abc.constants);
|
||||
if (ns.kind == Namespace.KIND_NAMESPACE) {
|
||||
customNs = ns.getName(abc.constants).toRawString();
|
||||
}
|
||||
getDependencies(scriptIndex, classIndex, isStatic, customNs, abc, dependencies, uses, ignorePackage, new ArrayList<>());
|
||||
getDependencies(scriptIndex, classIndex, isStatic, customNs, abc, dependencies, ignorePackage, new ArrayList<>());
|
||||
|
||||
List<DottedChain> imports = new ArrayList<>();
|
||||
for (Dependency d : dependencies) {
|
||||
@@ -240,21 +226,21 @@ public abstract class Trait implements Cloneable, Serializable {
|
||||
List<String> importnames = new ArrayList<>();
|
||||
importnames.addAll(namesInThisPackage);
|
||||
importnames.addAll(Arrays.asList(builtInClasses));
|
||||
for (int i = 0; i < imports.size(); i++) {
|
||||
DottedChain ipath = imports.get(i);
|
||||
if (ipath.getWithoutLast().equals(ignorePackage)) { //do not check classes from same package, they are imported automatically
|
||||
imports.remove(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
String name = ipath.getLast();
|
||||
if (importnames.contains(name)) {
|
||||
fullyQualifiedNames.add(DottedChain.parseWithSuffix(name));
|
||||
} else {
|
||||
importnames.add(name);
|
||||
|
||||
for (DottedChain imp : imports) {
|
||||
if (imp.getLast().equals("*")) {
|
||||
Set<String> objectsInPkg = abcIndex.getPackageObjects(imp.getWithoutLast());
|
||||
for (String objectName : objectsInPkg) {
|
||||
if (importnames.contains(objectName)) {
|
||||
fullyQualifiedNames.add(DottedChain.parseWithSuffix(objectName));
|
||||
} else {
|
||||
importnames.add(objectName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (int i = 0; i < imports.size(); i++) {
|
||||
DottedChain imp = imports.get(i);
|
||||
DottedChain pkg = imp.getWithoutLast();
|
||||
@@ -268,6 +254,28 @@ public abstract class Trait implements Cloneable, Serializable {
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < imports.size(); i++) {
|
||||
DottedChain ipath = imports.get(i);
|
||||
String name = ipath.getLast();
|
||||
if (ipath.getWithoutLast().equals(ignorePackage)) { //do not check classes from same package, they are imported automatically
|
||||
if (importnames.contains(name)) {
|
||||
fullyQualifiedNames.add(DottedChain.parseWithSuffix(name));
|
||||
}
|
||||
|
||||
imports.remove(i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (importnames.contains(name)) {
|
||||
fullyQualifiedNames.add(DottedChain.parseWithSuffix(name));
|
||||
} else {
|
||||
importnames.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
boolean hasImport = false;
|
||||
Collections.sort(imports);
|
||||
@@ -291,12 +299,6 @@ public abstract class Trait implements Cloneable, Serializable {
|
||||
if (hasImport) {
|
||||
writer.newLine();
|
||||
}
|
||||
/*for (String us : uses) {
|
||||
writer.appendNoHilight("use namespace " + us + ";").newLine();
|
||||
}
|
||||
if (uses.size() > 0) {
|
||||
writer.newLine();
|
||||
}*/
|
||||
}
|
||||
|
||||
public final GraphTextWriter getMetaData(Trait parent, ConvertData convertData, ABC abc, GraphTextWriter writer) {
|
||||
|
||||
@@ -78,31 +78,31 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
super.getDependencies(scriptIndex, -1, false, customNs, abc, dependencies, uses, ignorePackage == null ? getPackage(abc) : ignorePackage, fullyQualifiedNames);
|
||||
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
super.getDependencies(scriptIndex, -1, false, customNs, abc, dependencies, ignorePackage == null ? getPackage(abc) : ignorePackage, fullyQualifiedNames);
|
||||
ClassInfo classInfo = abc.class_info.get(class_info);
|
||||
InstanceInfo instanceInfo = abc.instance_info.get(class_info);
|
||||
DottedChain packageName = instanceInfo.getName(abc.constants).getNamespace(abc.constants).getName(abc.constants); //assume not null name
|
||||
|
||||
//DependencyParser.parseDependenciesFromMultiname(customNs, abc, dependencies, uses, abc.constants.getMultiname(instanceInfo.name_index), packageName, fullyQualifiedNames);
|
||||
if (instanceInfo.super_index > 0) {
|
||||
DependencyParser.parseDependenciesFromMultiname(customNs, abc, dependencies, uses, abc.constants.getMultiname(instanceInfo.super_index), packageName, fullyQualifiedNames, DependencyType.INHERITANCE);
|
||||
DependencyParser.parseDependenciesFromMultiname(customNs, abc, dependencies, abc.constants.getMultiname(instanceInfo.super_index), packageName, fullyQualifiedNames, DependencyType.INHERITANCE);
|
||||
}
|
||||
for (int i : instanceInfo.interfaces) {
|
||||
DependencyParser.parseDependenciesFromMultiname(customNs, abc, dependencies, uses, abc.constants.getMultiname(i), packageName, fullyQualifiedNames, DependencyType.INHERITANCE);
|
||||
DependencyParser.parseDependenciesFromMultiname(customNs, abc, dependencies, abc.constants.getMultiname(i), packageName, fullyQualifiedNames, DependencyType.INHERITANCE);
|
||||
}
|
||||
|
||||
//static
|
||||
classInfo.static_traits.getDependencies(scriptIndex, class_info, true, customNs, abc, dependencies, uses, packageName, fullyQualifiedNames);
|
||||
classInfo.static_traits.getDependencies(scriptIndex, class_info, true, customNs, abc, dependencies, packageName, fullyQualifiedNames);
|
||||
|
||||
//static initializer
|
||||
DependencyParser.parseDependenciesFromMethodInfo(null, scriptIndex, class_info, true, customNs, abc, classInfo.cinit_index, dependencies, uses, packageName, fullyQualifiedNames, new ArrayList<>());
|
||||
DependencyParser.parseDependenciesFromMethodInfo(null, scriptIndex, class_info, true, customNs, abc, classInfo.cinit_index, dependencies, packageName, fullyQualifiedNames, new ArrayList<>());
|
||||
|
||||
//instance
|
||||
instanceInfo.instance_traits.getDependencies(scriptIndex, class_info, false, customNs, abc, dependencies, uses, packageName, fullyQualifiedNames);
|
||||
instanceInfo.instance_traits.getDependencies(scriptIndex, class_info, false, customNs, abc, dependencies, packageName, fullyQualifiedNames);
|
||||
|
||||
//instance initializer
|
||||
DependencyParser.parseDependenciesFromMethodInfo(null, scriptIndex, class_info, false, customNs, abc, instanceInfo.iinit_index, dependencies, uses, packageName, fullyQualifiedNames, new ArrayList<>());
|
||||
DependencyParser.parseDependenciesFromMethodInfo(null, scriptIndex, class_info, false, customNs, abc, instanceInfo.iinit_index, dependencies, packageName, fullyQualifiedNames, new ArrayList<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -123,7 +123,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
|
||||
DottedChain packageName = instanceInfoMultiname.getNamespace(abc.constants).getName(abc.constants); //assume not null name
|
||||
|
||||
fullyQualifiedNames = new ArrayList<>();
|
||||
writeImportsUsages(scriptIndex, classIndex, false, abc, writer, packageName, fullyQualifiedNames);
|
||||
writeImports(abcIndex, scriptIndex, classIndex, false, abc, writer, packageName, fullyQualifiedNames);
|
||||
|
||||
String instanceInfoName = instanceInfoMultiname.getName(abc.constants, fullyQualifiedNames, false, true);
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ public class TraitFunction extends Trait implements TraitWithSlot {
|
||||
|
||||
@Override
|
||||
public GraphTextWriter toString(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel) throws InterruptedException {
|
||||
writeImportsUsages(scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames);
|
||||
writeImports(abcIndex, scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames);
|
||||
getMetaData(parent, convertData, abc, writer);
|
||||
writer.startMethod(method_info);
|
||||
toStringHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
|
||||
@@ -105,7 +105,7 @@ 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) throws InterruptedException {
|
||||
fullyQualifiedNames = new ArrayList<>();
|
||||
writeImportsUsages(scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames);
|
||||
writeImports(abcIndex, scriptIndex, classIndex, false, abc, writer, getPackage(abc), fullyQualifiedNames);
|
||||
writer.startMethod(method_info);
|
||||
convertHeader(parent, convertData, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
|
||||
int bodyIndex = abc.findBodyIndex(method_info);
|
||||
@@ -133,14 +133,14 @@ public class TraitFunction extends Trait implements TraitWithSlot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
if (ignorePackage == null) {
|
||||
ignorePackage = getPackage(abc);
|
||||
}
|
||||
super.getDependencies(scriptIndex, classIndex, false, customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
|
||||
super.getDependencies(scriptIndex, classIndex, false, customNs, abc, dependencies, ignorePackage, fullyQualifiedNames);
|
||||
//if (method_info != 0)
|
||||
{
|
||||
DependencyParser.parseDependenciesFromMethodInfo(this, scriptIndex, classIndex, false, customNs, abc, method_info, dependencies, uses, ignorePackage, fullyQualifiedNames, new ArrayList<>());
|
||||
DependencyParser.parseDependenciesFromMethodInfo(this, scriptIndex, classIndex, false, customNs, abc, method_info, dependencies, ignorePackage, fullyQualifiedNames, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,11 +63,11 @@ public class TraitMethodGetterSetter extends Trait {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
if (ignorePackage == null) {
|
||||
ignorePackage = getPackage(abc);
|
||||
}
|
||||
super.getDependencies(scriptIndex, classIndex, isStatic, customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
|
||||
super.getDependencies(scriptIndex, classIndex, isStatic, customNs, abc, dependencies, ignorePackage, fullyQualifiedNames);
|
||||
|
||||
if (customNs == null) {
|
||||
Namespace n = getName(abc).getNamespace(abc.constants);
|
||||
@@ -77,7 +77,7 @@ public class TraitMethodGetterSetter extends Trait {
|
||||
}
|
||||
//if (method_info != 0)
|
||||
{
|
||||
DependencyParser.parseDependenciesFromMethodInfo(this, scriptIndex, classIndex, isStatic, customNs, abc, method_info, dependencies, uses, ignorePackage, fullyQualifiedNames, new ArrayList<>());
|
||||
DependencyParser.parseDependenciesFromMethodInfo(this, scriptIndex, classIndex, isStatic, customNs, abc, method_info, dependencies, ignorePackage, fullyQualifiedNames, new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,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) throws InterruptedException {
|
||||
if (classIndex < 0) {
|
||||
writeImportsUsages(scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
|
||||
writeImports(abcIndex, scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
|
||||
}
|
||||
writer.startMethod(method_info);
|
||||
path = path + "." + getName(abc).getName(abc.constants, fullyQualifiedNames, false, true);
|
||||
@@ -132,7 +132,7 @@ public class TraitMethodGetterSetter extends Trait {
|
||||
public GraphTextWriter toString(AbcIndexing abcIndex, Trait parent, ConvertData convertData, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<DottedChain> fullyQualifiedNames, boolean parallel) throws InterruptedException {
|
||||
|
||||
if (classIndex < 0) {
|
||||
writeImportsUsages(scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
|
||||
writeImports(abcIndex, scriptIndex, classIndex, isStatic, abc, writer, getPackage(abc), fullyQualifiedNames);
|
||||
}
|
||||
getMetaData(parent, convertData, abc, writer);
|
||||
writer.startMethod(method_info);
|
||||
|
||||
@@ -221,12 +221,12 @@ public class TraitSlotConst extends Trait implements TraitWithSlot {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
if (ignorePackage == null) {
|
||||
ignorePackage = getPackage(abc);
|
||||
}
|
||||
super.getDependencies(scriptIndex, classIndex, isStatic, customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
|
||||
DependencyParser.parseDependenciesFromMultiname(customNs, abc, dependencies, uses, abc.constants.getMultiname(type_index), getPackage(abc), fullyQualifiedNames, DependencyType.SIGNATURE);
|
||||
super.getDependencies(scriptIndex, classIndex, isStatic, customNs, abc, dependencies, ignorePackage, fullyQualifiedNames);
|
||||
DependencyParser.parseDependenciesFromMultiname(customNs, abc, dependencies, abc.constants.getMultiname(type_index), getPackage(abc), fullyQualifiedNames, DependencyType.SIGNATURE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -298,9 +298,9 @@ public class Traits implements Cloneable, Serializable {
|
||||
}
|
||||
}
|
||||
|
||||
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
public void getDependencies(int scriptIndex, int classIndex, boolean isStatic, String customNs, ABC abc, List<Dependency> dependencies, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames) throws InterruptedException {
|
||||
for (Trait t : traits) {
|
||||
t.getDependencies(scriptIndex, classIndex, isStatic, customNs, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
|
||||
t.getDependencies(scriptIndex, classIndex, isStatic, customNs, abc, dependencies, ignorePackage, fullyQualifiedNames);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,15 @@ import com.jpexs.decompiler.flash.abc.avm2.AVM2Code;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.AVM2Deobfuscation;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.alchemy.AlchemyTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.ConstructPropIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.construction.NewFunctionIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.FindPropertyStrictIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetLexIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetPropertyIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.GetSuperIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetPropertyIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.other.SetSuperIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.AsTypeIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.instructions.types.CoerceIns;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.InitVectorAVM2Item;
|
||||
@@ -41,16 +46,36 @@ import java.util.List;
|
||||
|
||||
public class DependencyParser {
|
||||
|
||||
public static void parseDependenciesFromNS(String ignoredCustom, ABC abc, List<Dependency> dependencies, List<String> uses, int namespace_index, DottedChain ignorePackage, String name, DependencyType dependencyType) {
|
||||
public static void parseDependenciesFromNS(String ignoredCustom, ABC abc, List<Dependency> dependencies, int namespace_index, DottedChain ignorePackage, String name, DependencyType dependencyType) {
|
||||
Namespace ns = abc.constants.getNamespace(namespace_index);
|
||||
if (name.isEmpty()) {
|
||||
name = "*";
|
||||
}
|
||||
DottedChain newimport = ns.getName(abc.constants);
|
||||
|
||||
if (parseUsagesFromNS(ignoredCustom, abc, dependencies, uses, namespace_index, ignorePackage, name)) {
|
||||
return;
|
||||
} else if (ns.kind != Namespace.KIND_PACKAGE) { // && (ns.kind != Namespace.KIND_PACKAGE_INTERNAL)) {
|
||||
|
||||
if (ns.kind == Namespace.KIND_NAMESPACE || ns.kind == Namespace.KIND_PACKAGE_INTERNAL) {
|
||||
String nsVal = ns.getName(abc.constants).toRawString();
|
||||
for (ABCContainerTag abcTag : abc.getAbcTags()) {
|
||||
DottedChain nsimport = abcTag.getABC().nsValueToName(nsVal);
|
||||
if (nsimport.equals(AVM2Deobfuscation.BUILTIN)) {
|
||||
return; //builtin, no dependency
|
||||
}
|
||||
if (!nsimport.isEmpty()) {
|
||||
|
||||
Dependency depNs = new Dependency(nsimport, DependencyType.NAMESPACE);
|
||||
if ((ignorePackage == null || !nsimport.getWithoutLast().equals(ignorePackage)) && !dependencies.contains(depNs)) {
|
||||
dependencies.add(depNs);
|
||||
}
|
||||
if (ignoredCustom != null && nsVal.equals(ignoredCustom)) {
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ns.kind != Namespace.KIND_PACKAGE) { // && (ns.kind != Namespace.KIND_PACKAGE_INTERNAL)) {
|
||||
return;
|
||||
}
|
||||
newimport = newimport.addWithSuffix(name);
|
||||
@@ -68,15 +93,15 @@ public class DependencyParser {
|
||||
//}
|
||||
}
|
||||
|
||||
public static void parseDependenciesFromMultiname(String ignoredCustom, ABC abc, List<Dependency> dependencies, List<String> uses, Multiname m, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames, DependencyType dependencyType) {
|
||||
public static void parseDependenciesFromMultiname(String ignoredCustom, ABC abc, List<Dependency> dependencies, Multiname m, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames, DependencyType dependencyType) {
|
||||
if (m != null) {
|
||||
if (m.kind == Multiname.TYPENAME) {
|
||||
if (m.qname_index != 0) {
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames, dependencyType);
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames, dependencyType);
|
||||
}
|
||||
for (Integer i : m.params) {
|
||||
if (i != 0) {
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames, dependencyType);
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames, dependencyType);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -85,35 +110,35 @@ public class DependencyParser {
|
||||
String name = m.getName(abc.constants, fullyQualifiedNames, true, true);
|
||||
NamespaceSet nss = m.getNamespaceSet(abc.constants);
|
||||
if (ns != null) {
|
||||
parseDependenciesFromNS(ignoredCustom, abc, dependencies, uses, m.namespace_index, ignorePackage, name, dependencyType);
|
||||
parseDependenciesFromNS(ignoredCustom, abc, dependencies, m.namespace_index, ignorePackage, name, dependencyType);
|
||||
}
|
||||
if (nss != null) {
|
||||
for (int n : nss.namespaces) {
|
||||
parseDependenciesFromNS(ignoredCustom, abc, dependencies, uses, n, ignorePackage, nss.namespaces.length > 1 ? "" : name, dependencyType);
|
||||
parseDependenciesFromNS(ignoredCustom, abc, dependencies, n, ignorePackage, nss.namespaces.length > 1 ? "" : name, dependencyType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseDependenciesFromMethodInfo(Trait trait, int scriptIndex, int classIndex, boolean isStatic, String ignoredCustom, ABC abc, int method_index, List<Dependency> dependencies, List<String> uses, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames, List<Integer> visitedMethods) throws InterruptedException {
|
||||
public static void parseDependenciesFromMethodInfo(Trait trait, int scriptIndex, int classIndex, boolean isStatic, String ignoredCustom, ABC abc, int method_index, List<Dependency> dependencies, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames, List<Integer> visitedMethods) throws InterruptedException {
|
||||
if ((method_index < 0) || (method_index >= abc.method_info.size())) {
|
||||
return;
|
||||
}
|
||||
visitedMethods.add(method_index);
|
||||
if (abc.method_info.get(method_index).ret_type != 0) {
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(abc.method_info.get(method_index).ret_type), ignorePackage, fullyQualifiedNames, DependencyType.SIGNATURE);
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, abc.constants.getMultiname(abc.method_info.get(method_index).ret_type), ignorePackage, fullyQualifiedNames, DependencyType.SIGNATURE);
|
||||
}
|
||||
for (int t : abc.method_info.get(method_index).param_types) {
|
||||
if (t != 0) {
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(t), ignorePackage, fullyQualifiedNames, DependencyType.SIGNATURE);
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, abc.constants.getMultiname(t), ignorePackage, fullyQualifiedNames, DependencyType.SIGNATURE);
|
||||
}
|
||||
}
|
||||
MethodBody body = abc.findBody(method_index);
|
||||
if (body != null && body.convertException == null) {
|
||||
body = body.convertMethodBodyCanUseLast(Configuration.autoDeobfuscate.get(), "", isStatic, scriptIndex, classIndex, abc, trait);
|
||||
body.traits.getDependencies(scriptIndex, classIndex, isStatic, ignoredCustom, abc, dependencies, uses, ignorePackage, fullyQualifiedNames);
|
||||
body.traits.getDependencies(scriptIndex, classIndex, isStatic, ignoredCustom, abc, dependencies, ignorePackage, fullyQualifiedNames);
|
||||
for (ABCException ex : body.exceptions) {
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(ex.type_index), ignorePackage, fullyQualifiedNames, DependencyType.EXPRESSION /* or signature?*/);
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, abc.constants.getMultiname(ex.type_index), ignorePackage, fullyQualifiedNames, DependencyType.EXPRESSION /* or signature?*/);
|
||||
}
|
||||
for (AVM2Instruction ins : body.getCode().code) {
|
||||
if (ins.definition instanceof AlchemyTypeIns) {
|
||||
@@ -126,93 +151,20 @@ public class DependencyParser {
|
||||
if (ins.definition instanceof NewFunctionIns) {
|
||||
if (ins.operands[0] != method_index) {
|
||||
if (!visitedMethods.contains(ins.operands[0])) {
|
||||
parseDependenciesFromMethodInfo(trait, scriptIndex, classIndex, isStatic, ignoredCustom, abc, ins.operands[0], dependencies, uses, ignorePackage, fullyQualifiedNames, visitedMethods);
|
||||
parseDependenciesFromMethodInfo(trait, scriptIndex, classIndex, isStatic, ignoredCustom, abc, ins.operands[0], dependencies, ignorePackage, fullyQualifiedNames, visitedMethods);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((ins.definition instanceof FindPropertyStrictIns)
|
||||
|| (ins.definition instanceof FindPropertyIns)
|
||||
|| (ins.definition instanceof GetLexIns)
|
||||
|| (ins.definition instanceof CoerceIns)
|
||||
|| (ins.definition instanceof AsTypeIns)) {
|
||||
int m = ins.operands[0];
|
||||
if (m != 0) {
|
||||
for (int k = 0; k < ins.definition.operands.length; k++) {
|
||||
if (ins.definition.operands[k] == AVM2Code.DAT_MULTINAME_INDEX) {
|
||||
int m = ins.operands[k];
|
||||
if (m < abc.constants.getMultinameCount()) {
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(m), ignorePackage, fullyQualifiedNames, DependencyType.EXPRESSION);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int k = 0; k < ins.definition.operands.length; k++) {
|
||||
if (ins.definition.operands[k] == AVM2Code.DAT_MULTINAME_INDEX) {
|
||||
int multinameIndex = ins.operands[k];
|
||||
if (multinameIndex < abc.constants.getMultinameCount()) {
|
||||
parseUsagesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(multinameIndex), ignorePackage, fullyQualifiedNames, DependencyType.EXPRESSION);
|
||||
}
|
||||
parseDependenciesFromMultiname(ignoredCustom, abc, dependencies, abc.constants.getMultiname(m), ignorePackage, fullyQualifiedNames, DependencyType.EXPRESSION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void parseUsagesFromMultiname(String ignoredCustom, ABC abc, List<Dependency> dependencies, List<String> uses, Multiname m, DottedChain ignorePackage, List<DottedChain> fullyQualifiedNames, DependencyType dependencyType) {
|
||||
if (m != null) {
|
||||
if (m.kind == Multiname.TYPENAME) {
|
||||
if (m.qname_index != 0) {
|
||||
parseUsagesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(m.qname_index), ignorePackage, fullyQualifiedNames, dependencyType);
|
||||
}
|
||||
for (Integer i : m.params) {
|
||||
if (i != 0) {
|
||||
parseUsagesFromMultiname(ignoredCustom, abc, dependencies, uses, abc.constants.getMultiname(i), ignorePackage, fullyQualifiedNames, dependencyType);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
Namespace ns = m.getNamespace(abc.constants);
|
||||
String name = m.getName(abc.constants, fullyQualifiedNames, false, true);
|
||||
NamespaceSet nss = m.getNamespaceSet(abc.constants);
|
||||
if (ns != null) {
|
||||
parseUsagesFromNS(ignoredCustom, abc, dependencies, uses, m.namespace_index, ignorePackage, name);
|
||||
}
|
||||
if (nss != null) {
|
||||
if (nss.namespaces.length == 1) {
|
||||
parseUsagesFromNS(ignoredCustom, abc, dependencies, uses, nss.namespaces[0], ignorePackage, name);
|
||||
} else {
|
||||
for (int n : nss.namespaces) {
|
||||
parseUsagesFromNS(ignoredCustom, abc, dependencies, uses, n, ignorePackage, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean parseUsagesFromNS(String ignoredCustom, ABC abc, List<Dependency> dependencies, List<String> uses, int namespace_index, DottedChain ignorePackage, String name) {
|
||||
Namespace ns = abc.constants.getNamespace(namespace_index);
|
||||
|
||||
if (ns.kind == Namespace.KIND_NAMESPACE || ns.kind == Namespace.KIND_PACKAGE_INTERNAL) {
|
||||
String nsVal = ns.getName(abc.constants).toRawString();
|
||||
for (ABCContainerTag abcTag : abc.getAbcTags()) {
|
||||
DottedChain nsimport = abcTag.getABC().nsValueToName(nsVal);
|
||||
if (nsimport.equals(AVM2Deobfuscation.BUILTIN)) {
|
||||
return true; //handled, but import/use not added
|
||||
}
|
||||
if (!nsimport.isEmpty()) {
|
||||
|
||||
Dependency depNs = new Dependency(nsimport, DependencyType.NAMESPACE);
|
||||
if ((ignorePackage == null || !nsimport.getWithoutLast().equals(ignorePackage)) && !dependencies.contains(depNs)) {
|
||||
dependencies.add(depNs);
|
||||
}
|
||||
if (ignoredCustom != null && nsVal.equals(ignoredCustom)) {
|
||||
return true;
|
||||
}
|
||||
if (!uses.contains(nsimport.getLast())) {
|
||||
uses.add(nsimport.getLast());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -163,11 +163,9 @@ public class LinkReportExporter {
|
||||
reportTrait(scriptIndex, externalDefs, existingObjects, swf, abc, it);
|
||||
}
|
||||
List<Dependency> dependencies = new ArrayList<>();
|
||||
List<String> uses = new ArrayList<>();
|
||||
|
||||
sb.append(indent(3)).append("<dep id=\"AS3\" />").append(newLineChar); //Automatic
|
||||
|
||||
tc.getDependencies(scriptIndex, -1, false, null, abc, dependencies, uses, new DottedChain(new String[]{"FAKE!PACKAGE"}), new ArrayList<>());
|
||||
tc.getDependencies(scriptIndex, -1, false, null, abc, dependencies, new DottedChain(new String[]{"FAKE!PACKAGE"}), new ArrayList<>());
|
||||
for (Dependency dependency : dependencies) {
|
||||
DottedChain dc = dependency.getId();
|
||||
if (!"*".equals(dc.getLast())) {
|
||||
|
||||
@@ -148,8 +148,7 @@ public class SwfToSwcExporter {
|
||||
sb.append(" <dep id=\"AS3\" type=\"").append(DEPENDENCY_NAMESPACE).append("\" />\n");
|
||||
if (!skipDependencies) {
|
||||
List<Dependency> dependencies = new ArrayList<>();
|
||||
List<String> uses = new ArrayList<>();
|
||||
pack.abc.script_info.get(pack.scriptIndex).traits.getDependencies(pack.scriptIndex, -1, false, null, pack.abc, dependencies, uses, new DottedChain(new String[]{"NO:PACKAGE"}), new ArrayList<>());
|
||||
pack.abc.script_info.get(pack.scriptIndex).traits.getDependencies(pack.scriptIndex, -1, false, null, pack.abc, dependencies, new DottedChain(new String[]{"NO:PACKAGE"}), new ArrayList<>());
|
||||
|
||||
for (Dependency d : dependencies) {
|
||||
if ("*".equals(d.getId().getLast())) {
|
||||
|
||||
Reference in New Issue
Block a user