make static: allow to delegate (IDEA-24060)

This commit is contained in:
Anna Kozlova
2014-12-23 19:29:02 +01:00
parent f99580f6a5
commit 607d4e4f79
9 changed files with 125 additions and 11 deletions

View File

@@ -35,7 +35,7 @@ import java.util.*;
import static com.intellij.refactoring.changeSignature.ChangeSignatureUtil.deepTypeEqual;
class JavaChangeInfoImpl implements JavaChangeInfo {
public class JavaChangeInfoImpl implements JavaChangeInfo {
private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.changeSignature.JavaChangeInfoImpl");
@PsiModifier.ModifierConstant

View File

@@ -636,7 +636,7 @@ public class JavaChangeSignatureUsageProcessor implements ChangeSignatureUsagePr
!((JavaChangeInfoImpl)changeInfo).propagateParametersMethods.contains(method);
}
private static void generateDelegate(JavaChangeInfo changeInfo) throws IncorrectOperationException {
public static void generateDelegate(JavaChangeInfo changeInfo) throws IncorrectOperationException {
final PsiMethod delegate = (PsiMethod)changeInfo.getMethod().copy();
final PsiClass targetClass = changeInfo.getMethod().getContainingClass();
LOG.assertTrue(targetClass != null);

View File

@@ -52,7 +52,8 @@ public abstract class AbstractMakeStaticDialog extends RefactoringDialog {
final Settings settings = new Settings(
isReplaceUsages(),
isMakeClassParameter() ? getClassParameterName() : null,
getVariableData()
getVariableData(),
isGenerateDelegate()
);
if (myMember instanceof PsiMethod) {
invokeRefactoring(new MakeMethodStaticProcessor(getProject(), (PsiMethod)myMember, settings));
@@ -62,6 +63,10 @@ public abstract class AbstractMakeStaticDialog extends RefactoringDialog {
}
}
protected boolean isGenerateDelegate() {
return false;
}
protected abstract boolean validateData();
public abstract boolean isMakeClassParameter();

View File

@@ -16,6 +16,7 @@
package com.intellij.refactoring.makeStatic;
import com.intellij.codeInsight.TestFrameworks;
import com.intellij.lang.Language;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -25,18 +26,21 @@ import com.intellij.psi.javadoc.PsiDocTag;
import com.intellij.psi.util.InheritanceUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.refactoring.changeSignature.*;
import com.intellij.refactoring.changeSignature.inCallers.JavaCallerChooser;
import com.intellij.refactoring.util.CanonicalTypes;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.refactoring.util.javadoc.MethodJavaDocHelper;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.Consumer;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.VisibilityUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author dsl
@@ -131,9 +135,44 @@ public class MakeMethodStaticProcessor extends MakeMethodOrClassStaticProcessor<
PsiDocTag anchor = null;
List<PsiType> addedTypes = new ArrayList<PsiType>();
final PsiClass containingClass = myMember.getContainingClass();
LOG.assertTrue(containingClass != null);
if (mySettings.isDelegate()) {
List<ParameterInfoImpl> params = new ArrayList<ParameterInfoImpl>();
PsiParameter[] parameters = myMember.getParameterList().getParameters();
for (int i = 0; i < parameters.length; i++) {
params.add(new ParameterInfoImpl(i));
}
if (mySettings.isMakeClassParameter()) {
params.add(new ParameterInfoImpl(-1, mySettings.getClassParameterName(),
factory.createType(containingClass, PsiSubstitutor.EMPTY), "this"));
}
if (mySettings.isMakeFieldParameters()) {
for (Settings.FieldParameter parameter : mySettings.getParameterOrderList()) {
params.add(new ParameterInfoImpl(-1, mySettings.getClassParameterName(), parameter.type, parameter.field.getName()));
}
}
final PsiType returnType = myMember.getReturnType();
LOG.assertTrue(returnType != null);
JavaChangeSignatureUsageProcessor.generateDelegate(new JavaChangeInfoImpl(VisibilityUtil.getVisibilityModifier(myMember.getModifierList()),
myMember,
myMember.getName(),
CanonicalTypes.createTypeWrapper(returnType),
params.toArray(new ParameterInfoImpl[params.size()]),
new ThrownExceptionInfo[0],
false,
Collections.<PsiMethod>emptySet(),
Collections.<PsiMethod>emptySet()));
}
if (mySettings.isMakeClassParameter()) {
// Add parameter for object
PsiType parameterType = factory.createType(myMember.getContainingClass(), PsiSubstitutor.EMPTY);
PsiType parameterType = factory.createType(containingClass, PsiSubstitutor.EMPTY);
addedTypes.add(parameterType);
final String classParameterName = mySettings.getClassParameterName();
@@ -310,6 +349,7 @@ public class MakeMethodStaticProcessor extends MakeMethodOrClassStaticProcessor<
}
protected void findExternalUsages(final ArrayList<UsageInfo> result) {
if (mySettings.isDelegate()) return;
findExternalReferences(myMember, result);
}

View File

@@ -55,6 +55,7 @@ public class MakeParameterizedStaticDialog extends AbstractMakeStaticDialog {
private ParameterTablePanel myParameterPanel;
private VariableData[] myVariableData;
private final boolean myAnyNonFieldMembersUsed;
private JCheckBox myGenerateDelegateCb;
public MakeParameterizedStaticDialog(Project project,
@@ -212,12 +213,21 @@ public class MakeParameterizedStaticDialog extends AbstractMakeStaticDialog {
myMakeFieldParameters.addActionListener(inputFieldValidator);
if (myMember instanceof PsiMethod) {
myGenerateDelegateCb = new JCheckBox(RefactoringBundle.message("delegation.panel.delegate.via.overloading.method"));
panel.add(myGenerateDelegateCb, gbConstraints);
}
updateControls();
return panel;
}
@Override
protected boolean isGenerateDelegate() {
return myGenerateDelegateCb != null && myGenerateDelegateCb.isSelected();
}
protected boolean validateData() {
int ret = Messages.YES;
if (isMakeClassParameter()) {

View File

@@ -40,6 +40,7 @@ public final class Settings {
private final HashMap<PsiField,String> myFieldToNameMapping;
private final ArrayList<FieldParameter> myFieldToNameList;
private final boolean myReplaceUsages;
private final boolean myDelegate;
public static final class FieldParameter {
@@ -56,7 +57,15 @@ public final class Settings {
public Settings(boolean replaceUsages, @Nullable String classParameterName, @Nullable VariableData[] variableDatum) {
this(replaceUsages, classParameterName, variableDatum, false);
}
public Settings(boolean replaceUsages,
@Nullable String classParameterName,
@Nullable VariableData[] variableDatum,
boolean delegate) {
myReplaceUsages = replaceUsages;
myDelegate = delegate;
myMakeClassParameter = classParameterName != null;
myClassParameterName = classParameterName;
myMakeFieldParameters = variableDatum != null;
@@ -94,6 +103,7 @@ public final class Settings {
else {
myFieldToNameMapping = null;
}
myDelegate = false;
}
public boolean isReplaceUsages() {
@@ -112,6 +122,10 @@ public final class Settings {
return myMakeFieldParameters;
}
public boolean isDelegate() {
return myDelegate;
}
@Nullable
public String getNameForField(PsiField field) {
if (myFieldToNameMapping != null) {

View File

@@ -0,0 +1,18 @@
class C {
int i;
private void foo() {
foo(i);
}
private static void foo(int i) {
if (true) {
foo(i);
}
System.out.println(i);
}
{
foo();
}
}

View File

@@ -0,0 +1,13 @@
class C {
int i;
private void fo<caret>o() {
if (true) {
foo();
}
System.out.println(i);
}
{
foo();
}
}

View File

@@ -185,9 +185,11 @@ public class MakeMethodStaticTest extends LightRefactoringTestCase {
}
public void testPreserveTypeParams() throws Exception {
configureByFile("/refactoring/makeMethodStatic/beforePreserveTypeParams.java");
performWithFields();
checkResultByFile("/refactoring/makeMethodStatic/afterPreserveTypeParams.java");
doTestFields(false);
}
public void testFieldsAndDelegation() throws Exception {
doTestFields(true);
}
public void testInnerStaticClassUsed() throws Exception {
@@ -215,6 +217,14 @@ public class MakeMethodStaticTest extends LightRefactoringTestCase {
checkResultByFile("/refactoring/makeMethodStatic/after" + getTestName(false) + ".java");
}
private void doTestFields(boolean delegate) throws Exception {
final String testName = getTestName(false);
configureByFile("/refactoring/makeMethodStatic/before" + testName + ".java");
performWithFields(delegate);
checkResultByFile("/refactoring/makeMethodStatic/after" + testName + ".java");
}
private static void perform(boolean addClassParameter) {
PsiElement element = TargetElementUtilBase.findTargetElement(myEditor, TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
assertTrue(element instanceof PsiMethod);
@@ -227,6 +237,10 @@ public class MakeMethodStaticTest extends LightRefactoringTestCase {
}
private static void performWithFields() {
performWithFields(false);
}
private static void performWithFields(boolean delegate) {
PsiElement element = TargetElementUtilBase.findTargetElement(myEditor, TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
assertTrue(element instanceof PsiMethod);
PsiMethod method = (PsiMethod) element;
@@ -238,6 +252,6 @@ public class MakeMethodStaticTest extends LightRefactoringTestCase {
method,
new Settings(true, addClassParameter ? "anObject" : null,
parametersForFields.toArray(
new VariableData[parametersForFields.size()]))).run();
new VariableData[parametersForFields.size()]), delegate)).run();
}
}