Create from Usage: Support smart casts on explicit receivers
#KT-24069 Fixed
This commit is contained in:
+7
-3
@@ -164,7 +164,7 @@ fun KtExpression.guessTypes(
|
||||
// if we know the actual type of the expression
|
||||
val theType1 = context.getType(this)
|
||||
if (theType1 != null && isAcceptable(theType1)) {
|
||||
return getDataFlowAwareTypes(this, context).toTypedArray()
|
||||
return getDataFlowAwareTypes(this, context, theType1).toTypedArray()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,8 +341,12 @@ private fun TypePredicate.getRepresentativeTypes(): Set<KotlinType> {
|
||||
}
|
||||
}
|
||||
|
||||
fun getDataFlowAwareTypes(expression: KtExpression, bindingContext: BindingContext = expression.analyze()): List<KotlinType> {
|
||||
val originalType = bindingContext.getType(expression) ?: return emptyList()
|
||||
fun getDataFlowAwareTypes(
|
||||
expression: KtExpression,
|
||||
bindingContext: BindingContext = expression.analyze(),
|
||||
originalType: KotlinType? = bindingContext.getType(expression)
|
||||
): Collection<KotlinType> {
|
||||
if (originalType == null) return emptyList()
|
||||
val dataFlowInfo = bindingContext.getDataFlowInfoAfter(expression)
|
||||
val dataFlowValueFactory = expression.getResolutionFacade().frontendService<DataFlowValueFactory>()
|
||||
val dataFlowValue = dataFlowValueFactory.createDataFlowValue(
|
||||
|
||||
+7
-1
@@ -129,7 +129,13 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
|
||||
if (javaClass == null || !javaClass.canRefactor()) return null
|
||||
TypeInfo.StaticContextRequired(TypeInfo(javaClassifier.defaultType, Variance.IN_VARIANCE))
|
||||
}
|
||||
is ReceiverValue -> TypeInfo(receiver.type, Variance.IN_VARIANCE)
|
||||
is ReceiverValue -> {
|
||||
val originalType = receiver.type
|
||||
val finalType = if (receiver is ExpressionReceiver) {
|
||||
getDataFlowAwareTypes(receiver.expression, context, originalType).firstOrNull() ?: originalType
|
||||
} else originalType
|
||||
TypeInfo(finalType, Variance.IN_VARIANCE)
|
||||
}
|
||||
else -> throw AssertionError("Unexpected receiver: $receiver")
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Create member function 'SomeObj.doSomething'" "true"
|
||||
class SomeObj { }
|
||||
|
||||
fun doSomething(p: Any): List<Number>{
|
||||
if (p is SomeObj){
|
||||
p.<caret>doSomething()
|
||||
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Create member function 'SomeObj.doSomething'" "true"
|
||||
class SomeObj {
|
||||
fun doSomething() {
|
||||
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
|
||||
}
|
||||
}
|
||||
|
||||
fun doSomething(p: Any): List<Number>{
|
||||
if (p is SomeObj){
|
||||
p.doSomething()
|
||||
|
||||
}
|
||||
return emptyList()
|
||||
}
|
||||
@@ -3114,6 +3114,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
||||
runTest("idea/testData/quickfix/createFromUsage/createFunction/call/qualifiedCallInStringTemplateRuntime.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("receiverWithSmartCast.kt")
|
||||
public void testReceiverWithSmartCast() throws Exception {
|
||||
runTest("idea/testData/quickfix/createFromUsage/createFunction/call/receiverWithSmartCast.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("refInImport.kt")
|
||||
public void testRefInImport() throws Exception {
|
||||
runTest("idea/testData/quickfix/createFromUsage/createFunction/call/refInImport.kt");
|
||||
|
||||
Reference in New Issue
Block a user