From b92edd11a90654faa599ab07d49f7b4babd32986 Mon Sep 17 00:00:00 2001 From: Dmitry Timofeev Date: Thu, 10 Feb 2022 11:42:19 +0300 Subject: [PATCH] [kotlin] Prevent adding safe let call to the null constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added a check whether the nullable argument is the null constant to avoid proposing the fix resulting in the unreachable code like `f(null)` → `null?.let { f(it) }` ^KTIJ-20993 Fixed (cherry-picked from commit 22819bcce03e5d53687cd832375486635ffc1647) IJ-MR-20704 GitOrigin-RevId: 7932bc25ab2cfa4647c2b1dd046412ae419d92ad --- .../idea/quickfix/WrapWithSafeLetCallFix.kt | 3 +- .../QuickFixMultiFileTestGenerated.java | 5 ++ .../javaNullabilityMismatchDoNotWrapNull.test | 51 +++++++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 plugins/kotlin/idea/tests/testData/quickfix/wrapWithSafeLetCall/javaNullabilityMismatchDoNotWrapNull.test diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/quickfix/WrapWithSafeLetCallFix.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/quickfix/WrapWithSafeLetCallFix.kt index 1a923afbefcc..10c262e90d29 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/quickfix/WrapWithSafeLetCallFix.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/quickfix/WrapWithSafeLetCallFix.kt @@ -114,8 +114,7 @@ class WrapWithSafeLetCallFix( else -> return null } - if (!isNullabilityMismatch(expected = expectedType, actual = actualType)) return null - + if (element.isNull() || !isNullabilityMismatch(expected = expectedType, actual = actualType)) return null return WrapWithSafeLetCallFix(call.getLastParentOfTypeInRow() ?: call, element) } } diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java index bde510fdd090..e6d2121a43b9 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java @@ -2293,6 +2293,11 @@ public abstract class QuickFixMultiFileTestGenerated extends AbstractQuickFixMul runTest("testData/quickfix/wrapWithSafeLetCall/javaNullabilityMismatchArgument2.test"); } + @TestMetadata("javaNullabilityMismatchDoNotWrapNull.test") + public void testJavaNullabilityMismatchDoNotWrapNull() throws Exception { + runTest("testData/quickfix/wrapWithSafeLetCall/javaNullabilityMismatchDoNotWrapNull.test"); + } + @TestMetadata("javaReceiverNullabilityInvoke.test") public void testJavaReceiverNullabilityInvoke() throws Exception { runTest("testData/quickfix/wrapWithSafeLetCall/javaReceiverNullabilityInvoke.test"); diff --git a/plugins/kotlin/idea/tests/testData/quickfix/wrapWithSafeLetCall/javaNullabilityMismatchDoNotWrapNull.test b/plugins/kotlin/idea/tests/testData/quickfix/wrapWithSafeLetCall/javaNullabilityMismatchDoNotWrapNull.test new file mode 100644 index 000000000000..adf51f69fb2d --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/quickfix/wrapWithSafeLetCall/javaNullabilityMismatchDoNotWrapNull.test @@ -0,0 +1,51 @@ +// FILE: test.before.kt +// "Wrap with '?.let { ... }' call" "false" +// ACTION: Add 'toString()' call +// ACTION: Add names in comment to call arguments +// ACTION: Convert to run +// ACTION: Convert to with +// ACTION: Do not show hints for current method +package p; + +fun test(x: Foo) { + x.foo(null); +} + +// FILE: org/jspecify/nullness/NullMarked.java +package org.jspecify.nullness; + +import static java.lang.annotation.ElementType.MODULE; +import static java.lang.annotation.ElementType.PACKAGE; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Target({TYPE, PACKAGE, MODULE}) +@Retention(RUNTIME) +public @interface NullMarked {} + +// FILE: org/jspecify/nullness/Nullable.java +package org.jspecify.nullness; + +import static java.lang.annotation.ElementType.TYPE_USE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +@Target(TYPE_USE) +@Retention(RUNTIME) +public @interface Nullable {} + +// FILE: p/Foo.java +package p; + +import org.jspecify.nullness.NullMarked; + +@NullMarked +public class Foo { + public void foo(String arg) {} +}