AS highligter - support for obfuscated names

This commit is contained in:
Jindra Petřík
2025-06-11 21:07:25 +02:00
parent e594a96a39
commit b26791697c
13 changed files with 479 additions and 311 deletions

View File

@@ -26,6 +26,7 @@ import com.jpexs.decompiler.flash.simpleparser.Import;
import com.jpexs.decompiler.flash.simpleparser.LinkHandler;
import com.jpexs.decompiler.flash.simpleparser.MethodScope;
import com.jpexs.decompiler.flash.simpleparser.Namespace;
import com.jpexs.decompiler.flash.simpleparser.Path;
import com.jpexs.decompiler.flash.simpleparser.SimpleParseException;
import com.jpexs.decompiler.flash.simpleparser.SimpleParser;
import com.jpexs.decompiler.flash.simpleparser.TraitVarConstValueScope;
@@ -76,15 +77,15 @@ public class ActionScript3SimpleParser implements SimpleParser {
}
}
private String type(Reference<Variable> subTypeRef, List<SimpleParseException> errors, TypeItem thisType, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<NamespaceItem> openedNamespaces, List<VariableOrScope> variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
private Path type(Reference<Variable> subTypeRef, List<SimpleParseException> errors, TypeItem thisType, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<NamespaceItem> openedNamespaces, List<VariableOrScope> variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
ParsedSymbol s = lex();
subTypeRef.setVal(null);
if (s.type == SymbolType.MULTIPLY) {
variables.add(new Type(false, "*", s.position));
return "*";
variables.add(new Type(false, new Path("*"), s.position));
return new Path("*");
} else if (s.type == SymbolType.VOID) {
variables.add(new Type(false, "void", s.position));
return "void";
variables.add(new Type(false, new Path("void"), s.position));
return new Path("void");
} else {
lexer.pushback(s);
}
@@ -92,7 +93,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
boolean t = true;
List<VariableOrScope> nameVars = new ArrayList<>();
name(errors, thisType, needsActivation, openedNamespaces, null, false, false, true, nameVars, importedClasses, abc);
String ret = "*";
Path ret = new Path("*");
Variable nameVar = null;
if (!nameVars.isEmpty() && nameVars.get(nameVars.size() - 1) instanceof Variable) {
nameVar = (Variable) nameVars.get(nameVars.size() - 1);
@@ -144,7 +145,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
return ret;
}
private String memberOrCall(String lastVarName, List<SimpleParseException> errors, TypeItem thisType, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<NamespaceItem> openedNamespaces, boolean newcmds, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean isStatic, List<VariableOrScope> variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
private Path memberOrCall(Path lastVarName, List<SimpleParseException> errors, TypeItem thisType, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<NamespaceItem> openedNamespaces, boolean newcmds, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean isStatic, List<VariableOrScope> variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
if (debugMode) {
System.out.println("memberOrCall:");
}
@@ -168,7 +169,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
break;
case PARENT_OPEN:
call(errors, thisType, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, isStatic, variables, abc);
lastVarName += ".()";
lastVarName = lastVarName.add(Path.PATH_PARENTHESIS);
ret = true;
break;
case DESCENDANTS:
@@ -236,7 +237,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
return ret;
}
private String member(String lastVarName, List<SimpleParseException> errors, TypeItem thisType, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<NamespaceItem> openedNamespaces, boolean obj, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean isStatic, List<VariableOrScope> variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
private Path member(Path lastVarName, List<SimpleParseException> errors, TypeItem thisType, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, List<NamespaceItem> openedNamespaces, boolean obj, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean isStatic, List<VariableOrScope> variables, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
if (debugMode) {
System.out.println("member:");
}
@@ -261,13 +262,12 @@ public class ActionScript3SimpleParser implements SimpleParser {
ret = true;
s = lex();
} else if (s.type == SymbolType.BRACKET_OPEN) {
lastVarName += ".[]";
lastVarName = lastVarName.add(Path.PATH_BRACKETS);
expression(errors, thisType, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, isStatic, true, variables, false, abc);
expectedType(errors, SymbolType.BRACKET_CLOSE);
ret = true;
s = lex();
} else {
lastVarName += ".";
s = lex();
if (!expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.MULTIPLY)) {
break;
@@ -276,7 +276,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
int propPosition = s.position;
s = lex();
if (s.type == SymbolType.NAMESPACE_OP) {
variables.add(new Variable(false, propName, propPosition));
variables.add(new Variable(false, new Path(propName), propPosition));
s = lex();
if (s.type == SymbolType.BRACKET_OPEN) {
expression(errors, thisType, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, isStatic, true, variables, false, abc);
@@ -284,10 +284,10 @@ public class ActionScript3SimpleParser implements SimpleParser {
} else {
expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER);
}
lastVarName += propName + "::" + s.value.toString();
lastVarName = lastVarName.add(propName + "::" + s.value.toString());
variables.add(new Variable(false, lastVarName, s.position, null));
} else {
lastVarName += propName;
lastVarName = lastVarName.add(propName);
variables.add(new Variable(false, lastVarName, propPosition, null));
if (s.type == SymbolType.NAMESPACESUFFIX) {
//nsSuffix = "#" + s.value;
@@ -307,7 +307,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
return lastVarName;
}
private String name(List<SimpleParseException> errors, TypeItem thisType, Reference<Boolean> needsActivation, List<NamespaceItem> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean isStatic, List<VariableOrScope> variables, List<DottedChain> importedClasses, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
private Path name(List<SimpleParseException> errors, TypeItem thisType, Reference<Boolean> needsActivation, List<NamespaceItem> openedNamespaces, HashMap<String, Integer> registerVars, boolean inFunction, boolean inMethod, boolean isStatic, List<VariableOrScope> variables, List<DottedChain> importedClasses, ABC abc) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
ParsedSymbol s = lex();
String lastName = "";
@@ -316,7 +316,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
s = lex();
}
if (!expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolType.STRING_OP)) {
return "";
return new Path();
}
lastName += s.value.toString();
int identPos = s.position;
@@ -327,7 +327,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
lastName += "#" + s.value;
}
String fullName = lastName;
Path fullName = new Path(lastName);
while (s.isType(SymbolType.DOT)) {
variables.add(new Variable(false, fullName, identPos));
@@ -351,7 +351,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
}
} else {
if (!expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.NAMESPACE, SymbolType.MULTIPLY)) {
return "";
return new Path();
}
lastName = s.value.toString();
identPos = s.position;
@@ -361,14 +361,14 @@ public class ActionScript3SimpleParser implements SimpleParser {
lastName += "#" + s.value;
s = lex();
}
fullName += "." + lastName;
fullName = fullName.add(lastName);
}
if (s.type == SymbolType.NAMESPACE_OP) {
variables.add(new Namespace(false, lastName, identPos));
variables.add(new Namespace(false, new Path(lastName), identPos));
s = lex();
if (s.group == SymbolGroup.IDENTIFIER) {
String nsprop = s.value.toString();
variables.add(new Variable(false, fullName + "::" + nsprop, s.position));
variables.add(new Variable(false, fullName.getParent().add(fullName.getLast().toString() + "::" + nsprop), s.position));
} else if (s.type == SymbolType.BRACKET_OPEN) {
expression(errors, thisType, needsActivation, importedClasses, openedNamespaces, registerVars, inFunction, inMethod, isStatic, true, variables, false, abc);
expectedType(errors, SymbolType.BRACKET_CLOSE);
@@ -378,7 +378,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
variables.add(new Variable(false, fullName, identPos));
}
String ret = fullName;
Path ret = fullName;
if (s.type == SymbolType.BRACKET_OPEN) {
lexer.pushback(s);
if (attrBracket) {
@@ -449,18 +449,18 @@ public class ActionScript3SimpleParser implements SimpleParser {
}
}
private void method(List<SimpleParseException> errors, boolean outsidePackage, boolean isPrivate, boolean isInterface, boolean isNative, String customAccess, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, boolean override, boolean isFinal, TypeItem thisType, List<NamespaceItem> openedNamespaces, boolean isStatic, String functionName, boolean isMethod, List<VariableOrScope> variables, ABC abc, int methodNamePos, Reference<String> returnTypeRef, Reference<Variable> returnSubTypeRef) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
private void method(List<SimpleParseException> errors, boolean outsidePackage, boolean isPrivate, boolean isInterface, boolean isNative, String customAccess, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, boolean override, boolean isFinal, TypeItem thisType, List<NamespaceItem> openedNamespaces, boolean isStatic, Path functionName, boolean isMethod, List<VariableOrScope> variables, ABC abc, int methodNamePos, Reference<Path> returnTypeRef, Reference<Variable> returnSubTypeRef) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
function(errors, isInterface, isNative, needsActivation, importedClasses, thisType, openedNamespaces, functionName, isMethod, variables, abc, methodNamePos, isStatic, returnTypeRef, returnSubTypeRef);
}
private void function(List<SimpleParseException> errors, boolean isInterface, boolean isNative, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, TypeItem thisType, List<NamespaceItem> openedNamespaces, String functionName, boolean isMethod, List<VariableOrScope> variables, ABC abc, int functionNamePos, boolean isStatic, Reference<String> returnTypeRef, Reference<Variable> returnSubTypeRef) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
private void function(List<SimpleParseException> errors, boolean isInterface, boolean isNative, Reference<Boolean> needsActivation, List<DottedChain> importedClasses, TypeItem thisType, List<NamespaceItem> openedNamespaces, Path functionName, boolean isMethod, List<VariableOrScope> variables, ABC abc, int functionNamePos, boolean isStatic, Reference<Path> returnTypeRef, Reference<Variable> returnSubTypeRef) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
ParsedSymbol s;
expectedType(errors, SymbolType.PARENT_OPEN);
s = lex();
List<String> paramNames = new ArrayList<>();
List<Path> paramNames = new ArrayList<>();
List<Integer> paramPositions = new ArrayList<>();
List<String> paramTypes = new ArrayList<>();
List<Path> paramTypes = new ArrayList<>();
List<Variable> paramSubTypes = new ArrayList<>();
boolean hasRest = false;
@@ -477,7 +477,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
break;
}
paramNames.add(s.value.toString());
paramNames.add(new Path(s.value.toString()));
paramPositions.add(s.position);
s = lex();
if (!hasRest) {
@@ -487,7 +487,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
paramSubTypes.add(subTypeRef.getVal());
s = lex();
} else {
paramTypes.add("*");
paramTypes.add(new Path("*"));
paramSubTypes.add(null);
}
if (s.type == SymbolType.ASSIGN) {
@@ -514,25 +514,25 @@ public class ActionScript3SimpleParser implements SimpleParser {
if (s.type == SymbolType.COLON) {
returnTypeRef.setVal(type(returnSubTypeRef, errors, thisType, needsActivation, importedClasses, openedNamespaces, variables, abc));
} else {
returnTypeRef.setVal("*");
returnTypeRef.setVal(new Path("*"));
returnSubTypeRef.setVal(null);
lexer.pushback(s);
}
List<VariableOrScope> subvariables = new ArrayList<>();
if (!isMethod && functionName != null && !functionName.isEmpty()) {
subvariables.add(new Variable(true, functionName, functionNamePos));
subvariables.add(new Variable(true, new Path(functionName), functionNamePos));
}
for (int i = 0; i < paramNames.size() - (hasRest ? 1 : 0); i++) {
subvariables.add(new Variable(true, paramNames.get(i), paramPositions.get(i), null, paramTypes.get(i), null, paramSubTypes.get(i), null));
}
if (hasRest) {
subvariables.add(new Variable(true, paramNames.get(paramNames.size() - 1), paramPositions.get(paramNames.size() - 1), null, "Array", null));
subvariables.add(new Variable(true, paramNames.get(paramNames.size() - 1), paramPositions.get(paramNames.size() - 1), null, new Path("Array"), null));
}
Reference<Boolean> needsActivation2 = new Reference<>(false);
if (!isInterface && !isNative) {
s = lex();
expected(errors, s, lexer.yyline(), SymbolType.CURLY_OPEN);
subvariables.add(new Variable(true, "arguments", -s.position - 1, null, "Array", null));
subvariables.add(new Variable(true, new Path("arguments"), -s.position - 1, null, new Path("Array"), null));
commands(errors, thisType, needsActivation2, importedClasses, openedNamespaces, new Stack<>(), new HashMap<>(), new HashMap<>(), true, isMethod, isStatic, 0, subvariables, abc);
expectedType(errors, SymbolType.CURLY_CLOSE);
} else {
@@ -584,7 +584,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
lexer.pushback(s);
}
private void classTraits(List<SimpleParseException> errors, boolean outsidePackage, Reference<Boolean> cinitNeedsActivation, List<DottedChain> importedClasses, List<NamespaceItem> openedNamespaces, DottedChain pkg, String classNameStr, boolean isInterface, Reference<Boolean> iinitNeedsActivation, ABC abc, List<VariableOrScope> classVariables) throws AVM2ParseException, SimpleParseException, IOException, CompilationException, InterruptedException {
private void classTraits(List<SimpleParseException> errors, boolean outsidePackage, Reference<Boolean> cinitNeedsActivation, List<DottedChain> importedClasses, List<NamespaceItem> openedNamespaces, Path pkg, String classNameStr, boolean isInterface, Reference<Boolean> iinitNeedsActivation, ABC abc, List<VariableOrScope> classVariables) throws AVM2ParseException, SimpleParseException, IOException, CompilationException, InterruptedException {
Stack<Loop> cinitLoops = new Stack<>();
Map<Loop, String> cinitLoopLabels = new HashMap<>();
@@ -643,7 +643,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
isNative = true;
} else if (s.group == SymbolGroup.IDENTIFIER) {
customNs = s.value.toString();
classVariables.add(new Namespace(false, s.value.toString(), s.position));
classVariables.add(new Namespace(false, new Path(s.value.toString()), s.position));
if (isInterface) {
errors.add(new SimpleParseException("Namespace attributes are not permitted on interface methods", lexer.yyline(), s.position));
}
@@ -699,7 +699,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
s = lex();
}
String fullClassName = pkg.addWithSuffix(classNameStr).toPrintableString(true);
Path fullClassName = pkg.add(classNameStr);
switch (s.type) {
case FUNCTION:
s = lex();
@@ -713,24 +713,24 @@ public class ActionScript3SimpleParser implements SimpleParser {
if (!expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.PARENT_OPEN)) {
break;
}
String fname;
Path fname;
int fnamePos = s.position;
//fix for methods with name "get" or "set" - they are not getters/setters!
if (s.isType(SymbolType.PARENT_OPEN)) {
lexer.pushback(s);
if (isGetter) {
fname = "get";
fname = new Path("get");
//isGetter = false;
} else if (isSetter) {
fname = "set";
fname = new Path("set");
//isSetter = false;
} else {
errors.add(new SimpleParseException("Missing method name", lexer.yyline(), s.position));
break;
}
} else {
fname = s.value.toString();
fname = new Path(s.value.toString());
}
if (fname.equals(classNameStr)) { //constructor
if (isStatic) {
@@ -745,7 +745,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
if (isInterface) {
errors.add(new SimpleParseException("Interface cannot have constructor", lexer.yyline(), s.position));
}
method(errors, outsidePackage, isPrivate, false, false, customNs, iinitNeedsActivation, importedClasses, false, false, thisType, openedNamespaces, false, "", true, classVariables, abc, fnamePos, new Reference<>(null), new Reference<>(null));
method(errors, outsidePackage, isPrivate, false, false, customNs, iinitNeedsActivation, importedClasses, false, false, thisType, openedNamespaces, false, new Path(), true, classVariables, abc, fnamePos, new Reference<>(null), new Reference<>(null));
} else {
if (classNameStr == null) {
isStatic = true;
@@ -758,11 +758,11 @@ public class ActionScript3SimpleParser implements SimpleParser {
lexer.pushback(s);
}
Reference<String> returnTypeRef = new Reference<>(null);
Reference<Path> returnTypeRef = new Reference<>(null);
Reference<Variable> returnSubTypeRef = new Reference<>(null);
method(errors, outsidePackage, isPrivate, isInterface, isNative, customNs, new Reference<>(false), importedClasses, isOverride, isFinal, thisType, openedNamespaces, isStatic, fname, true, classVariables, abc, fnamePos, returnTypeRef, returnSubTypeRef);
traitVariables.add(new ClassTrait(fullClassName, fname, customNs, fnamePos, isStatic, "Function", returnTypeRef.getVal(), null, returnSubTypeRef.getVal()));
traitVariables.add(new ClassTrait(fullClassName, fname, customNs, fnamePos, isStatic, new Path("Function"), returnTypeRef.getVal(), null, returnSubTypeRef.getVal()));
/*
if (isGetter) {
@@ -793,10 +793,10 @@ public class ActionScript3SimpleParser implements SimpleParser {
if (!expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER)) {
break;
}
String nname = s.value.toString();
Path nname = new Path(s.value.toString());
int npos = s.position;
traitVariables.add(new ClassTrait(fullClassName, nname, customNs, npos, isStatic, "Namespace", null, null, null));
traitVariables.add(new ClassTrait(fullClassName, nname, customNs, npos, isStatic, new Path("Namespace"), null, null, null));
s = lex();
if (s.type == SymbolType.ASSIGN) {
@@ -836,13 +836,13 @@ public class ActionScript3SimpleParser implements SimpleParser {
}
Reference<Variable> subTypeRef = new Reference<>(null);
String traitType = "*";
Path traitType = new Path("*");
if (s.type == SymbolType.COLON) {
traitType = type(subTypeRef, errors, thisType, new Reference<>(false), importedClasses, openedNamespaces, classVariables, abc);
s = lex();
}
traitVariables.add(new ClassTrait(fullClassName, nameSymbol.value.toString(), customNs, nameSymbol.position, isStatic, traitType, "Function".equals(traitType) ? "*" : null, subTypeRef.getVal(), null));
traitVariables.add(new ClassTrait(fullClassName, new Path(nameSymbol.value.toString()), customNs, nameSymbol.position, isStatic, traitType, "Function".equals(traitType) ? new Path("*") : null, subTypeRef.getVal(), null));
if (s.type == SymbolType.ASSIGN) {
List<VariableOrScope> constVarVariables = new ArrayList<>();
@@ -879,7 +879,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
ABC abc,
Reference<Boolean> sinitNeedsActivation,
List<VariableOrScope> sinitVariables,
List<String> externalTypes
List<Path> externalTypes
) throws AVM2ParseException, SimpleParseException, IOException, CompilationException, InterruptedException {
Stack<Loop> sinitLoops = new Stack<>();
@@ -914,24 +914,27 @@ public class ActionScript3SimpleParser implements SimpleParser {
Map<Loop, String> sinitLoopLabels,
HashMap<String, Integer> sinitRegisterVars,
List<VariableOrScope> sinitVariables,
List<String> externalTypes
List<Path> externalTypes
) throws AVM2ParseException, SimpleParseException, SimpleParseException, IOException, CompilationException, InterruptedException {
ParsedSymbol s;
boolean inPackage = false;
s = lex();
DottedChain pkgName = DottedChain.TOPLEVEL;
DottedChain pkgNameDc = DottedChain.TOPLEVEL;
Path pkgName = new Path();
if (s.type == SymbolType.PACKAGE) {
s = lex();
if (s.type != SymbolType.CURLY_OPEN) {
expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER);
pkgName = pkgName.addWithSuffix(s.value.toString());
pkgNameDc = pkgNameDc.addWithSuffix(s.value.toString());
pkgName = pkgName.add(s.value.toString());
s = lex();
}
while (s.type == SymbolType.DOT) {
s = lex();
expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER);
pkgName = pkgName.addWithSuffix(s.value.toString());
pkgNameDc = pkgNameDc.addWithSuffix(s.value.toString());
pkgName = pkgName.add(s.value.toString());
s = lex();
}
expected(errors, s, lexer.yyline(), SymbolType.CURLY_OPEN);
@@ -942,8 +945,8 @@ public class ActionScript3SimpleParser implements SimpleParser {
allOpenedNamespaces.add(openedNamespaces);
for (String name : abc.getSwf().getAbcIndex().getPackageObjects(pkgName)) {
externalTypes.add(pkgName.add(name, "").toRawString());
for (String name : abc.getSwf().getAbcIndex().getPackageObjects(pkgNameDc)) {
externalTypes.add(pkgName.add(name));
}
List<VariableOrScope> sinitTraitVariables = new ArrayList<>();
@@ -1028,7 +1031,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
}
subNameStr = s.value.toString();
int subNamePos = s.position;
sinitTraitVariables.add(new Type(true, pkgName.addWithSuffix(subNameStr).toPrintableString(true), subNamePos));
sinitTraitVariables.add(new Type(true, pkgName.add(subNameStr), subNamePos));
s = lex();
if (s.type == SymbolType.NOT) {
@@ -1063,7 +1066,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
Reference<Boolean> cinitNeedsActivation = new Reference<>(false);
Reference<Boolean> iinitNeedsActivation = new Reference<>(false);
List<VariableOrScope> classVariables = new ArrayList<>();
classVariables.add(new Variable(true, "this", s.position, false, pkgName.add(subNameStr, null).toPrintableString(true), null));
classVariables.add(new Variable(true, new Path("this"), s.position, false, pkgName.add(subNameStr), null));
classTraits(errors, !inPackage, cinitNeedsActivation, importedClasses, subOpenedNamespaces, pkgName, subNameStr, isInterface, iinitNeedsActivation, abc, classVariables);
@@ -1077,11 +1080,11 @@ public class ActionScript3SimpleParser implements SimpleParser {
expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER);
String fname = s.value.toString();
Reference<String> returnTypeRef = new Reference<>(null);
Reference<Path> returnTypeRef = new Reference<>(null);
Reference<Variable> returnSubTypeRef = new Reference<>(null);
method(errors, !inPackage, false, false, isNative, null, new Reference<>(false), importedClasses, false, isFinal, null, openedNamespaces, true, "", true, sinitVariables, abc, s.position, returnTypeRef, returnSubTypeRef);
method(errors, !inPackage, false, false, isNative, null, new Reference<>(false), importedClasses, false, isFinal, null, openedNamespaces, true, new Path(""), true, sinitVariables, abc, s.position, returnTypeRef, returnSubTypeRef);
sinitTraitVariables.add(new Variable(true, fname, s.position, true, "Function", returnTypeRef.getVal(), null, returnSubTypeRef.getVal()));
sinitTraitVariables.add(new Variable(true, new Path(fname), s.position, true, new Path("Function"), returnTypeRef.getVal(), null, returnSubTypeRef.getVal()));
break;
case CONST:
case VAR:
@@ -1097,13 +1100,13 @@ public class ActionScript3SimpleParser implements SimpleParser {
}
ParsedSymbol traitSymb = s;
s = lex();
String traitType = "*";
Path traitType = new Path("*");
Reference<Variable> subTypeRef = new Reference<>(null);
if (s.type == SymbolType.COLON) {
traitType = type(subTypeRef, errors, null, new Reference<>(false), importedClasses, openedNamespaces, sinitVariables, abc);
s = lex();
}
sinitTraitVariables.add(new Variable(true, traitSymb.value.toString(), traitSymb.position, null, traitType, traitType.equals("Function") ? "*" : null, subTypeRef.getVal(), null));
sinitTraitVariables.add(new Variable(true, new Path(traitSymb.value.toString()), traitSymb.position, null, traitType, traitType.equals("Function") ? new Path("*") : null, subTypeRef.getVal(), null));
if (s.type == SymbolType.ASSIGN) {
expression(errors, null, new Reference<>(false), importedClasses, openedNamespaces, new HashMap<>(), false, false, true, true, sinitVariables, false, abc);
@@ -1122,7 +1125,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
if (!expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER)) {
break;
}
sinitTraitVariables.add(new Variable(true, s.value.toString(), s.position, null, "Namespace", null));
sinitTraitVariables.add(new Variable(true, new Path(s.value.toString()), s.position, null, new Path("Namespace"), null));
s = lex();
@@ -1329,7 +1332,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
s = lexer.lex();
expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER);
needsActivation.setVal(true);
function(errors, false, false, needsActivation, importedClasses, thisType, openedNamespaces, s.value.toString(), false, variables, abc, s.position, false, new Reference<>(null), new Reference<>(null));
function(errors, false, false, needsActivation, importedClasses, thisType, openedNamespaces, new Path(s.value.toString()), false, variables, abc, s.position, false, new Reference<>(null), new Reference<>(null));
ret = true;
break;
case VAR:
@@ -1338,10 +1341,10 @@ public class ActionScript3SimpleParser implements SimpleParser {
if (!expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER)) {
break;
}
String varIdentifier = s.value.toString();
Path varIdentifier = new Path(s.value.toString());
int varPos = s.position;
s = lex();
String varType = "*";
Path varType = new Path("*");
Reference<Variable> varSubTypeRef = new Reference<>(null);
if (s.type == SymbolType.COLON) {
varType = type(varSubTypeRef, errors, thisType, needsActivation, importedClasses, openedNamespaces, variables, abc);
@@ -1544,11 +1547,11 @@ public class ActionScript3SimpleParser implements SimpleParser {
if (!expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER, SymbolType.THIS, SymbolType.SUPER, SymbolType.STRING_OP)) {
break;
}
String enamestr = s.value.toString();
Path enamestr = new Path(s.value.toString());
int ePos = s.position;
expectedType(errors, SymbolType.COLON);
Reference<Variable> catchSubType = new Reference<>(null);
String catchType = type(catchSubType, errors, thisType, needsActivation, importedClasses, openedNamespaces, variables, abc);
Path catchType = type(catchSubType, errors, thisType, needsActivation, importedClasses, openedNamespaces, variables, abc);
expectedType(errors, SymbolType.PARENT_CLOSE);
List<VariableOrScope> catchVars = new ArrayList<>();
expectedType(errors, SymbolType.CURLY_OPEN);
@@ -1806,7 +1809,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
}
boolean ret = false;
ParsedSymbol s = lex();
String lastVarName = "";
Path lastVarName = new Path();
boolean allowMemberOrCall = false;
switch (s.type) {
case PREPROCESSOR:
@@ -1950,10 +1953,10 @@ public class ActionScript3SimpleParser implements SimpleParser {
break;
case FUNCTION:
s = lexer.lex();
String fname = "";
Path fname = new Path();
int fnamePos = -1;
if (s.isType(SymbolGroup.IDENTIFIER)) {
fname = s.value.toString();
fname = new Path(s.value.toString());
fnamePos = s.position;
} else {
lexer.pushback(s);
@@ -2035,10 +2038,10 @@ public class ActionScript3SimpleParser implements SimpleParser {
}
if (s.type == SymbolType.FUNCTION) {
s = lexer.lex();
String ffname = "";
Path ffname = new Path();
int ffnamePos = -1;
if (s.isType(SymbolGroup.IDENTIFIER)) {
ffname = s.value.toString();
ffname = new Path(s.value.toString());
ffnamePos = s.position;
} else {
lexer.pushback(s);
@@ -2097,7 +2100,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
private ActionScriptLexer lexer = null;
private boolean parseImportsUsages(List<SimpleParseException> errors, List<VariableOrScope> variables, List<DottedChain> importedClasses, List<NamespaceItem> openedNamespaces, ABC abc, List<String> externalTypes) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
private boolean parseImportsUsages(List<SimpleParseException> errors, List<VariableOrScope> variables, List<DottedChain> importedClasses, List<NamespaceItem> openedNamespaces, ABC abc, List<Path> externalTypes) throws IOException, AVM2ParseException, SimpleParseException, InterruptedException {
boolean isEmpty = true;
ParsedSymbol s;
@@ -2109,13 +2112,13 @@ public class ActionScript3SimpleParser implements SimpleParser {
isEmpty = false;
s = lex();
expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER);
String fullName = s.value.toString();
String lastName = s.value.toString();
Path fullName = new Path(s.value.toString());
Path lastName = new Path(s.value.toString());
s = lex();
boolean isStar = false;
int varPos = -1;
List<String> nameParts = new ArrayList<>();
nameParts.add(lastName);
nameParts.add(lastName.toString());
while (s.type == SymbolType.DOT) {
s = lex();
if (s.type == SymbolType.MULTIPLY) {
@@ -2124,16 +2127,16 @@ public class ActionScript3SimpleParser implements SimpleParser {
break;
}
expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER);
fullName = fullName + "." + s.value.toString();
lastName = s.value.toString();
fullName = fullName.add(s.value.toString());
lastName = new Path(s.value.toString());
varPos = s.position;
nameParts.add(lastName);
nameParts.add(s.value.toString());
s = lex();
}
if (isStar) {
for (String n : abc.getSwf().getAbcIndex().getPackageObjects(new DottedChain(nameParts))) {
externalTypes.add(fullName + "." + n);
externalTypes.add(fullName.add(n));
}
} else {
externalTypes.add(fullName);
@@ -2147,7 +2150,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
if (s.isType(SymbolType.NAMESPACE)) {
s = lex();
expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER);
String fullName = s.value.toString();
Path fullName = new Path(s.value.toString());
int lastPos = s.position;
s = lex();
while (s.type == SymbolType.DOT) {
@@ -2157,7 +2160,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
break;
}
expected(errors, s, lexer.yyline(), SymbolGroup.IDENTIFIER);
fullName = fullName + "." + s.value.toString();
fullName = fullName.add(s.value.toString());
lastPos = s.position;
s = lex();
}
@@ -2225,7 +2228,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
ABC abc,
Reference<Boolean> sinitNeedsActivation,
List<VariableOrScope> sinitVariables,
List<String> externalTypes
List<Path> externalTypes
) throws IOException, AVM2ParseException, SimpleParseException, CompilationException, InterruptedException {
scriptTraits(errors, importedClasses, openedNamespaces, allOpenedNamespaces, abc, sinitNeedsActivation, sinitVariables, externalTypes);
}
@@ -2255,7 +2258,7 @@ public class ActionScript3SimpleParser implements SimpleParser {
ABC abc,
Reference<Boolean> sinitNeedsActivation,
List<VariableOrScope> sinitVariables,
List<String> externalTypes
List<Path> externalTypes
) throws AVM2ParseException, SimpleParseException, IOException, CompilationException, InterruptedException {
lexer = new ActionScriptLexer(str);
@@ -2272,12 +2275,12 @@ public class ActionScript3SimpleParser implements SimpleParser {
Map<Integer, List<Integer>> definitionPosToReferences,
Map<Integer, Integer> referenceToDefinition,
List<SimpleParseException> errors,
List<String> externalTypes,
List<Path> externalTypes,
Map<Integer, Integer> referenceToExternalTypeIndex,
Map<Integer, List<Integer>> externalTypeIndexToReference,
LinkHandler linkHandler,
Map<Integer, String> referenceToExternalTraitKey,
Map<String, List<Integer>> externalTraitKeyToReference
Map<Integer, Path> referenceToExternalTraitKey,
Map<Path, List<Integer>> externalTraitKeyToReference
) throws SimpleParseException, IOException, InterruptedException {
List<List<NamespaceItem>> allOpenedNamespaces = new ArrayList<>();
Reference<Boolean> sinitNeedsActivation = new Reference<>(false);
@@ -2285,9 +2288,9 @@ public class ActionScript3SimpleParser implements SimpleParser {
List<DottedChain> importedClasses = new ArrayList<>();
List<NamespaceItem> openedNamespaces = new ArrayList<>();
for (String name : abc.getSwf().getAbcIndex().getPackageObjects(DottedChain.TOPLEVEL)) {
externalTypes.add(name);
externalTypes.add(new Path(name));
}
externalTypes.add("__AS3__.vec.Vector");
externalTypes.add(new Path("__AS3__", "vec", "Vector"));
try {
scriptTraitsFromString(errors, importedClasses, openedNamespaces, allOpenedNamespaces, str, abc, sinitNeedsActivation, vars, externalTypes);
} catch (AVM2ParseException ex) {

View File

@@ -23,6 +23,7 @@ import com.jpexs.decompiler.flash.simpleparser.ClassScope;
import com.jpexs.decompiler.flash.simpleparser.FunctionScope;
import com.jpexs.decompiler.flash.simpleparser.LinkHandler;
import com.jpexs.decompiler.flash.simpleparser.MethodScope;
import com.jpexs.decompiler.flash.simpleparser.Path;
import com.jpexs.decompiler.flash.simpleparser.SimpleParseException;
import com.jpexs.decompiler.flash.simpleparser.SimpleParser;
import com.jpexs.decompiler.flash.simpleparser.TraitVarConstValueScope;
@@ -75,24 +76,23 @@ public class ActionScript2SimpleParser implements SimpleParser {
}
}
private String type(List<SimpleParseException> errors, boolean definition, List<VariableOrScope> variables) throws IOException, InterruptedException, SimpleParseException, ActionParseException {
private Path type(List<SimpleParseException> errors, boolean definition, List<VariableOrScope> variables) throws IOException, InterruptedException, SimpleParseException, ActionParseException {
ParsedSymbol s = lex();
if (!expectedIdentifier(errors, s, lexer.yyline())) {
return null;
}
ParsedSymbol lastIdent = s;
Variable vret = new Variable(false, s.value.toString(), s.position);
Variable vret = new Variable(false, new Path(s.value.toString()), s.position);
variables.add(vret);
String ret = s.value.toString();
Path ret = new Path(s.value.toString());
s = lex();
while (s.type == SymbolType.DOT) {
ret += ".";
s = lex();
if (!expectedIdentifier(errors, s, lexer.yyline())) {
return null;
}
lastIdent = s;
ret += s.value.toString();
ret = ret.add(s.value.toString());
s = lex();
}
lexer.pushback(s);
@@ -162,11 +162,11 @@ public class ActionScript2SimpleParser implements SimpleParser {
return ret;
}
private FunctionScope function(List<SimpleParseException> errors, boolean withBody, String functionName, int functionNamePosition, boolean isMethod, List<VariableOrScope> variables, boolean inTellTarget, Reference<Boolean> hasEval, boolean isStatic) throws IOException, InterruptedException, SimpleParseException, ActionParseException {
private FunctionScope function(List<SimpleParseException> errors, boolean withBody, Path functionName, int functionNamePosition, boolean isMethod, List<VariableOrScope> variables, boolean inTellTarget, Reference<Boolean> hasEval, boolean isStatic) throws IOException, InterruptedException, SimpleParseException, ActionParseException {
ParsedSymbol s;
expectedType(errors, SymbolType.PARENT_OPEN);
s = lex();
List<String> paramNames = new ArrayList<>();
List<Path> paramNames = new ArrayList<>();
List<Integer> paramPositions = new ArrayList<>();
while (s.type != SymbolType.PARENT_CLOSE) {
@@ -175,7 +175,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
}
s = lex();
if (expectedIdentifier(errors, s, lexer.yyline())) {
paramNames.add(s.value.toString());
paramNames.add(new Path(s.value.toString()));
paramPositions.add(s.position);
}
s = lex();
@@ -217,7 +217,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
return new FunctionScope(subvariables, isStatic);
}
private boolean traits(List<SimpleParseException> errors, boolean isInterface, String className, List<VariableOrScope> variables, boolean inTellTarget, Reference<Boolean> hasEval) throws IOException, InterruptedException, SimpleParseException, ActionParseException {
private boolean traits(List<SimpleParseException> errors, boolean isInterface, Path className, List<VariableOrScope> variables, boolean inTellTarget, Reference<Boolean> hasEval) throws IOException, InterruptedException, SimpleParseException, ActionParseException {
ParsedSymbol s;
@@ -247,28 +247,28 @@ public class ActionScript2SimpleParser implements SimpleParser {
if (!expectedIdentifier(errors, s, lexer.yyline())) {
break;
}
String simpleClassName = className.contains(".") ? className.substring(className.lastIndexOf(".") + 1) : className;
if (!simpleClassName.equals(s.value.toString())) { //not constructor
traitVariables.add(new Variable(true, isStatic ? className + "." + s.value.toString() : "this." + s.value.toString(), s.position, isStatic));
}
Path simpleClassName = className.getLast();
if (!simpleClassName.equals(new Path(s.value.toString()))) { //not constructor
traitVariables.add(new Variable(true, isStatic ? className.add(s.value.toString()) : new Path("this", s.value.toString()), s.position, isStatic));
} else {
if (isStatic) {
errors.add(new SimpleParseException("Constructor cannot be static", lexer.yyline(), staticPos));
errors.add(new SimpleParseException("Constructor cannot be static", lexer.yyline(), staticPos));
}
}
if (!isInterface) {
variables.add(function(errors, !isInterface, isStatic ? className + "." + s.value.toString() : "this." + s.value.toString(), isStatic ? -1 : s.position, true, traitVariables, inTellTarget, hasEval, isStatic));
}
variables.add(function(errors, !isInterface, isStatic ? className.add(s.value.toString()) : new Path("this", s.value.toString()), isStatic ? -1 : s.position, true, traitVariables, inTellTarget, hasEval, isStatic));
}
break;
case VAR:
s = lex();
if (!expectedIdentifier(errors, s, lexer.yyline())) {
break;
}
traitVariables.add(new Variable(true, isStatic ? className + "." + s.value.toString() : "this." + s.value.toString(), s.position, isStatic));
traitVariables.add(new Variable(true, isStatic ? className.add(s.value.toString()) : new Path("this").add(s.value.toString()), s.position, isStatic));
s = lex();
if (s.type == SymbolType.COLON) {
type(errors, false, variables);
@@ -346,7 +346,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
case CHR:
case GETTIMER:
case TARGETPATH:
variables.add(new Variable(false, (String) s.value, s.position));
variables.add(new Variable(false, new Path("" + s.value), s.position));
break;
}
@@ -637,7 +637,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
s = lex();
if (s.type == SymbolType.DOT) {
lexer.pushback(s);
Variable vi = new Variable(false, sopn.value.toString(), sopn.position);
Variable vi = new Variable(false, new Path(sopn.value.toString()), sopn.position);
variables.add(vi);
ret = true;
} else {
@@ -652,7 +652,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
s = lex();
if (s.type == SymbolType.DOT) {
lexer.pushback(s);
Variable vi2 = new Variable(false, sop.value.toString(), sop.position);
Variable vi2 = new Variable(false, new Path(sop.value.toString()), sop.position);
variables.add(vi2);
ret = true;
} else {
@@ -782,7 +782,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
ret = true;
break;
case CLASS:
String className = type(errors, true, variables);
Path className = type(errors, true, variables);
if (className != null) {
s = lex();
if (s.type == SymbolType.EXTENDS) {
@@ -796,7 +796,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
} while (s.type == SymbolType.COMMA);
}
expected(errors, s, lexer.yyline(), SymbolType.CURLY_OPEN);
variables.add(new Variable(true, "this", s.position));
variables.add(new Variable(true, new Path("this"), s.position));
List<VariableOrScope> subVariables = new ArrayList<>();
traits(errors, false, className, subVariables, inTellTarget, hasEval);
ClassScope cs = new ClassScope(subVariables);
@@ -807,7 +807,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
}
break;
case INTERFACE:
String interfaceName = type(errors, true, variables);
Path interfaceName = type(errors, true, variables);
if (interfaceName != null) {
s = lex();
@@ -826,13 +826,13 @@ public class ActionScript2SimpleParser implements SimpleParser {
case FUNCTION:
s = lexer.lex();
if (expectedIdentifier(errors, s, lexer.yyline())) {
variables.add(function(errors, true, s.value.toString(), s.position, false, variables, inTellTarget, hasEval, false));
variables.add(function(errors, true, new Path(s.value.toString()), s.position, false, variables, inTellTarget, hasEval, false));
}
break;
case VAR:
s = lex();
if (expectedIdentifier(errors, s, lexer.yyline())) {
String varIdentifier = s.value.toString();
Path varIdentifier = new Path(s.value.toString());
int varPosition = s.position;
s = lex();
if (s.type == SymbolType.COLON) {
@@ -867,7 +867,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
ParsedSymbol ss2 = lex();
if (ss2.type == SymbolType.PARENT_OPEN) {
call(errors, inFunction, inMethod, inTellTarget, variables, hasEval);
Variable supItem = new Variable(false, s.value.toString(), s.position);
Variable supItem = new Variable(false, new Path(s.value.toString()), s.position);
variables.add(supItem);
ret = true;
} else { //no constructor call, but it could be calling parent methods... => handle in expression
@@ -907,7 +907,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
expectedType(errors, SymbolType.PARENT_OPEN);
s = lex();
boolean forin = false;
String objIdent;
Path objIdent;
Variable item;
boolean define = false;
if (s.type == SymbolType.VAR || isIdentifier(s)) {
@@ -920,7 +920,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
}
if (isIdentifier(ssel)) {
objIdent = ssel.value.toString();
objIdent = new Path(ssel.value.toString());
ParsedSymbol s3 = lex();
if (s3.type == SymbolType.IN) {
@@ -1007,7 +1007,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
command(errors, inFunction, inMethod, forinlevel, inTellTarget, subvariables, hasEval);
variables.add(new CatchScope(new Variable(true, (String) si.value, si.position), subvariables));
variables.add(new CatchScope(new Variable(true, new Path((String) si.value), si.position), subvariables));
}
s = lex();
found = true;
@@ -1252,7 +1252,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
expressionPrimary(errors, inFunction, inMethod, inTellTarget, false, variables, true, hasEval);
ret = true;
} else {
String varName = s.value.toString();
Path varName = new Path(s.value.toString());
Variable vret = new Variable(false, varName, s.position);
variables.add(vret);
@@ -1263,7 +1263,7 @@ public class ActionScript2SimpleParser implements SimpleParser {
if (s2.type == SymbolType.DOT) {
ParsedSymbol s3 = lex();
if (isIdentifier(s3)) {
Variable thisVar = new Variable(false, "this." + s3.value.toString(), s3.position);
Variable thisVar = new Variable(false, new Path("this", s3.value.toString()), s3.position);
variables.add(thisVar);
} else {
lexer.pushback(s3);
@@ -1274,15 +1274,14 @@ public class ActionScript2SimpleParser implements SimpleParser {
}
}
ParsedSymbol ss = lex();
String fullName = varName;
Path fullName = varName;
while (ss.type == SymbolType.DOT) {
ParsedSymbol si = lex();
if (!isIdentifier(si)) {
lexer.pushback(si);
break;
}
fullName += ".";
fullName += si.value.toString();
fullName = fullName.add(si.value.toString());
Variable v = new Variable(false, fullName, si.position);
variables.add(v);
ss = lex();
@@ -1412,10 +1411,10 @@ public class ActionScript2SimpleParser implements SimpleParser {
break;
case FUNCTION:
s = lex();
String fname = "";
Path fname = new Path();
int fnamePos = -1;
if (isIdentifier(s)) {
fname = s.value.toString();
fname = new Path(s.value.toString());
fnamePos = s.position;
} else {
lexer.pushback(s);
@@ -1575,14 +1574,14 @@ public class ActionScript2SimpleParser implements SimpleParser {
Map<Integer, List<Integer>> definitionPosToReferences,
Map<Integer, Integer> referenceToDefinition,
List<SimpleParseException> errors,
List<String> externalTypes,
List<Path> externalTypes,
Map<Integer, Integer> referenceToExternalTypeIndex,
Map<Integer, List<Integer>> externalTypeIndexToReference,
LinkHandler linkHandler,
Map<Integer, String> referenceToExternalTraitKey,
Map<String, List<Integer>> externalTraitKeyToReference
Map<Integer, Path> referenceToExternalTraitKey,
Map<Path, List<Integer>> externalTraitKeyToReference
) throws SimpleParseException, IOException, InterruptedException {
List<VariableOrScope> vars = new ArrayList<>();
try {
lexer = new ActionScriptLexer(new StringReader(str));

View File

@@ -18,16 +18,18 @@ package com.jpexs.decompiler.flash.simpleparser;
/**
* Class trait.
*
* @author JPEXS
*/
public class ClassTrait extends Variable {
public final String classFullName;
public final Path classFullName;
public final String customNs;
public final String simpleName;
public final Path simpleName;
/**
* Constructor
*
* @param classFullName Full class name including package
* @param name Name
* @param customNs Custom namespace
@@ -38,19 +40,19 @@ public class ClassTrait extends Variable {
* @param subType Sub type
* @param callSubType Call sub type
*/
public ClassTrait(String classFullName, String name, String customNs, int position, boolean isStatic, String type, String callType, Variable subType, Variable callSubType) {
super(true, isStatic ? classFullName + "." + name : "this." + (customNs != null ? customNs + "::" : "") + name, position, isStatic, type, callType, subType, callSubType);
public ClassTrait(Path classFullName, Path name, String customNs, int position, boolean isStatic, Path type, Path callType, Variable subType, Variable callSubType) {
super(true, isStatic ? classFullName.add(name) : new Path("this").add((customNs != null ? customNs + "::" : "") + name), position, isStatic, type, callType, subType, callSubType);
this.classFullName = classFullName;
this.customNs = customNs;
this.simpleName = name;
}
@Override
public String toString() {
return (isStatic ? "static " : "") + "trait " + name + " of class " + classFullName + " at " + position;
}
public String getFullIdentifier() {
return classFullName + "/" + (customNs != null ? customNs + "::" : "") + simpleName;
public Path getFullIdentifier() {
return classFullName.add((customNs != null ? customNs + "::" : "") + simpleName);
}
}

View File

@@ -22,14 +22,14 @@ package com.jpexs.decompiler.flash.simpleparser;
*/
public class Import extends Variable {
private final String fullName;
private final Path fullName;
public Import(String fullName, String name, int position) {
public Import(Path fullName, Path name, int position) {
super(false, name, position);
this.fullName = fullName;
}
public String getFullName() {
public Path getFullName() {
return fullName;
}
}

View File

@@ -22,20 +22,20 @@ package com.jpexs.decompiler.flash.simpleparser;
*/
public interface LinkHandler {
public LinkType getClassLinkType(String className);
public LinkType getClassLinkType(Path className);
public boolean traitExists(String className, String traitName);
public boolean traitExists(Path className, String traitName);
public String getTraitType(String className, String traitName);
public Path getTraitType(Path className, String traitName);
public String getTraitSubType(String className, String traitName, int level);
public Path getTraitSubType(Path className, String traitName, int level);
public String getTraitCallType(String className, String traitName);
public Path getTraitCallType(Path className, String traitName);
public String getTraitCallSubType(String className, String traitName, int level);
public Path getTraitCallSubType(Path className, String traitName, int level);
public void handleClassLink(String className);
public void handleClassLink(Path className);
public void handleTraitLink(String className, String traitName);
public void handleTraitLink(Path className, String traitName);
}

View File

@@ -22,7 +22,7 @@ package com.jpexs.decompiler.flash.simpleparser;
*/
public class Namespace extends Variable {
public Namespace(boolean definition, String name, int position) {
public Namespace(boolean definition, Path name, int position) {
super(definition, name, position);
}

View File

@@ -0,0 +1,167 @@
/*
* Copyright (C) 2010-2025 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.simpleparser;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
*
* @author JPEXS
*/
public class Path {
private List<String> parts;
private static final String PART_PARENTHESIS = "--FFDEC-()--";
private static final String PART_BRACKETS = "--FFDEC-[]--";
public static Path PATH_PARENTHESIS = new Path(PART_PARENTHESIS);
public static Path PATH_BRACKETS = new Path(PART_BRACKETS);
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < parts.size(); i++) {
if (i > 0) {
sb.append(".");
}
String part = parts.get(i);
switch (part) {
case PART_PARENTHESIS:
sb.append("()");
break;
case PART_BRACKETS:
sb.append("[]");
break;
default:
sb.append(part);
break;
}
}
return sb.toString();
}
public Path(String ...name) {
this.parts = new ArrayList<>();
for (String n : name) {
this.parts.add(n);
}
}
public Path(List<String> parent, String name) {
this(parent);
this.parts.add(name);
}
public Path(List<String> parts) {
this.parts = new ArrayList<>(parts);
}
public Path(Path path) {
this.parts = new ArrayList<>(path.parts);
}
public Path add(Path path) {
Path ret = new Path(this);
ret.parts.addAll(path.parts);
return ret;
}
public Path add(String ...name) {
Path ret = new Path(this);
for (String n : name) {
ret.parts.add(n);
}
return ret;
}
public Path add(List<String> names) {
Path ret = new Path(this);
ret.parts.addAll(names);
return ret;
}
public Path getLast() {
if (parts.isEmpty()) {
return null;
}
return new Path(parts.get(parts.size() - 1));
}
public Path getFirst() {
if (parts.isEmpty()) {
return null;
}
return new Path(parts.get(0));
}
public boolean isEmpty() {
return parts.isEmpty();
}
public boolean hasParent() {
return parts.size() >= 2;
}
public Path getParent() {
List<String> copy = new ArrayList<>(this.parts);
if (!copy.isEmpty()) {
copy.remove(copy.size() - 1);
}
return new Path(copy);
}
@Override
public int hashCode() {
int hash = 5;
hash = 89 * hash + Objects.hashCode(this.parts);
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Path other = (Path) obj;
return Objects.equals(this.parts, other.parts);
}
public List<String> getParts() {
return new ArrayList<>(parts);
}
public int size() {
return parts.size();
}
public Path get(int index) {
return new Path(parts.get(index));
}
}

View File

@@ -52,12 +52,12 @@ public interface SimpleParser {
Map<Integer, List<Integer>> definitionPosToReferences,
Map<Integer, Integer> referenceToDefinition,
List<SimpleParseException> errors,
List<String> externalTypes,
List<Path> externalTypes,
Map<Integer, Integer> referenceToExternalTypeIndex,
Map<Integer, List<Integer>> externalTypeIndexToReference,
LinkHandler linkHandler,
Map<Integer, String> referenceToExternalTraitKey,
Map<String, List<Integer>> externalTraitKeyToReference
Map<Integer, Path> referenceToExternalTraitKey,
Map<Path, List<Integer>> externalTraitKeyToReference
) throws SimpleParseException, IOException, InterruptedException;
public static void parseVariablesList(
@@ -67,26 +67,25 @@ public interface SimpleParser {
Map<Integer, Integer> referenceToDefinition,
List<SimpleParseException> errors,
boolean innerFunctionCanUseTraits,
List<String> externalTypes,
List<Path> externalTypes,
Map<Integer, Integer> referenceToExternalTypeIndex,
Map<Integer, List<Integer>> externalTypeIndexToReference,
LinkHandler linkHandler,
Map<Integer, String> referenceToExternalTraitKey,
Map<String, List<Integer>> externalTraitKeyToReference
Map<Integer, Path> referenceToExternalTraitKey,
Map<Path, List<Integer>> externalTraitKeyToReference
) {
List<String> externalSimpleTypes = new ArrayList<>();
Map<String, String> simpleExternalClassNameToFullClassName = new LinkedHashMap<>();
for (String type : externalTypes) {
String simpleName = type.contains(".") ? type.substring(type.lastIndexOf(".") + 1) : type;
externalSimpleTypes.add(simpleName);
simpleExternalClassNameToFullClassName.put(simpleName, type);
List<Path> externalSimpleTypes = new ArrayList<>();
Map<Path, Path> simpleExternalClassNameToFullClassName = new LinkedHashMap<>();
for (Path type : externalTypes) {
externalSimpleTypes.add(type.getLast());
simpleExternalClassNameToFullClassName.put(type.getLast(), type);
}
Map<Integer, String> definitionToType = new LinkedHashMap<>();
Map<Integer, String> definitionToCallType = new LinkedHashMap<>();
Map<Integer, Path> definitionToType = new LinkedHashMap<>();
Map<Integer, Path> definitionToCallType = new LinkedHashMap<>();
Map<Integer, Variable> definitionToSubType = new LinkedHashMap<>();
Map<Integer, Variable> definitionToCallSubType = new LinkedHashMap<>();
Map<String, Integer> traitFullNameToDefinition = new LinkedHashMap<>();
Map<Path, Integer> traitFullNameToDefinition = new LinkedHashMap<>();
Map<Integer, Boolean> positionToStatic = new LinkedHashMap<>();
findClassTraits(privateVariables, traitFullNameToDefinition, definitionPosToReferences, positionToStatic, definitionToType, definitionToCallType, definitionToSubType, definitionToCallSubType);
@@ -106,30 +105,30 @@ public interface SimpleParser {
List<VariableOrScope> sharedVariables,
Map<Integer, List<Integer>> definitionPosToReferences,
Map<Integer, Integer> referenceToDefinition,
Map<String, Integer> parentVarFullNameToDefinitionPosition,
Map<String, Integer> parentVarNameToDefinitionPosition,
Map<Path, Integer> parentVarFullNameToDefinitionPosition,
Map<Path, Integer> parentVarNameToDefinitionPosition,
Map<Integer, Boolean> positionToStatic,
boolean isStatic,
List<SimpleParseException> errors,
Scope scope,
boolean innerFunctionCanUseTraits,
List<String> externalSimpleTypes,
List<String> externalFullTypes,
List<Path> externalSimpleTypes,
List<Path> externalFullTypes,
Map<Integer, Integer> referenceToExternalTypeIndex,
Map<Integer, String> definitionToType,
Map<Integer, String> definitionToCallType,
Map<Integer, Path> definitionToType,
Map<Integer, Path> definitionToCallType,
Map<Integer, Variable> definitionToSubType,
Map<Integer, Variable> definitionToCallSubType,
Map<String, Integer> traitFullNameToDefinition,
Map<Path, Integer> traitFullNameToDefinition,
LinkHandler linkHandler,
Map<String, String> simpleExternalClassNameToFullClassName,
Map<Integer, String> referenceToExternalTraitKey,
Map<String, List<Integer>> externalTraitKeyToReference
Map<Path, Path> simpleExternalClassNameToFullClassName,
Map<Integer, Path> referenceToExternalTraitKey,
Map<Path, List<Integer>> externalTraitKeyToReference
) {
Map<String, Integer> privateVarNameToDefinitionPosition = new LinkedHashMap<>();
Map<Path, Integer> privateVarNameToDefinitionPosition = new LinkedHashMap<>();
privateVarNameToDefinitionPosition.putAll(parentVarNameToDefinitionPosition);
Map<String, Integer> privateVarFullNameToDefinitionPosition = new LinkedHashMap<>();
Map<Path, Integer> privateVarFullNameToDefinitionPosition = new LinkedHashMap<>();
privateVarFullNameToDefinitionPosition.putAll(parentVarFullNameToDefinitionPosition);
for (VariableOrScope vt : privateVariables) {
@@ -170,7 +169,7 @@ public interface SimpleParser {
}
} else {
if ("this".equals(v.name) && isStatic) {
if ("this".equals(v.name.toString()) && isStatic) {
errors.add(new SimpleParseException("Cannot use this in static context", -1, v.position));
} else {
int definitionPos;
@@ -201,21 +200,20 @@ public interface SimpleParser {
}
//if its inner function (not a method), remove all this variables
Map<String, Integer> subPrivateVarFullNameToDefinitionPosition = privateVarFullNameToDefinitionPosition;
Map<String, Integer> subPrivateVarNameToDefinitionPosition = privateVarNameToDefinitionPosition;
Map<Path, Integer> subPrivateVarFullNameToDefinitionPosition = privateVarFullNameToDefinitionPosition;
Map<Path, Integer> subPrivateVarNameToDefinitionPosition = privateVarNameToDefinitionPosition;
if ((vs instanceof FunctionScope) && (!(vs instanceof MethodScope))) {
subPrivateVarFullNameToDefinitionPosition = new LinkedHashMap<>(subPrivateVarFullNameToDefinitionPosition);
subPrivateVarNameToDefinitionPosition = new LinkedHashMap<>(subPrivateVarNameToDefinitionPosition);
Set<String> keys = new HashSet<>(subPrivateVarFullNameToDefinitionPosition.keySet());
for (String vName : keys) {
if (vName.equals("this") || vName.startsWith("this.")) {
Set<Path> keys = new HashSet<>(subPrivateVarFullNameToDefinitionPosition.keySet());
for (Path vName : keys) {
if (vName.toString().equals("this") || vName.getFirst().toString().equals("this")) {
subPrivateVarFullNameToDefinitionPosition.remove(vName);
if (vName.equals("this")) {
subPrivateVarNameToDefinitionPosition.remove("this");
if (vName.toString().equals("this")) {
subPrivateVarNameToDefinitionPosition.remove(new Path("this"));
}
if (!innerFunctionCanUseTraits) {
String lastName = vName.contains(".") ? vName.substring(vName.lastIndexOf(".") + 1) : vName;
subPrivateVarNameToDefinitionPosition.remove(lastName);
subPrivateVarNameToDefinitionPosition.remove(vName.getLast());
}
}
}
@@ -295,21 +293,20 @@ public interface SimpleParser {
}
//if its inner function (not a method), remove all this variables
Map<String, Integer> subPrivateVarFullNameToDefinitionPosition = privateVarFullNameToDefinitionPosition;
Map<String, Integer> subPrivateVarNameToDefinitionPosition = privateVarNameToDefinitionPosition;
Map<Path, Integer> subPrivateVarFullNameToDefinitionPosition = privateVarFullNameToDefinitionPosition;
Map<Path, Integer> subPrivateVarNameToDefinitionPosition = privateVarNameToDefinitionPosition;
if ((vs instanceof FunctionScope) && (!(vs instanceof MethodScope))) {
subPrivateVarFullNameToDefinitionPosition = new LinkedHashMap<>(subPrivateVarFullNameToDefinitionPosition);
subPrivateVarNameToDefinitionPosition = new LinkedHashMap<>(subPrivateVarNameToDefinitionPosition);
Set<String> keys = new HashSet<>(subPrivateVarFullNameToDefinitionPosition.keySet());
for (String vName : keys) {
if (vName.equals("this") || vName.startsWith("this.")) {
Set<Path> keys = new HashSet<>(subPrivateVarFullNameToDefinitionPosition.keySet());
for (Path vName : keys) {
if (vName.toString().equals("this") || vName.getFirst().toString().equals("this")) {
subPrivateVarFullNameToDefinitionPosition.remove(vName);
if (vName.equals("this")) {
subPrivateVarNameToDefinitionPosition.remove("this");
if (vName.toString().equals("this")) {
subPrivateVarNameToDefinitionPosition.remove(new Path("this"));
}
if (!innerFunctionCanUseTraits) {
String lastName = vName.contains(".") ? vName.substring(vName.lastIndexOf(".") + 1) : vName;
subPrivateVarNameToDefinitionPosition.remove(lastName);
if (!innerFunctionCanUseTraits) {
subPrivateVarNameToDefinitionPosition.remove(vName.getLast());
}
}
}
@@ -322,11 +319,11 @@ public interface SimpleParser {
public static void findClassTraits(
List<VariableOrScope> variables,
Map<String, Integer> traitFullNameToDefinition,
Map<Path, Integer> traitFullNameToDefinition,
Map<Integer, List<Integer>> definitionPosToReferences,
Map<Integer, Boolean> positionToStatic,
Map<Integer, String> definitionToType,
Map<Integer, String> definitionToCallType,
Map<Integer, Path> definitionToType,
Map<Integer, Path> definitionToCallType,
Map<Integer, Variable> definitionToSubType,
Map<Integer, Variable> definitionToCallSubType
) {
@@ -359,32 +356,33 @@ public interface SimpleParser {
public static boolean searchTrait(
Variable v,
Map<String, Integer> privateVarFullNameToDefinitionPosition,
Map<String, Integer> privateVarNameToDefinitionPosition,
Map<Integer, String> definitionToType,
Map<Integer, String> definitionToCallType,
Map<Path, Integer> privateVarFullNameToDefinitionPosition,
Map<Path, Integer> privateVarNameToDefinitionPosition,
Map<Integer, Path> definitionToType,
Map<Integer, Path> definitionToCallType,
Map<Integer, Variable> definitionToSubType,
Map<Integer, Variable> definitionToCallSubType,
Map<String, Integer> traitFullNameToDefinition,
Map<Path, Integer> traitFullNameToDefinition,
Map<Integer, List<Integer>> definitionPosToReferences,
Map<Integer, Integer> referenceToDefinition,
LinkHandler linkHandler,
Map<String, String> simpleExternalClassNameToFullClassName,
Map<Integer, String> referenceToExternalTraitKey,
Map<String, List<Integer>> externalTraitKeyToReference
Map<Path, Path> simpleExternalClassNameToFullClassName,
Map<Integer, Path> referenceToExternalTraitKey,
Map<Path, List<Integer>> externalTraitKeyToReference
) {
boolean traitFound = false;
if (v.hasParent()) {
List<String> parts = v.getParts();
//List<String> parts = v.getParts();
Path parts = v.name;
Integer definitionPos = null;
String firstName = parts.get(0);
Path firstName = v.getFirstName();
if (privateVarFullNameToDefinitionPosition.containsKey(firstName)) {
definitionPos = privateVarFullNameToDefinitionPosition.get(firstName);
} else if (privateVarNameToDefinitionPosition.containsKey(firstName)) {
definitionPos = privateVarNameToDefinitionPosition.get(firstName);
}
String type = null;
Path type = null;
if (definitionPos != null) {
if (definitionToType.containsKey(definitionPos)) {
type = definitionToType.get(definitionPos);
@@ -395,15 +393,15 @@ public interface SimpleParser {
if (type != null) {
traitFound = true;
Variable lastSubType = null;
String traitKey = null;
String externalCallType = null;
List<String> externalSubTypes = new ArrayList<>();
List<String> externalCallSubTypes = new ArrayList<>();
String part = null;
Path traitKey = null;
Path externalCallType = null;
List<Path> externalSubTypes = new ArrayList<>();
List<Path> externalCallSubTypes = new ArrayList<>();
Path part = null;
for (int p = 1; p < parts.size(); p++) {
part = parts.get(p);
if (part.equals("()")) {
if (parts.get(p - 1).equals("[]")) {
if (part.equals(Path.PATH_PARENTHESIS)) {
if (parts.get(p - 1).equals(Path.PATH_BRACKETS)) {
traitFound = false;
break;
}
@@ -415,11 +413,11 @@ public interface SimpleParser {
type = definitionToCallType.get(definitionPos);
}
lastSubType = null;
} else if (part.equals("[]")) {
} else if (part.equals(Path.PATH_BRACKETS)) {
if (definitionPos != null) {
if (lastSubType != null) {
lastSubType = lastSubType.subType;
} else if (parts.get(p - 1).equals("()")) {
} else if (parts.get(p - 1).toString().equals("()")) {
lastSubType = definitionToCallSubType.get(definitionPos);
} else {
lastSubType = definitionToSubType.get(definitionPos);
@@ -437,13 +435,13 @@ public interface SimpleParser {
type = externalSubTypes.remove(0);
}
} else {
traitKey = type + "/" + part;
traitKey = type.add(part);
if (!traitFullNameToDefinition.containsKey(traitKey)) {
if (simpleExternalClassNameToFullClassName.containsKey(type)) {
type = simpleExternalClassNameToFullClassName.get(type);
}
traitKey = type + "/" + part;
String newType = linkHandler.getTraitType(type, part);
traitKey = type.add(part);
Path newType = linkHandler.getTraitType(type, part.toString());
if (newType == null) {
traitFound = false;
break;
@@ -451,18 +449,18 @@ public interface SimpleParser {
externalSubTypes.clear();
int i = 1;
while (true) {
String st = linkHandler.getTraitSubType(type, part, i);
Path st = linkHandler.getTraitSubType(type, part.toString(), i);
if (st == null) {
break;
}
externalSubTypes.add(st);
i++;
}
externalCallType = linkHandler.getTraitCallType(type, part);
externalCallType = linkHandler.getTraitCallType(type, part.toString());
externalCallSubTypes.clear();
i = 1;
while (true) {
String st = linkHandler.getTraitCallSubType(type, part, i);
Path st = linkHandler.getTraitCallSubType(type, part.toString(), i);
if (st == null) {
break;
}

View File

@@ -22,7 +22,7 @@ package com.jpexs.decompiler.flash.simpleparser;
*/
public class Type extends Variable {
public Type(boolean definition, String name, int position) {
public Type(boolean definition, Path name, int position) {
super(definition, name, position, true);
}
}

View File

@@ -26,27 +26,27 @@ import java.util.List;
public class Variable implements VariableOrScope {
public boolean definition;
public String name;
public Path name;
public int position;
public Boolean isStatic;
public String type;
public String callType;
public Path type;
public Path callType;
public Variable subType;
public Variable callSubType;
public Variable(boolean definition, String name, int position) {
public Variable(boolean definition, Path name, int position) {
this(definition, name, position, null);
}
public Variable(boolean definition, String name, int position, Boolean isStatic) {
public Variable(boolean definition, Path name, int position, Boolean isStatic) {
this(definition, name, position, isStatic, null, null);
}
public Variable(boolean definition, String name, int position, Boolean isStatic, String type, String callType) {
public Variable(boolean definition, Path name, int position, Boolean isStatic, Path type, Path callType) {
this(definition, name, position, isStatic, type, callType, null, null);
}
public Variable(boolean definition, String name, int position, Boolean isStatic, String type, String callType, Variable subType, Variable callSubType) {
public Variable(boolean definition, Path name, int position, Boolean isStatic, Path type, Path callType, Variable subType, Variable callSubType) {
this.definition = definition;
this.name = name;
this.position = position;
@@ -62,34 +62,23 @@ public class Variable implements VariableOrScope {
return (definition ? "definition of " : "") + (isStatic == Boolean.TRUE ? "static " : "") + name + " at " + position;
}
public String getLastName() {
String ret = name;
if (ret.contains(".")) {
ret = ret.substring(ret.lastIndexOf(".") + 1);
}
return ret;
public Path getLastName() {
return name.getLast();
}
public String getFirstName() {
String ret = name;
if (ret.contains(".")) {
ret = ret.substring(0, ret.indexOf("."));
}
return ret;
public Path getFirstName() {
return name.getFirst();
}
public String getParentName() {
if (name.contains(".")) {
return name.substring(0, name.lastIndexOf("."));
}
return null;
public Path getParentName() {
return name.getParent();
}
public List<String> getParts() {
return Arrays.asList(name.split("\\.", -1));
return name.getParts();
}
public boolean hasParent() {
return name.contains(".");
return name.hasParent();
}
}