diff --git a/CHANGELOG.md b/CHANGELOG.md index cf192352a..5ef47edaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. ## [Unreleased] ### Added - Display object depth in flash panel +- Show imported files on script import, able to cancel import ### Fixed - [#1761] AS3 - try..finally inside another structure like if diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index c6fc16021..5b678d2fb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -1949,7 +1949,7 @@ public final class SWF implements SWFContainerItem, Timelined { } } - protected void informListeners(String event, Object data) { + public void informListeners(String event, Object data) { for (EventListener listener : listeners) { listener.handleEvent(event, data); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java index 85ba4c53b..8299153f0 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/abc/avm2/parser/script/ActionScript3Parser.java @@ -156,7 +156,7 @@ public class ActionScript3Parser { return uniqLast; } - private List commands(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, List variables) throws IOException, AVM2ParseException { + private List commands(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, List variables) throws IOException, AVM2ParseException, InterruptedException { List ret = new ArrayList<>(); if (debugMode) { System.out.println("commands:"); @@ -171,7 +171,7 @@ public class ActionScript3Parser { return ret; } - private GraphTargetItem type(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem type(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, List variables) throws IOException, AVM2ParseException, InterruptedException { ParsedSymbol s = lex(); if (s.type == SymbolType.MULTIPLY) { return new UnboundedTypeItem(); @@ -186,7 +186,7 @@ public class ActionScript3Parser { return t; } - private GraphTargetItem memberOrCall(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem newcmds, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem memberOrCall(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem newcmds, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException, InterruptedException { if (debugMode) { System.out.println("memberOrCall:"); } @@ -240,7 +240,7 @@ public class ActionScript3Parser { return ret; } - private GraphTargetItem applyType(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem applyType(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException, InterruptedException { GraphTargetItem ret = obj; ParsedSymbol s = lex(); if (s.type == SymbolType.TYPENAME) { @@ -272,7 +272,7 @@ public class ActionScript3Parser { return ret; } - private GraphTargetItem member(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem member(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, GraphTargetItem obj, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException, InterruptedException { if (debugMode) { System.out.println("member:"); } @@ -339,7 +339,7 @@ public class ActionScript3Parser { return ret; } - private GraphTargetItem name(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, boolean typeOnly, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, List importedClasses) throws IOException, AVM2ParseException { + private GraphTargetItem name(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, boolean typeOnly, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables, List importedClasses) throws IOException, AVM2ParseException, InterruptedException { ParsedSymbol s = lex(); DottedChain name = new DottedChain(new String[]{}, ""); String name2 = ""; @@ -447,13 +447,16 @@ public class ActionScript3Parser { } } - private ParsedSymbol expectedType(Object... type) throws IOException, AVM2ParseException { + private ParsedSymbol expectedType(Object... type) throws IOException, AVM2ParseException, InterruptedException { ParsedSymbol symb = lex(); expected(symb, lexer.yyline(), type); return symb; } - private ParsedSymbol lex() throws IOException, AVM2ParseException { + private ParsedSymbol lex() throws IOException, AVM2ParseException, InterruptedException { + if (Thread.currentThread().isInterrupted()) { + throw new InterruptedException(); + } ParsedSymbol ret = lexer.lex(); if (debugMode) { System.out.println(ret); @@ -461,7 +464,7 @@ public class ActionScript3Parser { return ret; } - private List call(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + private List call(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException, InterruptedException { List ret = new ArrayList<>(); //expected(SymbolType.PARENT_OPEN); //MUST BE HANDLED BY CALLER ParsedSymbol s = lex(); @@ -476,12 +479,12 @@ public class ActionScript3Parser { return ret; } - private MethodAVM2Item method(List> allOpenedNamespaces, boolean outsidePackage, boolean isPrivate, List>> metadata, NamespaceItem pkg, boolean isInterface, String customAccess, Reference needsActivation, List importedClasses, boolean override, boolean isFinal, TypeItem thisType, List openedNamespaces, boolean isStatic, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException { + private MethodAVM2Item method(List> allOpenedNamespaces, boolean outsidePackage, boolean isPrivate, List>> metadata, NamespaceItem pkg, boolean isInterface, String customAccess, Reference needsActivation, List importedClasses, boolean override, boolean isFinal, TypeItem thisType, List openedNamespaces, boolean isStatic, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException, InterruptedException { FunctionAVM2Item f = function(allOpenedNamespaces, metadata, pkg, isInterface, needsActivation, importedClasses, thisType, openedNamespaces, functionName, isMethod, variables); return new MethodAVM2Item(allOpenedNamespaces, outsidePackage, isPrivate, f.metadata, f.pkg, f.isInterface, customAccess, f.needsActivation, f.hasRest, f.line, override, isFinal, isStatic, functionName, f.paramTypes, f.paramNames, f.paramValues, f.body, f.subvariables, f.retType); } - private FunctionAVM2Item function(List> allOpenedNamespaces, List>> metadata, NamespaceItem pkg, boolean isInterface, Reference needsActivation, List importedClasses, TypeItem thisType, List openedNamespaces, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException { + private FunctionAVM2Item function(List> allOpenedNamespaces, List>> metadata, NamespaceItem pkg, boolean isInterface, Reference needsActivation, List importedClasses, TypeItem thisType, List openedNamespaces, String functionName, boolean isMethod, List variables) throws IOException, AVM2ParseException, InterruptedException { openedNamespaces = new ArrayList<>(openedNamespaces); //local copy allOpenedNamespaces.add(openedNamespaces); @@ -562,7 +565,7 @@ public class ActionScript3Parser { return new FunctionAVM2Item(metadata, pkg, isInterface, needsActivation2.getVal(), hasRest, line, functionName, paramTypes, paramNames, paramValues, body, subvariables, retType); } - private List>> parseMetadata() throws IOException, AVM2ParseException { + private List>> parseMetadata() throws IOException, AVM2ParseException, InterruptedException { List>> metadata = new ArrayList<>(); ParsedSymbol s = lex(); while (s.isType(SymbolType.BRACKET_OPEN)) { @@ -601,7 +604,7 @@ public class ActionScript3Parser { return metadata; } - private void classTraits(List> allOpenedNamespaces, boolean outsidePackage, List cinitVariables, Reference cinitNeedsActivation, List cinit, List importedClasses, List openedNamespaces, NamespaceItem pkg, String classNameStr, boolean isInterface, List traits, List iinitVariables, Reference iinitNeedsActivation, Reference iinit) throws AVM2ParseException, IOException, CompilationException { + private void classTraits(List> allOpenedNamespaces, boolean outsidePackage, List cinitVariables, Reference cinitNeedsActivation, List cinit, List importedClasses, List openedNamespaces, NamespaceItem pkg, String classNameStr, boolean isInterface, List traits, List iinitVariables, Reference iinitNeedsActivation, Reference iinit) throws AVM2ParseException, IOException, CompilationException, InterruptedException { NamespaceItem publicNs = new NamespaceItem("", Namespace.KIND_PACKAGE); NamespaceItem privateNs = new NamespaceItem(pkg.name.toRawString() + ":" + classNameStr, Namespace.KIND_PRIVATE); @@ -869,14 +872,14 @@ public class ActionScript3Parser { } } - private void scriptTraits(List> allOpenedNamespaces, int scriptIndex, String scriptName, List traits) throws AVM2ParseException, IOException, CompilationException { + private void scriptTraits(List> allOpenedNamespaces, int scriptIndex, String scriptName, List traits) throws AVM2ParseException, IOException, CompilationException, InterruptedException { while (scriptTraitsBlock(allOpenedNamespaces, scriptIndex, scriptName, traits)) { //empty } } - private boolean scriptTraitsBlock(List> allOpenedNamespaces, int scriptIndex, String scriptName, List traits) throws AVM2ParseException, IOException, CompilationException { + private boolean scriptTraitsBlock(List> allOpenedNamespaces, int scriptIndex, String scriptName, List traits) throws AVM2ParseException, IOException, CompilationException, InterruptedException { ParsedSymbol s; boolean inPackage = false; s = lex(); @@ -1220,7 +1223,7 @@ public class ActionScript3Parser { } } - private List xmltag(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference usesVars, List openedTags, Reference closedVarTags, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + private List xmltag(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference usesVars, List openedTags, Reference closedVarTags, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException, InterruptedException { ParsedSymbol s; List rets = new ArrayList<>(); //GraphTargetItem ret = null; @@ -1349,7 +1352,7 @@ public class ActionScript3Parser { return rets; } - private GraphTargetItem xml(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem xml(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException, InterruptedException { List openedTags = new ArrayList<>(); int closedVarTags = 0; @@ -1360,7 +1363,7 @@ public class ActionScript3Parser { return ret; } - private GraphTargetItem command(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, boolean mustBeCommand, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem command(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, Stack loops, Map loopLabels, HashMap registerVars, boolean inFunction, boolean inMethod, int forinlevel, boolean mustBeCommand, List variables) throws IOException, AVM2ParseException, InterruptedException { LexBufferer buf = new LexBufferer(); lexer.addListener(buf); GraphTargetItem ret = null; @@ -1837,7 +1840,7 @@ public class ActionScript3Parser { } - private GraphTargetItem expression(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables, boolean allowComma) throws IOException, AVM2ParseException { + private GraphTargetItem expression(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables, boolean allowComma) throws IOException, AVM2ParseException, InterruptedException { return expression(allOpenedNamespaces, thisType, pkg, needsActivation, importedClasses, openedNamespaces, false, registerVars, inFunction, inMethod, allowRemainder, variables, allowComma); } @@ -1871,7 +1874,7 @@ public class ActionScript3Parser { return (item instanceof NameAVM2Item); } - private int brackets(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, List ret, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException { + private int brackets(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, List ret, HashMap registerVars, boolean inFunction, boolean inMethod, List variables) throws IOException, AVM2ParseException, InterruptedException { ParsedSymbol s = lex(); int arrCnt = 0; if (s.type == SymbolType.BRACKET_OPEN) { @@ -1895,7 +1898,7 @@ public class ActionScript3Parser { return arrCnt; } - private GraphTargetItem expression(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables, boolean allowComma) throws IOException, AVM2ParseException { + private GraphTargetItem expression(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables, boolean allowComma) throws IOException, AVM2ParseException, InterruptedException { List commaItems = new ArrayList<>(); ParsedSymbol symb; @@ -1955,7 +1958,7 @@ public class ActionScript3Parser { } } - private ParsedSymbol peekExprToken() throws IOException, AVM2ParseException { + private ParsedSymbol peekExprToken() throws IOException, AVM2ParseException, InterruptedException { ParsedSymbol lookahead = lex(); xmlToLowerThanFix(lookahead); regexpToDivideFix(lookahead); @@ -1964,7 +1967,7 @@ public class ActionScript3Parser { return lookahead; } - private GraphTargetItem expression1(List> allOpenedNamespaces, GraphTargetItem lhs, int min_precedence, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem expression1(List> allOpenedNamespaces, GraphTargetItem lhs, int min_precedence, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException, InterruptedException { if (debugMode) { System.out.println("expression1:"); } @@ -2177,7 +2180,7 @@ public class ActionScript3Parser { return lhs; } - private GraphTargetItem expressionPrimary(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException { + private GraphTargetItem expressionPrimary(List> allOpenedNamespaces, TypeItem thisType, NamespaceItem pkg, Reference needsActivation, List importedClasses, List openedNamespaces, boolean allowEmpty, HashMap registerVars, boolean inFunction, boolean inMethod, boolean allowRemainder, List variables) throws IOException, AVM2ParseException, InterruptedException { if (debugMode) { System.out.println("primary:"); } @@ -2472,7 +2475,7 @@ public class ActionScript3Parser { private List constantPool; - private List parseImportsUsages(List openedNamespaces) throws IOException, AVM2ParseException { + private List parseImportsUsages(List openedNamespaces) throws IOException, AVM2ParseException, InterruptedException { ParsedSymbol s; List importedClasses = new ArrayList<>(); @@ -2519,7 +2522,7 @@ public class ActionScript3Parser { return importedClasses; } - private List parseScript(List> allOpenedNamespaces, int scriptIndex, String fileName) throws IOException, AVM2ParseException, CompilationException { + private List parseScript(List> allOpenedNamespaces, int scriptIndex, String fileName) throws IOException, AVM2ParseException, CompilationException, InterruptedException { //int scriptPrivateNs; if (fileName.contains("/")) { @@ -2533,7 +2536,7 @@ public class ActionScript3Parser { return items; } - public List scriptTraitsFromString(List> allOpenedNamespaces, String str, String fileName, int scriptIndex) throws AVM2ParseException, IOException, CompilationException { + public List scriptTraitsFromString(List> allOpenedNamespaces, String str, String fileName, int scriptIndex) throws AVM2ParseException, IOException, CompilationException, InterruptedException { lexer = new ActionScriptLexer(str); List ret = parseScript(allOpenedNamespaces, scriptIndex, fileName); @@ -2550,7 +2553,7 @@ public class ActionScript3Parser { abcIndex.getSelectedAbc().script_info.add(gen.generateScriptInfo(allOpenedNamespaces, localData, items, classPos)); } - public void addScript(String s, String fileName, int classPos, int scriptIndex) throws AVM2ParseException, IOException, CompilationException { + public void addScript(String s, String fileName, int classPos, int scriptIndex) throws AVM2ParseException, IOException, CompilationException, InterruptedException { List> allOpenedNamespaces = new ArrayList<>(); List traits = scriptTraitsFromString(allOpenedNamespaces, s, fileName, scriptIndex); addScriptFromTree(allOpenedNamespaces, traits, classPos); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2Parser.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2Parser.java index dfe7b1577..b83249bcf 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2Parser.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/action/parser/script/ActionScript2Parser.java @@ -263,7 +263,7 @@ public class ActionScript2Parser { return "" + uniqLast; } - private List commands(boolean inFunction, boolean inMethod, int forinlevel, boolean inTellTarget, List variables, List functions, Reference hasEval) throws IOException, ActionParseException { + private List commands(boolean inFunction, boolean inMethod, int forinlevel, boolean inTellTarget, List variables, List functions, Reference hasEval) throws IOException, ActionParseException, InterruptedException { List ret = new ArrayList<>(); if (debugMode) { System.out.println("commands:"); @@ -278,7 +278,7 @@ public class ActionScript2Parser { return ret; } - private GraphTargetItem type(List variables) throws IOException, ActionParseException { + private GraphTargetItem type(List variables) throws IOException, ActionParseException, InterruptedException { GraphTargetItem ret; ParsedSymbol s = lex(); @@ -329,13 +329,16 @@ public class ActionScript2Parser { } } - private ParsedSymbol expectedType(Object... type) throws IOException, ActionParseException { + private ParsedSymbol expectedType(Object... type) throws IOException, ActionParseException, InterruptedException { ParsedSymbol symb = lex(); expected(symb, lexer.yyline(), type); return symb; } - private ParsedSymbol lex() throws IOException, ActionParseException { + private ParsedSymbol lex() throws IOException, ActionParseException, InterruptedException { + if (Thread.currentThread().isInterrupted()) { + throw new InterruptedException(); + } ParsedSymbol ret = lexer.lex(); if (debugMode) { System.out.println(ret); @@ -343,7 +346,7 @@ public class ActionScript2Parser { return ret; } - private List call(boolean inFunction, boolean inMethod, boolean inTellTarget, List variables, List functions, Reference hasEval) throws IOException, ActionParseException { + private List call(boolean inFunction, boolean inMethod, boolean inTellTarget, List variables, List functions, Reference hasEval) throws IOException, ActionParseException, InterruptedException { List ret = new ArrayList<>(); //expected(SymbolType.PARENT_OPEN); //MUST BE HANDLED BY CALLER ParsedSymbol s = lex(); @@ -358,7 +361,7 @@ public class ActionScript2Parser { return ret; } - private FunctionActionItem function(boolean withBody, String functionName, boolean isMethod, List variables, List functions, boolean inTellTarget, Reference hasEval) throws IOException, ActionParseException { + private FunctionActionItem function(boolean withBody, String functionName, boolean isMethod, List variables, List functions, boolean inTellTarget, Reference hasEval) throws IOException, ActionParseException, InterruptedException { GraphTargetItem ret = null; ParsedSymbol s; expectedType(SymbolType.PARENT_OPEN); @@ -401,7 +404,7 @@ public class ActionScript2Parser { return retf; } - private GraphTargetItem traits(boolean isInterface, GraphTargetItem nameStr, GraphTargetItem extendsStr, List implementsStr, List variables, List functions, boolean inTellTarget, Reference hasEval) throws IOException, ActionParseException { + private GraphTargetItem traits(boolean isInterface, GraphTargetItem nameStr, GraphTargetItem extendsStr, List implementsStr, List variables, List functions, boolean inTellTarget, Reference hasEval) throws IOException, ActionParseException, InterruptedException { GraphTargetItem ret = null; /*for (int i = 0; i < nameStr.size() - 1; i++) { @@ -543,7 +546,7 @@ public class ActionScript2Parser { } } - private GraphTargetItem expressionCommands(ParsedSymbol s, boolean inFunction, boolean inMethod, boolean inTellTarget, int forinlevel, List variables, List functions, Reference hasEval) throws IOException, ActionParseException { + private GraphTargetItem expressionCommands(ParsedSymbol s, boolean inFunction, boolean inMethod, boolean inTellTarget, int forinlevel, List variables, List functions, Reference hasEval) throws IOException, ActionParseException, InterruptedException { if (debugMode) { System.out.println("expressionCommands:"); } @@ -950,7 +953,7 @@ public class ActionScript2Parser { } } - private GraphTargetItem command(boolean inFunction, boolean inMethod, int forinlevel, boolean inTellTarget, boolean mustBeCommand, List variables, List functions, Reference hasEval) throws IOException, ActionParseException { + private GraphTargetItem command(boolean inFunction, boolean inMethod, int forinlevel, boolean inTellTarget, boolean mustBeCommand, List variables, List functions, Reference hasEval) throws IOException, ActionParseException, InterruptedException { LexBufferer buf = new LexBufferer(); lexer.addListener(buf); GraphTargetItem ret = null; @@ -1375,7 +1378,7 @@ public class ActionScript2Parser { } - private GraphTargetItem expression(boolean inFunction, boolean inMethod, boolean inTellTarget, boolean allowRemainder, List variables, List functions, boolean allowComma, Reference hasEval) throws IOException, ActionParseException { + private GraphTargetItem expression(boolean inFunction, boolean inMethod, boolean inTellTarget, boolean allowRemainder, List variables, List functions, boolean allowComma, Reference hasEval) throws IOException, ActionParseException, InterruptedException { if (debugMode) { System.out.println("expression:"); } @@ -1402,7 +1405,7 @@ public class ActionScript2Parser { return new CommaExpressionItem(null, null, commaItems); } - private ParsedSymbol peekLex() throws IOException, ActionParseException { + private ParsedSymbol peekLex() throws IOException, ActionParseException, InterruptedException { ParsedSymbol lookahead = lex(); lexer.pushback(lookahead); return lookahead; @@ -1435,7 +1438,7 @@ public class ActionScript2Parser { return s.type.getPrecedence(); } - private GraphTargetItem expression1(GraphTargetItem lhs, int min_precedence, boolean inFunction, boolean inMethod, boolean inTellTarget, boolean allowRemainder, List variables, List functions, Reference hasEval) throws IOException, ActionParseException { + private GraphTargetItem expression1(GraphTargetItem lhs, int min_precedence, boolean inFunction, boolean inMethod, boolean inTellTarget, boolean allowRemainder, List variables, List functions, Reference hasEval) throws IOException, ActionParseException, InterruptedException { ParsedSymbol op; GraphTargetItem rhs; GraphTargetItem mhs = null; @@ -1663,7 +1666,7 @@ public class ActionScript2Parser { return (item instanceof VariableActionItem); } - private int brackets(List ret, boolean inFunction, boolean inMethod, boolean inTellTarget, List variables, List functions, Reference hasEval) throws IOException, ActionParseException { + private int brackets(List ret, boolean inFunction, boolean inMethod, boolean inTellTarget, List variables, List functions, Reference hasEval) throws IOException, ActionParseException, InterruptedException { ParsedSymbol s = lex(); int arrCnt = 0; if (s.type == SymbolType.BRACKET_OPEN) { @@ -1687,7 +1690,7 @@ public class ActionScript2Parser { return arrCnt; } - private GraphTargetItem handleVariable(ParsedSymbol s, GraphTargetItem ret, List variables, Reference allowMemberOrCall, boolean inFunction, boolean inMethod, boolean inTellTarget, List functions, Reference hasEval) throws IOException, ActionParseException { + private GraphTargetItem handleVariable(ParsedSymbol s, GraphTargetItem ret, List variables, Reference allowMemberOrCall, boolean inFunction, boolean inMethod, boolean inTellTarget, List functions, Reference hasEval) throws IOException, ActionParseException, InterruptedException { if (s.value.equals("not")) { ret = new NotItem(null, null, expressionPrimary(false, inFunction, inMethod, inTellTarget, false, variables, functions, true, hasEval)); } else { @@ -1710,7 +1713,7 @@ public class ActionScript2Parser { return ret; } - private GraphTargetItem expressionPrimary(boolean allowEmpty, boolean inFunction, boolean inMethod, boolean inTellTarget, boolean allowRemainder, List variables, List functions, boolean allowCall, Reference hasEval) throws IOException, ActionParseException { + private GraphTargetItem expressionPrimary(boolean allowEmpty, boolean inFunction, boolean inMethod, boolean inTellTarget, boolean allowRemainder, List variables, List functions, boolean allowCall, Reference hasEval) throws IOException, ActionParseException, InterruptedException { if (debugMode) { System.out.println("primary:"); } @@ -2008,7 +2011,7 @@ public class ActionScript2Parser { return false; } - private GraphTargetItem memberOrCall(GraphTargetItem ret, boolean inFunction, boolean inMethod, boolean inTellTarget, List variables, List functions, boolean allowCall, Reference hasEval) throws IOException, ActionParseException { + private GraphTargetItem memberOrCall(GraphTargetItem ret, boolean inFunction, boolean inMethod, boolean inTellTarget, List variables, List functions, boolean allowCall, Reference hasEval) throws IOException, ActionParseException, InterruptedException { ParsedSymbol op = lex(); while (op.isType(SymbolType.PARENT_OPEN, SymbolType.BRACKET_OPEN, SymbolType.DOT)) { if (op.type == SymbolType.PARENT_OPEN) { @@ -2100,7 +2103,7 @@ public class ActionScript2Parser { private List constantPool; - public List treeFromString(String str, List constantPool) throws ActionParseException, IOException { + public List treeFromString(String str, List constantPool) throws ActionParseException, IOException, InterruptedException { List retTree = new ArrayList<>(); this.constantPool = constantPool; lexer = new ActionScriptLexer(new StringReader(str)); @@ -2391,7 +2394,7 @@ public class ActionScript2Parser { return ret; } - public List actionsFromString(String s) throws ActionParseException, IOException, CompilationException { + public List actionsFromString(String s) throws ActionParseException, IOException, CompilationException, InterruptedException { try { List constantPool = new ArrayList<>(); List tree = treeFromString(s, constantPool); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java index 73eb8604c..5bf29bebb 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/PreviewExporter.java @@ -179,6 +179,8 @@ public class PreviewExporter { Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); } catch (ActionParseException ex) { Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); + } catch (InterruptedException ex) { + Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); } overVideoButton.actions.add(bca); @@ -205,6 +207,8 @@ public class PreviewExporter { Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); } catch (ActionParseException ex) { Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); + } catch (InterruptedException ex) { + Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); } progressBarButton.actions.add(bca); @@ -238,6 +242,8 @@ public class PreviewExporter { Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); } catch (ActionParseException ex) { Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); + } catch (InterruptedException ex) { + Logger.getLogger(PreviewExporter.class.getName()).log(Level.SEVERE, null, ex); } doAction.writeTag(sos2); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/AS2ScriptImporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/AS2ScriptImporter.java index da6974fc8..18f549a7d 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/AS2ScriptImporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/AS2ScriptImporter.java @@ -41,7 +41,10 @@ public class AS2ScriptImporter { private static final Logger logger = Logger.getLogger(AS2ScriptImporter.class.getName()); - public int importScripts(String scriptsFolder, Map asms) { + public int importScripts(String scriptsFolder, Map asms) throws InterruptedException { + return importScripts(scriptsFolder, asms, null); + } + public int importScripts(String scriptsFolder, Map asms, ScriptImporterProgressListener listener) throws InterruptedException { if (!scriptsFolder.endsWith(File.separator)) { scriptsFolder += File.separator; } @@ -50,6 +53,9 @@ public class AS2ScriptImporter { int importCount = 0; for (String key : asms.keySet()) { + if (Thread.currentThread().isInterrupted()) { + throw new InterruptedException(); + } ASMSource asm = asms.get(key); String currentOutDir = scriptsFolder + key + File.separator; currentOutDir = new File(currentOutDir).getParentFile().toString() + File.separator; @@ -71,6 +77,7 @@ public class AS2ScriptImporter { String fileName = Path.combine(currentOutDir, name) + ".as"; if (new File(fileName).exists()) { + asm.getSwf().informListeners("importing_as", fileName); String txt = Helper.readTextFile(fileName); ActionScript2Parser par = new ActionScript2Parser(asm.getSwf(), asm); @@ -82,16 +89,22 @@ public class AS2ScriptImporter { logger.log(Level.SEVERE, "%error% on line %line%, file: %file%".replace("%error%", ex.text).replace("%line%", Long.toString(ex.line)).replace("%file%", fileName), ex); } catch (IOException ex) { logger.log(Level.SEVERE, "error during script import, file: %file%".replace("%file%", fileName), ex); + } catch (InterruptedException ex) { + return importCount; } catch (Exception ex) { logger.log(Level.SEVERE, "error during script import, file: %file%".replace("%file%", fileName), ex); } asm.setModified(); importCount++; + if (listener != null) { + listener.scriptImported(); + } } fileName = Path.combine(currentOutDir, name) + ".pcode"; if (new File(fileName).exists()) { + asm.getSwf().informListeners("importing_as", fileName); String txt = Helper.readTextFile(fileName); try { @@ -104,19 +117,27 @@ public class AS2ScriptImporter { asm.setModified(); importCount++; + if (listener != null) { + listener.scriptImported(); + } } fileName = Path.combine(currentOutDir, name) + ".hex"; if (new File(fileName).exists()) { + asm.getSwf().informListeners("importing_as", fileName); String txt = Helper.readTextFile(fileName); asm.setActionBytes(Helper.getBytesFromHexaText(txt)); asm.setModified(); importCount++; + if (listener != null) { + listener.scriptImported(); + } } fileName = Path.combine(currentOutDir, name) + ".txt"; if (new File(fileName).exists()) { + asm.getSwf().informListeners("importing_as", fileName); String txt = Helper.readTextFile(fileName); try { @@ -126,6 +147,9 @@ public class AS2ScriptImporter { } asm.setModified(); importCount++; + if (listener != null) { + listener.scriptImported(); + } } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/AS3ScriptImporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/AS3ScriptImporter.java index 21afe4e50..512ccf581 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/AS3ScriptImporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/AS3ScriptImporter.java @@ -34,16 +34,24 @@ public class AS3ScriptImporter { private static final Logger logger = Logger.getLogger(AS3ScriptImporter.class.getName()); - public int importScripts(As3ScriptReplacerInterface scriptReplacer, String scriptsFolder, List packs) { + public int importScripts(As3ScriptReplacerInterface scriptReplacer, String scriptsFolder, List packs) throws InterruptedException { + return importScripts(scriptReplacer, scriptsFolder, packs, null); + } + + public int importScripts(As3ScriptReplacerInterface scriptReplacer, String scriptsFolder, List packs, ScriptImporterProgressListener listener) throws InterruptedException { if (!scriptsFolder.endsWith(File.separator)) { scriptsFolder += File.separator; } int importCount = 0; for (ScriptPack pack : packs) { + if (Thread.currentThread().isInterrupted()) { + return importCount; + } try { File file = pack.getExportFile(scriptsFolder, new ScriptExportSettings(ScriptExportMode.AS, false, false)); if (file.exists()) { + pack.getSwf().informListeners("importing_as", file.getAbsolutePath()); String fileName = file.getAbsolutePath(); String txt = Helper.readTextFile(fileName); @@ -54,10 +62,13 @@ public class AS3ScriptImporter { logger.log(Level.SEVERE, "%error% on line %line%, column %col%, file: %file%".replace("%error%", item.getMessage()).replace("%line%", Long.toString(item.getLine())).replace("%file%", fileName).replace("%col%", "" + item.getCol())); } } catch (InterruptedException ex) { - logger.log(Level.SEVERE, "error during script import, file: %file%".replace("%file%", fileName), ex); + return importCount; } importCount++; + if (listener != null) { + listener.scriptImported(); + } } } catch (IOException ex) { logger.log(Level.SEVERE, null, ex); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ScriptImporterProgressListener.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ScriptImporterProgressListener.java new file mode 100644 index 000000000..efa722ad2 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/importers/ScriptImporterProgressListener.java @@ -0,0 +1,9 @@ +package com.jpexs.decompiler.flash.importers; + +/** + * + * @author JPEXS + */ +public interface ScriptImporterProgressListener { + public void scriptImported(); +} diff --git a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript2ParserTest.java b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript2ParserTest.java index cf25cb45d..de9347606 100644 --- a/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript2ParserTest.java +++ b/libsrc/ffdec_lib/test/com/jpexs/decompiler/flash/ActionScript2ParserTest.java @@ -16,12 +16,15 @@ */ package com.jpexs.decompiler.flash; +import com.jpexs.decompiler.flash.action.parser.ActionParseException; import com.jpexs.decompiler.flash.action.parser.script.ActionScript2Parser; import com.jpexs.decompiler.flash.action.swf4.ActionPush; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.tags.DoActionTag; import com.jpexs.decompiler.graph.CompilationException; import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; import static org.testng.Assert.fail; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; @@ -44,7 +47,7 @@ public class ActionScript2ParserTest extends ActionScript2TestBase { swf.version = SWF.DEFAULT_VERSION; ActionScript2Parser par = new ActionScript2Parser(swf, new DoActionTag(swf)); par.actionsFromString(script); - } catch (IOException | CompilationException | ParseException ex) { + } catch (IOException | CompilationException | ParseException | InterruptedException ex) { fail("Unable to parse: " + script, ex); } } diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index 419c13d3f..19a604dbb 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -196,6 +196,8 @@ public class Main { public static SearchResultsStorage searchResultsStorage = new SearchResultsStorage(); + public static CancellableWorker importWorker = null; + //This method makes file watcher to shut up during our own file saving public static void startSaving(File savedFile) { savedFiles.add(savedFile); @@ -1046,6 +1048,9 @@ public class Main { if (event.equals("rename")) { startWork(AppStrings.translate("work.renaming") + "..." + (String) data, null); } + if (event.equals("importing_as")) { + startWork(AppStrings.translate("work.importing_as") + "..." + (String) data, importWorker); + } } }); } diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 21ed803ff..227357916 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -101,6 +101,7 @@ import com.jpexs.decompiler.flash.importers.As3ScriptReplacerInterface; import com.jpexs.decompiler.flash.importers.BinaryDataImporter; import com.jpexs.decompiler.flash.importers.FFDecAs3ScriptReplacer; import com.jpexs.decompiler.flash.importers.ImageImporter; +import com.jpexs.decompiler.flash.importers.ScriptImporterProgressListener; import com.jpexs.decompiler.flash.importers.ShapeImporter; import com.jpexs.decompiler.flash.importers.SwfXmlImporter; import com.jpexs.decompiler.flash.importers.SymbolClassImporter; @@ -2500,18 +2501,56 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { String selFile = Helper.fixDialogFile(chooser.getSelectedFile()).getAbsolutePath(); String scriptsFolder = Path.combine(selFile, ScriptExportSettings.EXPORT_FOLDER_NAME); + final long timeBefore = System.currentTimeMillis(); + new CancellableWorker() { + private int countAs2 = 0; + private int countAs3 = 0; + @Override + public Void doInBackground() throws Exception { + new AS2ScriptImporter().importScripts(scriptsFolder, swf.getASMs(true), new ScriptImporterProgressListener() { + @Override + public void scriptImported() { + countAs2++; + } + }); + new AS3ScriptImporter().importScripts(as3ScriptReplacer, scriptsFolder, swf.getAS3Packs(), new ScriptImporterProgressListener() { + @Override + public void scriptImported() { + countAs3++; + } + } + ); - int countAs2 = new AS2ScriptImporter().importScripts(scriptsFolder, swf.getASMs(true)); - int countAs3 = new AS3ScriptImporter().importScripts(as3ScriptReplacer, scriptsFolder, swf.getAS3Packs()); + if (countAs3 > 0) { + updateClassesList(); + } + return null; + } - if (countAs3 > 0) { - updateClassesList(); - } + @Override + protected void onStart() { + Main.importWorker = this; + Main.startWork(translate("work.importing_as") + "...", this); + } + + @Override + protected void done() { + Main.stopWork(); + long timeAfter = System.currentTimeMillis(); + final long timeMs = timeAfter - timeBefore; + + Main.importWorker = null; + View.execInEventDispatch(() -> { + setStatus(translate("importing_as.finishedin").replace("%time%", Helper.formatTimeSec(timeMs))); + + ViewMessages.showMessageDialog(MainPanel.this, translate("import.script.result").replace("%count%", Integer.toString(countAs2 + countAs3))); + if (countAs2 != 0 || countAs3 != 0) { + reload(true); + } + }); + } + }.execute(); - ViewMessages.showMessageDialog(this, translate("import.script.result").replace("%count%", Integer.toString(countAs2 + countAs3))); - if (countAs2 != 0 || countAs3 != 0) { - reload(true); - } } } diff --git a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties index ca9b3de5d..81fd076b8 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/MainFrame.properties @@ -848,4 +848,7 @@ message.info.importXml = For XML importing, you need a XML file in special forma tagInfo.dependentFrames = Dependent Frames -imagePanel.depth = depth: \ No newline at end of file +imagePanel.depth = depth: + +work.importing_as = Importing script +importing_as.finishedin = Imported in %time% \ No newline at end of file