2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.codeInsight
.highlighting
;
18 import com
.intellij
.codeInsight
.CodeInsightBundle
;
19 import com
.intellij
.codeInsight
.ExceptionUtil
;
20 import com
.intellij
.lang
.LangBundle
;
21 import com
.intellij
.openapi
.editor
.Editor
;
22 import com
.intellij
.openapi
.project
.Project
;
23 import com
.intellij
.openapi
.util
.Condition
;
24 import com
.intellij
.psi
.*;
25 import com
.intellij
.util
.Consumer
;
27 import java
.util
.Arrays
;
28 import java
.util
.List
;
30 public class HighlightExceptionsHandler
extends HighlightUsagesHandlerBase
<PsiClass
> {
31 private final PsiElement myTarget
;
32 private final PsiClassType
[] myClassTypes
;
33 private final PsiElement myPlace
;
34 private final Condition
<PsiType
> myTypeFilter
;
36 public HighlightExceptionsHandler(final Editor editor
, final PsiFile file
, final PsiElement target
, final PsiClassType
[] classTypes
,
37 final PsiElement place
, final Condition
<PsiType
> typeFilter
) {
40 myClassTypes
= classTypes
;
42 myTypeFilter
= typeFilter
;
45 public List
<PsiClass
> getTargets() {
46 return ChooseClassAndDoHighlightRunnable
.resolveClasses(myClassTypes
);
49 protected void selectTargets(final List
<PsiClass
> targets
, final Consumer
<List
<PsiClass
>> selectionConsumer
) {
50 new ChooseClassAndDoHighlightRunnable(myClassTypes
, myEditor
, CodeInsightBundle
.message("highlight.exceptions.thrown.chooser.title")) {
51 protected void selected(PsiClass
... classes
) {
52 selectionConsumer
.consume(Arrays
.asList(classes
));
57 public void computeUsages(final List
<PsiClass
> targets
) {
58 final Project project
= myEditor
.getProject();
59 final PsiElementFactory factory
= JavaPsiFacade
.getInstance(project
).getElementFactory();
61 addOccurrence(myTarget
);
62 for (PsiClass aClass
: targets
) {
63 addExceptionThrownPlaces(factory
.createType(aClass
));
65 buildStatusText(LangBundle
.message("java.terms.exception"), myReadUsages
.size()-1 /* exclude target */);
68 private void addExceptionThrownPlaces(final PsiType type
) {
69 if (type
instanceof PsiClassType
) {
70 myPlace
.accept(new JavaRecursiveElementWalkingVisitor() {
71 @Override public void visitReferenceExpression(PsiReferenceExpression expression
) {
72 visitElement(expression
);
75 @Override public void visitThrowStatement(PsiThrowStatement statement
) {
76 super.visitThrowStatement(statement
);
77 PsiClassType actualType
= ExceptionUtil
.getUnhandledException(statement
, myPlace
);
78 if (actualType
!= null && type
.isAssignableFrom(actualType
) && myTypeFilter
.value(actualType
)) {
79 PsiExpression psiExpression
= statement
.getException();
80 if (psiExpression
instanceof PsiReferenceExpression
) {
81 addOccurrence(psiExpression
);
83 else if (psiExpression
instanceof PsiNewExpression
) {
84 PsiJavaCodeReferenceElement ref
= ((PsiNewExpression
)psiExpression
).getClassReference();
88 addOccurrence(statement
.getException());
93 @Override public void visitMethodCallExpression(PsiMethodCallExpression expression
) {
94 super.visitMethodCallExpression(expression
);
95 PsiReference reference
= expression
.getMethodExpression().getReference();
96 if (reference
== null) return;
97 List
<PsiClassType
> exceptionTypes
= ExceptionUtil
.getUnhandledExceptions(expression
, myPlace
);
98 for (final PsiClassType actualType
: exceptionTypes
) {
99 if (type
.isAssignableFrom(actualType
) && myTypeFilter
.value(actualType
)) {
100 addOccurrence(expression
.getMethodExpression());
106 @Override public void visitNewExpression(PsiNewExpression expression
) {
107 super.visitNewExpression(expression
);
108 PsiJavaCodeReferenceElement classReference
= expression
.getClassOrAnonymousClassReference();
109 if (classReference
== null) return;
110 List
<PsiClassType
> exceptionTypes
= ExceptionUtil
.getUnhandledExceptions(expression
, myPlace
);
111 for (PsiClassType actualType
: exceptionTypes
) {
112 if (type
.isAssignableFrom(actualType
) && myTypeFilter
.value(actualType
)) {
113 addOccurrence(classReference
);