blob: 86651f49987fc690e6f9ee0eb3adfc9997dddfc8 [file] [log] [blame]
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.ide.util.SuperMethodWarningUtil;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.RefactoringBundle;
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
import com.intellij.refactoring.changeSignature.JavaChangeSignatureDialog;
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
import com.intellij.refactoring.introduceParameter.IntroduceParameterHandler;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author Mike
*/
public class CreateParameterFromUsageFix extends CreateVarFromUsageFix {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.CreateParameterFromUsageFix");
public CreateParameterFromUsageFix(PsiReferenceExpression referenceElement) {
super(referenceElement);
}
@Override
protected boolean isAvailableImpl(int offset) {
if (!super.isAvailableImpl(offset)) return false;
if(myReferenceExpression.isQualified()) return false;
PsiElement scope = myReferenceExpression;
do {
scope = PsiTreeUtil.getParentOfType(scope, PsiMethod.class, PsiClass.class);
if (!(scope instanceof PsiAnonymousClass)) {
return scope instanceof PsiMethod &&
((PsiMethod)scope).getParameterList().isPhysical();
}
}
while (true);
}
@Override
public String getText(String varName) {
return QuickFixBundle.message("create.parameter.from.usage.text", varName);
}
@Override
protected void invokeImpl(PsiClass targetClass) {
if (CreateFromUsageUtils.isValidReference(myReferenceExpression, false)) return;
final Project project = myReferenceExpression.getProject();
PsiType[] expectedTypes = CreateFromUsageUtils.guessType(myReferenceExpression, false);
PsiType type = expectedTypes[0];
final String varName = myReferenceExpression.getReferenceName();
PsiMethod method = PsiTreeUtil.getParentOfType(myReferenceExpression, PsiMethod.class);
LOG.assertTrue(method != null);
method = IntroduceParameterHandler.chooseEnclosingMethod(method);
if (method == null) return;
method = SuperMethodWarningUtil.checkSuperMethod(method, RefactoringBundle.message("to.refactor"));
if (method == null) return;
final List<ParameterInfoImpl> parameterInfos =
new ArrayList<ParameterInfoImpl>(Arrays.asList(ParameterInfoImpl.fromMethod(method)));
ParameterInfoImpl parameterInfo = new ParameterInfoImpl(-1, varName, type, varName, false);
if (!method.isVarArgs()) {
parameterInfos.add(parameterInfo);
}
else {
parameterInfos.add(parameterInfos.size() - 1, parameterInfo);
}
final Application application = ApplicationManager.getApplication();
if (application.isUnitTestMode()) {
ParameterInfoImpl[] array = parameterInfos.toArray(new ParameterInfoImpl[parameterInfos.size()]);
String modifier = PsiUtil.getAccessModifier(PsiUtil.getAccessLevel(method.getModifierList()));
ChangeSignatureProcessor processor =
new ChangeSignatureProcessor(project, method, false, modifier, method.getName(), method.getReturnType(), array);
processor.run();
}
else {
final PsiMethod finalMethod = method;
application.invokeLater(new Runnable() {
@Override
public void run() {
if (project.isDisposed()) return;
try {
JavaChangeSignatureDialog dialog = JavaChangeSignatureDialog.createAndPreselectNew(project, finalMethod, parameterInfos, true, myReferenceExpression);
dialog.setParameterInfos(parameterInfos);
dialog.show();
if (dialog.isOK()) {
for (ParameterInfoImpl info : parameterInfos) {
if (info.getOldIndex() == -1) {
final String newParamName = info.getName();
if (!Comparing.strEqual(varName, newParamName)) {
final PsiExpression newExpr = JavaPsiFacade.getElementFactory(project).createExpressionFromText(newParamName, finalMethod);
new WriteCommandAction(project){
@Override
protected void run(Result result) throws Throwable {
final PsiReferenceExpression[] refs =
CreateFromUsageUtils.collectExpressions(myReferenceExpression, PsiMember.class, PsiFile.class);
for (PsiReferenceExpression ref : refs) {
ref.replace(newExpr.copy());
}
}
}.execute();
}
break;
}
}
}
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
});
}
}
@Override
protected boolean isAllowOuterTargetClass() {
return false;
}
@Override
@NotNull
public String getFamilyName() {
return QuickFixBundle.message("create.parameter.from.usage.family");
}
}