ConvertToAnonymousObjectFix: do not suggest when there is no lambda

#KT-31912 Fixed
This commit is contained in:
Toshiaki Kameyama
2019-11-26 16:05:41 +09:00
committed by Roman Golyshev
parent d3c54f664b
commit 09304bbd54
6 changed files with 47 additions and 9 deletions
@@ -78,12 +78,7 @@ class SamConversionToAnonymousObjectIntention : SelfTargetingRangeIntention<KtCa
}
companion object {
fun convertToAnonymousObject(call: KtCallExpression, functionDescriptor: FunctionDescriptor, functionName: String) {
val lambda = getLambdaExpression(call) ?: return
convertToAnonymousObject(call, lambda, functionDescriptor, functionName)
}
private fun convertToAnonymousObject(
fun convertToAnonymousObject(
call: KtCallExpression,
lambda: KtLambdaExpression,
functionDescriptor: FunctionDescriptor,
@@ -108,7 +103,7 @@ class SamConversionToAnonymousObjectIntention : SelfTargetingRangeIntention<KtCa
}
}
private fun getLambdaExpression(element: KtCallExpression): KtLambdaExpression? {
fun getLambdaExpression(element: KtCallExpression): KtLambdaExpression? {
return element.lambdaArguments.firstOrNull()?.getLambdaExpression()
?: element.valueArguments.firstOrNull()?.getArgumentExpression() as? KtLambdaExpression
}
@@ -31,11 +31,12 @@ class ConvertToAnonymousObjectFix(element: KtNameReferenceExpression) : KotlinQu
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
val nameReference = element ?: return
val call = nameReference.parent as? KtCallExpression ?: return
val lambda = SamConversionToAnonymousObjectIntention.getLambdaExpression(call) ?: return
val functionDescriptor = nameReference.analyze().diagnostics.forElement(nameReference).firstNotNullResult {
if (it.factory == Errors.RESOLUTION_TO_CLASSIFIER) getFunctionDescriptor(Errors.RESOLUTION_TO_CLASSIFIER.cast(it)) else null
} ?: return
val functionName = functionDescriptor.name.asString()
SamConversionToAnonymousObjectIntention.convertToAnonymousObject(call, functionDescriptor, functionName)
SamConversionToAnonymousObjectIntention.convertToAnonymousObject(call, lambda, functionDescriptor, functionName)
}
companion object : KotlinSingleIntentionActionFactory() {
@@ -43,7 +44,8 @@ class ConvertToAnonymousObjectFix(element: KtNameReferenceExpression) : KotlinQu
val casted = Errors.RESOLUTION_TO_CLASSIFIER.cast(diagnostic)
if (casted.b != WrongResolutionToClassifier.INTERFACE_AS_FUNCTION) return null
val nameReference = casted.psiElement as? KtNameReferenceExpression ?: return null
if (nameReference.parent as? KtCallExpression == null) return null
val call = nameReference.parent as? KtCallExpression ?: return null
if (SamConversionToAnonymousObjectIntention.getLambdaExpression(call) == null) return null
if (getFunctionDescriptor(casted) == null) return null
return ConvertToAnonymousObjectFix(nameReference)
}
@@ -0,0 +1,8 @@
// "Convert to anonymous object" "true"
interface I {
fun foo(): String
}
fun test() {
val i = <caret>I({ "" })
}
@@ -0,0 +1,12 @@
// "Convert to anonymous object" "true"
interface I {
fun foo(): String
}
fun test() {
val i = object : I {
override fun foo(): String {
return ""
}
}
}
@@ -0,0 +1,11 @@
// "Convert to anonymous object" "false"
// ACTION: Introduce import alias
// ACTION: Split property declaration
// ERROR: Interface I does not have constructors
interface I {
fun foo(): String
}
fun test() {
val i = <caret>I()
}
@@ -2838,11 +2838,21 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
runTest("idea/testData/quickfix/convertToAnonymousObject/labeledReturn.kt");
}
@TestMetadata("lambdaInParentheses.kt")
public void testLambdaInParentheses() throws Exception {
runTest("idea/testData/quickfix/convertToAnonymousObject/lambdaInParentheses.kt");
}
@TestMetadata("multiMethod.kt")
public void testMultiMethod() throws Exception {
runTest("idea/testData/quickfix/convertToAnonymousObject/multiMethod.kt");
}
@TestMetadata("noLambda.kt")
public void testNoLambda() throws Exception {
runTest("idea/testData/quickfix/convertToAnonymousObject/noLambda.kt");
}
@TestMetadata("parameter.kt")
public void testParameter() throws Exception {
runTest("idea/testData/quickfix/convertToAnonymousObject/parameter.kt");