From ff3be16d675a86aa29bc6850ed5930c8b8ef08ca Mon Sep 17 00:00:00 2001 From: "Maxim.Medvedev" Date: Thu, 10 May 2012 15:07:48 +0400 Subject: [PATCH] 'remove catch block' fix for groovy --- .../groovy/annotator/GroovyAnnotator.java | 5 +- .../intentions/GrRemoveExceptionFix.java | 108 ++++++++++++++++++ .../GroovyIntentionsBundle.properties | 5 +- .../types/GrDisjunctionTypeElementImpl.java | 26 +++++ 4 files changed, 141 insertions(+), 3 deletions(-) create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GrRemoveExceptionFix.java diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java index af683cbe996c..0ce3941bd63d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/GroovyAnnotator.java @@ -266,7 +266,7 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { for (int j = 0; j < types.length; j++) { if (i != j && types[j].isAssignableFrom(types[i])) { myHolder.createWarningAnnotation(elements[i], GroovyBundle.message("unnecessary.type", types[i].getCanonicalText(), - types[j].getCanonicalText())); + types[j].getCanonicalText())).registerFix(new GrRemoveExceptionFix(true)); } } } @@ -285,7 +285,8 @@ public class GroovyAnnotator extends GroovyElementVisitor implements Annotator { private boolean checkExceptionUsed(List usedExceptions, GrParameter parameter, GrTypeElement typeElement, PsiType type) { for (PsiType exception : usedExceptions) { if (exception.isAssignableFrom(type)) { - myHolder.createWarningAnnotation(typeElement != null ? typeElement : parameter.getNameIdentifierGroovy(), GroovyBundle.message("exception.0.has.already.been.caught", type.getCanonicalText())); + myHolder.createWarningAnnotation(typeElement != null ? typeElement : parameter.getNameIdentifierGroovy(),GroovyBundle.message("exception.0.has.already.been.caught", type.getCanonicalText())) + .registerFix(new GrRemoveExceptionFix(parameter.getTypeElementGroovy() instanceof GrDisjunctionTypeElement)); return false; } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GrRemoveExceptionFix.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GrRemoveExceptionFix.java new file mode 100644 index 000000000000..9402f682e1e3 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/annotator/intentions/GrRemoveExceptionFix.java @@ -0,0 +1,108 @@ +/* + * Copyright 2000-2012 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jetbrains.plugins.groovy.annotator.intentions; + +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.plugins.groovy.intentions.GroovyIntentionsBundle; +import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrCatchClause; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrDisjunctionTypeElement; +import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; + +/** + * @author Max Medvedev + */ +public class GrRemoveExceptionFix implements IntentionAction { + private String myText; + private final boolean myDisjunction; + + public GrRemoveExceptionFix(boolean isDisjunction) { + myDisjunction = isDisjunction; + if (isDisjunction) { + myText = GroovyIntentionsBundle.message("remove.exception"); + } + else { + myText = GroovyIntentionsBundle.message("remove.catch.block"); + } + } + + @NotNull + @Override + public String getText() { + return myText; + } + + @NotNull + @Override + public String getFamilyName() { + return GroovyIntentionsBundle.message("try.catch.fix"); + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + return myDisjunction && findTypeElementInDisjunction(editor, file) != null || !myDisjunction && findCatch(editor, file) != null; + } + + @Nullable + private static GrTypeElement findTypeElementInDisjunction(Editor editor, PsiFile file) { + final int offset = editor.getCaretModel().getOffset(); + final PsiElement at = file.findElementAt(offset); + final GrDisjunctionTypeElement disjunction = PsiTreeUtil.getParentOfType(at, GrDisjunctionTypeElement.class); + if (disjunction == null) return null; + for (GrTypeElement element : disjunction.getTypeElements()) { + if (element.getTextRange().contains(offset)) { + return element; + } + } + return null; + } + + @Nullable + private static GrCatchClause findCatch(Editor editor, PsiFile file) { + final int offset = editor.getCaretModel().getOffset(); + final PsiElement at = file.findElementAt(offset); + return PsiTreeUtil.getParentOfType(at, GrCatchClause.class); + } + + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + if (myDisjunction) { + final GrTypeElement element = findTypeElementInDisjunction(editor, file); + if (element != null) { + element.delete(); + } + } + else { + final GrCatchClause aCatch = findCatch(editor, file); + if (aCatch != null) { + aCatch.delete(); + } + } + } + + @Override + public boolean startInWriteAction() { + return true; + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties index 7e388d2f9f6d..00d90c07f79d 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/intentions/GroovyIntentionsBundle.properties @@ -149,4 +149,7 @@ split.into.declaration.and.assignment=Split into declaration and assignment split.into.separate.declaration=Split into separate declaration gr.split.declaration.family.name=Split Variable Declaration remove.parameter.0=Remove parameter ''{0}'' -remove.unused.parameter=Remove unused parameter \ No newline at end of file +remove.unused.parameter=Remove unused parameter +remove.exception=Remove exception +remove.catch.block=Remove catch block +try.catch.fix=Try-catch fix \ No newline at end of file diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrDisjunctionTypeElementImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrDisjunctionTypeElementImpl.java index e6cdd85cf07f..1c79f9fbf112 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrDisjunctionTypeElementImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/types/GrDisjunctionTypeElementImpl.java @@ -17,11 +17,14 @@ package org.jetbrains.plugins.groovy.lang.psi.impl.types; import com.intellij.lang.ASTNode; import com.intellij.psi.PsiDisjunctionType; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiType; import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrDisjunctionTypeElement; import org.jetbrains.plugins.groovy.lang.psi.api.types.GrTypeElement; import org.jetbrains.plugins.groovy.lang.psi.impl.GroovyPsiElementImpl; +import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil; import java.util.ArrayList; @@ -69,4 +72,27 @@ public class GrDisjunctionTypeElementImpl extends GroovyPsiElementImpl implement public String toString() { return "disjunction type element"; } + + @Override + public void deleteChildInternal(@NotNull ASTNode child) { + final PsiElement psi = child.getPsi(); + if (psi instanceof GrTypeElement) { + PsiElement next = PsiUtil.skipWhitespaces(psi.getNextSibling(), true); + if (next != null) { + if (next.getNode().getElementType() == GroovyTokenTypes.mBOR) { + super.deleteChildInternal(next.getNode()); + } + } + else { + PsiElement prev = PsiUtil.skipWhitespaces(psi.getPrevSibling(), false); + if (prev != null) { + if (prev.getNode().getElementType() == GroovyTokenTypes.mBOR) { + super.deleteChildInternal(prev.getNode()); + } + } + } + } + + super.deleteChildInternal(child); + } }