"Wrap with let": fix for nullable extension function call #KT-6364 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
093842932f
commit
b6564ed19a
@@ -28,11 +28,12 @@ import org.jetbrains.kotlin.psi.*
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getLastParentOfTypeInRow
|
import org.jetbrains.kotlin.psi.psiUtil.getLastParentOfTypeInRow
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelector
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isNullabilityMismatch
|
import org.jetbrains.kotlin.types.typeUtil.isNullabilityMismatch
|
||||||
|
|
||||||
class WrapWithSafeLetCallFix(
|
class WrapWithSafeLetCallFix(
|
||||||
expression: KtExpression,
|
expression: KtExpression,
|
||||||
nullableExpression: KtExpression
|
nullableExpression: KtExpression
|
||||||
) : KotlinQuickFixAction<KtExpression>(expression) {
|
) : KotlinQuickFixAction<KtExpression>(expression) {
|
||||||
private val nullableExpressionPointer = nullableExpression.createSmartPointer()
|
private val nullableExpressionPointer = nullableExpression.createSmartPointer()
|
||||||
|
|
||||||
@@ -43,16 +44,19 @@ class WrapWithSafeLetCallFix(
|
|||||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||||
val element = element ?: return
|
val element = element ?: return
|
||||||
val nullableExpression = nullableExpressionPointer.element ?: return
|
val nullableExpression = nullableExpressionPointer.element ?: return
|
||||||
|
val qualifiedExpression = element.getQualifiedExpressionForSelector()
|
||||||
|
val receiverExpression = qualifiedExpression?.receiverExpression
|
||||||
val factory = KtPsiFactory(element)
|
val factory = KtPsiFactory(element)
|
||||||
val nullableText = nullableExpression.text
|
val nullableText = nullableExpression.text
|
||||||
val validator = NewDeclarationNameValidator(element, nullableExpression, NewDeclarationNameValidator.Target.VARIABLES)
|
val validator = NewDeclarationNameValidator(element, nullableExpression, NewDeclarationNameValidator.Target.VARIABLES)
|
||||||
val name = KotlinNameSuggester.suggestNameByName("it", validator)
|
val name = KotlinNameSuggester.suggestNameByName("it", validator)
|
||||||
nullableExpression.replace(factory.createExpression(name))
|
nullableExpression.replace(factory.createExpression(name))
|
||||||
|
val newExpression: Any = if (receiverExpression != null) "${receiverExpression.text}.${element.text}" else element
|
||||||
val wrapped = when (name) {
|
val wrapped = when (name) {
|
||||||
"it" -> factory.createExpressionByPattern("$0?.let { $1 }", nullableText, element)
|
"it" -> factory.createExpressionByPattern("$0?.let { $1 }", nullableText, newExpression)
|
||||||
else -> factory.createExpressionByPattern("$0?.let { $1 -> $2 }", nullableText, name, element)
|
else -> factory.createExpressionByPattern("$0?.let { $1 -> $2 }", nullableText, name, newExpression)
|
||||||
}
|
}
|
||||||
element.replace(wrapped)
|
(qualifiedExpression ?: element).replace(wrapped)
|
||||||
}
|
}
|
||||||
|
|
||||||
object UnsafeFactory : KotlinSingleIntentionActionFactory() {
|
object UnsafeFactory : KotlinSingleIntentionActionFactory() {
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// "Wrap with '?.let { ... }' call" "true"
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
fun f(s: String, action: (String.() -> Unit)?) {
|
||||||
|
s.action<caret>()
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// "Wrap with '?.let { ... }' call" "true"
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
fun f(s: String, action: (String.() -> Unit)?) {
|
||||||
|
action?.let { s.it() }
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// "Wrap with '?.let { ... }' call" "true"
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
fun f(s: String, action: (String.() -> Unit)?) {
|
||||||
|
s.foo().bar().action<caret>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun String.foo() = ""
|
||||||
|
|
||||||
|
fun String.bar() = ""
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// "Wrap with '?.let { ... }' call" "true"
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
fun f(s: String, action: (String.() -> Unit)?) {
|
||||||
|
action?.let { s.foo().bar().it() }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun String.foo() = ""
|
||||||
|
|
||||||
|
fun String.bar() = ""
|
||||||
@@ -12059,6 +12059,16 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
runTest("idea/testData/quickfix/wrapWithSafeLetCall/extensionMethod.kt");
|
runTest("idea/testData/quickfix/wrapWithSafeLetCall/extensionMethod.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extentionFunctionCall.kt")
|
||||||
|
public void testExtentionFunctionCall() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/wrapWithSafeLetCall/extentionFunctionCall.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extentionFunctionCall2.kt")
|
||||||
|
public void testExtentionFunctionCall2() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/wrapWithSafeLetCall/extentionFunctionCall2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("insideLet.kt")
|
@TestMetadata("insideLet.kt")
|
||||||
public void testInsideLet() throws Exception {
|
public void testInsideLet() throws Exception {
|
||||||
runTest("idea/testData/quickfix/wrapWithSafeLetCall/insideLet.kt");
|
runTest("idea/testData/quickfix/wrapWithSafeLetCall/insideLet.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user