Wrap with let: fix it works correctly for invoking function type
#KT-39182 Fixed
This commit is contained in:
committed by
igoriakovlev
parent
babdeacdaf
commit
f6e70cfed8
@@ -20,12 +20,16 @@ import com.intellij.codeInsight.intention.HighPriorityAction
|
|||||||
import com.intellij.codeInsight.intention.IntentionAction
|
import com.intellij.codeInsight.intention.IntentionAction
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||||
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
import org.jetbrains.kotlin.idea.core.KotlinNameSuggester
|
||||||
import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator
|
import org.jetbrains.kotlin.idea.core.NewDeclarationNameValidator
|
||||||
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
|
import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor
|
||||||
import org.jetbrains.kotlin.psi.*
|
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
|
||||||
@@ -48,13 +52,25 @@ class WrapWithSafeLetCallFix(
|
|||||||
val nullableExpression = nullableExpressionPointer.element ?: return
|
val nullableExpression = nullableExpressionPointer.element ?: return
|
||||||
val qualifiedExpression = element.getQualifiedExpressionForSelector()
|
val qualifiedExpression = element.getQualifiedExpressionForSelector()
|
||||||
val receiverExpression = qualifiedExpression?.receiverExpression
|
val receiverExpression = qualifiedExpression?.receiverExpression
|
||||||
|
val isInvokingFunctionType = if (nullableExpression.parent is KtCallExpression) {
|
||||||
|
val property = nullableExpression.mainReference?.resolve() as? KtProperty
|
||||||
|
(property?.descriptor as? PropertyDescriptor)?.type?.isFunctionType == true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
val factory = KtPsiFactory(element)
|
val factory = KtPsiFactory(element)
|
||||||
val nullableText = nullableExpression.text
|
val nullableText = if (receiverExpression != null && isInvokingFunctionType) {
|
||||||
|
"${receiverExpression.text}${qualifiedExpression.operationSign.value}${nullableExpression.text}"
|
||||||
|
} else {
|
||||||
|
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 underLetExpression = when {
|
val underLetExpression = when {
|
||||||
receiverExpression != null -> factory.createExpressionByPattern("$0.$1", receiverExpression, element)
|
receiverExpression != null && !isInvokingFunctionType -> factory.createExpressionByPattern("$0.$1", receiverExpression, element)
|
||||||
else -> element
|
else -> element
|
||||||
}
|
}
|
||||||
val wrapped = when (name) {
|
val wrapped = when (name) {
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// "Wrap with '?.let { ... }' call" "true"
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
val bar: ((Int) -> Unit)?
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(foo: Foo) {
|
||||||
|
foo.bar<caret>(1)
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// "Wrap with '?.let { ... }' call" "true"
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
val bar: ((Int) -> Unit)?
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test(foo: Foo) {
|
||||||
|
foo.bar?.let { it(1) }
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// "Wrap with '?.let { ... }' call" "true"
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
val bar: ((Int) -> Unit)?
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
<caret>bar(1)
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// "Wrap with '?.let { ... }' call" "true"
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
interface Foo {
|
||||||
|
val bar: ((Int) -> Unit)?
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Foo.test() {
|
||||||
|
bar?.let { it(1) }
|
||||||
|
}
|
||||||
@@ -15474,6 +15474,16 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
runTest("idea/testData/quickfix/wrapWithSafeLetCall/invokeFuncUnsafe.kt");
|
runTest("idea/testData/quickfix/wrapWithSafeLetCall/invokeFuncUnsafe.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("invokeFunctionType.kt")
|
||||||
|
public void testInvokeFunctionType() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/wrapWithSafeLetCall/invokeFunctionType.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("invokeFunctionType2.kt")
|
||||||
|
public void testInvokeFunctionType2() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/wrapWithSafeLetCall/invokeFunctionType2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("invokeUnsafe.kt")
|
@TestMetadata("invokeUnsafe.kt")
|
||||||
public void testInvokeUnsafe() throws Exception {
|
public void testInvokeUnsafe() throws Exception {
|
||||||
runTest("idea/testData/quickfix/wrapWithSafeLetCall/invokeUnsafe.kt");
|
runTest("idea/testData/quickfix/wrapWithSafeLetCall/invokeUnsafe.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user