Descriptors in calls are substituted,

and symbols refer to the original descriptors.
This commit is contained in:
Dmitry Petrov
2017-04-12 15:35:25 +03:00
parent d7a362b4f6
commit 2b0d3440ad
10 changed files with 76 additions and 18 deletions
@@ -189,15 +189,21 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
): PropertyLValueBase {
val superQualifierSymbol = superQualifier?.let { context.symbolTable.referenceClass(it) }
val getterSymbol = descriptor.getter?.let { context.symbolTable.referenceFunction(it) }
val setterSymbol = descriptor.setter?.let { context.symbolTable.referenceFunction(it) }
val getterDescriptor = descriptor.getter
val getterSymbol = getterDescriptor?.let { context.symbolTable.referenceFunction(it.original) }
val setterDescriptor = descriptor.setter
val setterSymbol = setterDescriptor?.let { context.symbolTable.referenceFunction(it.original) }
return if (getterSymbol != null || setterSymbol != null) {
AccessorPropertyLValue(
scope,
ktExpression.startOffset, ktExpression.endOffset, origin,
descriptor.type,
getterSymbol,
getterDescriptor,
setterSymbol,
setterDescriptor,
typeArguments,
propertyReceiver,
superQualifierSymbol
@@ -135,10 +135,11 @@ class CallGenerator(statementGenerator: StatementGenerator): StatementGeneratorE
val getterDescriptor = descriptor.getter
if (getterDescriptor != null) {
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor)
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original)
IrGetterCallImpl(
startOffset, endOffset,
getterSymbol,
getterDescriptor,
getTypeArguments(call.original),
dispatchReceiverValue?.load(),
extensionReceiverValue?.load(),
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.psi2ir.intermediate
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.expressions.IrExpression
@@ -112,7 +113,9 @@ class AccessorPropertyLValue(
origin: IrStatementOrigin?,
type: KotlinType,
val getter: IrFunctionSymbol?,
val getterDescriptor: FunctionDescriptor?,
val setter: IrFunctionSymbol?,
val setterDescriptor: FunctionDescriptor?,
val typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
callReceiver: CallReceiver,
superQualifier: IrClassSymbol?
@@ -121,7 +124,7 @@ class AccessorPropertyLValue(
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
IrGetterCallImpl(
startOffset, endOffset,
getter!!,
getter!!, getterDescriptor!!,
typeArguments,
dispatchReceiverValue?.load(),
extensionReceiverValue?.load(),
@@ -134,7 +137,7 @@ class AccessorPropertyLValue(
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
IrSetterCallImpl(
startOffset, endOffset,
setter!!,
setter!!, setterDescriptor!!,
typeArguments,
dispatchReceiverValue?.load(),
extensionReceiverValue?.load(),
@@ -147,7 +150,7 @@ class AccessorPropertyLValue(
override fun withReceiver(dispatchReceiver: VariableLValue?, extensionReceiver: VariableLValue?): PropertyLValueBase =
AccessorPropertyLValue(
scope, startOffset, endOffset, origin,
type, getter, setter,
type, getter, getterDescriptor, setter, setterDescriptor,
typeArguments,
SimpleCallReceiver(dispatchReceiver, extensionReceiver),
superQualifier
@@ -135,7 +135,7 @@ fun IrBuilderWithScope.irNotEquals(arg1: IrExpression, arg2: IrExpression) =
arg1, arg2))
fun IrBuilderWithScope.irGet(receiver: IrExpression, getterSymbol: IrFunctionSymbol): IrCall =
IrGetterCallImpl(startOffset, endOffset, getterSymbol, null, receiver, null, IrStatementOrigin.GET_PROPERTY)
IrGetterCallImpl(startOffset, endOffset, getterSymbol, getterSymbol.descriptor, null, receiver, null, IrStatementOrigin.GET_PROPERTY)
fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol, type: KotlinType): IrCall =
IrCallImpl(startOffset, endOffset, type, callee, callee.descriptor, null)
@@ -16,9 +16,10 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrCallWithShallowCopy
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
@@ -63,7 +64,7 @@ class IrCallImpl(
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, symbol.descriptor.returnType!!, symbol, descriptor, typeArguments, origin, superQualifierSymbol)
) : this(startOffset, endOffset, descriptor.returnType!!, symbol, descriptor, typeArguments, origin, superQualifierSymbol)
constructor(startOffset: Int, endOffset: Int, symbol: IrFunctionSymbol) :
this(startOffset, endOffset, symbol, symbol.descriptor)
@@ -36,11 +36,11 @@ import java.lang.UnsupportedOperationException
abstract class IrPropertyAccessorCallBase(
startOffset: Int, endOffset: Int,
override val symbol: IrFunctionSymbol,
override val descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
override val origin: IrStatementOrigin? = null,
override val superQualifierSymbol: IrClassSymbol? = null
) : IrMemberAccessExpressionBase(startOffset, endOffset, symbol.descriptor.returnType!!, typeArguments), IrCall {
override val descriptor: FunctionDescriptor get() = symbol.descriptor
) : IrMemberAccessExpressionBase(startOffset, endOffset, descriptor.returnType!!, typeArguments), IrCall {
override val superQualifier: ClassDescriptor? get() = superQualifierSymbol?.descriptor
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
@@ -55,18 +55,20 @@ abstract class IrPropertyAccessorCallBase(
class IrGetterCallImpl(
startOffset: Int, endOffset: Int,
symbol: IrFunctionSymbol,
descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : IrPropertyAccessorCallBase(startOffset, endOffset, symbol, typeArguments, origin, superQualifierSymbol), IrCallWithShallowCopy {
) : IrPropertyAccessorCallBase(startOffset, endOffset, symbol, descriptor, typeArguments, origin, superQualifierSymbol), IrCallWithShallowCopy {
constructor(startOffset: Int, endOffset: Int,
symbol: IrFunctionSymbol,
descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
dispatchReceiver: IrExpression?,
extensionReceiver: IrExpression?,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, symbol, typeArguments, origin, superQualifierSymbol) {
) : this(startOffset, endOffset, symbol, descriptor, typeArguments, origin, superQualifierSymbol) {
this.dispatchReceiver = dispatchReceiver
this.extensionReceiver = extensionReceiver
}
@@ -82,12 +84,15 @@ class IrGetterCallImpl(
}
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: IrFunctionSymbol, newSuperQualifier: IrClassSymbol?): IrCall =
IrGetterCallImpl(startOffset, endOffset, newCallee, typeArguments, dispatchReceiver, extensionReceiver, newOrigin, newSuperQualifier)
IrGetterCallImpl(startOffset, endOffset, newCallee,
descriptor, // TODO substitute descriptor for new callee?
typeArguments, dispatchReceiver, extensionReceiver, newOrigin, newSuperQualifier)
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: FunctionDescriptor, newSuperQualifier: ClassDescriptor?): IrCall =
IrGetterCallImpl(
startOffset, endOffset,
createFunctionSymbol(newCallee),
newCallee,
typeArguments, dispatchReceiver, extensionReceiver,
newOrigin,
createClassSymbolOrNull(newSuperQualifier)
@@ -97,19 +102,21 @@ class IrGetterCallImpl(
class IrSetterCallImpl(
startOffset: Int, endOffset: Int,
symbol: IrFunctionSymbol,
descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : IrPropertyAccessorCallBase(startOffset, endOffset, symbol, typeArguments, origin, superQualifierSymbol), IrCallWithShallowCopy {
) : IrPropertyAccessorCallBase(startOffset, endOffset, symbol, descriptor, typeArguments, origin, superQualifierSymbol), IrCallWithShallowCopy {
constructor(startOffset: Int, endOffset: Int,
symbol: IrFunctionSymbol,
descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
dispatchReceiver: IrExpression?,
extensionReceiver: IrExpression?,
argument: IrExpression,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, symbol, typeArguments, origin, superQualifierSymbol) {
) : this(startOffset, endOffset, symbol, descriptor, typeArguments, origin, superQualifierSymbol) {
this.dispatchReceiver = dispatchReceiver
this.extensionReceiver = extensionReceiver
putValueArgument(SETTER_ARGUMENT_INDEX, argument)
@@ -131,12 +138,15 @@ class IrSetterCallImpl(
}
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: IrFunctionSymbol, newSuperQualifier: IrClassSymbol?): IrCall =
IrSetterCallImpl(startOffset, endOffset, newCallee, typeArguments, newOrigin, newSuperQualifier)
IrSetterCallImpl(startOffset, endOffset, newCallee,
descriptor, // TODO substitute newCallee.descriptor?
typeArguments, newOrigin, newSuperQualifier)
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: FunctionDescriptor, newSuperQualifier: ClassDescriptor?): IrCall =
IrSetterCallImpl(
startOffset, endOffset,
createFunctionSymbol(newCallee),
newCallee,
typeArguments,
newOrigin,
createClassSymbolOrNull(newSuperQualifier)
@@ -24,6 +24,18 @@ abstract class IrSymbolBase<out D : DeclarationDescriptor>(override val descript
abstract class IrBindableSymbolBase<out D : DeclarationDescriptor, B : IrSymbolOwner>(descriptor: D) :
IrBindableSymbol<D, B>, IrSymbolBase<D>(descriptor) {
init {
assert(isOriginalDescriptor(descriptor)) {
"Substituted descriptor $descriptor for ${descriptor.original}"
}
}
private fun isOriginalDescriptor(descriptor: DeclarationDescriptor): Boolean =
if (descriptor is ValueParameterDescriptor)
isOriginalDescriptor(descriptor.containingDeclaration)
else
descriptor == descriptor.original
private var _owner: B? = null
override val owner: B
get() = _owner ?: throw IllegalStateException("Symbol for $descriptor is unbound")
@@ -0,0 +1,3 @@
val <T> T.id get() = this
val test = "abc".id
@@ -0,0 +1,16 @@
FILE /genericPropertyCall.kt
PROPERTY public val <T> T.id: T
FUN public fun T.<get-id>(): T
$receiver: VALUE_PARAMETER <receiver: id: T on T>
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-id>() on T: T'
GET_VAR '<receiver: id: T on T>' type=T origin=null
PROPERTY public val test: kotlin.String
FIELD PROPERTY_BACKING_FIELD public val test: kotlin.String
EXPRESSION_BODY
CALL '<get-id>() on String: String' type=kotlin.String origin=GET_PROPERTY
$receiver: CONST String type=kotlin.String value='abc'
FUN DEFAULT_PROPERTY_ACCESSOR public fun <get-test>(): kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='<get-test>(): String'
GET_FIELD 'test: String' type=kotlin.String origin=null
@@ -647,6 +647,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
doTest(fileName);
}
@TestMetadata("genericPropertyCall.kt")
public void testGenericPropertyCall() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/genericPropertyCall.kt");
doTest(fileName);
}
@TestMetadata("identity.kt")
public void testIdentity() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/identity.kt");