Replace explicit parameter with it: don't suggest if overload resolution ambiguity error occurs
#KT-20795 Fixed
This commit is contained in:
committed by
Yan Zhulanow
parent
69a2697598
commit
5b927d798c
+21
-6
@@ -27,14 +27,16 @@ import com.intellij.usageView.UsageInfo
|
|||||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
|
import org.jetbrains.kotlin.idea.analysis.analyzeAsReplacement
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.core.copied
|
||||||
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
||||||
import org.jetbrains.kotlin.psi.KtFunctionLiteral
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
class ReplaceExplicitFunctionLiteralParamWithItIntention : PsiElementBaseIntentionAction() {
|
class ReplaceExplicitFunctionLiteralParamWithItIntention : PsiElementBaseIntentionAction() {
|
||||||
override fun getFamilyName() = KotlinBundle.message("replace.explicit.lambda.parameter.with.it")
|
override fun getFamilyName() = KotlinBundle.message("replace.explicit.lambda.parameter.with.it")
|
||||||
@@ -50,6 +52,19 @@ class ReplaceExplicitFunctionLiteralParamWithItIntention : PsiElementBaseIntenti
|
|||||||
literal.usesName(element.text) && (!literal.hasParameterSpecification() || literal.usesName("it"))
|
literal.usesName(element.text) && (!literal.hasParameterSpecification() || literal.usesName("it"))
|
||||||
}) return false
|
}) return false
|
||||||
|
|
||||||
|
val lambda = functionLiteral.parent as? KtLambdaExpression ?: return false
|
||||||
|
val call = lambda.getStrictParentOfType<KtCallExpression>()
|
||||||
|
if (call != null) {
|
||||||
|
val argumentIndex = call.valueArguments.indexOfFirst { it.getArgumentExpression() == lambda }
|
||||||
|
val callOrQualified = call.getQualifiedExpressionForSelectorOrThis()
|
||||||
|
val newCallOrQualified = callOrQualified.copied()
|
||||||
|
val newCall = newCallOrQualified.safeAs<KtQualifiedExpression>()?.callExpression ?: newCallOrQualified.safeAs() ?: return false
|
||||||
|
val newArgument = newCall.valueArguments.getOrNull(argumentIndex) ?: newCall.lambdaArguments.singleOrNull() ?: return false
|
||||||
|
newArgument.replace(KtPsiFactory(element).createLambdaExpression("", "TODO()"))
|
||||||
|
val newContext = newCallOrQualified.analyzeAsReplacement(callOrQualified, callOrQualified.analyze(BodyResolveMode.PARTIAL))
|
||||||
|
if (newCallOrQualified.getResolvedCall(newContext)?.resultingDescriptor == null) return false
|
||||||
|
}
|
||||||
|
|
||||||
text = KotlinBundle.message("replace.explicit.parameter.0.with.it", parameter.name.toString())
|
text = KotlinBundle.message("replace.explicit.parameter.0.with.it", parameter.name.toString())
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo() {
|
||||||
|
val a: (Int) -> Unit = { <caret>a -> bar(a) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(i: Int) {}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
fun foo() {
|
||||||
|
val a: (Int) -> Unit = { bar(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(i: Int) {}
|
||||||
idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_qualifiedExpression.kt
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
fun test() {
|
||||||
|
C().foo { <caret>i -> i + 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun foo(f: (Int) -> Int) {}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
fun test() {
|
||||||
|
C().foo { it + 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun foo(f: (Int) -> Int) {}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// IS_APPLICABLE: false
|
||||||
|
fun test() {
|
||||||
|
foo { <caret>i -> i + 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(f: (Int) -> Int) {}
|
||||||
|
fun foo(f: (Int, Int) -> Int) {}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// IS_APPLICABLE: false
|
||||||
|
fun test() {
|
||||||
|
C().foo { <caret>i -> i + 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
class C {
|
||||||
|
fun foo(f: (Int) -> Int) {}
|
||||||
|
fun foo(f: (Int, Int) -> Int) {}
|
||||||
|
}
|
||||||
@@ -14634,11 +14634,21 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
runTest("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_formatsProperly.kt");
|
runTest("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_formatsProperly.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("applicable_inPropertyInitializer.kt")
|
||||||
|
public void testApplicable_inPropertyInitializer() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_inPropertyInitializer.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("applicable_nestedLiteralsNoUseInside.kt")
|
@TestMetadata("applicable_nestedLiteralsNoUseInside.kt")
|
||||||
public void testApplicable_nestedLiteralsNoUseInside() throws Exception {
|
public void testApplicable_nestedLiteralsNoUseInside() throws Exception {
|
||||||
runTest("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_nestedLiteralsNoUseInside.kt");
|
runTest("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_nestedLiteralsNoUseInside.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("applicable_qualifiedExpression.kt")
|
||||||
|
public void testApplicable_qualifiedExpression() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/applicable_qualifiedExpression.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("notApplicable_alreadyUsesImplicitIt.kt")
|
@TestMetadata("notApplicable_alreadyUsesImplicitIt.kt")
|
||||||
public void testNotApplicable_alreadyUsesImplicitIt() throws Exception {
|
public void testNotApplicable_alreadyUsesImplicitIt() throws Exception {
|
||||||
runTest("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_alreadyUsesImplicitIt.kt");
|
runTest("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_alreadyUsesImplicitIt.kt");
|
||||||
@@ -14674,6 +14684,16 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
runTest("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_notFunctionLiteralParameter.kt");
|
runTest("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_notFunctionLiteralParameter.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notApplicable_overloadResolutionAmbiguity.kt")
|
||||||
|
public void testNotApplicable_overloadResolutionAmbiguity() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_overloadResolutionAmbiguity.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("notApplicable_overloadResolutionAmbiguity2.kt")
|
||||||
|
public void testNotApplicable_overloadResolutionAmbiguity2() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_overloadResolutionAmbiguity2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("notApplicable_parameterHasExplicitType.kt")
|
@TestMetadata("notApplicable_parameterHasExplicitType.kt")
|
||||||
public void testNotApplicable_parameterHasExplicitType() throws Exception {
|
public void testNotApplicable_parameterHasExplicitType() throws Exception {
|
||||||
runTest("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_parameterHasExplicitType.kt");
|
runTest("idea/testData/intentions/replaceExplicitFunctionLiteralParamWithIt/notApplicable_parameterHasExplicitType.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user