diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/rules/RootTypeConversionRule.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/rules/RootTypeConversionRule.java index 7c4551fe8466..75f4c8f2092a 100644 --- a/java/java-impl/src/com/intellij/refactoring/typeMigration/rules/RootTypeConversionRule.java +++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/rules/RootTypeConversionRule.java @@ -118,8 +118,7 @@ public class RootTypeConversionRule extends TypeConversionRule { } final PsiType migrationType = methodTypeParamsSubstitutor.substitute(type); - if (!originalType.equals(migrationType) && - !TypeConversionUtil.areTypesAssignmentCompatible(migrationType, actualParams[i])) { + if (!originalType.equals(migrationType) && !areParametersAssignable(migrationType, i, actualParams)) { labeler.migrateExpressionType(actualParams[i], migrationType, context, false, true); } } @@ -139,6 +138,19 @@ public class RootTypeConversionRule extends TypeConversionRule { return null; } + private static boolean areParametersAssignable(PsiType migrationType, int paramId, PsiExpression[] actualParams) { + if (migrationType instanceof PsiEllipsisType) { + for (int i = paramId; i < actualParams.length; i++) { + if (!TypeConversionUtil.areTypesAssignmentCompatible(migrationType, actualParams[i])) { + return false; + } + } + return true; + } else { + return TypeConversionUtil.areTypesAssignmentCompatible(migrationType, actualParams[paramId]); + } + } + private static class MyStaticMethodConversionDescriptor extends TypeConversionDescriptorBase { private final @NotNull String myTargetClassQName; diff --git a/java/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java b/java/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java index ad7548e1e444..9c8145e51faf 100644 --- a/java/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java +++ b/java/typeMigration/test/com/intellij/refactoring/TypeMigrationTest.java @@ -862,6 +862,10 @@ public class TypeMigrationTest extends TypeMigrationTestBase { doTestMethodType("migrationMethod", PsiType.VOID); } + public void testGenericEllipsis() { + doTestFieldType("migrationField", myJavaFacade.getElementFactory().createTypeFromText("Test", null)); + } + private void doTestReturnType(final String methodName, final String migrationType) { start(new RulesProvider() { @Override diff --git a/java/typeMigration/testData/refactoring/typeMigration/genericEllipsis/after/Test.items b/java/typeMigration/testData/refactoring/typeMigration/genericEllipsis/after/Test.items new file mode 100644 index 000000000000..a00e0a47d582 --- /dev/null +++ b/java/typeMigration/testData/refactoring/typeMigration/genericEllipsis/after/Test.items @@ -0,0 +1,10 @@ +Types: +PsiField:migrationField : Test +PsiMethodCallExpression:migrationField.method() : void +PsiReferenceExpression:migrationField : Test + +Conversions: +migrationField.method() -> $ + +New expression type changes: +Fails: diff --git a/java/typeMigration/testData/refactoring/typeMigration/genericEllipsis/after/test.java b/java/typeMigration/testData/refactoring/typeMigration/genericEllipsis/after/test.java new file mode 100644 index 000000000000..f3f5ea781739 --- /dev/null +++ b/java/typeMigration/testData/refactoring/typeMigration/genericEllipsis/after/test.java @@ -0,0 +1,11 @@ +class Test { + private static Test migrationField; + + private static void m() { + migrationField.method(); + } + + void method(X... xes) { + + } +} diff --git a/java/typeMigration/testData/refactoring/typeMigration/genericEllipsis/before/test.java b/java/typeMigration/testData/refactoring/typeMigration/genericEllipsis/before/test.java new file mode 100644 index 000000000000..001d53331836 --- /dev/null +++ b/java/typeMigration/testData/refactoring/typeMigration/genericEllipsis/before/test.java @@ -0,0 +1,11 @@ +class Test { + private static Test migrationField; + + private static void m() { + migrationField.method(); + } + + void method(X... xes) { + + } +}