diff --git a/generators/idea-generator/tests/org/jetbrains/kotlin/generators/tests/idea/GenerateTests.kt b/generators/idea-generator/tests/org/jetbrains/kotlin/generators/tests/idea/GenerateTests.kt index 0aad1d5426b..cded4987b5b 100644 --- a/generators/idea-generator/tests/org/jetbrains/kotlin/generators/tests/idea/GenerateTests.kt +++ b/generators/idea-generator/tests/org/jetbrains/kotlin/generators/tests/idea/GenerateTests.kt @@ -1171,7 +1171,7 @@ fun main(args: Array) { model("quickfix/expressions", pattern = pattern, filenameStartsLowerCase = true) model("quickfix/lateinit", pattern = pattern, filenameStartsLowerCase = true) model("quickfix/modifiers", pattern = pattern, filenameStartsLowerCase = true, recursive = false) - model("quickfix/nullables/unsafeInfixCall", pattern = pattern, filenameStartsLowerCase = true) + model("quickfix/nullables", pattern = pattern, filenameStartsLowerCase = true) model("quickfix/override", pattern = pattern, filenameStartsLowerCase = true, recursive = false) model("quickfix/override/typeMismatchOnOverride", pattern = pattern, filenameStartsLowerCase = true, recursive = false) model("quickfix/replaceInfixOrOperatorCall", pattern = pattern, filenameStartsLowerCase = true) diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/MainKtQuickFixRegistrar.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/MainKtQuickFixRegistrar.kt index 8eb0db29064..70d29458ca6 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/MainKtQuickFixRegistrar.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/quickfix/MainKtQuickFixRegistrar.kt @@ -132,6 +132,9 @@ class MainKtQuickFixRegistrar : KtQuickFixRegistrar() { registerApplicator(WrapWithSafeLetCallFixFactories.forUnsafeInfixCall) registerApplicator(WrapWithSafeLetCallFixFactories.forUnsafeOperatorCall) registerApplicator(WrapWithSafeLetCallFixFactories.forArgumentTypeMismatch) + + registerPsiQuickFixes(KtFirDiagnostic.NullableSupertype::class, RemoveNullableFix.removeForSuperType) + registerPsiQuickFixes(KtFirDiagnostic.InapplicableLateinitModifier::class, RemoveNullableFix.removeForLateInitProperty) } private val returnTypes = KtQuickFixesListBuilder.registerPsiQuickFix { diff --git a/idea/idea-fir/tests/org/jetbrains/kotlin/idea/fir/quickfix/HighLevelQuickFixTestGenerated.java b/idea/idea-fir/tests/org/jetbrains/kotlin/idea/fir/quickfix/HighLevelQuickFixTestGenerated.java index 16755e7320f..44892db435a 100644 --- a/idea/idea-fir/tests/org/jetbrains/kotlin/idea/fir/quickfix/HighLevelQuickFixTestGenerated.java +++ b/idea/idea-fir/tests/org/jetbrains/kotlin/idea/fir/quickfix/HighLevelQuickFixTestGenerated.java @@ -1133,76 +1133,109 @@ public class HighLevelQuickFixTestGenerated extends AbstractHighLevelQuickFixTes } } - @TestMetadata("idea/testData/quickfix/nullables/unsafeInfixCall") + @TestMetadata("idea/testData/quickfix/nullables") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) - public static class UnsafeInfixCall extends AbstractHighLevelQuickFixTest { + public static class Nullables extends AbstractHighLevelQuickFixTest { private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); } - public void testAllFilesPresentInUnsafeInfixCall() throws Exception { - KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/nullables/unsafeInfixCall"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), null, true); + public void testAllFilesPresentInNullables() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/nullables"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), null, true); } - @TestMetadata("noComparison.kt") - public void testNoComparison() throws Exception { - runTest("idea/testData/quickfix/nullables/unsafeInfixCall/noComparison.kt"); + @TestMetadata("removeRedundantNullable.kt") + public void testRemoveRedundantNullable() throws Exception { + runTest("idea/testData/quickfix/nullables/removeRedundantNullable.kt"); } - @TestMetadata("unsafeComparisonInCondition.kt") - public void testUnsafeComparisonInCondition() throws Exception { - runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInCondition.kt"); + @TestMetadata("removeSupertypeNullable1.kt") + public void testRemoveSupertypeNullable1() throws Exception { + runTest("idea/testData/quickfix/nullables/removeSupertypeNullable1.kt"); } - @TestMetadata("unsafeComparisonInLogic.kt") - public void testUnsafeComparisonInLogic() throws Exception { - runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInLogic.kt"); + @TestMetadata("removeSupertypeNullable2.kt") + public void testRemoveSupertypeNullable2() throws Exception { + runTest("idea/testData/quickfix/nullables/removeSupertypeNullable2.kt"); } - @TestMetadata("unsafeComparisonInWhen.kt") - public void testUnsafeComparisonInWhen() throws Exception { - runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInWhen.kt"); + @TestMetadata("removeUselessNullable.kt") + public void testRemoveUselessNullable() throws Exception { + runTest("idea/testData/quickfix/nullables/removeUselessNullable.kt"); } - @TestMetadata("unsafeComparisonInWhile.kt") - public void testUnsafeComparisonInWhile() throws Exception { - runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInWhile.kt"); - } + @TestMetadata("idea/testData/quickfix/nullables/unsafeInfixCall") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class UnsafeInfixCall extends AbstractHighLevelQuickFixTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } - @TestMetadata("unsafeGet.kt") - public void testUnsafeGet() throws Exception { - runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeGet.kt"); - } + public void testAllFilesPresentInUnsafeInfixCall() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/nullables/unsafeInfixCall"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), null, true); + } - @TestMetadata("unsafeInfixCall.kt") - public void testUnsafeInfixCall() throws Exception { - runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeInfixCall.kt"); - } + @TestMetadata("noComparison.kt") + public void testNoComparison() throws Exception { + runTest("idea/testData/quickfix/nullables/unsafeInfixCall/noComparison.kt"); + } - @TestMetadata("unsafeInvoke.kt") - public void testUnsafeInvoke() throws Exception { - runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeInvoke.kt"); - } + @TestMetadata("unsafeComparisonInCondition.kt") + public void testUnsafeComparisonInCondition() throws Exception { + runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInCondition.kt"); + } - @TestMetadata("unsafeInvokeWithImplicitReceiver.kt") - public void testUnsafeInvokeWithImplicitReceiver() throws Exception { - runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeInvokeWithImplicitReceiver.kt"); - } + @TestMetadata("unsafeComparisonInLogic.kt") + public void testUnsafeComparisonInLogic() throws Exception { + runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInLogic.kt"); + } - @TestMetadata("unsafeInvokeWithReceiver.kt") - public void testUnsafeInvokeWithReceiver() throws Exception { - runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeInvokeWithReceiver.kt"); - } + @TestMetadata("unsafeComparisonInWhen.kt") + public void testUnsafeComparisonInWhen() throws Exception { + runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInWhen.kt"); + } - @TestMetadata("unsafePlus.kt") - public void testUnsafePlus() throws Exception { - runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafePlus.kt"); - } + @TestMetadata("unsafeComparisonInWhile.kt") + public void testUnsafeComparisonInWhile() throws Exception { + runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInWhile.kt"); + } - @TestMetadata("unsafeSet.kt") - public void testUnsafeSet() throws Exception { - runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeSet.kt"); + @TestMetadata("unsafeGet.kt") + public void testUnsafeGet() throws Exception { + runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeGet.kt"); + } + + @TestMetadata("unsafeInfixCall.kt") + public void testUnsafeInfixCall() throws Exception { + runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeInfixCall.kt"); + } + + @TestMetadata("unsafeInvoke.kt") + public void testUnsafeInvoke() throws Exception { + runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeInvoke.kt"); + } + + @TestMetadata("unsafeInvokeWithImplicitReceiver.kt") + public void testUnsafeInvokeWithImplicitReceiver() throws Exception { + runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeInvokeWithImplicitReceiver.kt"); + } + + @TestMetadata("unsafeInvokeWithReceiver.kt") + public void testUnsafeInvokeWithReceiver() throws Exception { + runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeInvokeWithReceiver.kt"); + } + + @TestMetadata("unsafePlus.kt") + public void testUnsafePlus() throws Exception { + runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafePlus.kt"); + } + + @TestMetadata("unsafeSet.kt") + public void testUnsafeSet() throws Exception { + runTest("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeSet.kt"); + } } } diff --git a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/quickfix/RemoveNullableFix.kt b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/quickfix/RemoveNullableFix.kt index 1fe726658d2..5e24311524e 100644 --- a/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/quickfix/RemoveNullableFix.kt +++ b/idea/idea-frontend-independent/src/org/jetbrains/kotlin/idea/quickfix/RemoveNullableFix.kt @@ -8,10 +8,7 @@ package org.jetbrains.kotlin.idea.quickfix import com.intellij.openapi.editor.Editor import com.intellij.openapi.project.Project import org.jetbrains.kotlin.idea.KotlinBundle -import org.jetbrains.kotlin.psi.KtElement -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.KtNullableType -import org.jetbrains.kotlin.psi.KtProperty +import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType class RemoveNullableFix(element: KtNullableType, private val typeOfError: NullableKind) : @@ -43,7 +40,10 @@ class RemoveNullableFix(element: KtNullableType, private val typeOfError: Nullab return quickFixesPsiBasedFactory { e -> when (typeOfError) { NullableKind.REDUNDANT, NullableKind.SUPERTYPE, NullableKind.USELESS -> { - val nullType = e.getNonStrictParentOfType() + val nullType: KtNullableType? = when (e) { + is KtTypeReference -> e.typeElement as? KtNullableType + else -> e.getNonStrictParentOfType() + } if (nullType?.innerType == null) return@quickFixesPsiBasedFactory emptyList() listOf(RemoveNullableFix(nullType, typeOfError)) } diff --git a/idea/testData/quickfix/lateinit/nullable.kt b/idea/testData/quickfix/lateinit/nullable.kt index 8cbadc9000f..845cc34778a 100644 --- a/idea/testData/quickfix/lateinit/nullable.kt +++ b/idea/testData/quickfix/lateinit/nullable.kt @@ -2,5 +2,4 @@ class A() { lateinit var foo: String? -} -/* IGNORE_FIR */ \ No newline at end of file +} \ No newline at end of file diff --git a/idea/testData/quickfix/lateinit/nullable.kt.after b/idea/testData/quickfix/lateinit/nullable.kt.after index 92d5c378856..ad81581c0c2 100644 --- a/idea/testData/quickfix/lateinit/nullable.kt.after +++ b/idea/testData/quickfix/lateinit/nullable.kt.after @@ -2,5 +2,4 @@ class A() { lateinit var foo: String -} -/* IGNORE_FIR */ \ No newline at end of file +} \ No newline at end of file diff --git a/idea/testData/quickfix/nullables/removeRedundantNullable.kt b/idea/testData/quickfix/nullables/removeRedundantNullable.kt index e06372018de..58ac3320bba 100644 --- a/idea/testData/quickfix/nullables/removeRedundantNullable.kt +++ b/idea/testData/quickfix/nullables/removeRedundantNullable.kt @@ -2,3 +2,5 @@ fun main(args : Array) { val x : Int?? = 15 } + +/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/nullables/removeRedundantNullable.kt.after b/idea/testData/quickfix/nullables/removeRedundantNullable.kt.after index 4ddf231cd74..e126a26dbfa 100644 --- a/idea/testData/quickfix/nullables/removeRedundantNullable.kt.after +++ b/idea/testData/quickfix/nullables/removeRedundantNullable.kt.after @@ -2,3 +2,5 @@ fun main(args : Array) { val x : Int? = 15 } + +/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/nullables/removeUselessNullable.kt b/idea/testData/quickfix/nullables/removeUselessNullable.kt index 5012cb87f10..17df2fb3b34 100644 --- a/idea/testData/quickfix/nullables/removeUselessNullable.kt +++ b/idea/testData/quickfix/nullables/removeUselessNullable.kt @@ -1,4 +1,5 @@ // "Remove useless '?'" "true" fun f(a: Int) : Boolean { return a is Int? -} \ No newline at end of file +} +/* IGNORE_FIR */ \ No newline at end of file diff --git a/idea/testData/quickfix/nullables/removeUselessNullable.kt.after b/idea/testData/quickfix/nullables/removeUselessNullable.kt.after index 52da19f9152..e58ce9ab3df 100644 --- a/idea/testData/quickfix/nullables/removeUselessNullable.kt.after +++ b/idea/testData/quickfix/nullables/removeUselessNullable.kt.after @@ -1,4 +1,5 @@ // "Remove useless '?'" "true" fun f(a: Int) : Boolean { return a is Int -} \ No newline at end of file +} +/* IGNORE_FIR */ \ No newline at end of file