KT-13111: lambda --> reference support methods called via this now

This commit is contained in:
Mikhail Glukhikh
2017-03-10 17:38:03 +03:00
parent 19db4869e6
commit 2c692de98f
4 changed files with 35 additions and 13 deletions
@@ -240,22 +240,30 @@ class ConvertLambdaToReferenceIntention : SelfTargetingOffsetIndependentIntentio
is KtNameReferenceExpression -> selector.getReferencedName() is KtNameReferenceExpression -> selector.getReferencedName()
else -> return null else -> return null
} }
val receiver = singleStatement.receiverExpression as? KtNameReferenceExpression ?: return null val receiver = singleStatement.receiverExpression
val context = receiver.analyze() val context = receiver.analyze()
val receiverDescriptor = context[REFERENCE_TARGET, receiver] ?: return null when (receiver) {
val lambdaValueParameters = context[FUNCTION, lambdaExpression.functionLiteral]?.valueParameters ?: return null is KtNameReferenceExpression -> {
if (receiverDescriptor is ParameterDescriptor && receiverDescriptor == lambdaValueParameters.firstOrNull()) { val receiverDescriptor = context[REFERENCE_TARGET, receiver] ?: return null
val originalReceiverType = receiverDescriptor.type val lambdaValueParameters = context[FUNCTION, lambdaExpression.functionLiteral]?.valueParameters ?: return null
val receiverType = originalReceiverType.approximateFlexibleTypes(preferNotNull = true) if (receiverDescriptor is ParameterDescriptor && receiverDescriptor == lambdaValueParameters.firstOrNull()) {
if (shortTypes) { val originalReceiverType = receiverDescriptor.type
"${IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(receiverType)}::$selectorReferenceName" val receiverType = originalReceiverType.approximateFlexibleTypes(preferNotNull = true)
if (shortTypes) {
"${IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(receiverType)}::$selectorReferenceName"
}
else {
"${IdeDescriptorRenderers.SOURCE_CODE.renderType(receiverType)}::$selectorReferenceName"
}
}
else {
"${receiverDescriptor.name}::$selectorReferenceName"
}
} }
else { is KtThisExpression -> {
"${IdeDescriptorRenderers.SOURCE_CODE.renderType(receiverType)}::$selectorReferenceName" "${receiver.text}::$selectorReferenceName"
} }
} else -> null
else {
"${receiverDescriptor.name}::$selectorReferenceName"
} }
} }
else -> null else -> null
@@ -0,0 +1,4 @@
class Owner(val z: Int) {
fun foo(y: Int) = y + z
val x = { y: Int -><caret> this.foo(y) }
}
@@ -0,0 +1,4 @@
class Owner(val z: Int) {
fun foo(y: Int) = y + z
val x = this::foo
}
@@ -4466,6 +4466,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("memberViaThis.kt")
public void testMemberViaThis() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/memberViaThis.kt");
doTest(fileName);
}
@TestMetadata("name.kt") @TestMetadata("name.kt")
public void testName() throws Exception { public void testName() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/name.kt"); String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/name.kt");