KT-34509 Properly unwrap callable reference descriptor

NB there's a problem with callable references to SAM constructors,
see also KT-16789
This commit is contained in:
Dmitry Petrov
2019-10-21 16:01:33 +03:00
parent 7dde503697
commit eebb071ae9
6 changed files with 187 additions and 7 deletions
@@ -1212,6 +1212,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
runTest("compiler/testData/ir/irText/expressions/tryCatchWithImplicitCast.kt"); runTest("compiler/testData/ir/irText/expressions/tryCatchWithImplicitCast.kt");
} }
@TestMetadata("typeAliasConstructorReference.kt")
public void testTypeAliasConstructorReference() throws Exception {
runTest("compiler/testData/ir/irText/expressions/typeAliasConstructorReference.kt");
}
@TestMetadata("typeArguments.kt") @TestMetadata("typeArguments.kt")
public void testTypeArguments() throws Exception { public void testTypeArguments() throws Exception {
runTest("compiler/testData/ir/irText/expressions/typeArguments.kt"); runTest("compiler/testData/ir/irText/expressions/typeArguments.kt");
@@ -29,7 +29,6 @@ import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.psiUtil.endOffset import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments import org.jetbrains.kotlin.psi.psiUtil.startOffsetSkippingComments
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.ImportedFromObjectCallableDescriptor
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
@@ -58,22 +57,21 @@ class ReflectionReferencesGenerator(statementGenerator: StatementGenerator) : St
fun generateCallableReference(ktCallableReference: KtCallableReferenceExpression): IrExpression { fun generateCallableReference(ktCallableReference: KtCallableReferenceExpression): IrExpression {
val resolvedCall = getResolvedCall(ktCallableReference.callableReference)!! val resolvedCall = getResolvedCall(ktCallableReference.callableReference)!!
val resolvedDescriptor = resolvedCall.resultingDescriptor
val resultingDescriptor = resolvedCall.resultingDescriptor val callBuilder = unwrapCallableDescriptorAndTypeArguments(resolvedCall, context.extensions.samConversion)
val descriptorImportedFromObject = resultingDescriptor as? ImportedFromObjectCallableDescriptor<*>
val referencedDescriptor = descriptorImportedFromObject?.callableFromObject ?: resultingDescriptor
return statementGenerator.generateCallReceiver( return statementGenerator.generateCallReceiver(
ktCallableReference, ktCallableReference,
resultingDescriptor, resolvedDescriptor,
resolvedCall.dispatchReceiver, resolvedCall.extensionReceiver, resolvedCall.dispatchReceiver, resolvedCall.extensionReceiver,
isSafe = false isSafe = false
).call { dispatchReceiverValue, extensionReceiverValue -> ).call { dispatchReceiverValue, extensionReceiverValue ->
generateCallableReference( generateCallableReference(
ktCallableReference, ktCallableReference,
getInferredTypeWithImplicitCastsOrFail(ktCallableReference), getInferredTypeWithImplicitCastsOrFail(ktCallableReference),
referencedDescriptor, callBuilder.descriptor,
resolvedCall.typeArguments callBuilder.typeArguments
).also { irCallableReference -> ).also { irCallableReference ->
irCallableReference.dispatchReceiver = dispatchReceiverValue?.loadIfExists() irCallableReference.dispatchReceiver = dispatchReceiverValue?.loadIfExists()
irCallableReference.extensionReceiver = extensionReceiverValue?.loadIfExists() irCallableReference.extensionReceiver = extensionReceiverValue?.loadIfExists()
@@ -0,0 +1,78 @@
FILE fqName:<root> fileName:/typeAliasConstructorReference.kt
CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.C
CONSTRUCTOR visibility:public <> (x:kotlin.Int) returnType:<root>.C [primary]
VALUE_PARAMETER name:x index:0 type:kotlin.Int
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
CLASS OBJECT name:Host modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Host
CONSTRUCTOR visibility:private <> () returnType:<root>.Host [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS OBJECT name:Host modality:FINAL visibility:public superTypes:[kotlin.Any]'
CLASS CLASS name:Nested modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Host.Nested
CONSTRUCTOR visibility:public <> (x:kotlin.Int) returnType:<root>.Host.Nested [primary]
VALUE_PARAMETER name:x index:0 type:kotlin.Int
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Nested modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
PROPERTY name:test1 visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.Function1<kotlin.Int, <root>.C> visibility:private [final,static]
EXPRESSION_BODY
GET_OBJECT 'CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test1> visibility:public modality:FINAL <> () returnType:kotlin.Function1<kotlin.Int, <root>.C>
correspondingProperty: PROPERTY name:test1 visibility:public modality:FINAL [val]
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-test1> (): kotlin.Function1<kotlin.Int, <root>.C> declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.Function1<kotlin.Int, <root>.C> visibility:private [final,static]' type=kotlin.Function1<kotlin.Int, <root>.C> origin=null
PROPERTY name:test2 visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Function1<kotlin.Int, <root>.Host.Nested> visibility:private [final,static]
EXPRESSION_BODY
GET_OBJECT 'CLASS CLASS name:Nested modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.Unit
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test2> visibility:public modality:FINAL <> () returnType:kotlin.Function1<kotlin.Int, <root>.Host.Nested>
correspondingProperty: PROPERTY name:test2 visibility:public modality:FINAL [val]
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-test2> (): kotlin.Function1<kotlin.Int, <root>.Host.Nested> declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Function1<kotlin.Int, <root>.Host.Nested> visibility:private [final,static]' type=kotlin.Function1<kotlin.Int, <root>.Host.Nested> origin=null
@@ -0,0 +1,14 @@
import Host.Nested
class C(x: Int)
typealias CA = C
object Host {
class Nested(x: Int)
}
typealias NA = Nested
val test1: (Int) -> CA = ::CA
val test2: (Int) -> NA = ::NA
@@ -0,0 +1,80 @@
FILE fqName:<root> fileName:/typeAliasConstructorReference.kt
CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.C
CONSTRUCTOR visibility:public <> (x:kotlin.Int) returnType:<root>.C [primary]
VALUE_PARAMETER name:x index:0 type:kotlin.Int
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
TYPEALIAS name:CA visibility:public expandedType:<root>.C
CLASS OBJECT name:Host modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Host
CONSTRUCTOR visibility:private <> () returnType:<root>.Host [primary]
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS OBJECT name:Host modality:FINAL visibility:public superTypes:[kotlin.Any]'
CLASS CLASS name:Nested modality:FINAL visibility:public superTypes:[kotlin.Any]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:<root>.Host.Nested
CONSTRUCTOR visibility:public <> (x:kotlin.Int) returnType:<root>.Host.Nested [primary]
VALUE_PARAMETER name:x index:0 type:kotlin.Int
BLOCK_BODY
DELEGATING_CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in kotlin.Any'
INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Nested modality:FINAL visibility:public superTypes:[kotlin.Any]'
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean
overridden:
public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int
overridden:
public open fun hashCode (): kotlin.Int declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String
overridden:
public open fun toString (): kotlin.String declared in kotlin.Any
$this: VALUE_PARAMETER name:<this> type:kotlin.Any
TYPEALIAS name:NA visibility:public expandedType:<root>.Host.Nested
PROPERTY name:test1 visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.Function1<kotlin.Int, <root>.C{ <root>.CA }> visibility:private [final,static]
EXPRESSION_BODY
FUNCTION_REFERENCE 'public constructor <init> (x: kotlin.Int) [primary] declared in <root>.C' type=kotlin.reflect.KFunction1<@[ParameterName(name = 'x')] kotlin.Int, <root>.C{ <root>.CA }> origin=null
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test1> visibility:public modality:FINAL <> () returnType:kotlin.Function1<kotlin.Int, <root>.C{ <root>.CA }>
correspondingProperty: PROPERTY name:test1 visibility:public modality:FINAL [val]
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-test1> (): kotlin.Function1<kotlin.Int, <root>.C{ <root>.CA }> declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test1 type:kotlin.Function1<kotlin.Int, <root>.C{ <root>.CA }> visibility:private [final,static]' type=kotlin.Function1<kotlin.Int, <root>.C{ <root>.CA }> origin=null
PROPERTY name:test2 visibility:public modality:FINAL [val]
FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Function1<kotlin.Int, <root>.Host.Nested{ <root>.NA }> visibility:private [final,static]
EXPRESSION_BODY
FUNCTION_REFERENCE 'public constructor <init> (x: kotlin.Int) [primary] declared in <root>.Host.Nested' type=kotlin.reflect.KFunction1<@[ParameterName(name = 'x')] kotlin.Int, <root>.Host.Nested{ <root>.NA }> origin=null
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test2> visibility:public modality:FINAL <> () returnType:kotlin.Function1<kotlin.Int, <root>.Host.Nested{ <root>.NA }>
correspondingProperty: PROPERTY name:test2 visibility:public modality:FINAL [val]
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun <get-test2> (): kotlin.Function1<kotlin.Int, <root>.Host.Nested{ <root>.NA }> declared in <root>'
GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:test2 type:kotlin.Function1<kotlin.Int, <root>.Host.Nested{ <root>.NA }> visibility:private [final,static]' type=kotlin.Function1<kotlin.Int, <root>.Host.Nested{ <root>.NA }> origin=null
@@ -1212,6 +1212,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
runTest("compiler/testData/ir/irText/expressions/tryCatchWithImplicitCast.kt"); runTest("compiler/testData/ir/irText/expressions/tryCatchWithImplicitCast.kt");
} }
@TestMetadata("typeAliasConstructorReference.kt")
public void testTypeAliasConstructorReference() throws Exception {
runTest("compiler/testData/ir/irText/expressions/typeAliasConstructorReference.kt");
}
@TestMetadata("typeArguments.kt") @TestMetadata("typeArguments.kt")
public void testTypeArguments() throws Exception { public void testTypeArguments() throws Exception {
runTest("compiler/testData/ir/irText/expressions/typeArguments.kt"); runTest("compiler/testData/ir/irText/expressions/typeArguments.kt");