update copyright
[fedora-idea.git] / java / java-impl / src / com / intellij / codeInspection / sameParameterValue / SameParameterValueInspection.java
blob2beb28ebe9fa9508ed4f5ba15d8732500e11f994
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.sameParameterValue;
18 import com.intellij.analysis.AnalysisScope;
19 import com.intellij.codeInsight.daemon.GroupNames;
20 import com.intellij.codeInspection.*;
21 import com.intellij.codeInspection.reference.*;
22 import com.intellij.openapi.application.ApplicationManager;
23 import com.intellij.openapi.diagnostic.Logger;
24 import com.intellij.openapi.project.Project;
25 import com.intellij.openapi.util.Comparing;
26 import com.intellij.psi.*;
27 import com.intellij.psi.search.searches.ReferencesSearch;
28 import com.intellij.psi.util.PsiTreeUtil;
29 import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
30 import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
31 import com.intellij.refactoring.util.CommonRefactoringUtil;
32 import com.intellij.refactoring.util.InlineUtil;
33 import com.intellij.util.IncorrectOperationException;
34 import org.jetbrains.annotations.NotNull;
35 import org.jetbrains.annotations.Nullable;
37 import java.util.ArrayList;
38 import java.util.Collection;
39 import java.util.List;
41 /**
42 * @author max
44 public class SameParameterValueInspection extends GlobalJavaInspectionTool {
45 private static final Logger LOG = Logger.getInstance("#" + SameParameterValueInspection.class.getName());
47 @Nullable
48 public CommonProblemDescriptor[] checkElement(RefEntity refEntity, AnalysisScope scope, InspectionManager manager, GlobalInspectionContext globalContext,
49 ProblemDescriptionsProcessor processor) {
50 ArrayList<ProblemDescriptor> problems = null;
51 if (refEntity instanceof RefMethod) {
52 final RefMethod refMethod = (RefMethod)refEntity;
54 if (refMethod.hasSuperMethods()) return null;
56 if (refMethod.isEntry()) return null;
58 RefParameter[] parameters = refMethod.getParameters();
59 for (RefParameter refParameter : parameters) {
60 String value = refParameter.getActualValueIfSame();
61 if (value != null) {
62 if (problems == null) problems = new ArrayList<ProblemDescriptor>(1);
63 final String paramName = refParameter.getName();
64 problems.add(manager.createProblemDescriptor(refParameter.getElement(), InspectionsBundle.message(
65 "inspection.same.parameter.problem.descriptor", "<code>" + paramName + "</code>", "<code>" + value + "</code>"),
66 new InlineParameterValueFix(paramName, value),
67 ProblemHighlightType.GENERIC_ERROR_OR_WARNING));
72 return problems == null ? null : problems.toArray(new CommonProblemDescriptor[problems.size()]);
76 protected boolean queryExternalUsagesRequests(final RefManager manager, final GlobalJavaInspectionContext globalContext,
77 final ProblemDescriptionsProcessor processor) {
78 manager.iterate(new RefJavaVisitor() {
79 @Override public void visitElement(RefEntity refEntity) {
80 if (refEntity instanceof RefElement && processor.getDescriptions(refEntity) != null) {
81 refEntity.accept(new RefJavaVisitor() {
82 @Override public void visitMethod(final RefMethod refMethod) {
83 globalContext.enqueueMethodUsagesProcessor(refMethod, new GlobalJavaInspectionContext.UsagesProcessor() {
84 public boolean process(PsiReference psiReference) {
85 processor.ignoreElement(refMethod);
86 return false;
88 });
90 });
93 });
95 return false;
98 @NotNull
99 public String getDisplayName() {
100 return InspectionsBundle.message("inspection.same.parameter.display.name");
103 @NotNull
104 public String getGroupDisplayName() {
105 return GroupNames.DECLARATION_REDUNDANCY;
108 @NotNull
109 public String getShortName() {
110 return "SameParameterValue";
113 @Nullable
114 public QuickFix getQuickFix(final String hint) {
115 if (hint == null) return null;
116 final int spaceIdx = hint.indexOf(' ');
117 if (spaceIdx == -1 || spaceIdx >= hint.length() - 1) return null; //invalid hint
118 final String paramName = hint.substring(0, spaceIdx);
119 final String value = hint.substring(spaceIdx + 1);
120 return new InlineParameterValueFix(paramName, value);
123 @Nullable
124 public String getHint(final QuickFix fix) {
125 final InlineParameterValueFix valueFix = (InlineParameterValueFix)fix;
126 return valueFix.getParamName() + " " + valueFix.getValue();
129 public static class InlineParameterValueFix implements LocalQuickFix {
130 private final String myValue;
131 private final String myParameterName;
133 public InlineParameterValueFix(final String parameterName, final String value) {
134 myValue = value;
135 myParameterName = parameterName;
138 @NotNull
139 public String getName() {
140 return InspectionsBundle.message("inspection.same.parameter.fix.name", myParameterName, myValue);
143 @NotNull
144 public String getFamilyName() {
145 return getName();
148 public void applyFix(@NotNull final Project project, @NotNull ProblemDescriptor descriptor) {
149 final PsiElement element = descriptor.getPsiElement();
150 final PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
151 LOG.assertTrue(method != null);
152 PsiParameter parameter = PsiTreeUtil.getParentOfType(element, PsiParameter.class, false);
153 if (parameter == null) {
154 final PsiParameter[] parameters = method.getParameterList().getParameters();
155 for (PsiParameter psiParameter : parameters) {
156 if (Comparing.strEqual(psiParameter.getName(), myParameterName)) {
157 parameter = psiParameter;
158 break;
162 if (parameter == null) return;
163 if (!CommonRefactoringUtil.checkReadOnlyStatus(project, parameter)) return;
165 final PsiExpression defToInline;
166 try {
167 defToInline = JavaPsiFacade.getInstance(project).getElementFactory().createExpressionFromText(myValue, parameter);
169 catch (IncorrectOperationException e) {
170 return;
173 inlineSameParameterValue(method, parameter, defToInline);
176 public static void inlineSameParameterValue(final PsiMethod method, final PsiParameter parameter, final PsiExpression defToInline) {
177 final Collection<PsiReference> refsToInline = ReferencesSearch.search(parameter).findAll();
179 final Runnable runnable = new Runnable() {
180 public void run() {
181 try {
182 PsiExpression[] exprs = new PsiExpression[refsToInline.size()];
183 int idx = 0;
184 for (PsiReference reference : refsToInline) {
185 if (reference instanceof PsiJavaCodeReferenceElement) {
186 exprs[idx++] = InlineUtil.inlineVariable(parameter, defToInline, (PsiJavaCodeReferenceElement)reference);
190 for (final PsiExpression expr : exprs) {
191 if (expr != null) InlineUtil.tryToInlineArrayCreationForVarargs(expr);
194 removeParameter(method, parameter);
196 catch (IncorrectOperationException e) {
197 LOG.error(e);
202 ApplicationManager.getApplication().runWriteAction(runnable);
205 public static void removeParameter(final PsiMethod method, final PsiParameter parameter) {
206 final PsiParameter[] parameters = method.getParameterList().getParameters();
207 final List<ParameterInfoImpl> psiParameters = new ArrayList<ParameterInfoImpl>();
208 int paramIdx = 0;
209 final String paramName = parameter.getName();
210 for (PsiParameter param : parameters) {
211 if (!Comparing.strEqual(paramName, param.getName())) {
212 psiParameters.add(new ParameterInfoImpl(paramIdx, param.getName(), param.getType()));
214 paramIdx++;
217 new ChangeSignatureProcessor(method.getProject(), method, false, null, method.getName(), method.getReturnType(),
218 psiParameters.toArray(new ParameterInfoImpl[psiParameters.size()])).run();
221 public String getValue() {
222 return myValue;
225 public String getParamName() {
226 return myParameterName;