enhanced API for nullness
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInspection / deprecation / DeprecationInspection.java
blob98f7013d4b6e50fba9734df420f62882fab993b1
1 /*
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;
32 /**
33 * @author max
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;
41 @NotNull
42 public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
43 return new DeprecationElementVisitor(holder);
46 @NotNull
47 public String getDisplayName() {
48 return DISPLAY_NAME;
51 @NotNull
52 public String getGroupDisplayName() {
53 return "";
56 @NotNull
57 public String getShortName() {
58 return SHORT_NAME;
61 @NotNull
62 @NonNls
63 public String getID() {
64 return ID;
67 public boolean isEnabledByDefault() {
68 return true;
71 private static class DeprecationElementVisitor extends JavaElementVisitor {
72 private final ProblemsHolder myHolder;
74 public DeprecationElementVisitor(final ProblemsHolder holder) {
75 myHolder = 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);
124 //@top
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);