mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 14:23:28 +07:00
introduce field: selected type should be used instead of local variable type
This commit is contained in:
@@ -20,6 +20,7 @@ import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
@@ -27,6 +28,7 @@ import com.intellij.refactoring.RefactoringBundle;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.refactoring.util.CommonRefactoringUtil;
|
||||
import com.intellij.refactoring.util.occurences.*;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
|
||||
@@ -90,6 +92,7 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
|
||||
final boolean currentMethodConstructor = containingMethod != null && containingMethod.isConstructor();
|
||||
final boolean allowInitInMethod = (!currentMethodConstructor || !isInSuperOrThis) && anchorElement instanceof PsiStatement;
|
||||
final boolean allowInitInMethodIfAll = (!currentMethodConstructor || !isInSuperOrThis) && anchorElementIfAll instanceof PsiStatement;
|
||||
type = checkIfTypeAccessible(type, project, parentClass, containingMethod);
|
||||
IntroduceFieldDialog dialog = new IntroduceFieldDialog(
|
||||
project, parentClass, expr, localVariable,
|
||||
currentMethodConstructor,
|
||||
@@ -118,6 +121,23 @@ public class IntroduceFieldHandler extends BaseExpressionToFieldHandler {
|
||||
dialog.getFieldType(), localVariable != null, (TargetDestination)null, false, false);
|
||||
}
|
||||
|
||||
private static PsiType checkIfTypeAccessible(PsiType type, Project project, PsiClass parentClass, PsiMethod containingMethod) {
|
||||
final PsiClass typeClass = PsiUtil.resolveClassInType(type);
|
||||
if (typeClass != null) {
|
||||
if (typeClass instanceof PsiTypeParameter) {
|
||||
if (ArrayUtil.find(parentClass.getTypeParameters(), typeClass) == -1) { //unknown type parameter
|
||||
type = PsiType.getJavaLangObject(PsiManager.getInstance(project), GlobalSearchScope.allScope(project));
|
||||
}
|
||||
} else if (PsiTreeUtil.isAncestor(containingMethod, typeClass, true)) { //local class type
|
||||
final PsiClassType[] superTypes = typeClass.getSuperTypes();
|
||||
if (superTypes.length > 0) {
|
||||
return checkIfTypeAccessible(superTypes[0], project, parentClass, containingMethod);
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private static boolean isInSuperOrThis(PsiExpression occurence) {
|
||||
return !NotInSuperCallOccurenceFilter.INSTANCE.isOK(occurence) || !NotInThisCallFilter.INSTANCE.isOK(occurence);
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ public abstract class LocalToFieldHandler {
|
||||
|
||||
final PsiMethod enclosingConstructor = BaseExpressionToFieldHandler.getEnclosingConstructor(aaClass, local);
|
||||
PsiField field = settings.isIntroduceEnumConstant() ? EnumConstantsUtil.createEnumConstant(aaClass, local, fieldName)
|
||||
: createField(local, fieldName, initializerPlace == IN_FIELD_DECLARATION);
|
||||
: createField(local, settings.getForcedType(), fieldName, initializerPlace == IN_FIELD_DECLARATION);
|
||||
field = (PsiField)aaClass.add(field);
|
||||
BaseExpressionToFieldHandler.setModifiers(field, settings, isStatic);
|
||||
if (!settings.isIntroduceEnumConstant()) {
|
||||
@@ -175,7 +175,7 @@ public abstract class LocalToFieldHandler {
|
||||
return true;
|
||||
}
|
||||
|
||||
private PsiField createField(PsiLocalVariable local, String fieldName, boolean includeInitializer) {
|
||||
private PsiField createField(PsiLocalVariable local, PsiType forcedType, String fieldName, boolean includeInitializer) {
|
||||
@NonNls StringBuilder pattern = new StringBuilder();
|
||||
pattern.append("private int ");
|
||||
pattern.append(fieldName);
|
||||
@@ -191,10 +191,10 @@ public abstract class LocalToFieldHandler {
|
||||
PsiField field = factory.createFieldFromText(pattern.toString(), null);
|
||||
field = (PsiField)CodeStyleManager.getInstance(myProject).reformat(field);
|
||||
|
||||
field.getTypeElement().replace(factory.createTypeElement(local.getType()));
|
||||
field.getTypeElement().replace(factory.createTypeElement(forcedType));
|
||||
if (includeInitializer) {
|
||||
PsiExpression initializer =
|
||||
RefactoringUtil.convertInitializerToNormalExpression(local.getInitializer(), local.getType());
|
||||
RefactoringUtil.convertInitializerToNormalExpression(local.getInitializer(), forcedType);
|
||||
field.getInitializer().replace(initializer);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
public class FieldTest {
|
||||
public final int integer;
|
||||
|
||||
void foo() {
|
||||
integer = new Integer(0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
public class FieldTest {
|
||||
void foo() {
|
||||
Integer <selection>ii</selection> = new Integer(0);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.intellij.refactoring;
|
||||
|
||||
import com.intellij.psi.PsiPrimitiveType;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.refactoring.introduceField.BaseExpressionToFieldHandler;
|
||||
import com.intellij.testFramework.LightCodeInsightTestCase;
|
||||
import com.intellij.JavaTestUtil;
|
||||
@@ -34,4 +36,15 @@ public class IntroduceFieldInSameClassTest extends LightCodeInsightTestCase {
|
||||
private static void performRefactoring(final BaseExpressionToFieldHandler.InitializationPlace initializationPlace, final boolean declareStatic) {
|
||||
new MockIntroduceFieldHandler(initializationPlace, declareStatic).invoke(getProject(), myEditor, myFile, null);
|
||||
}
|
||||
|
||||
public void testForcedFieldType() throws Exception {
|
||||
configureByFile("/refactoring/introduceField/beforeForcedFieldType.java");
|
||||
new MockIntroduceFieldHandler(BaseExpressionToFieldHandler.InitializationPlace.IN_CURRENT_METHOD, false){
|
||||
@Override
|
||||
protected PsiType getFieldType(PsiType type) {
|
||||
return PsiPrimitiveType.INT;
|
||||
}
|
||||
}.invoke(getProject(), myEditor, myFile, null);
|
||||
checkResultByFile("/refactoring/introduceField/afterForcedFieldType.java");
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,10 @@ public class MockIntroduceFieldHandler extends IntroduceFieldHandler {
|
||||
return new Settings(name.names[0], true, myDeclareStatic, true, myInitializationPlace,
|
||||
PsiModifier.PUBLIC,
|
||||
null,
|
||||
type, true, (TargetDestination)null, false, false);
|
||||
getFieldType(type), true, (TargetDestination)null, false, false);
|
||||
}
|
||||
|
||||
protected PsiType getFieldType(PsiType type) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,6 @@ public class MockLocalToFieldHandler extends LocalToFieldHandler {
|
||||
protected BaseExpressionToFieldHandler.Settings showRefactoringDialog(PsiClass aClass, PsiLocalVariable local, PsiExpression[] occurences,
|
||||
boolean isStatic) {
|
||||
return new BaseExpressionToFieldHandler.Settings("xxx", true, isStatic, true, BaseExpressionToFieldHandler.InitializationPlace.IN_FIELD_DECLARATION,
|
||||
PsiModifier.PRIVATE, local, null, false, aClass, true, myMakeEnumConstant);
|
||||
PsiModifier.PRIVATE, local, local.getType(), false, aClass, true, myMakeEnumConstant);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user