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
.codeInspection
.deprecation
;
18 import com
.intellij
.codeInsight
.daemon
.JavaErrorMessages
;
19 import com
.intellij
.codeInsight
.daemon
.impl
.HighlightInfoType
;
20 import com
.intellij
.codeInsight
.daemon
.impl
.analysis
.HighlightMessageUtil
;
21 import com
.intellij
.codeInspection
.BaseJavaLocalInspectionTool
;
22 import com
.intellij
.codeInspection
.ProblemHighlightType
;
23 import com
.intellij
.codeInspection
.ProblemsHolder
;
24 import com
.intellij
.psi
.*;
25 import com
.intellij
.psi
.infos
.MethodCandidateInfo
;
26 import com
.intellij
.psi
.util
.MethodSignatureBackedByPsiMethod
;
27 import org
.jetbrains
.annotations
.NonNls
;
28 import org
.jetbrains
.annotations
.NotNull
;
30 import java
.util
.List
;
35 public class DeprecationInspection
extends BaseJavaLocalInspectionTool
{
36 @NonNls public static final String SHORT_NAME
= HighlightInfoType
.DEPRECATION_SHORT_NAME
;
37 @NonNls public static final String ID
= HighlightInfoType
.DEPRECATION_ID
;
38 public static final String DISPLAY_NAME
= HighlightInfoType
.DEPRECATION_DISPLAY_NAME
;
42 public PsiElementVisitor
buildVisitor(@NotNull final ProblemsHolder holder
, boolean isOnTheFly
) {
43 return new DeprecationElementVisitor(holder
);
47 public String
getDisplayName() {
52 public String
getGroupDisplayName() {
57 public String
getShortName() {
63 public String
getID() {
67 public boolean isEnabledByDefault() {
71 private static class DeprecationElementVisitor
extends JavaElementVisitor
{
72 private final ProblemsHolder myHolder
;
74 public DeprecationElementVisitor(final ProblemsHolder holder
) {
78 @Override public void visitReferenceElement(PsiJavaCodeReferenceElement reference
) {
79 JavaResolveResult result
= reference
.advancedResolve(true);
80 PsiElement resolved
= result
.getElement();
81 checkDeprecated(resolved
, reference
.getReferenceNameElement(), myHolder
);
84 @Override public void visitReferenceExpression(PsiReferenceExpression expression
) {
85 visitReferenceElement(expression
);
88 @Override public void visitNewExpression(PsiNewExpression expression
) {
89 PsiType type
= expression
.getType();
90 PsiExpressionList list
= expression
.getArgumentList();
91 if (!(type
instanceof PsiClassType
)) return;
92 PsiClassType
.ClassResolveResult typeResult
= ((PsiClassType
)type
).resolveGenerics();
93 PsiClass aClass
= typeResult
.getElement();
94 if (aClass
== null) return;
95 if (aClass
instanceof PsiAnonymousClass
) {
96 type
= ((PsiAnonymousClass
)aClass
).getBaseClassType();
97 typeResult
= ((PsiClassType
)type
).resolveGenerics();
98 aClass
= typeResult
.getElement();
99 if (aClass
== null) return;
101 final PsiResolveHelper resolveHelper
= JavaPsiFacade
.getInstance(expression
.getProject()).getResolveHelper();
102 final PsiMethod
[] constructors
= aClass
.getConstructors();
103 if (constructors
.length
> 0 && list
!= null) {
104 JavaResolveResult
[] results
= resolveHelper
.multiResolveConstructor((PsiClassType
)type
, list
, list
);
105 MethodCandidateInfo result
= null;
106 if (results
.length
== 1) result
= (MethodCandidateInfo
)results
[0];
108 PsiMethod constructor
= result
== null ?
null : result
.getElement();
109 if (constructor
!= null && expression
.getClassReference() != null) {
110 checkDeprecated(constructor
, expression
.getClassReference(), myHolder
);
115 @Override public void visitMethod(PsiMethod method
){
116 MethodSignatureBackedByPsiMethod methodSignature
= MethodSignatureBackedByPsiMethod
.create(method
, PsiSubstitutor
.EMPTY
);
117 if (!method
.isConstructor()) {
118 List
<MethodSignatureBackedByPsiMethod
> superMethodSignatures
= method
.findSuperMethodSignaturesIncludingStatic(true);
119 checkMethodOverridesDeprecated(methodSignature
, superMethodSignatures
, myHolder
);
125 static void checkMethodOverridesDeprecated(MethodSignatureBackedByPsiMethod methodSignature
,
126 List
<MethodSignatureBackedByPsiMethod
> superMethodSignatures
,
127 ProblemsHolder holder
) {
128 PsiMethod method
= methodSignature
.getMethod();
129 PsiElement methodName
= method
.getNameIdentifier();
130 for (MethodSignatureBackedByPsiMethod superMethodSignature
: superMethodSignatures
) {
131 PsiMethod superMethod
= superMethodSignature
.getMethod();
132 PsiClass aClass
= superMethod
.getContainingClass();
133 if (aClass
== null) continue;
134 // do not show deprecated warning for class implementing deprecated methods
135 if (!aClass
.isDeprecated() && superMethod
.hasModifierProperty(PsiModifier
.ABSTRACT
)) continue;
136 if (superMethod
.isDeprecated()) {
137 String description
= JavaErrorMessages
.message("overrides.deprecated.method",
138 HighlightMessageUtil
.getSymbolName(aClass
, PsiSubstitutor
.EMPTY
));
139 holder
.registerProblem(methodName
, description
, ProblemHighlightType
.LIKE_DEPRECATED
);
144 static void checkDeprecated(PsiElement refElement
,
145 PsiElement elementToHighlight
,
146 ProblemsHolder holder
) {
147 if (!(refElement
instanceof PsiDocCommentOwner
)) return;
148 if (!((PsiDocCommentOwner
)refElement
).isDeprecated()) return;
150 String description
= JavaErrorMessages
.message("deprecated.symbol",
151 HighlightMessageUtil
.getSymbolName(refElement
, PsiSubstitutor
.EMPTY
));
153 holder
.registerProblem(elementToHighlight
, description
, ProblemHighlightType
.LIKE_DEPRECATED
);