IDEA-52817 ("Empty finally block" should offer intention to remove try/finally block)
authorBas Leijdekkers <leijdekkers@carp-technologies.nl>
Tue, 16 Mar 2010 13:26:45 +0000 (14:26 +0100)
committerBas Leijdekkers <leijdekkers@carp-technologies.nl>
Tue, 16 Mar 2010 13:26:45 +0000 (14:26 +0100)
plugins/InspectionGadgets/src/com/siyeh/InspectionGadgetsBundle.properties
plugins/InspectionGadgets/src/com/siyeh/ig/errorhandling/EmptyFinallyBlockInspection.java

index adb7cb3c2d11ca08e9ab8c118eb9a25cbbe21db1..c0802ef69c121259c0ea726a19feabe7ae110737 100644 (file)
@@ -1757,3 +1757,5 @@ unnecessary.javadoc.link.problem.descriptor=<code>#ref</code> is unnecessary
 unnecessary.javadoc.link.quickfix=Remove unnecessary {0}
 thread.local.not.static.final.display.name=ThreadLocal field not declared static final
 thread.local.not.static.final.problem.descriptor=ThreadLocal <code>#ref</code> is not declared 'static final'
+remove.try.finally.block.quickfix=Remove try-finally block
+remove.finally.block.quickfix=Remove finally block
index a164460895d9fb4cc23539e4295e5d7f8b3f51f9..dca798e9d15408e60e5b0591da4b3516660197a0 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2003-2007 Dave Griffith, Bas Leijdekkers
+ * Copyright 2003-2010 Dave Griffith, Bas Leijdekkers
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 package com.siyeh.ig.errorhandling;
 
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.IncorrectOperationException;
 import com.siyeh.InspectionGadgetsBundle;
 import com.siyeh.ig.BaseInspection;
 import com.siyeh.ig.BaseInspectionVisitor;
+import com.siyeh.ig.InspectionGadgetsFix;
 import org.jetbrains.annotations.NotNull;
 
 public class EmptyFinallyBlockInspection extends BaseInspection {
 
+    @Override
     @NotNull
     public String getDisplayName() {
         return InspectionGadgetsBundle.message(
                 "empty.finally.block.display.name");
     }
 
+    @Override
     public boolean isEnabledByDefault() {
         return true;
     }
 
+    @Override
     @NotNull
     protected String buildErrorString(Object... infos) {
         return InspectionGadgetsBundle.message(
                 "empty.finally.block.problem.descriptor");
     }
 
+    @Override
+    protected InspectionGadgetsFix buildFix(Object... infos) {
+        final Integer count = (Integer)infos[0];
+        if (count.intValue() == 0) {
+            return new RemoveTryFinallyBlockFix();
+        } else {
+            return new RemoveFinallyBlockFix();
+        }
+    }
+
+    private static class RemoveTryFinallyBlockFix extends InspectionGadgetsFix {
+
+        @NotNull
+        public String getName() {
+            return InspectionGadgetsBundle.message(
+                    "remove.try.finally.block.quickfix");
+        }
+
+        @Override
+        protected void doFix(Project project, ProblemDescriptor descriptor)
+                throws IncorrectOperationException {
+            final PsiElement element = descriptor.getPsiElement();
+            final PsiTryStatement tryStatement =
+                    PsiTreeUtil.getParentOfType(element, PsiTryStatement.class);
+            if (tryStatement == null) {
+                return;
+            }
+            final PsiCodeBlock tryBlock = tryStatement.getTryBlock();
+            if (tryBlock == null) {
+                return;
+            }
+            final PsiStatement[] statements = tryBlock.getStatements();
+            final PsiElement parent = tryStatement.getParent();
+            for (PsiStatement statement : statements) {
+                parent.addBefore(statement, tryStatement);
+            }
+            tryStatement.delete();
+        }
+    }
+
+    private static class RemoveFinallyBlockFix extends InspectionGadgetsFix {
+
+        @NotNull
+        public String getName() {
+            return InspectionGadgetsBundle.message(
+                    "remove.finally.block.quickfix");
+        }
+
+        @Override
+        protected void doFix(Project project, ProblemDescriptor descriptor)
+                throws IncorrectOperationException {
+            final PsiElement element = descriptor.getPsiElement();
+            final PsiTryStatement tryStatement =
+                    PsiTreeUtil.getParentOfType(element, PsiTryStatement.class);
+            if (tryStatement == null) {
+                return;
+            }
+            final PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock();
+            if (finallyBlock == null) {
+                return;
+            }
+            deleteUntilFinally(finallyBlock);
+        }
+
+        private static void deleteUntilFinally(PsiElement element) {
+            if (element instanceof PsiJavaToken) {
+                final PsiJavaToken keyword = (PsiJavaToken)element;
+                final IElementType tokenType = keyword.getTokenType();
+                if (tokenType.equals(JavaTokenType.FINALLY_KEYWORD)) {
+                    keyword.delete();
+                    return;
+                }
+            }
+            deleteUntilFinally(element.getPrevSibling());
+            if (!(element instanceof PsiWhiteSpace)) {
+                element.delete();
+            }
+        }
+    }
+
+    @Override
     public BaseInspectionVisitor buildVisitor() {
         return new EmptyFinallyBlockVisitor();
     }
@@ -46,7 +136,8 @@ public class EmptyFinallyBlockInspection extends BaseInspection {
     private static class EmptyFinallyBlockVisitor
             extends BaseInspectionVisitor {
 
-        @Override public void visitTryStatement(@NotNull PsiTryStatement statement) {
+        @Override public void visitTryStatement(
+                @NotNull PsiTryStatement statement) {
             super.visitTryStatement(statement);
             if (JspPsiUtil.isInJspFile(statement.getContainingFile())) {
                 return;
@@ -58,11 +149,12 @@ public class EmptyFinallyBlockInspection extends BaseInspection {
             if (finallyBlock.getStatements().length != 0) {
                 return;
             }
+            final PsiCodeBlock[] catchBlocks = statement.getCatchBlocks();
             final PsiElement[] children = statement.getChildren();
             for (final PsiElement child : children) {
                 final String childText = child.getText();
                 if (PsiKeyword.FINALLY.equals(childText)) {
-                    registerError(child);
+                    registerError(child, Integer.valueOf(catchBlocks.length));
                     return;
                 }
             }