Better multi packs handling (Alchemy) - direct editing allowed

Better package/class splitting for obfuscated names
This commit is contained in:
Jindra Petřík
2015-06-07 13:46:15 +02:00
parent 47578bd13f
commit 650aefede2
28 changed files with 3747 additions and 3623 deletions

View File

@@ -59,17 +59,21 @@ import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.helpers.utf8.Utf8PrintWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.collections.transformation.SortedList;
public class ABC {
@@ -107,7 +111,7 @@ public class ABC {
public ABCContainerTag parentTag;
/* Map from multiname index of namespace value to namespace name**/
private Map<String, String> namespaceMap;
private Map<String, DottedChain> namespaceMap;
public ABC(ABCContainerTag tag) {
this.parentTag = tag;
@@ -323,7 +327,7 @@ public class ABC {
int mIndex = body.getCode().code.get(ip).operands[0];
if (mIndex > 0) {
Multiname m = constants.getMultiname(mIndex);
if (m.getNameWithNamespace(constants, true).equals("flash.utils.getDefinitionByName")) {
if (m.getNameWithNamespace(constants).equals("flash.utils.getDefinitionByName")) {
if (ip > 0) {
if (body.getCode().code.get(ip - 1).definition instanceof PushStringIns) {
int strIndex = body.getCode().code.get(ip - 1).operands[0];
@@ -812,16 +816,16 @@ public class ABC {
}
}
private Map<String, String> getNamespaceMap() {
private Map<String, DottedChain> getNamespaceMap() {
if (namespaceMap == null) {
Map<String, String> map = new HashMap<>();
Map<String, DottedChain> map = new HashMap<>();
for (ScriptInfo si : script_info) {
for (Trait t : si.traits.traits) {
if (t instanceof TraitSlotConst) {
TraitSlotConst s = ((TraitSlotConst) t);
if (s.isNamespace()) {
String key = constants.getNamespace(s.value_index).getName(constants, true); // assume not null
String val = constants.getMultiname(s.name_index).getNameWithNamespace(constants, true);
DottedChain val = constants.getMultiname(s.name_index).getNameWithNamespace(constants);
map.put(key, val);
}
}
@@ -855,15 +859,15 @@ public class ABC {
return bodyIdxFromMethodIdx;
}
public String nsValueToName(String value) {
public DottedChain nsValueToName(String value) {
if (getNamespaceMap().containsKey(value)) {
return getNamespaceMap().get(value);
} else {
String ns = getDeobfuscation().builtInNs(value);
if (ns == null) {
return "";
return new DottedChain("");
} else {
return ns;
return new DottedChain(ns);
}
}
}
@@ -1037,8 +1041,8 @@ public class ABC {
public int findClassByName(String name) {
for (int c = 0; c < instance_info.size(); c++) {
String s = constants.getMultiname(instance_info.get(c).name_index).getNameWithNamespace(constants, true);
if (name.equals(s)) {
DottedChain s = constants.getMultiname(instance_info.get(c).name_index).getNameWithNamespace(constants);
if (name.equals(s.toString())) {
return c;
}
}
@@ -1229,31 +1233,54 @@ public class ABC {
method_info.remove(index);
}
public void replaceScriptPack(ScriptPack pack, String as) throws AVM2ParseException, CompilationException, IOException, InterruptedException {
public boolean replaceScriptPack(ScriptPack pack, String as) throws AVM2ParseException, CompilationException, IOException, InterruptedException {
String scriptName = pack.getPathScriptName() + ".as";
int oldIndex = pack.scriptIndex;
int newIndex = script_info.size();
String documentClass = getSwf().getDocumentClass();
boolean isDocumentClass = documentClass != null && documentClass.equals(pack.getClassPath().toString());
boolean isSimple = pack.isSimple;
ScriptInfo si = script_info.get(oldIndex);
si.delete(this, true);
int newClassIndex = instance_info.size();
for (Trait t : si.traits.traits) {
if (t instanceof TraitClass) {
TraitClass tc = (TraitClass) t;
newClassIndex = tc.class_info + 1;
if (isSimple) {
si.delete(this, true);
} else {
for (int t : pack.traitIndices) {
si.traits.traits.get(t).delete(this, true);
}
}
int newClassIndex = instance_info.size();
for (int t : pack.traitIndices) {
if (si.traits.traits.get(t) instanceof TraitClass) {
TraitClass tc = (TraitClass) si.traits.traits.get(t);
newClassIndex = tc.class_info + 1;
}
}
List<ABC> otherAbcs = new ArrayList<>(pack.allABCs);
otherAbcs.remove(this);
ActionScriptParser.compile(as, this, otherAbcs, isDocumentClass, scriptName, newClassIndex);
// Move newly added script to its position
script_info.set(oldIndex, script_info.get(newIndex));
script_info.remove(newIndex);
if (isSimple) {
// Move newly added script to its position
script_info.set(oldIndex, script_info.get(newIndex));
script_info.remove(newIndex);
} else {
script_info.get(newIndex).setModified(true);
//Note: Is deleting traits safe?
List<Integer> todel = new ArrayList<>(new TreeSet<>(pack.traitIndices));
for (int i = todel.size() - 1; i >= 0; i--) {
si.traits.traits.remove((int) todel.get(i));
}
}
script_info.get(oldIndex).setModified(true);
pack(); // removes old classes/methods
((Tag) parentTag).setModified(true);
return !isSimple;
}
public void pack() {

View File

@@ -61,6 +61,7 @@ public class ScriptPack extends AS3ClassTreeItem {
public final List<Integer> traitIndices;
private final ClassPath path;
public boolean isSimple = false;
@Override
public SWF getSwf() {

View File

@@ -85,7 +85,7 @@ public class DeclarationAVM2Item extends AVM2Item {
if (lti.value instanceof ConvertAVM2Item) {
coerType = ((ConvertAVM2Item) lti.value).type;
}
srcData.declaredType = (coerType instanceof TypeItem) ? ((TypeItem) coerType).fullTypeName : "*";
srcData.declaredType = (coerType instanceof TypeItem) ? ((TypeItem) coerType).fullTypeName.toPrintableString() : "*";
writer.append("var ");
writer.append(localName);
writer.append(":");
@@ -97,7 +97,7 @@ public class DeclarationAVM2Item extends AVM2Item {
SetSlotAVM2Item ssti = (SetSlotAVM2Item) assignment;
srcData.localName = ssti.getNameAsStr(localData);
srcData.declaration = true;
srcData.declaredType = (type instanceof TypeItem) ? ((TypeItem) type).fullTypeName : "*";
srcData.declaredType = (type instanceof TypeItem) ? ((TypeItem) type).fullTypeName.toPrintableString() : "*";
writer.append("var ");
ssti.getName(writer, localData);
writer.append(":");

View File

@@ -96,7 +96,7 @@ public class TryAVM2Item extends AVM2Item implements Block {
int eti = catchExceptions.get(e).type_index;
data.declaredType = eti <= 0 ? "*" : localData.constantsAvm2.constant_multiname.get(eti).getNameWithNamespace(localData.constantsAvm2, true);
data.declaredType = eti <= 0 ? "*" : localData.constantsAvm2.constant_multiname.get(eti).getNameWithNamespace(localData.constantsAvm2).toPrintableString();
writer.hilightSpecial(localName, HighlightSpecialType.TRY_NAME, e, data);
writer.append(":");
writer.hilightSpecial(catchExceptions.get(e).getTypeName(localData.constantsAvm2, localData.fullyQualifiedNames), HighlightSpecialType.TRY_TYPE, e);

View File

@@ -108,6 +108,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.Loop;
@@ -1194,7 +1195,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
return abc;
}
public void generateClass(List<String> importedClasses, List<AssignableAVM2Item> sinitVariables, boolean staticNeedsActivation, List<GraphTargetItem> staticInit, List<Integer> openedNamespaces, int namespace, int initScope, String pkg, ClassInfo classInfo, InstanceInfo instanceInfo, SourceGeneratorLocalData localData, boolean isInterface, String name, String superName, GraphTargetItem extendsVal, List<GraphTargetItem> implementsStr, GraphTargetItem constructor, List<GraphTargetItem> traitItems, Reference<Integer> class_index) throws AVM2ParseException, CompilationException {
public void generateClass(List<DottedChain> importedClasses, List<AssignableAVM2Item> sinitVariables, boolean staticNeedsActivation, List<GraphTargetItem> staticInit, List<Integer> openedNamespaces, int namespace, int initScope, String pkg, ClassInfo classInfo, InstanceInfo instanceInfo, SourceGeneratorLocalData localData, boolean isInterface, String name, String superName, GraphTargetItem extendsVal, List<GraphTargetItem> implementsStr, GraphTargetItem constructor, List<GraphTargetItem> traitItems, Reference<Integer> class_index) throws AVM2ParseException, CompilationException {
localData.currentClass = name;
localData.pkg = pkg;
List<GraphSourceItem> ret = new ArrayList<>();
@@ -1706,7 +1707,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
TraitSlotConst tsc = (TraitSlotConst) mbody.traits.traits.get(i);
GraphTargetItem type = TypeItem.UNBOUNDED;
if (tsc.type_index > 0) {
type = new TypeItem(abc.constants.constant_multiname.get(tsc.type_index).getNameWithNamespace(abc.constants, true));
type = new TypeItem(abc.constants.constant_multiname.get(tsc.type_index).getNameWithNamespace(abc.constants));
}
NameAVM2Item d = new NameAVM2Item(type, 0, tsc.getName(abc).getName(abc.constants, new ArrayList<>(), true), NameAVM2Item.getDefaultValue("" + type), true, new ArrayList<Integer>());
d.setSlotNumber(tsc.slot_id);
@@ -1867,7 +1868,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
return null;
}
private int genNs(List<String> importedClasses, String pkg, String custom, int namespace, List<Integer> openedNamespaces, SourceGeneratorLocalData localData, int line) throws CompilationException {
private int genNs(List<DottedChain> importedClasses, String pkg, String custom, int namespace, List<Integer> openedNamespaces, SourceGeneratorLocalData localData, int line) throws CompilationException {
if (custom != null) {
PropertyAVM2Item prop = new PropertyAVM2Item(null, custom, abc, allABCs, openedNamespaces, new ArrayList<MethodBody>());
Reference<ValueKind> value = new Reference<>(null);
@@ -1878,11 +1879,9 @@ public class AVM2SourceGenerator implements SourceGenerator {
}
if (!resolved) {
String customPkg = "";
String fullCustom = "";
for (String imp : importedClasses) {
if (imp.endsWith("." + custom)) {
customPkg = imp.substring(0, imp.lastIndexOf('.'));
DottedChain fullCustom = null;
for (DottedChain imp : importedClasses) {
if (imp.getLast().equals(custom)) {
fullCustom = imp;
break;
}
@@ -1895,7 +1894,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
for (ScriptInfo si : a.script_info) {
for (Trait t : si.traits.traits) {
Multiname m = t.getName(a);
if (fullCustom.equals(m.getNameWithNamespace(a.constants, true))) {
if (fullCustom != null && fullCustom.equals(m.getNameWithNamespace(a.constants))) {
if (t instanceof TraitSlotConst) {
if (((TraitSlotConst) t).isNamespace()) {
Namespace ns = a.constants.getNamespace(((TraitSlotConst) t).value_index);
@@ -1914,7 +1913,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
return namespace;
}
public void generateTraitsPhase2(List<String> importedClasses, String pkg, List<GraphTargetItem> items, Trait[] traits, List<Integer> openedNamespaces, SourceGeneratorLocalData localData) throws CompilationException {
public void generateTraitsPhase2(List<DottedChain> importedClasses, String pkg, List<GraphTargetItem> items, Trait[] traits, List<Integer> openedNamespaces, SourceGeneratorLocalData localData) throws CompilationException {
for (int k = 0; k < items.size(); k++) {
GraphTargetItem item = items.get(k);
if (traits[k] == null) {
@@ -2145,7 +2144,7 @@ public class AVM2SourceGenerator implements SourceGenerator {
ScriptInfo si = new ScriptInfo();
localData.currentScript = si;
Trait[] traitArr = generateTraitsPhase1(null, null, true, localData, commands, si.traits, class_index);
generateTraitsPhase2(new ArrayList<>(), null/*FIXME*/, commands, traitArr, new ArrayList<Integer>(), localData);
generateTraitsPhase2(new ArrayList<DottedChain>(), null/*FIXME*/, commands, traitArr, new ArrayList<Integer>(), localData);
MethodInfo mi = new MethodInfo(new int[0], 0, 0, 0, new ValueKind[0], new int[0]);
MethodBody mb = new MethodBody();
mb.method_info = abc.addMethodInfo(mi);
@@ -2457,12 +2456,9 @@ public class AVM2SourceGenerator implements SourceGenerator {
TypeItem type = (TypeItem) typeItem;
String name = type.fullTypeName;
String pkg = "";
if (name.contains(".")) {
pkg = name.substring(0, name.lastIndexOf('.'));
name = name.substring(name.lastIndexOf('.') + 1);
}
DottedChain dname = type.fullTypeName;
String pkg = dname.getWithoutLast().toString();
String name = dname.getLast();
for (InstanceInfo ii : abc.instance_info) {
Multiname mname = abc.constants.constant_multiname.get(ii.name_index);
if (mname != null && name.equals(mname.getName(abc.constants, new ArrayList<>(), true))) {

View File

@@ -86,6 +86,7 @@ import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.Loop;
import com.jpexs.decompiler.graph.TypeItem;
@@ -144,7 +145,7 @@ public class ActionScriptParser {
return uniqLast;
}
private List<GraphTargetItem> commands(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, Stack<Loop> loops, Map<Loop, String> loopLabels, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, int forinlevel, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private List<GraphTargetItem> commands(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, Stack<Loop> loops, Map<Loop, String> loopLabels, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, int forinlevel, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
List<GraphTargetItem> ret = new ArrayList<>();
if (debugMode) {
System.out.println("commands:");
@@ -159,7 +160,7 @@ public class ActionScriptParser {
return ret;
}
private GraphTargetItem type(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private GraphTargetItem type(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
ParsedSymbol s = lex();
if (s.type == SymbolType.MULTIPLY) {
return new UnboundedTypeItem();
@@ -174,7 +175,7 @@ public class ActionScriptParser {
return t;
}
private GraphTargetItem memberOrCall(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, GraphTargetItem newcmds, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private GraphTargetItem memberOrCall(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, GraphTargetItem newcmds, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
if (debugMode) {
System.out.println("memberOrCall:");
}
@@ -223,7 +224,7 @@ public class ActionScriptParser {
return ret;
}
private GraphTargetItem applyType(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, GraphTargetItem obj, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private GraphTargetItem applyType(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, GraphTargetItem obj, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
GraphTargetItem ret = obj;
ParsedSymbol s = lex();
if (s.type == SymbolType.TYPENAME) {
@@ -250,7 +251,7 @@ public class ActionScriptParser {
return ret;
}
private GraphTargetItem member(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, GraphTargetItem obj, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private GraphTargetItem member(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, GraphTargetItem obj, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
if (debugMode) {
System.out.println("member:");
}
@@ -286,7 +287,7 @@ public class ActionScriptParser {
s = lex();
GraphTargetItem ns = null;
if (s.type == SymbolType.NAMESPACE_OP) {
ns = new UnresolvedAVM2Item(new ArrayList<GraphTargetItem>(), importedClasses, false, null, lexer.yyline(), propName, null, openedNamespaces);
ns = new UnresolvedAVM2Item(new ArrayList<GraphTargetItem>(), importedClasses, false, null, lexer.yyline(), new DottedChain(propName), null, openedNamespaces);
variables.add((UnresolvedAVM2Item) ns);
s = lex();
if (s.type == SymbolType.BRACKET_OPEN) {
@@ -317,28 +318,31 @@ public class ActionScriptParser {
return ret;
}
private GraphTargetItem name(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, boolean typeOnly, List<Integer> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables, List<String> importedClasses) throws IOException, AVM2ParseException {
private GraphTargetItem name(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, boolean typeOnly, List<Integer> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables, List<DottedChain> importedClasses) throws IOException, AVM2ParseException {
ParsedSymbol s = lex();
String name = "";
DottedChain name = new DottedChain();
String name2 = "";
if (s.type == SymbolType.ATTRIBUTE) {
name += "@";
name2 += "@";
s = lex();
}
expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolType.STRING_OP);
name += s.value.toString();
name2 += s.value.toString();
s = lex();
boolean attrBracket = false;
name.parts.add(name2);
while (s.isType(SymbolType.DOT)) {
name += s.value.toString(); //. or ::
//name += s.value.toString(); //. or ::
s = lex();
name2 = "";
if (s.type == SymbolType.ATTRIBUTE) {
name += "@";
name2 += "@";
s = lex();
if (s.type == SymbolType.MULTIPLY) {
name += s.value.toString();
name2 += s.value.toString();
} else if (s.group == SymbolGroup.IDENTIFIER) {
name += s.value.toString();
name2 += s.value.toString();
} else {
if (s.type != SymbolType.BRACKET_OPEN) {
throw new AVM2ParseException("Attribute identifier or bracket expected", lexer.yyline());
@@ -348,19 +352,16 @@ public class ActionScriptParser {
}
} else {
expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE);
name += s.value.toString();
name2 += s.value.toString();
}
name.parts.add(name2);
s = lex();
}
String nsname = null;
String nsprop = null;
GraphTargetItem nspropItem = null;
if (s.type == SymbolType.NAMESPACE_OP) {
if (name.contains(".")) {
nsname = name.substring(name.lastIndexOf('.') + 1);
} else {
nsname = name;
}
nsname = name.getLast();
s = lex();
if (s.group == SymbolGroup.IDENTIFIER) {
nsprop = s.value.toString();
@@ -368,16 +369,12 @@ public class ActionScriptParser {
nspropItem = expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, true, variables);
expectedType(SymbolType.BRACKET_CLOSE);
}
if (name.contains(".")) {
name = name.substring(0, name.lastIndexOf('.'));
} else {
name = null;
}
name = name.getWithoutLast();
s = lex();
}
GraphTargetItem ret = null;
if (name != null) {
if (!name.parts.isEmpty()) {
UnresolvedAVM2Item unr = new UnresolvedAVM2Item(new ArrayList<GraphTargetItem>(), importedClasses, typeOnly, null, lexer.yyline(), name, null, openedNamespaces);
//unr.setIndex(index);
variables.add(unr);
@@ -388,7 +385,7 @@ public class ActionScriptParser {
if (attr) {
nsname = nsname.substring(1);
}
UnresolvedAVM2Item ns = new UnresolvedAVM2Item(new ArrayList<GraphTargetItem>(), importedClasses, typeOnly, null, lexer.yyline(), nsname, null, openedNamespaces);
UnresolvedAVM2Item ns = new UnresolvedAVM2Item(new ArrayList<GraphTargetItem>(), importedClasses, typeOnly, null, lexer.yyline(), new DottedChain(nsname), null, openedNamespaces);
variables.add(ns);
ret = new NamespacedAVM2Item(ns, nsprop, nspropItem, ret, attr, openedNamespaces, null);
}
@@ -443,7 +440,7 @@ public class ActionScriptParser {
return ret;
}
private List<GraphTargetItem> call(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private List<GraphTargetItem> call(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
List<GraphTargetItem> ret = new ArrayList<>();
//expected(SymbolType.PARENT_OPEN); //MUST BE HANDLED BY CALLER
ParsedSymbol s = lex();
@@ -458,12 +455,12 @@ public class ActionScriptParser {
return ret;
}
private MethodAVM2Item method(String pkg, boolean isInterface, String customAccess, Reference<Boolean> needsActivation, List<String> importedClasses, boolean override, boolean isFinal, TypeItem thisType, List<Integer> openedNamespaces, boolean isStatic, int namespace, String functionName, boolean isMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private MethodAVM2Item method(String pkg, boolean isInterface, String customAccess, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, boolean override, boolean isFinal, TypeItem thisType, List<Integer> openedNamespaces, boolean isStatic, int namespace, String functionName, boolean isMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
FunctionAVM2Item f = function(pkg, isInterface, needsActivation, importedClasses, namespace, thisType, openedNamespaces, functionName, isMethod, variables);
return new MethodAVM2Item(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(String pkg, boolean isInterface, Reference<Boolean> needsActivation, List<String> importedClasses, int namespace, TypeItem thisType, List<Integer> openedNamespaces, String functionName, boolean isMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private FunctionAVM2Item function(String pkg, boolean isInterface, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, int namespace, TypeItem thisType, List<Integer> openedNamespaces, String functionName, boolean isMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
openedNamespaces = new ArrayList<>(openedNamespaces); //local copy
int line = lexer.yyline();
ParsedSymbol s;
@@ -544,7 +541,7 @@ public class ActionScriptParser {
return new FunctionAVM2Item(pkg, isInterface, needsActivation2.getVal(), namespace, hasRest, line, functionName, paramTypes, paramNames, paramValues, body, subvariables, retType);
}
private GraphTargetItem traits(String scriptName, boolean scriptTraits, List<AssignableAVM2Item> sinitVariables, Reference<Boolean> sinitNeedsActivation, List<GraphTargetItem> staticInitializer, List<String> importedClasses, int privateNs, int protectedNs, int publicNs, int packageInternalNs, int protectedStaticNs, List<Integer> openedNamespaces, String pkg, String classNameStr, boolean isInterface, List<GraphTargetItem> traits) throws AVM2ParseException, IOException, CompilationException {
private GraphTargetItem traits(String scriptName, boolean scriptTraits, List<AssignableAVM2Item> sinitVariables, Reference<Boolean> sinitNeedsActivation, List<GraphTargetItem> staticInitializer, List<DottedChain> importedClasses, int privateNs, int protectedNs, int publicNs, int packageInternalNs, int protectedStaticNs, List<Integer> openedNamespaces, String pkg, String classNameStr, boolean isInterface, List<GraphTargetItem> traits) throws AVM2ParseException, IOException, CompilationException {
ParsedSymbol s;
GraphTargetItem constr = null;
TypeItem thisType = pkg == null && classNameStr == null ? null : new TypeItem(pkg == null || "".equals(pkg) ? classNameStr : pkg + "." + classNameStr);
@@ -892,7 +889,7 @@ public class ActionScriptParser {
return constr;
}
private GraphTargetItem classTraits(String scriptName, int gpublicNs, String pkg, List<String> importedClasses, boolean isDynamic, boolean isFinal, List<Integer> openedNamespaces, String packageName, int namespace, boolean isInterface, String nameStr, GraphTargetItem extendsStr, List<GraphTargetItem> implementsStr, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException, CompilationException {
private GraphTargetItem classTraits(String scriptName, int gpublicNs, String pkg, List<DottedChain> importedClasses, boolean isDynamic, boolean isFinal, List<Integer> openedNamespaces, String packageName, int namespace, boolean isInterface, String nameStr, GraphTargetItem extendsStr, List<GraphTargetItem> implementsStr, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException, CompilationException {
GraphTargetItem ret = null;
@@ -1049,7 +1046,7 @@ public class ActionScriptParser {
}
}
private List<GraphTargetItem> xmltag(TypeItem thisType, String pkg, Reference<Boolean> usesVars, List<String> openedTags, Reference<Integer> closedVarTags, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private List<GraphTargetItem> xmltag(TypeItem thisType, String pkg, Reference<Boolean> usesVars, List<String> openedTags, Reference<Integer> closedVarTags, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
ParsedSymbol s = null;
List<GraphTargetItem> rets = new ArrayList<>();
//GraphTargetItem ret = null;
@@ -1178,7 +1175,7 @@ public class ActionScriptParser {
return rets;
}
private GraphTargetItem xml(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private GraphTargetItem xml(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
List<String> openedTags = new ArrayList<>();
int closedVarTags = 0;
@@ -1189,7 +1186,7 @@ public class ActionScriptParser {
return ret;
}
private GraphTargetItem command(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, Stack<Loop> loops, Map<Loop, String> loopLabels, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, int forinlevel, boolean mustBeCommand, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private GraphTargetItem command(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, Stack<Loop> loops, Map<Loop, String> loopLabels, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, int forinlevel, boolean mustBeCommand, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
LexBufferer buf = new LexBufferer();
lexer.addListener(buf);
GraphTargetItem ret = null;
@@ -1672,7 +1669,7 @@ public class ActionScriptParser {
}
private GraphTargetItem expression(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private GraphTargetItem expression(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
return expression(thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, allowRemainder, variables);
}
@@ -1704,7 +1701,7 @@ public class ActionScriptParser {
return ret;
}
/*private GraphTargetItem expressionRemainder(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<Integer> openedNamespaces, GraphTargetItem expr, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List<AssignableAVM2Item> variables, List<String> importedClasses) throws IOException, AVM2ParseException {
/*private GraphTargetItem expressionRemainder(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<Integer> openedNamespaces, GraphTargetItem expr, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List<AssignableAVM2Item> variables, List<DottedChain> importedClasses) throws IOException, AVM2ParseException {
GraphTargetItem ret = null;
ParsedSymbol s = lex();
@@ -1740,7 +1737,7 @@ public class ActionScriptParser {
return false;
}
private int brackets(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, List<GraphTargetItem> ret, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private int brackets(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, List<GraphTargetItem> ret, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
ParsedSymbol s = lex();
int arrCnt = 0;
if (s.type == SymbolType.BRACKET_OPEN) {
@@ -1764,7 +1761,7 @@ public class ActionScriptParser {
return arrCnt;
}
private GraphTargetItem commaExpression(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, Stack<Loop> loops, Map<Loop, String> loopLabels, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, int forInLevel, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private GraphTargetItem commaExpression(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, Stack<Loop> loops, Map<Loop, String> loopLabels, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, int forInLevel, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
GraphTargetItem cmd = null;
List<GraphTargetItem> expr = new ArrayList<>();
ParsedSymbol s;
@@ -1786,7 +1783,7 @@ public class ActionScriptParser {
return new CommaExpressionItem(null, expr);
}
private GraphTargetItem expression(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, boolean allowEmpty, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private GraphTargetItem expression(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, boolean allowEmpty, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
GraphTargetItem prim = expressionPrimary(thisType, pkg, needsActivation, importedClasses, openedNamespaces, allowEmpty, registerVars, inFunction, inMethod, allowRemainder, variables);
if (prim == null) {
return null;
@@ -1816,7 +1813,7 @@ public class ActionScriptParser {
return lookahead;
}
private GraphTargetItem expression1(GraphTargetItem lhs, int min_precedence, TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, boolean allowEmpty, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private GraphTargetItem expression1(GraphTargetItem lhs, int min_precedence, TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, boolean allowEmpty, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
if (debugMode) {
System.out.println("expression1:");
}
@@ -2029,7 +2026,7 @@ public class ActionScriptParser {
return lhs;
}
private GraphTargetItem expressionPrimary(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<String> importedClasses, List<Integer> openedNamespaces, boolean allowEmpty, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
private GraphTargetItem expressionPrimary(TypeItem thisType, String pkg, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<Integer> openedNamespaces, boolean allowEmpty, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List<AssignableAVM2Item> variables) throws IOException, AVM2ParseException {
if (debugMode) {
System.out.println("primary:");
}
@@ -2279,39 +2276,34 @@ public class ActionScriptParser {
s = lex();
}
List<String> importedClasses = new ArrayList<>();
List<DottedChain> importedClasses = new ArrayList<>();
s = lex();
while (s.type == SymbolType.IMPORT) {
String impPackage = "";
String impName = null;
boolean all = false;
s = lex();
expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER);
impName = s.value.toString();
DottedChain imp = new DottedChain();
imp.parts.add(s.value.toString());
s = lex();
boolean isStar = false;
while (s.type == SymbolType.DOT) {
if (!"".equals(impPackage)) {
impPackage += ".";
}
impPackage += impName;
s = lex();
if (s.type == SymbolType.MULTIPLY) {
impName = null;
isStar = true;
s = lex();
break;
}
expected(s, lexer.yyline(), SymbolGroup.IDENTIFIER);
impName = s.value.toString();
imp.parts.add(s.value.toString());
s = lex();
}
if (impName == null) {
openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(impPackage, true)), 0, true));
if (isStar) {
openedNamespaces.add(abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId(imp.toString(), true)), 0, true));
} else {
importedClasses.add(impPackage + "." + impName);
importedClasses.add(imp);
}
expected(s, lexer.yyline(), SymbolType.SEMICOLON);
@@ -2349,7 +2341,7 @@ public class ActionScriptParser {
openedNamespaces.add(publicNs = abc.constants.getNamespaceId(new Namespace(Namespace.KIND_PACKAGE, abc.constants.getStringId("", true)), 0, true));
List<GraphTargetItem> items = new ArrayList<>();
traits(fileName, true, new ArrayList<AssignableAVM2Item>(), new Reference<>(false), new ArrayList<GraphTargetItem>(), new ArrayList<>(), scriptPrivateNs, 0, publicNs, 0, 0, openedNamespaces, null, null, false, items);
traits(fileName, true, new ArrayList<AssignableAVM2Item>(), new Reference<>(false), new ArrayList<GraphTargetItem>(), new ArrayList<DottedChain>(), scriptPrivateNs, 0, publicNs, 0, 0, openedNamespaces, null, null, false, items);
return items;
}

View File

@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.abc.avm2.parser.script;
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.Block;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.model.ContinueItem;
import com.jpexs.decompiler.graph.model.LocalData;
@@ -54,7 +55,7 @@ public class ClassAVM2Item extends AVM2Item implements Block {
public List<AssignableAVM2Item> sinitVariables;
public List<String> importedClasses;
public List<DottedChain> importedClasses;
public String pkg;
@@ -67,7 +68,7 @@ public class ClassAVM2Item extends AVM2Item implements Block {
return ret;
}
public ClassAVM2Item(List<String> importedClasses, String pkg, List<Integer> openedNamespaces, int protectedNs, boolean isDynamic, boolean isFinal, int namespace, String className, GraphTargetItem extendsOp, List<GraphTargetItem> implementsOp, List<GraphTargetItem> staticInit, boolean staticInitActivation, List<AssignableAVM2Item> sinitVariables, GraphTargetItem constructor, List<GraphTargetItem> traits) {
public ClassAVM2Item(List<DottedChain> importedClasses, String pkg, List<Integer> openedNamespaces, int protectedNs, boolean isDynamic, boolean isFinal, int namespace, String className, GraphTargetItem extendsOp, List<GraphTargetItem> implementsOp, List<GraphTargetItem> staticInit, boolean staticInitActivation, List<AssignableAVM2Item> sinitVariables, GraphTargetItem constructor, List<GraphTargetItem> traits) {
super(null, NOPRECEDENCE);
this.importedClasses = importedClasses;
this.pkg = pkg;

View File

@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.abc.avm2.parser.script;
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.model.LocalData;
import com.jpexs.decompiler.graph.model.UnboundedTypeItem;
@@ -43,9 +44,9 @@ public class InterfaceAVM2Item extends AVM2Item {
public String pkg;
public List<String> importedClasses;
public List<DottedChain> importedClasses;
public InterfaceAVM2Item(List<String> importedClasses, String pkg, List<Integer> openedNamespaces, boolean isFinal, int namespace, String name, List<GraphTargetItem> superInterfaces, List<GraphTargetItem> traits) {
public InterfaceAVM2Item(List<DottedChain> importedClasses, String pkg, List<Integer> openedNamespaces, boolean isFinal, int namespace, String name, List<GraphTargetItem> superInterfaces, List<GraphTargetItem> traits) {
super(null, NOPRECEDENCE);
this.importedClasses = importedClasses;
this.pkg = pkg;

View File

@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.abc.avm2.parser.script;
import com.jpexs.decompiler.flash.abc.avm2.model.AVM2Item;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.model.LocalData;
import com.jpexs.decompiler.graph.model.UnboundedTypeItem;
@@ -34,11 +35,11 @@ public class PackageAVM2Item extends AVM2Item {
public String packageName;
public List<String> importedClasses = new ArrayList<>();
public List<DottedChain> importedClasses = new ArrayList<>();
public int publicNs = 0;
public PackageAVM2Item(int publicNs, List<String> importedClasses, String packageName, List<GraphTargetItem> items) {
public PackageAVM2Item(int publicNs, List<DottedChain> importedClasses, String packageName, List<GraphTargetItem> items) {
super(null, NOPRECEDENCE);
this.publicNs = publicNs;
this.importedClasses = importedClasses;

View File

@@ -44,6 +44,7 @@ import com.jpexs.decompiler.flash.abc.types.traits.Trait;
import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.graph.CompilationException;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.GraphSourceItem;
import com.jpexs.decompiler.graph.GraphTargetItem;
import com.jpexs.decompiler.graph.SourceGenerator;
@@ -115,7 +116,7 @@ public class PropertyAVM2Item extends AssignableAVM2Item {
}
return new ApplyTypeAVM2Item(null, obj, params);
} else {
return new TypeItem(m.getNameWithNamespace(constants, true));
return new TypeItem(m.getNameWithNamespace(constants));
}
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.abc.avm2.parser.script;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.flash.SourceGeneratorLocalData;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.instructions.AVM2Instruction;
@@ -48,7 +49,7 @@ import java.util.List;
*/
public class UnresolvedAVM2Item extends AssignableAVM2Item {
private String name;
private DottedChain name;
private int nsKind = -1;
@@ -65,7 +66,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
private final boolean mustBeType;
public List<String> importedClasses;
public List<DottedChain> importedClasses;
public List<GraphTargetItem> scopeStack = new ArrayList<>();
@@ -128,7 +129,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
*/
public void appendName(String name) {
this.name += "." + name;
this.name.parts.add(name);
}
public void setDefinition(boolean definition) {
@@ -150,15 +151,15 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
this.assignedValue = storeValue;
}
public String getVariableName() {
public DottedChain getVariableName() {
return name;
}
public void setVariableName(String name) {
public void setVariableName(DottedChain name) {
this.name = name;
}
public UnresolvedAVM2Item(List<GraphTargetItem> subtypes, List<String> importedClasses, boolean mustBeType, GraphTargetItem type, int line, String name, GraphTargetItem storeValue, List<Integer> openedNamespaces) {
public UnresolvedAVM2Item(List<GraphTargetItem> subtypes, List<DottedChain> importedClasses, boolean mustBeType, GraphTargetItem type, int line, DottedChain name, GraphTargetItem storeValue, List<Integer> openedNamespaces) {
super(storeValue);
this.name = name;
this.assignedValue = storeValue;
@@ -264,7 +265,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
if (resolved != null) {
return resolved.toString();
}
return name;
return name.toString();
}
@Override
@@ -290,14 +291,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
}
public GraphTargetItem resolve(GraphTargetItem thisType, List<GraphTargetItem> paramTypes, List<String> paramNames, ABC abc, List<ABC> otherAbcs, List<MethodBody> callStack, List<AssignableAVM2Item> variables) throws CompilationException {
List<String> parts = new ArrayList<>();
if (name.contains(".")) {
String[] partsArr = name.split("\\.");
parts.addAll(Arrays.asList(partsArr));
} else {
parts.add(name);
}
List<String> parts = name.parts;
if (scopeStack.isEmpty()) { //Everything is multiname property in with command
//search for variable
@@ -326,13 +320,9 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
}
}
//Search for types in imported classes
for (String imp : importedClasses) {
String impName = imp;
String impPkg = "";
if (impName.contains(".")) {
impPkg = impName.substring(0, impName.lastIndexOf('.'));
impName = impName.substring(impName.lastIndexOf('.') + 1);
}
for (DottedChain imp : importedClasses) {
String impName = imp.getLast();
if (impName.equals(parts.get(0))) {
TypeItem ret = new TypeItem(imp);
resolved = ret;
@@ -354,13 +344,13 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
allAbcs.add(abc);
allAbcs.addAll(otherAbcs);
for (int i = 0; i < parts.size(); i++) {
String fname = Helper.joinStrings(parts.subList(0, i + 1), ".");
DottedChain fname = new DottedChain(parts.subList(0, i + 1)); //Helper.joinStrings(parts.subList(0, i + 1), ".");
for (ABC a : allAbcs) {
for (int c = 0; c < a.instance_info.size(); c++) {
if (a.instance_info.get(c).deleted) {
continue;
}
if (a.instance_info.get(c).name_index > 0 && fname.equals(a.instance_info.get(c).getName(a.constants).getNameWithNamespace(a.constants, true))) {
if (a.instance_info.get(c).name_index > 0 && fname.equals(a.instance_info.get(c).getName(a.constants).getNameWithNamespace(a.constants))) {
if (!subtypes.isEmpty() && parts.size() > i + 1) {
continue;
}
@@ -400,7 +390,7 @@ public class UnresolvedAVM2Item extends AssignableAVM2Item {
if (!subtypes.isEmpty() && parts.size() > 1) {
continue;
}
TypeItem ret = new TypeItem(a.instance_info.get(c).getName(a.constants).getNameWithNamespace(a.constants, true));
TypeItem ret = new TypeItem(a.instance_info.get(c).getName(a.constants).getNameWithNamespace(a.constants));
/*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);

View File

@@ -1,140 +1,140 @@
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.types;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.helpers.Helper;
import java.util.ArrayList;
import java.util.List;
public class InstanceInfo {
public int name_index;
public int super_index;
public int flags; // 1 = sealed, 0 = dynamic, 2 = final, 4 = interface, 8 = ProtectedNs
public int protectedNS; //if flags & 8
public int[] interfaces;
public int iinit_index; // MethodInfo - constructor
public Traits instance_traits;
public static final int CLASS_SEALED = 1; //not dynamic
public static final int CLASS_FINAL = 2;
public static final int CLASS_INTERFACE = 4;
public static final int CLASS_PROTECTEDNS = 8;
@Internal
public boolean deleted;
public InstanceInfo() {
instance_traits = new Traits();
}
public InstanceInfo(Traits traits) {
instance_traits = traits;
}
@Override
public String toString() {
return "name_index=" + name_index + " super_index=" + super_index + " flags=" + flags + " protectedNS=" + protectedNS + " interfaces=" + Helper.intArrToString(interfaces) + " method_index=" + iinit_index + "\r\n" + instance_traits.toString();
}
public String toString(ABC abc, List<String> fullyQualifiedNames) {
String supIndexStr = "[nothing]";
if (super_index > 0) {
supIndexStr = abc.constants.getMultiname(super_index).toString(abc.constants, fullyQualifiedNames);
}
return "name_index=" + abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " super_index=" + supIndexStr + " flags=" + flags + " protectedNS=" + protectedNS + " interfaces=" + Helper.intArrToString(interfaces) + " method_index=" + iinit_index + "\r\n" + instance_traits.toString(abc, fullyQualifiedNames);
}
public GraphTextWriter getClassHeaderStr(GraphTextWriter writer, ABC abc, List<String> fullyQualifiedNames, boolean allowPrivate) {
String modifiers;
Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants);
modifiers = ns.getPrefix(abc);
if (!allowPrivate && modifiers.equals("private")) {
modifiers = "";
}
if (!modifiers.isEmpty()) {
modifiers += " ";
}
if (isFinal()) {
modifiers += "final ";
}
if (!isInterface() && isDynamic()) {
modifiers += "dynamic ";
}
String objType = "class ";
if (isInterface()) {
objType = "interface ";
}
writer.appendNoHilight(modifiers + objType);
writer.hilightSpecial(abc.constants.getMultiname(name_index).getName(abc.constants, new ArrayList<>()/* No full names here*/, false), HighlightSpecialType.CLASS_NAME);
if (super_index > 0) {
String typeName = abc.constants.getMultiname(super_index).getNameWithNamespace(abc.constants, true);
writer.appendNoHilight(" extends ");
writer.hilightSpecial(abc.constants.getMultiname(super_index).getName(abc.constants, fullyQualifiedNames, false), HighlightSpecialType.TYPE_NAME, typeName);
}
if (interfaces.length > 0) {
if (isInterface()) {
writer.appendNoHilight(" extends ");
} else {
writer.appendNoHilight(" implements ");
}
for (int i = 0; i < interfaces.length; i++) {
if (i > 0) {
writer.append(", ");
}
String typeName = abc.constants.getMultiname(interfaces[i]).getNameWithNamespace(abc.constants, true);
writer.hilightSpecial(abc.constants.getMultiname(interfaces[i]).getName(abc.constants, fullyQualifiedNames, false), HighlightSpecialType.TYPE_NAME, typeName);
}
}
return writer;
}
public Multiname getName(AVM2ConstantPool constants) {
return constants.getMultiname(name_index);
}
public boolean isInterface() {
return ((flags & CLASS_INTERFACE) == CLASS_INTERFACE);
}
public boolean isDynamic() {
return (flags & CLASS_SEALED) == 0;
}
public boolean isFinal() {
return (flags & CLASS_FINAL) == CLASS_FINAL;
}
}
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.types;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.abc.types.traits.Traits;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.hilight.HighlightSpecialType;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.helpers.Helper;
import java.util.ArrayList;
import java.util.List;
public class InstanceInfo {
public int name_index;
public int super_index;
public int flags; // 1 = sealed, 0 = dynamic, 2 = final, 4 = interface, 8 = ProtectedNs
public int protectedNS; //if flags & 8
public int[] interfaces;
public int iinit_index; // MethodInfo - constructor
public Traits instance_traits;
public static final int CLASS_SEALED = 1; //not dynamic
public static final int CLASS_FINAL = 2;
public static final int CLASS_INTERFACE = 4;
public static final int CLASS_PROTECTEDNS = 8;
@Internal
public boolean deleted;
public InstanceInfo() {
instance_traits = new Traits();
}
public InstanceInfo(Traits traits) {
instance_traits = traits;
}
@Override
public String toString() {
return "name_index=" + name_index + " super_index=" + super_index + " flags=" + flags + " protectedNS=" + protectedNS + " interfaces=" + Helper.intArrToString(interfaces) + " method_index=" + iinit_index + "\r\n" + instance_traits.toString();
}
public String toString(ABC abc, List<String> fullyQualifiedNames) {
String supIndexStr = "[nothing]";
if (super_index > 0) {
supIndexStr = abc.constants.getMultiname(super_index).toString(abc.constants, fullyQualifiedNames);
}
return "name_index=" + abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " super_index=" + supIndexStr + " flags=" + flags + " protectedNS=" + protectedNS + " interfaces=" + Helper.intArrToString(interfaces) + " method_index=" + iinit_index + "\r\n" + instance_traits.toString(abc, fullyQualifiedNames);
}
public GraphTextWriter getClassHeaderStr(GraphTextWriter writer, ABC abc, List<String> fullyQualifiedNames, boolean allowPrivate) {
String modifiers;
Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants);
modifiers = ns.getPrefix(abc);
if (!allowPrivate && modifiers.equals("private")) {
modifiers = "";
}
if (!modifiers.isEmpty()) {
modifiers += " ";
}
if (isFinal()) {
modifiers += "final ";
}
if (!isInterface() && isDynamic()) {
modifiers += "dynamic ";
}
String objType = "class ";
if (isInterface()) {
objType = "interface ";
}
writer.appendNoHilight(modifiers + objType);
writer.hilightSpecial(abc.constants.getMultiname(name_index).getName(abc.constants, new ArrayList<String>()/* No full names here*/, false), HighlightSpecialType.CLASS_NAME);
if (super_index > 0) {
String typeName = abc.constants.getMultiname(super_index).getNameWithNamespace(abc.constants).toPrintableString();
writer.appendNoHilight(" extends ");
writer.hilightSpecial(abc.constants.getMultiname(super_index).getName(abc.constants, fullyQualifiedNames, false), HighlightSpecialType.TYPE_NAME, typeName);
}
if (interfaces.length > 0) {
if (isInterface()) {
writer.appendNoHilight(" extends ");
} else {
writer.appendNoHilight(" implements ");
}
for (int i = 0; i < interfaces.length; i++) {
if (i > 0) {
writer.append(", ");
}
String typeName = abc.constants.getMultiname(interfaces[i]).getNameWithNamespace(abc.constants).toPrintableString();
writer.hilightSpecial(abc.constants.getMultiname(interfaces[i]).getName(abc.constants, fullyQualifiedNames, false), HighlightSpecialType.TYPE_NAME, typeName);
}
}
return writer;
}
public Multiname getName(AVM2ConstantPool constants) {
return constants.getMultiname(name_index);
}
public boolean isInterface() {
return ((flags & CLASS_INTERFACE) == CLASS_INTERFACE);
}
public boolean isDynamic() {
return (flags & CLASS_SEALED) == 0;
}
public boolean isFinal() {
return (flags & CLASS_FINAL) == CLASS_FINAL;
}
}

View File

@@ -310,7 +310,7 @@ public class MethodInfo {
}
String ptype = "*";
if (param_types[i] > 0) {
ptype = constants.getMultiname(param_types[i]).getNameWithNamespace(constants, false);
ptype = constants.getMultiname(param_types[i]).getNameWithNamespace(constants).toPrintableString();
}
HighlightData pdata = new HighlightData();

View File

@@ -19,7 +19,9 @@ package com.jpexs.decompiler.flash.abc.types;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
import com.jpexs.decompiler.flash.abc.avm2.AVM2ConstantPool;
import com.jpexs.decompiler.flash.types.annotations.Internal;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.helpers.Helper;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@@ -288,23 +290,28 @@ public class Multiname {
} else {
String name = constants.getString(name_index);
if (fullyQualifiedNames != null && fullyQualifiedNames.contains(name)) {
return getNameWithNamespace(constants, raw);
DottedChain dc = getNameWithNamespace(constants);
return raw ? dc.toString() : dc.toPrintableString();
}
return (isAttribute() ? "@" : "") + (raw ? name : IdentifiersDeobfuscation.printIdentifier(true, name));
}
}
public String getNameWithNamespace(AVM2ConstantPool constants, boolean raw) {
public DottedChain getNameWithNamespace(AVM2ConstantPool constants) {
StringBuilder ret = new StringBuilder();
Namespace ns = getNamespace(constants);
List<String> chain = new ArrayList<>();
if (ns != null) {
String nsname = ns.getName(constants, raw);
String nsname = ns.getName(constants, true);
if (nsname != null && !nsname.isEmpty()) {
ret.append(nsname).append(".");
String parts[] = nsname.split("\\.");
for (String p : parts) {
chain.add(p);
}
}
}
ret.append(getName(constants, null, raw));
return ret.toString();
chain.add(getName(constants, null, true));
return new DottedChain(chain);
}
public Namespace getNamespace(AVM2ConstantPool constants) {

View File

@@ -88,6 +88,9 @@ public class ScriptInfo {
}
}
}
if (ret.size() == 1) {
ret.get(0).isSimple = true;
}
return ret;
}

View File

@@ -1,200 +1,200 @@
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.types.traits;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.ClassPath;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.NulWriter;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.helpers.Helper;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public abstract class Trait implements Serializable {
private static final int[] EMPTY_METADATA_ARRAY = new int[0];
public int name_index;
public int kindType;
public int kindFlags;
public int[] metadata = EMPTY_METADATA_ARRAY;
public long fileOffset;
public byte[] bytes;
public static final int ATTR_Final = 0x1;
public static final int ATTR_Override = 0x2;
public static final int ATTR_Metadata = 0x4;
public static final int TRAIT_SLOT = 0;
public static final int TRAIT_METHOD = 1;
public static final int TRAIT_GETTER = 2;
public static final int TRAIT_SETTER = 3;
public static final int TRAIT_CLASS = 4;
public static final int TRAIT_FUNCTION = 5;
public static final int TRAIT_CONST = 6;
public abstract void delete(ABC abc, boolean d);
public String getModifiers(ABC abc, boolean isStatic) {
String ret = "";
if ((kindFlags & ATTR_Override) > 0) {
ret += "override";
}
Multiname m = getName(abc);
if (m != null) {
String nsname = "";
//if (abc.constants.getNamespace(m.namespace_index).kind == Namespace.KIND_NAMESPACE) {
{
for (ABCContainerTag abcTag : abc.getAbcTags()) {
if (m.namespace_index == -1) {
break;
}
nsname = abcTag.getABC().nsValueToName(abc.constants.getNamespace(m.namespace_index).getName(abc.constants, true));
if (nsname == null) {
break;
}
if (nsname.contains(".")) {
nsname = nsname.substring(nsname.lastIndexOf('.') + 1);
}
if (!nsname.isEmpty()) {
break;
}
}
}
Namespace ns = m.getNamespace(abc.constants);
if (nsname.contains(":")) {
nsname = "";
}
if ((!nsname.isEmpty()) && (!nsname.equals("-"))) {
} else {
if (ns != null) {
if (ns.kind == Namespace.KIND_NAMESPACE) {
nsname = ns.getName(abc.constants, true);
}
}
}
if (nsname != null && (!nsname.contains(":")) && (!nsname.isEmpty())) {
ret += " " + nsname;
}
if (ns != null) {
ret += " " + ns.getPrefix(abc);
}
}
if (isStatic) {
if ((this instanceof TraitSlotConst) && ((TraitSlotConst) this).isNamespace()) {
//static is automatic
} else {
ret += " static";
}
}
if ((kindFlags & ATTR_Final) > 0) {
if (!isStatic) {
ret += " final";
}
}
return ret.trim();
}
@Override
public String toString() {
return "name_index=" + name_index + " kind=" + kindType + " metadata=" + Helper.intArrToString(metadata);
}
public String toString(ABC abc, List<String> fullyQualifiedNames) {
return abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " kind=" + kindType + " metadata=" + Helper.intArrToString(metadata);
}
public GraphTextWriter toString(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
writer.appendNoHilight(abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " kind=" + kindType + " metadata=" + Helper.intArrToString(metadata));
return writer;
}
public void convert(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
}
public GraphTextWriter toStringPackaged(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) {
String nsname = ns.getName(abc.constants, false);
writer.appendNoHilight("package");
if (!nsname.isEmpty()) {
writer.appendNoHilight(" " + nsname); //assume not null name
}
writer.startBlock();
toString(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
writer.endBlock();
writer.newLine();
}
return writer;
}
public void convertPackaged(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) {
String nsname = ns.getName(abc.constants, false);
convert(parent, path + nsname, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
}
}
public GraphTextWriter toStringHeader(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
toString(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
return writer;
}
public void convertHeader(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
convert(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
}
public Multiname getName(ABC abc) {
if (name_index == 0) {
return null;
} else {
return abc.constants.getMultiname(name_index);
}
}
public abstract int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) throws InterruptedException;
public ClassPath getPath(ABC abc) {
Multiname name = getName(abc);
Namespace ns = name.getNamespace(abc.constants);
String packageName = ns.getName(abc.constants, false);
String objectName = name.getName(abc.constants, new ArrayList<>(), false);
return new ClassPath(packageName, objectName); //assume not null name
}
}
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.abc.types.traits;
import com.jpexs.decompiler.flash.abc.ABC;
import com.jpexs.decompiler.flash.abc.ClassPath;
import com.jpexs.decompiler.flash.abc.types.Multiname;
import com.jpexs.decompiler.flash.abc.types.Namespace;
import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.NulWriter;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.helpers.Helper;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public abstract class Trait implements Serializable {
private static final int[] EMPTY_METADATA_ARRAY = new int[0];
public int name_index;
public int kindType;
public int kindFlags;
public int[] metadata = EMPTY_METADATA_ARRAY;
public long fileOffset;
public byte[] bytes;
public static final int ATTR_Final = 0x1;
public static final int ATTR_Override = 0x2;
public static final int ATTR_Metadata = 0x4;
public static final int TRAIT_SLOT = 0;
public static final int TRAIT_METHOD = 1;
public static final int TRAIT_GETTER = 2;
public static final int TRAIT_SETTER = 3;
public static final int TRAIT_CLASS = 4;
public static final int TRAIT_FUNCTION = 5;
public static final int TRAIT_CONST = 6;
public abstract void delete(ABC abc, boolean d);
public String getModifiers(ABC abc, boolean isStatic) {
String ret = "";
if ((kindFlags & ATTR_Override) > 0) {
ret += "override";
}
Multiname m = getName(abc);
if (m != null) {
String nsname = "";
//if (abc.constants.getNamespace(m.namespace_index).kind == Namespace.KIND_NAMESPACE) {
{
for (ABCContainerTag abcTag : abc.getAbcTags()) {
if (m.namespace_index == -1) {
break;
}
nsname = abcTag.getABC().nsValueToName(abc.constants.getNamespace(m.namespace_index).getName(abc.constants, true)).toString();
if (nsname == null) {
break;
}
if (nsname.contains(".")) {
nsname = nsname.substring(nsname.lastIndexOf('.') + 1);
}
if (!nsname.isEmpty()) {
break;
}
}
}
Namespace ns = m.getNamespace(abc.constants);
if (nsname.contains(":")) {
nsname = "";
}
if ((!nsname.isEmpty()) && (!nsname.equals("-"))) {
} else {
if (ns != null) {
if (ns.kind == Namespace.KIND_NAMESPACE) {
nsname = ns.getName(abc.constants, true);
}
}
}
if (nsname != null && (!nsname.contains(":")) && (!nsname.isEmpty())) {
ret += " " + nsname;
}
if (ns != null) {
ret += " " + ns.getPrefix(abc);
}
}
if (isStatic) {
if ((this instanceof TraitSlotConst) && ((TraitSlotConst) this).isNamespace()) {
//static is automatic
} else {
ret += " static";
}
}
if ((kindFlags & ATTR_Final) > 0) {
if (!isStatic) {
ret += " final";
}
}
return ret.trim();
}
@Override
public String toString() {
return "name_index=" + name_index + " kind=" + kindType + " metadata=" + Helper.intArrToString(metadata);
}
public String toString(ABC abc, List<String> fullyQualifiedNames) {
return abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " kind=" + kindType + " metadata=" + Helper.intArrToString(metadata);
}
public GraphTextWriter toString(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
writer.appendNoHilight(abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " kind=" + kindType + " metadata=" + Helper.intArrToString(metadata));
return writer;
}
public void convert(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
}
public GraphTextWriter toStringPackaged(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) {
String nsname = ns.getName(abc.constants, false);
writer.appendNoHilight("package");
if (!nsname.isEmpty()) {
writer.appendNoHilight(" " + nsname); //assume not null name
}
writer.startBlock();
toString(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
writer.endBlock();
writer.newLine();
}
return writer;
}
public void convertPackaged(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
Namespace ns = abc.constants.getMultiname(name_index).getNamespace(abc.constants);
if ((ns.kind == Namespace.KIND_PACKAGE) || (ns.kind == Namespace.KIND_PACKAGE_INTERNAL)) {
String nsname = ns.getName(abc.constants, false);
convert(parent, path + nsname, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
}
}
public GraphTextWriter toStringHeader(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, GraphTextWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
toString(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
return writer;
}
public void convertHeader(Trait parent, String path, ABC abc, boolean isStatic, ScriptExportMode exportMode, int scriptIndex, int classIndex, NulWriter writer, List<String> fullyQualifiedNames, boolean parallel) throws InterruptedException {
convert(parent, path, abc, isStatic, exportMode, scriptIndex, classIndex, writer, fullyQualifiedNames, parallel);
}
public Multiname getName(ABC abc) {
if (name_index == 0) {
return null;
} else {
return abc.constants.getMultiname(name_index);
}
}
public abstract int removeTraps(int scriptIndex, int classIndex, boolean isStatic, ABC abc, String path) throws InterruptedException;
public ClassPath getPath(ABC abc) {
Multiname name = getName(abc);
Namespace ns = name.getNamespace(abc.constants);
String packageName = ns.getName(abc.constants, false);
String objectName = name.getName(abc.constants, new ArrayList<String>(), false);
return new ClassPath(packageName, objectName); //assume not null name
}
}

View File

@@ -37,6 +37,7 @@ import com.jpexs.decompiler.flash.exporters.modes.ScriptExportMode;
import com.jpexs.decompiler.flash.helpers.GraphTextWriter;
import com.jpexs.decompiler.flash.helpers.NulWriter;
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
import com.jpexs.decompiler.graph.DottedChain;
import com.jpexs.decompiler.graph.ScopeStack;
import com.jpexs.helpers.Helper;
import java.util.ArrayList;
@@ -90,57 +91,53 @@ public class TraitClass extends Trait implements TraitWithSlot {
return "Class " + abc.constants.getMultiname(name_index).toString(abc.constants, fullyQualifiedNames) + " slot=" + slot_id + " class_info=" + class_info + " metadata=" + Helper.intArrToString(metadata);
}
private boolean parseUsagesFromNS(ABC abc, List<String> imports, List<String> uses, int namespace_index, String ignorePackage, String name) {
private boolean parseUsagesFromNS(ABC abc, List<DottedChain> imports, List<String> uses, int namespace_index, String ignorePackage, String name) {
Namespace ns = abc.constants.getNamespace(namespace_index);
if (name.isEmpty()) {
name = "*";
}
String newimport = ns.getName(abc.constants, ns.kind == Namespace.KIND_NAMESPACE);
String nsname = ns.getName(abc.constants, ns.kind == Namespace.KIND_NAMESPACE);
DottedChain newimport = nsname == null ? new DottedChain() : new DottedChain(nsname.split("\\."));
/*if ((ns.kind != Namespace.KIND_PACKAGE)
&& (ns.kind != Namespace.KIND_NAMESPACE)
&& (ns.kind != Namespace.KIND_STATIC_PROTECTED)) {
return false;
}*/
/*if (ns.kind == Namespace.KIND_NAMESPACE)*/ {
String oldimport = newimport;
newimport = null;
DottedChain oldimport = newimport;
newimport = new DottedChain();
for (ABCContainerTag abcTag : abc.getAbcTags()) {
String newname = abcTag.getABC().nsValueToName(oldimport);
if (newname.equals("-")) {
DottedChain newname = abcTag.getABC().nsValueToName(oldimport == null ? null : oldimport.toString());
if (newname.toString().equals("-")) {
return true;
}
if (!newname.isEmpty()) {
if (!newname.toString().isEmpty()) {
newimport = newname;
break;
}
}
if (newimport == null) {
if (newimport.parts.isEmpty()) {
newimport = oldimport;
newimport += "." + name;
newimport.parts.add(name);
}
if (newimport != null && newimport.isEmpty()) {
newimport = null;
if (!newimport.parts.isEmpty() && newimport.toString().isEmpty()) {
newimport.parts.clear();
}
if (newimport != null) {
if (newimport.parts.isEmpty()) {
/* if(ns.kind==Namespace.KIND_PACKAGE){
newimport+=".*";
}*/
if (!imports.contains(newimport)) {
if (newimport.contains(":")) {
return true;
}
String pkg = "";
if (newimport.contains(".")) {
pkg = newimport.substring(0, newimport.lastIndexOf('.'));
}
String usname = newimport;
if (usname.contains(".")) {
usname = usname.substring(usname.lastIndexOf('.') + 1);
}
//??
/*if (newimport.contains(":")) {
return true;
}*/
DottedChain pkg = newimport.getWithoutLast();
String usname = newimport.getLast();
if (ns.kind == Namespace.KIND_PACKAGE) {
if (!pkg.equals(ignorePackage)) {
if (!pkg.equals("__AS3__.vec")) { //Automatic import
if (!pkg.toString().equals("__AS3__.vec")) { //Automatic import
imports.add(newimport);
}
}
@@ -162,38 +159,39 @@ public class TraitClass extends Trait implements TraitWithSlot {
return false;
}
private void parseImportsUsagesFromNS(ABC abc, List<String> imports, List<String> uses, int namespace_index, String ignorePackage, String name) {
private void parseImportsUsagesFromNS(ABC abc, List<DottedChain> imports, List<String> uses, int namespace_index, String ignorePackage, String name) {
Namespace ns = abc.constants.getNamespace(namespace_index);
if (name.isEmpty()) {
name = "*";
}
String newimport = ns.getName(abc.constants, false);
String niS = ns.getName(abc.constants, false);
DottedChain newimport = niS == null ? new DottedChain() : new DottedChain(niS.split("\\."));
if (parseUsagesFromNS(abc, imports, uses, namespace_index, ignorePackage, name)) {
return;
} else if ((ns.kind != Namespace.KIND_PACKAGE) && (ns.kind != Namespace.KIND_PACKAGE_INTERNAL)) {
return;
}
if (newimport == null) {
newimport = "";
}
//if (!newimport.equals("")) {
newimport += "." + name;
if (newimport.contains(":")) {
return;
if (newimport.parts.isEmpty()) {
newimport = new DottedChain("");
}
newimport.parts.add(name);
//WUT?
/*if (newimport.contains(":")) {
return;
}*/
if (!imports.contains(newimport)) {
String pkg = newimport.substring(0, newimport.lastIndexOf('.'));
if (pkg.equals("__AS3__.vec")) { //special case - is imported always
DottedChain pkg = newimport.getWithoutLast(); //.substring(0, newimport.lastIndexOf('.'));
if (pkg.toString().equals("__AS3__.vec")) { //special case - is imported always
return;
}
if (!pkg.equals(ignorePackage)) {
if (!pkg.toString().equals(ignorePackage)) {
imports.add(newimport);
}
}
//}
}
private void parseUsagesFromMultiname(ABC abc, List<String> imports, List<String> uses, Multiname m, String ignorePackage, List<String> fullyQualifiedNames) {
private void parseUsagesFromMultiname(ABC abc, List<DottedChain> imports, List<String> uses, Multiname m, String ignorePackage, List<String> fullyQualifiedNames) {
if (m != null) {
if (m.kind == Multiname.TYPENAME) {
if (m.qname_index != 0) {
@@ -224,7 +222,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
}
}
private void parseImportsUsagesFromMultiname(ABC abc, List<String> imports, List<String> uses, Multiname m, String ignorePackage, List<String> fullyQualifiedNames) {
private void parseImportsUsagesFromMultiname(ABC abc, List<DottedChain> imports, List<String> uses, Multiname m, String ignorePackage, List<String> fullyQualifiedNames) {
if (m != null) {
if (m.kind == Multiname.TYPENAME) {
if (m.qname_index != 0) {
@@ -251,7 +249,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
}
}
private void parseImportsUsagesFromMethodInfo(ABC abc, int method_index, List<String> imports, List<String> uses, String ignorePackage, List<String> fullyQualifiedNames, List<Integer> visitedMethods) {
private void parseImportsUsagesFromMethodInfo(ABC abc, int method_index, List<DottedChain> imports, List<String> uses, String ignorePackage, List<String> fullyQualifiedNames, List<Integer> visitedMethods) {
if ((method_index < 0) || (method_index >= abc.method_info.size())) {
return;
}
@@ -272,7 +270,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
}
for (AVM2Instruction ins : body.getCode().code) {
if (ins.definition instanceof AlchemyTypeIns) {
String nimport = AlchemyTypeIns.ALCHEMY_PACKAGE + "." + ins.definition.instructionName;
DottedChain nimport = new DottedChain((AlchemyTypeIns.ALCHEMY_PACKAGE + "." + ins.definition.instructionName).split("\\."));
if (!imports.contains(nimport)) {
imports.add(nimport);
}
@@ -306,13 +304,13 @@ public class TraitClass extends Trait implements TraitWithSlot {
}
}
private void parseImportsUsagesFromTraits(ABC abc, Traits ts, List<String> imports, List<String> uses, String ignorePackage, List<String> fullyQualifiedNames) {
private void parseImportsUsagesFromTraits(ABC abc, Traits ts, List<DottedChain> imports, List<String> uses, String ignorePackage, List<String> fullyQualifiedNames) {
for (Trait t : ts.traits) {
parseImportsUsagesFromTrait(abc, t, imports, uses, ignorePackage, fullyQualifiedNames);
}
}
private void parseImportsUsagesFromTrait(ABC abc, Trait t, List<String> imports, List<String> uses, String ignorePackage, List<String> fullyQualifiedNames) {
private void parseImportsUsagesFromTrait(ABC abc, Trait t, List<DottedChain> imports, List<String> uses, String ignorePackage, List<String> fullyQualifiedNames) {
if (t instanceof TraitMethodGetterSetter) {
TraitMethodGetterSetter tm = (TraitMethodGetterSetter) t;
parseImportsUsagesFromMultiname(abc, imports, uses, abc.constants.getMultiname(tm.name_index), ignorePackage, fullyQualifiedNames);
@@ -328,7 +326,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
}
}
private List<String> getImportsUsages(ABC abc, List<String> imports, List<String> uses, List<String> fullyQualifiedNames) {
private List<DottedChain> getImportsUsages(ABC abc, List<DottedChain> imports, List<String> uses, List<String> fullyQualifiedNames) {
//constructor
String packageName = abc.instance_info.get(class_info).getName(abc.constants).getNamespace(abc.constants).getName(abc.constants, false); //assume not null name
@@ -384,7 +382,7 @@ public class TraitClass extends Trait implements TraitWithSlot {
}
//imports
List<String> imports = new ArrayList<>();
List<DottedChain> imports = new ArrayList<>();
List<String> uses = new ArrayList<>();
getImportsUsages(abc, imports, uses, new ArrayList<>());
@@ -392,20 +390,16 @@ public class TraitClass extends Trait implements TraitWithSlot {
List<String> importnames = new ArrayList<>();
importnames.addAll(namesInThisPackage);
for (String ipath : imports) {
String name = ipath;
String pkg = "";
if (name.contains(".")) {
pkg = name.substring(0, name.lastIndexOf('.'));
name = name.substring(name.lastIndexOf('.') + 1);
}
if (importnames.contains(name) || ((!pkg.isEmpty()) && isBuiltInClass(name))) {
for (DottedChain ipath : imports) {
String name = ipath.getLast();
DottedChain pkg = ipath.getWithoutLast();
if (importnames.contains(name) || ((!pkg.toString().isEmpty()) && isBuiltInClass(name))) {
fullyQualifiedNames.add(name);
} else {
importnames.add(name);
}
}
/*List<String> imports2 = new ArrayList<>();
/*List<DottedChain> imports2 = new ArrayList<String>();
for (String path : imports) {
String name = path;
String pkg = "";
@@ -421,21 +415,23 @@ public class TraitClass extends Trait implements TraitWithSlot {
imports = imports2;*/
for (int i = 0; i < imports.size(); i++) {
String imp = imports.get(i);
String pkg = imp.substring(0, imp.lastIndexOf('.'));
String name = imp.substring(imp.lastIndexOf('.') + 1);
DottedChain imp = imports.get(i);
DottedChain pkg = imp.getWithoutLast(); //imp.substring(0, imp.lastIndexOf('.'));
String name = imp.getLast();//imp.substring(imp.lastIndexOf('.') + 1);
if (name.equals("*")) {
continue;
}
if (imports.contains(pkg + ".*")) {
DottedChain dAll = new DottedChain(pkg.parts);
dAll.parts.add("*");
if (imports.contains(dAll)) {
imports.remove(i);
i--;
}
}
boolean hasImport = false;
for (String imp : imports) {
if (!imp.startsWith(".")) {
for (DottedChain imp : imports) {
if (!imp.parts.get(0).isEmpty()) { //No imports from root package
writer.appendNoHilight("import " + imp + ";").newLine();
hasImport = true;
}

View File

@@ -30,6 +30,6 @@ public class ClassNameMultinameUsage extends InsideClassMultinameUsage implement
@Override
public String toString() {
return "class " + abc.constants.getMultiname(abc.instance_info.get(classIndex).name_index).getNameWithNamespace(abc.constants, false);
return "class " + abc.constants.getMultiname(abc.instance_info.get(classIndex).name_index).getNameWithNamespace(abc.constants).toPrintableString();
}
}

View File

@@ -36,7 +36,7 @@ public abstract class InsideClassMultinameUsage extends MultinameUsage {
@Override
public String toString() {
return "class " + abc.constants.getMultiname(abc.instance_info.get(classIndex).name_index).getNameWithNamespace(abc.constants, false);
return "class " + abc.constants.getMultiname(abc.instance_info.get(classIndex).name_index).getNameWithNamespace(abc.constants).toPrintableString();
}
public int getMultinameIndex() {

View File

@@ -0,0 +1,106 @@
/*
* Copyright (C) 2010-2015 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.graph;
import com.jpexs.decompiler.flash.IdentifiersDeobfuscation;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
*
* @author JPEXS
*/
public class DottedChain {
public List<String> parts = new ArrayList<>();
public DottedChain(List<String> parts) {
this.parts = new ArrayList<>(parts);
}
public DottedChain(String... parts) {
for (int i = 0; i < parts.length; i++) {
this.parts.add(parts[i]);
}
}
public String getLast() {
if (parts.isEmpty()) {
return "";
} else {
return parts.get(parts.size() - 1);
}
}
public DottedChain getWithoutLast() {
List<String> nparts = new ArrayList<>(parts);
if (!nparts.isEmpty()) {
nparts.remove(nparts.size() - 1);
}
return new DottedChain(nparts);
}
public String toPrintableString() {
String ret = "";
for (int i = 0; i < parts.size(); i++) {
if (i > 0) {
ret += ".";
}
ret += IdentifiersDeobfuscation.printIdentifier(true, parts.get(0));
}
return ret;
}
@Override
public String toString() {
String ret = "";
for (int i = 0; i < parts.size(); i++) {
if (i > 0) {
ret += ".";
}
ret += parts.get(i);
}
return ret;
}
@Override
public int hashCode() {
int hash = 3;
hash = 89 * hash + Objects.hashCode(this.parts);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof String) {
obj = new DottedChain(((String) obj).split("\\."));
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final DottedChain other = (DottedChain) obj;
if (!Objects.equals(this.parts, other.parts)) {
return false;
}
return true;
}
}

View File

@@ -31,33 +31,37 @@ import java.util.Objects;
* @author JPEXS
*/
public class TypeItem extends GraphTargetItem {
public static TypeItem BOOLEAN = new TypeItem("Boolean");
public static TypeItem STRING = new TypeItem("String");
public static TypeItem ARRAY = new TypeItem("Array");
public static UnboundedTypeItem UNBOUNDED = new UnboundedTypeItem();
public String fullTypeName;
public TypeItem(String fullTypeName) {
public DottedChain fullTypeName;
public TypeItem(String s) {
this(s == null ? new DottedChain() : new DottedChain(s.split("\\.")));
}
public TypeItem(DottedChain fullTypeName) {
this(fullTypeName, new ArrayList<GraphTargetItem>());
}
public TypeItem(String fullTypeName, List<GraphTargetItem> subtypes) {
public TypeItem(DottedChain fullTypeName, List<GraphTargetItem> subtypes) {
super(null, NOPRECEDENCE);
this.fullTypeName = fullTypeName;
}
@Override
public int hashCode() {
int hash = 7;
hash = 83 * hash + Objects.hashCode(this.fullTypeName);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
@@ -72,37 +76,33 @@ public class TypeItem extends GraphTargetItem {
}
return true;
}
@Override
public GraphTextWriter appendTo(GraphTextWriter writer, LocalData localData) throws InterruptedException {
if (localData.fullyQualifiedNames.contains(fullTypeName)) {
writer.hilightSpecial(IdentifiersDeobfuscation.printNamespace(localData.constantsAvm2 != null, fullTypeName), HighlightSpecialType.TYPE_NAME, fullTypeName);
writer.hilightSpecial(IdentifiersDeobfuscation.printNamespace(localData.constantsAvm2 != null, fullTypeName.toPrintableString()), HighlightSpecialType.TYPE_NAME, fullTypeName.toPrintableString());
} else {
String simpleName = fullTypeName;
if (simpleName.contains(".")) {
simpleName = simpleName.substring(simpleName.lastIndexOf('.') + 1);
}
writer.hilightSpecial(IdentifiersDeobfuscation.printNamespace(localData.constantsAvm2 != null, simpleName), HighlightSpecialType.TYPE_NAME, fullTypeName);
writer.hilightSpecial(IdentifiersDeobfuscation.printIdentifier(localData.constantsAvm2 != null, fullTypeName.getLast()), HighlightSpecialType.TYPE_NAME, fullTypeName.toPrintableString());
}
return writer;
}
@Override
public GraphTargetItem returnType() {
return this;
}
@Override
public boolean hasReturnValue() {
return true;
}
@Override
public String toString() {
return fullTypeName;
return fullTypeName.toString();
}
@Override
public List<GraphSourceItem> toSource(SourceGeneratorLocalData localData, SourceGenerator generator) throws CompilationException {
return generator.generate(localData, this);

File diff suppressed because it is too large Load Diff