create param from field in case of chained calls

This commit is contained in:
anna
2010-07-12 16:46:30 +04:00
parent 88efc0190f
commit f0fcf606f5
6 changed files with 71 additions and 24 deletions
@@ -28,9 +28,13 @@ import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.jsp.jspJava.JspClass;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.Comparator;
public class CreateConstructorParameterFromFieldFix implements IntentionAction {
private final SmartPsiElementPointer<PsiField> myField;
@@ -76,8 +80,22 @@ public class CreateConstructorParameterFromFieldFix implements IntentionAction {
aClass = getField().getContainingClass();
constructors = aClass.getConstructors();
}
for (int i = 0; i < constructors.length; i++){
if (!addParameterToConstructor(project, file, editor, getField().getContainingClass().getConstructors()[i])) break;
Arrays.sort(constructors, new Comparator<PsiMethod>() {
@Override
public int compare(PsiMethod c1, PsiMethod c2) {
final PsiMethod cc1 = RefactoringUtil.getChainedConstructor(c1);
final PsiMethod cc2 = RefactoringUtil.getChainedConstructor(c2);
if (cc1 == c2) return 1;
if (cc2 == c1) return -1;
if (cc1 == null) {
return cc2 == null ? 0 : compare(c1, cc2);
} else {
return cc2 == null ? compare(cc1, c2) : compare(cc1, cc2);
}
}
});
for (PsiMethod constructor : constructors) {
if (!addParameterToConstructor(project, file, editor, constructor)) break;
}
}
@@ -25,7 +25,7 @@ import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.codeStyle.VariableKind;
import com.intellij.psi.util.PropertyUtil;
import org.jetbrains.annotations.Nullable;
import com.intellij.refactoring.util.RefactoringUtil;
import java.util.Map;
@@ -51,7 +51,7 @@ public class ParameterData {
initParameterData(parameter, result);
}
final PsiMethod chainedConstructor = getChainedConstructor(constructor);
final PsiMethod chainedConstructor = RefactoringUtil.getChainedConstructor(constructor);
if (chainedConstructor != null) {
final PsiCodeBlock constructorBody = constructor.getBody();
LOG.assertTrue(constructorBody != null);
@@ -68,24 +68,6 @@ public class ParameterData {
}
}
@Nullable
public static PsiMethod getChainedConstructor(PsiMethod constructor) {
final PsiCodeBlock constructorBody = constructor.getBody();
LOG.assertTrue(constructorBody != null);
final PsiStatement[] statements = constructorBody.getStatements();
if (statements.length == 1 && statements[0] instanceof PsiExpressionStatement) {
final PsiExpression expression = ((PsiExpressionStatement)statements[0]).getExpression();
if (expression instanceof PsiMethodCallExpression) {
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
final PsiReferenceExpression methodExpr = methodCallExpression.getMethodExpression();
if ("this".equals(methodExpr.getReferenceName())) {
return (PsiMethod)methodExpr.resolve();
}
}
}
return null;
}
private static ParameterData initParameterData(PsiParameter parameter, Map<String, ParameterData> result) {
JavaCodeStyleManager styleManager = JavaCodeStyleManager.getInstance(parameter.getProject());
final String paramName = parameter.getName();
@@ -40,6 +40,7 @@ import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.replaceConstructorWithBuilder.usageInfo.ReplaceConstructorWithSettersChainInfo;
import com.intellij.refactoring.util.FixableUsageInfo;
import com.intellij.refactoring.util.FixableUsagesRefactoringProcessor;
import com.intellij.refactoring.util.RefactoringUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.usageView.UsageViewDescriptor;
import com.intellij.util.IncorrectOperationException;
@@ -234,7 +235,7 @@ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefacto
if (myConstructors.length == 1) return myConstructors[0];
PsiMethod commonConstructor = null;
for (PsiMethod constructor : myConstructors) {
final PsiMethod chainedConstructor = ParameterData.getChainedConstructor(constructor);
final PsiMethod chainedConstructor = RefactoringUtil.getChainedConstructor(constructor);
if (chainedConstructor == null) {
if (commonConstructor != null) {
if (!isChained(commonConstructor, constructor)) {
@@ -258,7 +259,7 @@ public class ReplaceConstructorWithBuilderProcessor extends FixableUsagesRefacto
private static boolean isChained(PsiMethod first, PsiMethod last) {
if (first == null) return false;
if (first == last) return true;
return isChained(ParameterData.getChainedConstructor(first), last);
return isChained(RefactoringUtil.getChainedConstructor(first), last);
}
private String createMethodName() {
@@ -53,6 +53,7 @@ import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.refactoring.PackageWrapper;
import com.intellij.refactoring.introduceField.ElementToWorkOn;
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
import com.intellij.refactoring.replaceConstructorWithBuilder.ParameterData;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.HashMap;
@@ -913,6 +914,24 @@ public class RefactoringUtil {
return array;
}
@Nullable
public static PsiMethod getChainedConstructor(PsiMethod constructor) {
final PsiCodeBlock constructorBody = constructor.getBody();
LOG.assertTrue(constructorBody != null);
final PsiStatement[] statements = constructorBody.getStatements();
if (statements.length == 1 && statements[0] instanceof PsiExpressionStatement) {
final PsiExpression expression = ((PsiExpressionStatement)statements[0]).getExpression();
if (expression instanceof PsiMethodCallExpression) {
final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expression;
final PsiReferenceExpression methodExpr = methodCallExpression.getMethodExpression();
if ("this".equals(methodExpr.getReferenceName())) {
return (PsiMethod)methodExpr.resolve();
}
}
}
return null;
}
public static interface ImplicitConstructorUsageVisitor {
void visitConstructor(PsiMethod constructor, PsiMethod baseConstructor);
@@ -0,0 +1,14 @@
// "Add constructor parameter" "true"
class A {
private final int field;
private int j;
A(int field) {
this(0, field);
}
A(int j, int field) {
this.j = j;
this.field = field;
}
}
@@ -0,0 +1,13 @@
// "Add constructor parameter" "true"
class A {
private final int <caret>field;
private int j;
A() {
this(0);
}
A(int j) {
this.j = j;
}
}