Inspections - pass onTheFly into ProblemDescriptors & use it to create LAZY refs...
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInspection / miscGenerics / RedundantTypeArgsInspection.java
blob37df723c47fbfe6db8b8d745f35ea68356ef0c4d
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.miscGenerics;
18 import com.intellij.codeInsight.daemon.GroupNames;
19 import com.intellij.codeInspection.*;
20 import com.intellij.openapi.diagnostic.Logger;
21 import com.intellij.openapi.project.Project;
22 import com.intellij.psi.*;
23 import com.intellij.util.IncorrectOperationException;
24 import org.jetbrains.annotations.NotNull;
26 import java.util.ArrayList;
27 import java.util.List;
29 /**
30 * @author ven
32 public class RedundantTypeArgsInspection extends GenericsInspectionToolBase {
33 private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.miscGenerics.RedundantTypeArgsInspection");
35 public RedundantTypeArgsInspection() {
36 myQuickFixAction = new MyQuickFixAction();
39 private final LocalQuickFix myQuickFixAction;
41 @NotNull
42 public String getGroupDisplayName() {
43 return GroupNames.VERBOSE_GROUP_NAME;
46 @NotNull
47 public String getDisplayName() {
48 return InspectionsBundle.message("inspection.redundant.type.display.name");
51 @NotNull
52 public String getShortName() {
53 return "RedundantTypeArguments";
58 public ProblemDescriptor[] checkMethod(@NotNull PsiMethod psiMethod, @NotNull InspectionManager manager, boolean isOnTheFly) {
59 final PsiCodeBlock body = psiMethod.getBody();
60 if (body != null) {
61 return getDescriptions(body, manager, isOnTheFly);
63 return null;
66 public ProblemDescriptor[] getDescriptions(PsiElement place, final InspectionManager inspectionManager, boolean isOnTheFly) {
67 final List<ProblemDescriptor> problems = new ArrayList<ProblemDescriptor>();
68 place.accept(new JavaRecursiveElementWalkingVisitor() {
69 @Override public void visitMethodCallExpression(PsiMethodCallExpression expression) {
70 final PsiType[] typeArguments = expression.getTypeArguments();
71 if (typeArguments.length > 0) {
72 checkCallExpression(expression.getMethodExpression(), typeArguments, expression, inspectionManager, problems);
76 @Override public void visitNewExpression(PsiNewExpression expression) {
77 final PsiType[] typeArguments = expression.getTypeArguments();
78 if (typeArguments.length > 0) {
79 final PsiJavaCodeReferenceElement classReference = expression.getClassReference();
80 if (classReference != null) {
81 checkCallExpression(classReference, typeArguments, expression, inspectionManager, problems);
86 private void checkCallExpression(final PsiJavaCodeReferenceElement reference,
87 final PsiType[] typeArguments,
88 PsiCallExpression expression,
89 final InspectionManager inspectionManager, final List<ProblemDescriptor> problems) {
91 PsiExpressionList argumentList = expression.getArgumentList();
92 if (argumentList == null) return;
93 final JavaResolveResult resolveResult = reference.advancedResolve(false);
95 final PsiElement element = resolveResult.getElement();
96 if (element instanceof PsiMethod && resolveResult.isValidResult()) {
97 PsiMethod method = (PsiMethod)element;
98 final PsiTypeParameter[] typeParameters = method.getTypeParameters();
99 if (typeParameters.length == typeArguments.length) {
100 final PsiParameter[] parameters = method.getParameterList().getParameters();
101 PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(expression.getProject()).getResolveHelper();
102 for (int i = 0; i < typeParameters.length; i++) {
103 PsiTypeParameter typeParameter = typeParameters[i];
104 final PsiType inferedType = resolveHelper.inferTypeForMethodTypeParameter(typeParameter, parameters,
105 argumentList.getExpressions(),
106 resolveResult.getSubstitutor(), expression, false);
107 if (!typeArguments[i].equals(inferedType)) return;
110 final PsiCallExpression copy = (PsiCallExpression)expression.copy(); //see IDEADEV-8174
111 try {
112 copy.getTypeArgumentList().delete();
113 if (copy.resolveMethod() != element) return;
115 catch (IncorrectOperationException e) {
116 LOG.error(e);
117 return;
120 final ProblemDescriptor descriptor = inspectionManager.createProblemDescriptor(expression.getTypeArgumentList(),
121 InspectionsBundle.message("inspection.redundant.type.problem.descriptor"),
122 myQuickFixAction,
123 ProblemHighlightType.LIKE_UNUSED_SYMBOL, false);
124 problems.add(descriptor);
131 if (problems.isEmpty()) return null;
132 return problems.toArray(new ProblemDescriptor[problems.size()]);
135 private static class MyQuickFixAction implements LocalQuickFix {
136 @NotNull
137 public String getName() {
138 return InspectionsBundle.message("inspection.redundant.type.remove.quickfix");
141 public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
142 final PsiReferenceParameterList typeArgumentList = (PsiReferenceParameterList)descriptor.getPsiElement();
143 try {
144 final PsiMethodCallExpression expr =
145 (PsiMethodCallExpression)JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText("foo()", null);
146 typeArgumentList.replace(expr.getTypeArgumentList());
148 catch (IncorrectOperationException e) {
149 LOG.error(e);
153 @NotNull
154 public String getFamilyName() {
155 return getName();