blob: 555b5a1fe3bb04c1e0625d862e3e288d721e26b2 [file] [log] [blame]
/*
* Copyright 2011-2013 Bas Leijdekkers
*
* 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 com.siyeh.ig.errorhandling;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.lang.LanguageDocumentation;
import com.intellij.lang.documentation.CodeDocumentationProvider;
import com.intellij.lang.documentation.CompositeDocumentationProvider;
import com.intellij.lang.documentation.DocumentationProvider;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.javadoc.PsiDocTagValue;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.InspectionGadgetsFix;
import org.jetbrains.annotations.NotNull;
public class ThrowsRuntimeExceptionInspection extends ThrowsRuntimeExceptionInspectionBase {
@NotNull
@Override
protected InspectionGadgetsFix[] buildFixes(Object... infos) {
final String exceptionName = (String)infos[0];
if (MoveExceptionToJavadocFix.isApplicable((PsiJavaCodeReferenceElement)infos[1])) {
return new InspectionGadgetsFix[] {
new ThrowsRuntimeExceptionFix(exceptionName),
new MoveExceptionToJavadocFix(exceptionName)
};
}
return new InspectionGadgetsFix[] {new ThrowsRuntimeExceptionFix(exceptionName)};
}
private static class MoveExceptionToJavadocFix extends InspectionGadgetsFix {
private final String myExceptionName;
private MoveExceptionToJavadocFix(String exceptionName) {
myExceptionName = exceptionName;
}
@NotNull
@Override
public String getName() {
return InspectionGadgetsBundle.message("throws.runtime.exception.move.quickfix", myExceptionName);
}
@NotNull
@Override
public String getFamilyName() {
return "Move to Javadoc '@throws'";
}
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
final PsiElement element = descriptor.getPsiElement();
final PsiElement parent = element.getParent();
final PsiElement grandParent = parent.getParent();
if (!(grandParent instanceof PsiMethod)) {
return;
}
final PsiMethod method = (PsiMethod)grandParent;
final PsiDocComment comment = method.getDocComment();
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
if (comment != null) {
final PsiDocTag docTag = factory.createDocTagFromText("@throws " + element.getText());
comment.add(docTag);
}
else {
final PsiDocComment docComment = factory.createDocCommentFromText("/** */");
final PsiComment resultComment = (PsiComment)method.addBefore(docComment, method.getModifierList());
final DocumentationProvider documentationProvider = LanguageDocumentation.INSTANCE.forLanguage(method.getLanguage());
final CodeDocumentationProvider codeDocumentationProvider;
if (documentationProvider instanceof CodeDocumentationProvider) {
codeDocumentationProvider = (CodeDocumentationProvider)documentationProvider;
} else if (documentationProvider instanceof CompositeDocumentationProvider) {
final CompositeDocumentationProvider compositeDocumentationProvider = (CompositeDocumentationProvider)documentationProvider;
codeDocumentationProvider = compositeDocumentationProvider.getFirstCodeDocumentationProvider();
if (codeDocumentationProvider == null) {
return;
}
} else {
return;
}
final String commentStub = codeDocumentationProvider.generateDocumentationContentStub(resultComment);
final PsiDocComment newComment = factory.createDocCommentFromText("/**\n" + commentStub + "*/");
resultComment.replace(newComment);
}
element.delete();
}
public static boolean isApplicable(@NotNull PsiJavaCodeReferenceElement reference) {
final PsiElement parent = reference.getParent();
final PsiElement grandParent = parent.getParent();
if (!(grandParent instanceof PsiMethod)) {
return false;
}
final PsiMethod method = (PsiMethod)grandParent;
final PsiDocComment docComment = method.getDocComment();
if (docComment == null) {
return true;
}
final PsiElement throwsTarget = reference.resolve();
if (throwsTarget == null) {
return true;
}
final PsiDocTag[] tags = docComment.findTagsByName("throws");
for (PsiDocTag tag : tags) {
final PsiDocTagValue valueElement = tag.getValueElement();
if (valueElement == null) {
continue;
}
final PsiElement child = valueElement.getFirstChild();
if (child == null) {
continue;
}
final PsiElement grandChild = child.getFirstChild();
if (!(grandChild instanceof PsiJavaCodeReferenceElement)) {
continue;
}
final PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)grandChild;
final PsiElement target = referenceElement.resolve();
if (throwsTarget.equals(target)) {
return false;
}
}
return true;
}
}
private static class ThrowsRuntimeExceptionFix extends InspectionGadgetsFix {
private final String myClassName;
public ThrowsRuntimeExceptionFix(String className) {
myClassName = className;
}
@NotNull
@Override
public String getName() {
return InspectionGadgetsBundle.message("throws.runtime.exception.quickfix", myClassName);
}
@NotNull
@Override
public String getFamilyName() {
return "Remove from \"throws\" clause";
}
@Override
protected void doFix(Project project, ProblemDescriptor descriptor) throws IncorrectOperationException {
descriptor.getPsiElement().delete();
}
}
}