make static: move field initialization to constructors if it depends on introduced fields

This commit is contained in:
anna
2010-02-03 15:50:22 +03:00
parent 992b49b219
commit 4b271bdb3d
4 changed files with 78 additions and 0 deletions
@@ -109,6 +109,18 @@ public class MakeClassStaticProcessor extends MakeMethodOrClassStaticProcessor<P
anchor = javaDocHelper.addParameterAfter(fieldParameter.name, anchor);
addAssignmentToField(fieldParameter.name, constructor);
}
for (UsageInfo usage : usages) {
if (usage instanceof InternalUsageInfo) {
final PsiElement element = usage.getElement();
final PsiElement referencedElement = ((InternalUsageInfo)usage).getReferencedElement();
if (referencedElement instanceof PsiField && mySettings.getNameForField((PsiField)referencedElement) != null) {
final PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class);
if (field != null) {
moveInitializerToConstructor(factory, constructor, field);
}
}
}
}
}
}
@@ -121,6 +133,34 @@ public class MakeClassStaticProcessor extends MakeMethodOrClassStaticProcessor<P
modifierList.setModifierProperty(PsiModifier.FINAL, false);
}
private static void moveInitializerToConstructor(PsiElementFactory factory, PsiMethod constructor, PsiField field) {
final PsiExpression initializer = field.getInitializer();
PsiExpression initializerCopy = (PsiExpression)initializer.copy();
final PsiCodeBlock body = constructor.getBody();
if (body != null) {
try {
String fieldName = field.getName();
final PsiReferenceExpression refExpr = (PsiReferenceExpression)factory.createExpressionFromText(fieldName, body);
if (refExpr.resolve() != null) fieldName = "this." + fieldName;
PsiExpressionStatement statement = (PsiExpressionStatement)factory.createStatementFromText(fieldName + "= y;", null);
if (initializerCopy instanceof PsiArrayInitializerExpression) {
PsiType type = initializer.getType();
PsiNewExpression newExpression =
(PsiNewExpression)factory.createExpressionFromText("new " + type.getCanonicalText() + "{}", body);
newExpression.getArrayInitializer().replace(initializerCopy);
initializerCopy = newExpression;
}
((PsiAssignmentExpression)statement.getExpression()).getRExpression().replace(initializerCopy);
statement = (PsiExpressionStatement)field.getManager().getCodeStyleManager().reformat(statement);
body.add(statement);
initializer.delete();
}
catch (IncorrectOperationException e) {
LOG.error(e);
}
}
}
private void addAssignmentToField(final String parameterName, final PsiMethod constructor) {
@NonNls String fieldName = convertToFieldName(parameterName);
final PsiManager manager = PsiManager.getInstance(myProject);
@@ -0,0 +1,13 @@
public class YoYo {
Object y;
class <caret>YoYoYo {
Object x = y;
Object[] xx = {y};
void foo (){
YoYo yoYoy = YoYo.this;
Object t = y;
Object t1 = yoYoy.y;
}
}
}
@@ -0,0 +1,23 @@
public class YoYo {
Object y;
static class YoYoYo {
Object x;
Object[] xx;
private YoYo anObject;
private Object y;
public YoYoYo(YoYo anObject, Object y) {
this.anObject = anObject;
this.y = y;
this.x = y;
this.xx = new Object[]{y};
}
void foo (){
YoYo yoYoy = anObject;
Object t = y;
Object t1 = yoYoy.y;
}
}
}
@@ -29,6 +29,8 @@ public class MakeClassStaticTest extends LightCodeInsightTestCase {
public void testSimpleWithFields() throws Exception { performWithFields(); }
public void testFieldInitializerMoveToConstructor() throws Exception { performWithFields(); }
public void testQualifiedThisInSibling() throws Exception { perform(); }
public void testIDEADEV3247() throws Exception { perform(); }