mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 09:19:13 +07:00
extract enum: do not migrate other constants to enum
This commit is contained in:
@@ -30,7 +30,15 @@ import com.intellij.refactoring.typeMigration.TypeConversionDescriptorBase;
|
||||
import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
|
||||
import com.intellij.refactoring.typeMigration.rules.TypeConversionRule;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class EnumTypeConversionRule extends TypeConversionRule {
|
||||
private final List<PsiField> myEnumConstants;
|
||||
|
||||
public EnumTypeConversionRule(List<PsiField> enumConstants) {
|
||||
myEnumConstants = enumConstants;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeConversionDescriptorBase findConversion(PsiType from,
|
||||
PsiType to,
|
||||
@@ -47,6 +55,14 @@ public class EnumTypeConversionRule extends TypeConversionRule {
|
||||
}
|
||||
}
|
||||
}
|
||||
final PsiField field = PsiTreeUtil.getParentOfType(context, PsiField.class);
|
||||
if (field != null &&
|
||||
!myEnumConstants.contains(field) &&
|
||||
field.hasModifierProperty(PsiModifier.STATIC) &&
|
||||
field.hasModifierProperty(PsiModifier.FINAL) &&
|
||||
field.hasInitializer()) {
|
||||
return null;
|
||||
}
|
||||
final PsiClass toClass = PsiUtil.resolveClassInType(to);
|
||||
if (toClass != null && toClass.isEnum()) {
|
||||
final PsiMethod[] constructors = toClass.getConstructors();
|
||||
|
||||
+20
-31
@@ -70,9 +70,9 @@ public class ExtractEnumProcessor {
|
||||
MutationUtils.replaceExpression(expression.getReferenceName() + "." + link, expression);
|
||||
}
|
||||
});
|
||||
continue;
|
||||
} else if (element != null) {
|
||||
resolvableConflicts.add(new ConflictUsageInfo(element, null));
|
||||
}
|
||||
conflicts.putValue(element, "Failed to migrate");
|
||||
}
|
||||
if (!resolvableConflicts.isEmpty()) {
|
||||
final List<UsageInfo> usageInfos = new ArrayList<UsageInfo>(Arrays.asList(refUsages.get()));
|
||||
@@ -89,21 +89,6 @@ public class ExtractEnumProcessor {
|
||||
refUsages.set(resolvableConflicts.toArray(new UsageInfo[resolvableConflicts.size()]));
|
||||
}
|
||||
}
|
||||
for (final PsiField enumConstant : myEnumConstants) {
|
||||
final PsiExpression initializer = enumConstant.getInitializer();
|
||||
assert initializer != null;
|
||||
initializer.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
super.visitReferenceExpression(expression);
|
||||
final PsiElement resolved = expression.resolve();
|
||||
if (!myEnumConstants.contains(resolved) && myFields.contains(resolved)) {
|
||||
conflicts.putValue(initializer, "Enum constant " + RefactoringUIUtil.getDescription(enumConstant, false) +
|
||||
" would forward reference on field " + RefactoringUIUtil.getDescription(resolved, false));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasUsages2Migrate() {
|
||||
@@ -132,7 +117,6 @@ public class ExtractEnumProcessor {
|
||||
}
|
||||
final PsiType enumValueType = myEnumConstants.get(0).getType();
|
||||
|
||||
final Set<PsiElement> toMigrate = new HashSet<PsiElement>();
|
||||
for (PsiSwitchStatement switchStatement : switchStatements) {
|
||||
final PsiStatement errStatement = EnumConstantsUtil.isEnumSwitch(switchStatement, enumValueType, enumValues);
|
||||
if (errStatement != null) {
|
||||
@@ -140,7 +124,7 @@ public class ExtractEnumProcessor {
|
||||
if (errStatement instanceof PsiSwitchLabelStatement) {
|
||||
final PsiExpression caseValue = ((PsiSwitchLabelStatement)errStatement).getCaseValue();
|
||||
if (caseValue != null) {
|
||||
description = caseValue.getText() + " can't be replaced with enum";
|
||||
description = caseValue.getText() + " can not be replaced with enum";
|
||||
}
|
||||
}
|
||||
result.add(new ConflictUsageInfo(errStatement, description));
|
||||
@@ -154,9 +138,6 @@ public class ExtractEnumProcessor {
|
||||
if (!element.getManager().isInProject(element)) {
|
||||
result.add(new ConflictUsageInfo(expression, StringUtil.capitalize(RefactoringUIUtil.getDescription(element, false)) + " is out of project"));
|
||||
}
|
||||
else {
|
||||
toMigrate.add(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -165,16 +146,24 @@ public class ExtractEnumProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
if (!toMigrate.isEmpty()) {
|
||||
final TypeMigrationRules rules = new TypeMigrationRules(this.myEnumConstants.get(0).getType());
|
||||
rules.addConversionDescriptor(new EnumTypeConversionRule());
|
||||
rules.setMigrationRootType(
|
||||
JavaPsiFacade.getElementFactory(myProject).createType(myClass));
|
||||
rules.setBoundScope(GlobalSearchScope.projectScope(myProject));
|
||||
myTypeMigrationProcessor = new TypeMigrationProcessor(myProject, toMigrate.toArray(new PsiElement[toMigrate.size()]), rules);
|
||||
for (UsageInfo usageInfo : myTypeMigrationProcessor.findUsages()) {
|
||||
result.add(new EnumTypeMigrationUsageInfo(usageInfo));
|
||||
final TypeMigrationRules rules = new TypeMigrationRules(myEnumConstants.get(0).getType());
|
||||
rules.addConversionDescriptor(new EnumTypeConversionRule(myEnumConstants));
|
||||
rules.setMigrationRootType(
|
||||
JavaPsiFacade.getElementFactory(myProject).createType(myClass));
|
||||
rules.setBoundScope(GlobalSearchScope.projectScope(myProject));
|
||||
myTypeMigrationProcessor = new TypeMigrationProcessor(myProject, myEnumConstants.toArray(new PsiElement[myEnumConstants.size()]), rules);
|
||||
for (UsageInfo usageInfo : myTypeMigrationProcessor.findUsages()) {
|
||||
final PsiElement migrateElement = usageInfo.getElement();
|
||||
if (migrateElement instanceof PsiField) {
|
||||
final PsiField enumConstantField = (PsiField)migrateElement;
|
||||
if (enumConstantField.hasModifierProperty(PsiModifier.STATIC) &&
|
||||
enumConstantField.hasModifierProperty(PsiModifier.FINAL) &&
|
||||
enumConstantField.hasInitializer() &&
|
||||
!myEnumConstants.contains(enumConstantField)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
result.add(new EnumTypeMigrationUsageInfo(usageInfo));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
public class Test {
|
||||
public static final int OK = 0;
|
||||
public static final int ERROR = 1;
|
||||
|
||||
void foo(int status) {
|
||||
switch (status) {
|
||||
case OK:
|
||||
break;
|
||||
case ERROR:
|
||||
break;
|
||||
case Node.WARNING:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Node {
|
||||
int WARNING = 2;
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
public class Test {
|
||||
public static final int OK = 0;
|
||||
public static final int ERROR = 1;
|
||||
|
||||
void foo(int status) {
|
||||
switch (status) {
|
||||
case OK:
|
||||
break;
|
||||
case ERROR:
|
||||
break;
|
||||
case Node.WARNING:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Node {
|
||||
int WARNING = 2;
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public class ExtractEnumTest extends MultiFileTestCase {
|
||||
}
|
||||
|
||||
public void testForwardReferenceConflict() throws Exception {
|
||||
doTest("Enum constant field <b><code>BAR</code></b> would forward reference on field field <b><code>FOO</code></b>", false,
|
||||
doTest("Unable to migrate statement to enum constant.", false,
|
||||
new RefactoringTestUtil.MemberDescriptor("FOO", PsiField.class, false),
|
||||
new RefactoringTestUtil.MemberDescriptor("BAR", PsiField.class, true));
|
||||
}
|
||||
@@ -76,13 +76,19 @@ public class ExtractEnumTest extends MultiFileTestCase {
|
||||
}
|
||||
|
||||
public void testCantChangeMethodParameter() throws Exception {
|
||||
doTest("Failed to migrate", false,
|
||||
doTest("Unable to migrate statement to enum constant.", false,
|
||||
new RefactoringTestUtil.MemberDescriptor("FOO", PsiField.class, true),
|
||||
new RefactoringTestUtil.MemberDescriptor("BAR", PsiField.class, true));
|
||||
}
|
||||
|
||||
public void testDontChangeOtherConstants() throws Exception {
|
||||
doTest("Unable to migrate statement to enum constant. Node.WARNING can not be replaced with enum", false,
|
||||
new RefactoringTestUtil.MemberDescriptor("OK", PsiField.class, true),
|
||||
new RefactoringTestUtil.MemberDescriptor("ERROR", PsiField.class, true));
|
||||
}
|
||||
|
||||
public void testCantChangeMethodParameter1() throws Exception {
|
||||
doTest("Failed to migrate", false,
|
||||
doTest("Unable to migrate statement to enum constant.", false,
|
||||
new RefactoringTestUtil.MemberDescriptor("FOO", PsiField.class, true),
|
||||
new RefactoringTestUtil.MemberDescriptor("BAR", PsiField.class, true));
|
||||
}
|
||||
@@ -115,7 +121,7 @@ public class ExtractEnumTest extends MultiFileTestCase {
|
||||
}
|
||||
|
||||
public void testUnknownSwitchLabel() throws Exception {
|
||||
doTest("Unable to migrate statement to enum constant. 8 can't be replaced with enum", false,
|
||||
doTest("Unable to migrate statement to enum constant. 8 can not be replaced with enum", false,
|
||||
new RefactoringTestUtil.MemberDescriptor("FOO", PsiField.class, true),
|
||||
new RefactoringTestUtil.MemberDescriptor("BAR", PsiField.class, true));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user