blob: bd57f733a72bb50d4f90400ceceb6e1c663992f6 [file] [log] [blame]
/*
* Copyright 2000-2009 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 com.intellij.codeInsight.highlighting;
import com.intellij.codeInsight.CodeInsightBundle;
import com.intellij.codeInsight.ExceptionUtil;
import com.intellij.lang.LangBundle;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.*;
import com.intellij.util.Consumer;
import java.util.Arrays;
import java.util.List;
public class HighlightExceptionsHandler extends HighlightUsagesHandlerBase<PsiClass> {
private final PsiElement myTarget;
private final PsiClassType[] myClassTypes;
private final PsiElement myPlace;
private final Condition<PsiType> myTypeFilter;
public HighlightExceptionsHandler(final Editor editor, final PsiFile file, final PsiElement target, final PsiClassType[] classTypes,
final PsiElement place, final Condition<PsiType> typeFilter) {
super(editor, file);
myTarget = target;
myClassTypes = classTypes;
myPlace = place;
myTypeFilter = typeFilter;
}
@Override
public List<PsiClass> getTargets() {
return ChooseClassAndDoHighlightRunnable.resolveClasses(myClassTypes);
}
@Override
protected void selectTargets(final List<PsiClass> targets, final Consumer<List<PsiClass>> selectionConsumer) {
new ChooseClassAndDoHighlightRunnable(myClassTypes, myEditor, CodeInsightBundle.message("highlight.exceptions.thrown.chooser.title")) {
@Override
protected void selected(PsiClass... classes) {
selectionConsumer.consume(Arrays.asList(classes));
}
}.run();
}
@Override
public void computeUsages(final List<PsiClass> targets) {
final Project project = myEditor.getProject();
final PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
addOccurrence(myTarget);
for (PsiClass aClass : targets) {
addExceptionThrownPlaces(factory.createType(aClass));
}
buildStatusText(LangBundle.message("java.terms.exception"), myReadUsages.size()-1 /* exclude target */);
}
private void addExceptionThrownPlaces(final PsiType type) {
if (type instanceof PsiClassType) {
myPlace.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitReferenceExpression(PsiReferenceExpression expression) {
visitElement(expression);
}
@Override
public void visitThrowStatement(PsiThrowStatement statement) {
super.visitThrowStatement(statement);
final List<PsiClassType> actualTypes = ExceptionUtil.getUnhandledExceptions(statement, myPlace);
for (PsiClassType actualType : actualTypes) {
if (actualType != null && type.isAssignableFrom(actualType) && myTypeFilter.value(actualType)) {
PsiExpression psiExpression = statement.getException();
if (psiExpression instanceof PsiReferenceExpression) {
addOccurrence(psiExpression);
}
else if (psiExpression instanceof PsiNewExpression) {
PsiJavaCodeReferenceElement ref = ((PsiNewExpression)psiExpression).getClassReference();
if (ref != null) {
addOccurrence(ref);
}
}
else {
addOccurrence(statement.getException());
}
}
}
}
@Override
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
super.visitMethodCallExpression(expression);
PsiReference reference = expression.getMethodExpression().getReference();
if (reference == null) return;
List<PsiClassType> exceptionTypes = ExceptionUtil.getUnhandledExceptions(expression, myPlace);
for (final PsiClassType actualType : exceptionTypes) {
if (type.isAssignableFrom(actualType) && myTypeFilter.value(actualType)) {
addOccurrence(expression.getMethodExpression());
break;
}
}
}
@Override
public void visitNewExpression(PsiNewExpression expression) {
super.visitNewExpression(expression);
PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
if (classReference == null) return;
List<PsiClassType> exceptionTypes = ExceptionUtil.getUnhandledExceptions(expression, myPlace);
for (PsiClassType actualType : exceptionTypes) {
if (type.isAssignableFrom(actualType) && myTypeFilter.value(actualType)) {
addOccurrence(classReference);
break;
}
}
}
});
}
}
}