From c17451cf5c325c1468b312a56110b495b94d5a0d Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Mon, 31 Aug 2015 19:54:01 +0300 Subject: [PATCH] Add quickfix for JAVA_TYPE_MISMATCH --- .../idea/quickfix/CastExpressionFix.java | 23 ++++++++++++++++++- .../kotlin/idea/quickfix/QuickFixRegistrar.kt | 3 +++ .../basicMultiple.after.kt | 6 +++++ .../basicMultiple.before.Main.kt | 6 +++++ .../basicMultiple.before.data.Sample.java | 5 ++++ .../QuickFixMultiFileTestGenerated.java | 15 ++++++++++++ 6 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 idea/testData/quickfix/typeMismatch/genericVarianceViolation/basicMultiple.after.kt create mode 100644 idea/testData/quickfix/typeMismatch/genericVarianceViolation/basicMultiple.before.Main.kt create mode 100644 idea/testData/quickfix/typeMismatch/genericVarianceViolation/basicMultiple.before.data.Sample.java diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/CastExpressionFix.java b/idea/src/org/jetbrains/kotlin/idea/quickfix/CastExpressionFix.java index 7662011a1e6..675d083a05f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/CastExpressionFix.java +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/CastExpressionFix.java @@ -31,7 +31,9 @@ import org.jetbrains.kotlin.idea.caches.resolve.ResolvePackage; import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers; import org.jetbrains.kotlin.idea.util.ShortenReferences; import org.jetbrains.kotlin.psi.*; +import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm; import org.jetbrains.kotlin.types.JetType; +import org.jetbrains.kotlin.types.TypesPackage; import org.jetbrains.kotlin.types.checker.JetTypeChecker; import static org.jetbrains.kotlin.psi.PsiPackage.JetPsiFactory; @@ -64,7 +66,11 @@ public class CastExpressionFix extends JetIntentionAction { public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { if (!super.isAvailable(project, editor, file)) return false; JetType expressionType = ResolvePackage.analyze(element).getType(element); - return expressionType != null && JetTypeChecker.DEFAULT.isSubtypeOf(type, expressionType); + return expressionType != null + && ( + JetTypeChecker.DEFAULT.isSubtypeOf(type, expressionType) // downcast + || JetTypeChecker.DEFAULT.isSubtypeOf(expressionType, type) // upcast + ); } @Override @@ -106,4 +112,19 @@ public class CastExpressionFix extends JetIntentionAction { } }; } + + @NotNull + public static JetSingleIntentionActionFactory createFactoryForGenericVarianceConversion() { + return new JetSingleIntentionActionFactory() { + @Nullable + @Override + public IntentionAction createAction(@NotNull Diagnostic diagnostic) { + DiagnosticWithParameters2 diagnosticWithParameters = + ErrorsJvm.JAVA_TYPE_MISMATCH.cast(diagnostic); + return new CastExpressionFix( + diagnosticWithParameters.getPsiElement(), TypesPackage.flexibility(diagnosticWithParameters.getB()).getUpperBound() + ); + } + }; + } } diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt index 8e1f5b36903..2acbc441b84 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/QuickFixRegistrar.kt @@ -31,6 +31,7 @@ import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createVariable.CreateP import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createVariable.CreateParameterByRefActionFactory import org.jetbrains.kotlin.lexer.JetTokens.* import org.jetbrains.kotlin.psi.JetClass +import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.DEPRECATED_ANNOTATION_METHOD_CALL import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.NO_REFLECTION_IN_CLASS_PATH import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm.POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION @@ -315,5 +316,7 @@ public class QuickFixRegistrar : QuickFixContributor { POSITIONED_VALUE_ARGUMENT_FOR_JAVA_ANNOTATION.registerFactory(ReplaceJavaAnnotationPositionedArgumentsFix) NO_REFLECTION_IN_CLASS_PATH.registerFactory(AddReflectionQuickFix) + + ErrorsJvm.JAVA_TYPE_MISMATCH.registerFactory(CastExpressionFix.createFactoryForGenericVarianceConversion()) } } diff --git a/idea/testData/quickfix/typeMismatch/genericVarianceViolation/basicMultiple.after.kt b/idea/testData/quickfix/typeMismatch/genericVarianceViolation/basicMultiple.after.kt new file mode 100644 index 00000000000..3b70ca5371d --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/genericVarianceViolation/basicMultiple.after.kt @@ -0,0 +1,6 @@ +// "Cast expression 'x' to 'List?'" "true" +// ERROR: Java type mismatch expected kotlin.(Mutable)List! but found kotlin.MutableList. Use explicit cast + +fun main(x: MutableList) { + A.foo(x as List?) +} diff --git a/idea/testData/quickfix/typeMismatch/genericVarianceViolation/basicMultiple.before.Main.kt b/idea/testData/quickfix/typeMismatch/genericVarianceViolation/basicMultiple.before.Main.kt new file mode 100644 index 00000000000..02ff97ccbb6 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/genericVarianceViolation/basicMultiple.before.Main.kt @@ -0,0 +1,6 @@ +// "Cast expression 'x' to 'List?'" "true" +// ERROR: Java type mismatch expected kotlin.(Mutable)List! but found kotlin.MutableList. Use explicit cast + +fun main(x: MutableList) { + A.foo(x) +} diff --git a/idea/testData/quickfix/typeMismatch/genericVarianceViolation/basicMultiple.before.data.Sample.java b/idea/testData/quickfix/typeMismatch/genericVarianceViolation/basicMultiple.before.data.Sample.java new file mode 100644 index 00000000000..b2005528e76 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/genericVarianceViolation/basicMultiple.before.data.Sample.java @@ -0,0 +1,5 @@ +import java.util.* + +class A { + static void foo(List x) {} +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java index fc8542a1afd..47d08f13e66 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java @@ -1220,6 +1220,21 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/typeMismatch"), Pattern.compile("^(\\w+)\\.before\\.Main\\.kt$"), true); } + @TestMetadata("idea/testData/quickfix/typeMismatch/genericVarianceViolation") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class GenericVarianceViolation extends AbstractQuickFixMultiFileTest { + public void testAllFilesPresentInGenericVarianceViolation() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/typeMismatch/genericVarianceViolation"), Pattern.compile("^(\\w+)\\.before\\.Main\\.kt$"), true); + } + + @TestMetadata("basicMultiple.before.Main.kt") + public void testBasicMultiple() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/genericVarianceViolation/basicMultiple.before.Main.kt"); + doTestWithExtraFile(fileName); + } + } + } @TestMetadata("idea/testData/quickfix/variables")