diff --git a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/RemoveFinallyStatementsVisitor.java b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/RemoveFinallyStatementsVisitor.java index ac8d7216..4f703c2e 100644 --- a/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/RemoveFinallyStatementsVisitor.java +++ b/src/main/java/org/jd/core/v1/service/converter/classfiletojavasyntax/visitor/RemoveFinallyStatementsVisitor.java @@ -20,6 +20,7 @@ public class RemoveFinallyStatementsVisitor implements StatementVisitor { protected LocalVariableMaker localVariableMaker; protected int statementCountInFinally; protected int statementCountToRemove; + protected boolean lastFinallyStatementIsATryStatement; public RemoveFinallyStatementsVisitor(LocalVariableMaker localVariableMaker) { this.localVariableMaker = localVariableMaker; @@ -28,6 +29,7 @@ public RemoveFinallyStatementsVisitor(LocalVariableMaker localVariableMaker) { public void init() { this.statementCountInFinally = 0; this.statementCountToRemove = 0; + this.lastFinallyStatementIsATryStatement = false; } @Override @@ -64,34 +66,40 @@ public void visit(Statements statements) { } // Remove 'finally' statements - declaredSyntheticLocalVariableVisitor.init(); - if (statementCountToRemove > 0) { - // Remove 'finally' statements - if (i > statementCountToRemove) { - List list = statements.subList(i - statementCountToRemove, i); - - for (Statement statement : list) { - statement.accept(declaredSyntheticLocalVariableVisitor); - } - - lastStatement.accept(declaredSyntheticLocalVariableVisitor); - list.clear(); - i -= statementCountToRemove; + if (!lastFinallyStatementIsATryStatement && (i > 0) && (stmts.get(i-1).getClass() == ClassFileTryStatement.class)) { + stmts.get(i-1).accept(this); statementCountToRemove = 0; + i--; } else { - List list = statements; + declaredSyntheticLocalVariableVisitor.init(); - for (Statement statement : list) { - statement.accept(declaredSyntheticLocalVariableVisitor); - } + // Remove 'finally' statements + if (i > statementCountToRemove) { + List list = statements.subList(i - statementCountToRemove, i); - list.clear(); - if (i < size) { - list.add(lastStatement); + for (Statement statement : list) { + statement.accept(declaredSyntheticLocalVariableVisitor); + } + + lastStatement.accept(declaredSyntheticLocalVariableVisitor); + list.clear(); + i -= statementCountToRemove; + statementCountToRemove = 0; + } else { + List list = statements; + + for (Statement statement : list) { + statement.accept(declaredSyntheticLocalVariableVisitor); + } + + list.clear(); + if (i < size) { + list.add(lastStatement); + } + statementCountToRemove -= i; + i = 0; } - statementCountToRemove -= i; - i = 0; } } @@ -152,11 +160,22 @@ public void visit(SwitchStatement statement) { @Override public void visit(TryStatement statement) { + boolean oldLastFinallyStatementIsTryStatement = lastFinallyStatementIsATryStatement; ClassFileTryStatement ts = (ClassFileTryStatement)statement; Statements tryStatements = (Statements)ts.getTryStatements(); Statements finallyStatements = (Statements)ts.getFinallyStatements(); - safeAccept(finallyStatements); + if (finallyStatements != null) { + switch (finallyStatements.size()) { + case 0: break; + case 1: finallyStatements.getFirst().accept(this); break; + default: for (Statement stmt : finallyStatements) stmt.accept(this); break; + } + + if ((statementCountInFinally == 0) && (finallyStatements.size() > 0)) { + lastFinallyStatementIsATryStatement = (finallyStatements.getLast().getClass() == ClassFileTryStatement.class); + } + } if (ts.isJsr() || (finallyStatements == null) || (finallyStatements.size() == 0)) { tryStatements.accept(this); @@ -168,13 +187,13 @@ public void visit(TryStatement statement) { statementCountInFinally += finallyStatementsSize; - removeFinallyStatements(tryStatements); + tryStatements.accept(this); statementCountToRemove = finallyStatementsSize; if (catchClauses != null) { for (TryStatement.CatchClause cc : catchClauses) { - removeFinallyStatements((Statements)cc.getStatements()); + cc.getStatements().accept(this); } } @@ -192,11 +211,11 @@ public void visit(TryStatement statement) { statementCountInFinally += finallyStatementsSize; statementCountToRemove += finallyStatementsSize; - removeFinallyStatements(tryStatements); + tryStatements.accept(this); if (catchClauses != null) { for (TryStatement.CatchClause cc : catchClauses) { - removeFinallyStatements((Statements)cc.getStatements()); + cc.getStatements().accept(this); } } @@ -207,20 +226,8 @@ public void visit(TryStatement statement) { ts.setFinallyStatements(null); } } - } - - public void removeFinallyStatements(Statements list) { - if ((list.size() == 1) && (list.get(0).getClass() == ClassFileTryStatement.class)) { - int oldStatementCountToRemove = statementCountToRemove; - assert list.getFirst().getClass() == ClassFileTryStatement.class; - - statementCountToRemove = 0; - list.accept(this); - statementCountToRemove = oldStatementCountToRemove; - } else { - list.accept(this); - } + lastFinallyStatementIsATryStatement = oldLastFinallyStatementIsTryStatement; } @Override public void visit(DoWhileStatement statement) { safeAccept(statement.getStatements()); }