Create from Usage: Strip first parameter of extension function when expected type is non-extension
This commit is contained in:
+7
-3
@@ -41,15 +41,19 @@ object CreateFunctionFromCallableReferenceActionFactory : CreateCallableMemberFr
|
||||
.guessTypes(context, resolutionFacade.moduleDescriptor)
|
||||
.filter { KotlinBuiltIns.isExactFunctionType(it) || KotlinBuiltIns.isExactExtensionFunctionType(it) }
|
||||
.mapNotNull {
|
||||
val receiverTypeInfo = element.typeReference?.let { TypeInfo(it, Variance.IN_VARIANCE) } ?: TypeInfo.Empty
|
||||
val expectedReceiverType = KotlinBuiltIns.getReceiverType(it)
|
||||
val actualReceiverTypeRef = element.typeReference
|
||||
val receiverTypeInfo = actualReceiverTypeRef?.let { TypeInfo(it, Variance.IN_VARIANCE) } ?: TypeInfo.Empty
|
||||
val returnTypeInfo = TypeInfo(KotlinBuiltIns.getReturnTypeFromFunctionType(it), Variance.OUT_VARIANCE)
|
||||
val containers = element.getExtractionContainers(includeAll = true).ifEmpty { return@mapNotNull null }
|
||||
val parameterInfos = SmartList<ParameterInfo>().apply {
|
||||
if (element.typeReference == null) {
|
||||
KotlinBuiltIns.getReceiverType(it)?.let { add(ParameterInfo(TypeInfo(it, Variance.IN_VARIANCE))) }
|
||||
if (actualReceiverTypeRef == null && expectedReceiverType != null) {
|
||||
add(ParameterInfo(TypeInfo(expectedReceiverType, Variance.IN_VARIANCE)))
|
||||
}
|
||||
|
||||
KotlinBuiltIns
|
||||
.getParameterTypeProjectionsFromFunctionType(it)
|
||||
.let { if (actualReceiverTypeRef != null && expectedReceiverType == null && it.isNotEmpty()) it.subList(1, it.size) else it }
|
||||
.mapTo(this) { ParameterInfo(TypeInfo(it.type, it.projectionKind)) }
|
||||
}
|
||||
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Create extension function 'foo'" "true"
|
||||
// WITH_RUNTIME
|
||||
fun <T, U> T.map(f: (T) -> U) = f(this)
|
||||
|
||||
fun consume(s: String) {}
|
||||
|
||||
fun test() {
|
||||
consume(1.map(Int::<caret>foo))
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// "Create extension function 'foo'" "true"
|
||||
// WITH_RUNTIME
|
||||
fun <T, U> T.map(f: (T) -> U) = f(this)
|
||||
|
||||
fun consume(s: String) {}
|
||||
|
||||
fun test() {
|
||||
consume(1.map(Int::foo))
|
||||
}
|
||||
|
||||
fun Int.foo(): String {
|
||||
<selection>throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates.</selection>
|
||||
}
|
||||
@@ -2228,6 +2228,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nonExtensionWithReceiverInCallableRef.kt")
|
||||
public void testNonExtensionWithReceiverInCallableRef() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/callableReferences/nonExtensionWithReceiverInCallableRef.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("withExpectedReturnType.kt")
|
||||
public void testWithExpectedReturnType() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/createFromUsage/createFunction/callableReferences/withExpectedReturnType.kt");
|
||||
|
||||
Reference in New Issue
Block a user