[kotlin] Prevent adding safe let call to the null constant

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
This commit is contained in:
Dmitry Timofeev
2022-02-19 00:51:08 +00:00
committed by intellij-monorepo-bot
parent 7f53808613
commit b92edd11a9
3 changed files with 57 additions and 2 deletions
@@ -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<KtQualifiedExpression>() ?: call, element)
}
}
@@ -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");
@@ -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(<caret>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) {}
}