Store type arguments by indices instead of TypeParameterDescriptor keys

This commit is contained in:
Dmitry Petrov
2018-03-26 12:43:02 +03:00
parent f4936d3e31
commit b5607e4b3d
16 changed files with 415 additions and 177 deletions
@@ -32,7 +32,7 @@ class IsArrayOf : IntrinsicMethod() {
"Expected only one type parameter for Any?.isArrayOf(), got: ${descriptor.typeParameters}"
}
/*TODO original?*/
val elementType = expression.getTypeArgument(descriptor.original.typeParameters.first())!!
val elementType = expression.getTypeArgument(descriptor.original.typeParameters.first().index)!!
val arrayKtType = builtIns.getArrayType(Variance.INVARIANT, elementType)
val arrayType = typeMapper.mapType(arrayKtType)
@@ -30,8 +30,9 @@ interface IrMemberAccessExpression : IrExpression {
val descriptor: CallableDescriptor
val origin: IrStatementOrigin?
// NB `typeParameterDescriptor` should be taken from `descriptor.original`
fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): KotlinType?
val typeArgumentsCount: Int
fun getTypeArgument(index: Int): KotlinType?
fun putTypeArgument(index: Int, type: KotlinType?)
val valueArgumentsCount: Int
fun getValueArgument(index: Int): IrExpression?
@@ -39,6 +40,34 @@ interface IrMemberAccessExpression : IrExpression {
fun removeValueArgument(index: Int)
}
fun IrMemberAccessExpression.getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): KotlinType? =
getTypeArgument(typeParameterDescriptor.index)
fun IrMemberAccessExpression.copyTypeArgumentsFrom(other: IrMemberAccessExpression) {
assert(typeArgumentsCount == other.typeArgumentsCount) {
"Mismatching type arguments: $typeArgumentsCount vs ${other.typeArgumentsCount} "
}
for (i in 0 until typeArgumentsCount) {
putTypeArgument(i, other.getTypeArgument(i))
}
}
fun IrMemberAccessExpression.copyTypeArgumentsFrom(source: Map<TypeParameterDescriptor, KotlinType>?) {
if (source == null) return
for ((typeParameter, typeArgument) in source) {
val index = typeParameter.index
assert(index < typeArgumentsCount) {
"Index out of range for type parameter $typeParameter; " +
"containingDeclaration: ${typeParameter.containingDeclaration}; " +
"callee: $descriptor"
}
putTypeArgument(index, typeArgument)
}
}
val Map<TypeParameterDescriptor, KotlinType>?.typeArgumentsCount: Int
get() = this?.size ?: 0
fun IrMemberAccessExpression.getTypeArgumentOrDefault(typeParameterDescriptor: TypeParameterDescriptor) =
getTypeArgument(typeParameterDescriptor) ?: typeParameterDescriptor.defaultType
@@ -21,6 +21,8 @@ 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.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
import org.jetbrains.kotlin.ir.expressions.typeArgumentsCount
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.createClassSymbolOrNull
@@ -34,11 +36,50 @@ class IrCallImpl(
type: KotlinType,
override val symbol: IrFunctionSymbol,
override val descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
override val origin: IrStatementOrigin? = null,
typeArgumentsCount: Int,
origin: IrStatementOrigin? = null,
override val superQualifierSymbol: IrClassSymbol? = null
) : IrCall,
IrCallWithIndexedArgumentsBase(startOffset, endOffset, type, symbol.descriptor.valueParameters.size, typeArguments) {
) :
IrCallWithIndexedArgumentsBase(
startOffset, endOffset, type,
typeArgumentsCount,
symbol.descriptor.valueParameters.size,
origin
),
IrCall {
constructor(
startOffset: Int,
endOffset: Int,
type: KotlinType,
symbol: IrFunctionSymbol,
descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, type, symbol, descriptor, typeArguments.typeArgumentsCount, origin, superQualifierSymbol) {
copyTypeArgumentsFrom(typeArguments)
}
@Deprecated("Creates unbound symbols")
constructor(
startOffset: Int,
endOffset: Int,
type: KotlinType,
calleeDescriptor: FunctionDescriptor,
typeArgumentsCount: Int,
origin: IrStatementOrigin? = null,
superQualifierDescriptor: ClassDescriptor? = null
) : this(
startOffset, endOffset,
type,
createFunctionSymbol(calleeDescriptor),
calleeDescriptor,
typeArgumentsCount,
origin,
createClassSymbolOrNull(superQualifierDescriptor)
)
@Deprecated("Creates unbound symbols")
constructor(
startOffset: Int,
@@ -53,9 +94,11 @@ class IrCallImpl(
type,
createFunctionSymbol(calleeDescriptor),
calleeDescriptor,
typeArguments, origin,
typeArguments.typeArgumentsCount, origin,
createClassSymbolOrNull(superQualifierDescriptor)
)
) {
copyTypeArgumentsFrom(typeArguments)
}
@Deprecated("Creates unbound symbols")
constructor(
@@ -70,9 +113,11 @@ class IrCallImpl(
calleeDescriptor.returnType!!,
createFunctionSymbol(calleeDescriptor),
calleeDescriptor,
typeArguments, origin,
typeArguments.typeArgumentsCount, origin,
createClassSymbolOrNull(superQualifierDescriptor)
)
) {
copyTypeArgumentsFrom(typeArguments)
}
constructor(
startOffset: Int, endOffset: Int,
@@ -81,7 +126,18 @@ class IrCallImpl(
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, descriptor.returnType!!, symbol, descriptor, typeArguments, origin, superQualifierSymbol)
) : this(
startOffset,
endOffset,
descriptor.returnType!!,
symbol,
descriptor,
typeArguments.typeArgumentsCount,
origin,
superQualifierSymbol
) {
copyTypeArgumentsFrom(typeArguments)
}
constructor(startOffset: Int, endOffset: Int, symbol: IrFunctionSymbol) :
this(startOffset, endOffset, symbol, symbol.descriptor)
@@ -19,27 +19,46 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
import org.jetbrains.kotlin.ir.expressions.typeArgumentsCount
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
import java.lang.AssertionError
abstract class IrCallWithIndexedArgumentsBase(
startOffset: Int, endOffset: Int, type: KotlinType,
startOffset: Int,
endOffset: Int,
type: KotlinType,
typeArgumentsCount: Int,
valueArgumentsCount: Int,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
override val origin: IrStatementOrigin? = null
) : IrMemberAccessExpressionBase(startOffset, endOffset, type, typeArguments, valueArgumentsCount) {
origin: IrStatementOrigin? = null
) : IrMemberAccessExpressionBase(startOffset, endOffset, type, typeArgumentsCount, valueArgumentsCount, origin) {
private val argumentsByParameterIndex =
arrayOfNulls<IrExpression>(valueArgumentsCount)
constructor(
startOffset: Int,
endOffset: Int,
type: KotlinType,
valueArgumentsCount: Int,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
origin: IrStatementOrigin? = null
) : this(startOffset, endOffset, type, typeArguments.typeArgumentsCount, valueArgumentsCount, origin) {
copyTypeArgumentsFrom(typeArguments)
}
override fun getValueArgument(index: Int): IrExpression? =
argumentsByParameterIndex[index]
private val argumentsByParameterIndex: Array<IrExpression?> = arrayOfNulls(valueArgumentsCount)
override fun getValueArgument(index: Int): IrExpression? {
if (index >= argumentsByParameterIndex.size) {
throw AssertionError("$this: No such argument slot: $index in ${render()}")
}
return argumentsByParameterIndex[index]
}
override fun putValueArgument(index: Int, valueArgument: IrExpression?) {
if (index >= argumentsByParameterIndex.size) {
throw AssertionError("$this: No such argument slot: $index")
throw AssertionError("$this: No such argument slot: $index in ${render()}")
}
argumentsByParameterIndex[index] = valueArgument
}
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
import org.jetbrains.kotlin.ir.expressions.typeArgumentsCount
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -30,24 +32,51 @@ class IrDelegatingConstructorCallImpl(
endOffset: Int,
override val symbol: IrConstructorSymbol,
override val descriptor: ClassConstructorDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null
) : IrDelegatingConstructorCall,
typeArgumentsCount: Int
) :
IrCallWithIndexedArgumentsBase(
startOffset, endOffset,
startOffset,
endOffset,
symbol.descriptor.builtIns.unitType,
symbol.descriptor.valueParameters.size,
typeArguments
) {
typeArgumentsCount = typeArgumentsCount,
valueArgumentsCount = symbol.descriptor.valueParameters.size
),
IrDelegatingConstructorCall {
@Deprecated("Use constructor with typeArgumentsCount and fill type arguments explicitly or with copyTypeArgumentsFrom")
constructor(
startOffset: Int,
endOffset: Int,
symbol: IrConstructorSymbol,
descriptor: ClassConstructorDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null
) : this(startOffset, endOffset, symbol, descriptor, typeArguments.typeArgumentsCount) {
copyTypeArgumentsFrom(typeArguments)
}
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int,
endOffset: Int,
constructorDescriptor: ClassConstructorDescriptor,
descriptor: ClassConstructorDescriptor,
typeArgumentsCount: Int
) : this(
startOffset, endOffset,
IrConstructorSymbolImpl(descriptor.original),
descriptor,
typeArgumentsCount
)
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int,
endOffset: Int,
descriptor: ClassConstructorDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null
) : this(
startOffset, endOffset,
IrConstructorSymbolImpl(constructorDescriptor.original),
constructorDescriptor,
IrConstructorSymbolImpl(descriptor.original),
descriptor,
typeArguments
)
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrEnumConstructorCall
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
import org.jetbrains.kotlin.ir.expressions.typeArgumentsCount
import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -29,14 +31,34 @@ class IrEnumConstructorCallImpl(
startOffset: Int,
endOffset: Int,
override val symbol: IrConstructorSymbol,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?
) : IrEnumConstructorCall,
typeArgumentsCount: Int
) :
IrCallWithIndexedArgumentsBase(
startOffset, endOffset,
startOffset,
endOffset,
symbol.descriptor.builtIns.unitType,
symbol.descriptor.valueParameters.size,
typeArguments
) {
typeArgumentsCount = typeArgumentsCount,
valueArgumentsCount = symbol.descriptor.valueParameters.size
),
IrEnumConstructorCall {
@Deprecated("Use constructor with typeArgumentsCount and fill type arguments explicitly or with copyTypeArgumentsFrom")
constructor(
startOffset: Int,
endOffset: Int,
symbol: IrConstructorSymbol,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null
) : this(startOffset, endOffset, symbol, typeArguments.typeArgumentsCount) {
copyTypeArgumentsFrom(typeArguments)
}
@Deprecated("Creates unbound symbols")
constructor(
startOffset: Int,
endOffset: Int,
descriptor: ClassConstructorDescriptor,
typeArgumentsCount: Int
) : this(startOffset, endOffset, IrConstructorSymbolImpl(descriptor), typeArgumentsCount)
@Deprecated("Creates unbound symbols")
constructor(
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
import org.jetbrains.kotlin.ir.expressions.typeArgumentsCount
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.createFunctionSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -31,15 +33,30 @@ class IrFunctionReferenceImpl(
type: KotlinType,
override val symbol: IrFunctionSymbol,
override val descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
typeArgumentsCount: Int,
origin: IrStatementOrigin? = null
) : IrFunctionReference,
) :
IrCallWithIndexedArgumentsBase(
startOffset, endOffset, type,
startOffset,
endOffset,
type,
typeArgumentsCount,
symbol.descriptor.valueParameters.size,
typeArguments,
origin
) {
),
IrFunctionReference {
constructor(
startOffset: Int,
endOffset: Int,
type: KotlinType,
symbol: IrFunctionSymbol,
descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null,
origin: IrStatementOrigin? = null
) : this(startOffset, endOffset, type, symbol, descriptor, typeArguments.typeArgumentsCount, origin) {
copyTypeArgumentsFrom(typeArguments)
}
@Deprecated("Creates unbound symbol")
constructor(
@@ -47,9 +64,23 @@ class IrFunctionReferenceImpl(
endOffset: Int,
type: KotlinType,
descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
typeArgumentsCount: Int,
origin: IrStatementOrigin? = null
) : this(startOffset, endOffset, type, createFunctionSymbol(descriptor.original), descriptor, typeArguments, origin)
) : this(startOffset, endOffset, type, createFunctionSymbol(descriptor.original), descriptor, typeArgumentsCount, origin)
@Deprecated("Creates unbound symbol")
constructor(
startOffset: Int,
endOffset: Int,
type: KotlinType,
descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null,
origin: IrStatementOrigin? = null
) : this(
startOffset, endOffset, type, createFunctionSymbol(descriptor.original), descriptor, typeArguments.typeArgumentsCount, origin
) {
copyTypeArgumentsFrom(typeArguments)
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitFunctionReference(this, data)
@@ -33,8 +33,9 @@ class IrLocalDelegatedPropertyReferenceImpl(
override val getter: IrFunctionSymbol,
override val setter: IrFunctionSymbol?,
origin: IrStatementOrigin? = null
) : IrLocalDelegatedPropertyReference,
IrNoArgumentsCallableReferenceBase(startOffset, endOffset, type, null, origin) {
) : IrNoArgumentsCallableReferenceBase(startOffset, endOffset, type, 0, origin),
IrLocalDelegatedPropertyReference {
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitLocalDelegatedPropertyReference(this, data)
}
@@ -16,9 +16,9 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.types.KotlinType
@@ -27,14 +27,23 @@ abstract class IrMemberAccessExpressionBase(
startOffset: Int,
endOffset: Int,
type: KotlinType,
val typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
override val valueArgumentsCount: Int
) : IrExpressionBase(startOffset, endOffset, type), IrMemberAccessExpression {
final override val typeArgumentsCount: Int,
final override val valueArgumentsCount: Int,
final override val origin: IrStatementOrigin? = null
) : IrExpressionBase(startOffset, endOffset, type),
IrMemberAccessExpression {
override var dispatchReceiver: IrExpression? = null
override var extensionReceiver: IrExpression? = null
override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): KotlinType? =
typeArguments?.get(typeParameterDescriptor)
private val typeArgumentsByIndex = arrayOfNulls<KotlinType>(typeArgumentsCount)
override fun getTypeArgument(index: Int): KotlinType? =
typeArgumentsByIndex[index]
override fun putTypeArgument(index: Int, type: KotlinType?) {
typeArgumentsByIndex[index] = type
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
dispatchReceiver?.accept(visitor, data)
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.ir.expressions.impl
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrCallableReference
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
@@ -26,10 +25,10 @@ abstract class IrNoArgumentsCallableReferenceBase(
startOffset: Int,
endOffset: Int,
type: KotlinType,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
override val origin: IrStatementOrigin? = null
) : IrCallableReference,
IrMemberAccessExpressionBase(startOffset, endOffset, type, typeArguments, 0) {
typeArgumentsCount: Int,
origin: IrStatementOrigin? = null
) : IrMemberAccessExpressionBase(startOffset, endOffset, type, typeArgumentsCount, 0, origin),
IrCallableReference {
private fun throwNoValueArguments(): Nothing {
throw UnsupportedOperationException("Property reference $descriptor has no value arguments")
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.ir.expressions.impl
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.IrExpression
@@ -44,6 +43,12 @@ abstract class IrPrimitiveCallBase(
override val superQualifier: ClassDescriptor? get() = null
override val superQualifierSymbol: IrClassSymbol? get() = null
override val typeArgumentsCount: Int = 0
override fun getTypeArgument(index: Int): KotlinType? = null
override fun putTypeArgument(index: Int, type: KotlinType?) {}
override var dispatchReceiver: IrExpression?
get() = null
set(value) {
@@ -58,9 +63,6 @@ abstract class IrPrimitiveCallBase(
throw UnsupportedOperationException("Operator call expression can't have a receiver")
}
override fun getTypeArgument(typeParameterDescriptor: TypeParameterDescriptor): KotlinType? =
null // IR primitives have no type parameters
override fun removeValueArgument(index: Int) {
throw AssertionError("Operator call expression can't have a default argument")
}
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.ir.expressions.impl
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.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.createClassSymbolOrNull
@@ -37,11 +34,11 @@ abstract class IrPropertyAccessorCallBase(
startOffset: Int, endOffset: Int,
override val symbol: IrFunctionSymbol,
override val descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
typeArgumentsCount: Int,
valueArgumentsCount: Int,
override val origin: IrStatementOrigin? = null,
origin: IrStatementOrigin? = null,
override val superQualifierSymbol: IrClassSymbol? = null
) : IrMemberAccessExpressionBase(startOffset, endOffset, descriptor.returnType!!, typeArguments, valueArgumentsCount),
) : IrMemberAccessExpressionBase(startOffset, endOffset, descriptor.returnType!!, typeArgumentsCount, valueArgumentsCount, origin),
IrCall {
override val superQualifier: ClassDescriptor? get() = superQualifierSymbol?.descriptor
@@ -56,17 +53,34 @@ abstract class IrPropertyAccessorCallBase(
}
class IrGetterCallImpl(
startOffset: Int, endOffset: Int,
startOffset: Int,
endOffset: Int,
symbol: IrFunctionSymbol,
descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
typeArgumentsCount: Int,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : IrPropertyAccessorCallBase(startOffset, endOffset, symbol, descriptor, typeArguments, 0, origin, superQualifierSymbol),
) : IrPropertyAccessorCallBase(startOffset, endOffset, symbol, descriptor, typeArgumentsCount, 0, origin, superQualifierSymbol),
IrCallWithShallowCopy {
constructor(
startOffset: Int, endOffset: Int,
startOffset: Int,
endOffset: Int,
symbol: IrFunctionSymbol,
descriptor: FunctionDescriptor,
typeArgumentsCount: Int,
dispatchReceiver: IrExpression?,
extensionReceiver: IrExpression?,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, symbol, descriptor, typeArgumentsCount, origin, superQualifierSymbol) {
this.dispatchReceiver = dispatchReceiver
this.extensionReceiver = extensionReceiver
}
constructor(
startOffset: Int,
endOffset: Int,
symbol: IrFunctionSymbol,
descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
@@ -74,9 +88,12 @@ class IrGetterCallImpl(
extensionReceiver: IrExpression?,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, symbol, descriptor, typeArguments, origin, superQualifierSymbol) {
this.dispatchReceiver = dispatchReceiver
this.extensionReceiver = extensionReceiver
) : this(
startOffset, endOffset, symbol, descriptor,
typeArguments.typeArgumentsCount,
dispatchReceiver, extensionReceiver, origin, superQualifierSymbol
) {
copyTypeArgumentsFrom(typeArguments)
}
override fun getValueArgument(index: Int): IrExpression? = null
@@ -93,30 +110,50 @@ class IrGetterCallImpl(
IrGetterCallImpl(
startOffset, endOffset, newCallee,
descriptor, // TODO substitute descriptor for new callee?
typeArguments, dispatchReceiver, extensionReceiver, newOrigin, newSuperQualifier
)
typeArgumentsCount, newOrigin, newSuperQualifier
).also { newCall ->
newCall.copyTypeArgumentsFrom(this)
}
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: FunctionDescriptor, newSuperQualifier: ClassDescriptor?): IrCall =
IrGetterCallImpl(
startOffset, endOffset,
createFunctionSymbol(newCallee),
newCallee,
typeArguments, dispatchReceiver, extensionReceiver,
typeArgumentsCount,
newOrigin,
createClassSymbolOrNull(newSuperQualifier)
)
).also { newCall ->
newCall.copyTypeArgumentsFrom(this)
}
}
class IrSetterCallImpl(
startOffset: Int, endOffset: Int,
symbol: IrFunctionSymbol,
descriptor: FunctionDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
typeArgumentsCount: Int,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : IrPropertyAccessorCallBase(startOffset, endOffset, symbol, descriptor, typeArguments, 1, origin, superQualifierSymbol),
) : IrPropertyAccessorCallBase(startOffset, endOffset, symbol, descriptor, typeArgumentsCount, 1, origin, superQualifierSymbol),
IrCallWithShallowCopy {
constructor(
startOffset: Int, endOffset: Int,
symbol: IrFunctionSymbol,
descriptor: FunctionDescriptor,
typeArgumentsCount: Int,
dispatchReceiver: IrExpression?,
extensionReceiver: IrExpression?,
argument: IrExpression,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, symbol, descriptor, typeArgumentsCount, origin, superQualifierSymbol) {
this.dispatchReceiver = dispatchReceiver
this.extensionReceiver = extensionReceiver
putValueArgument(SETTER_ARGUMENT_INDEX, argument)
}
constructor(
startOffset: Int, endOffset: Int,
symbol: IrFunctionSymbol,
@@ -127,7 +164,8 @@ class IrSetterCallImpl(
argument: IrExpression,
origin: IrStatementOrigin? = null,
superQualifierSymbol: IrClassSymbol? = null
) : this(startOffset, endOffset, symbol, descriptor, typeArguments, origin, superQualifierSymbol) {
) : this(startOffset, endOffset, symbol, descriptor, typeArguments.typeArgumentsCount, origin, superQualifierSymbol) {
copyTypeArgumentsFrom(typeArguments)
this.dispatchReceiver = dispatchReceiver
this.extensionReceiver = extensionReceiver
putValueArgument(SETTER_ARGUMENT_INDEX, argument)
@@ -152,18 +190,22 @@ class IrSetterCallImpl(
IrSetterCallImpl(
startOffset, endOffset, newCallee,
descriptor, // TODO substitute newCallee.descriptor?
typeArguments, newOrigin, newSuperQualifier
)
typeArgumentsCount, newOrigin, newSuperQualifier
).also { newCall ->
newCall.copyTypeArgumentsFrom(this)
}
override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: FunctionDescriptor, newSuperQualifier: ClassDescriptor?): IrCall =
IrSetterCallImpl(
startOffset, endOffset,
createFunctionSymbol(newCallee),
newCallee,
typeArguments,
typeArgumentsCount,
newOrigin,
createClassSymbolOrNull(newSuperQualifier)
)
).also { newCall ->
newCall.copyTypeArgumentsFrom(this)
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
super.transformChildren(transformer, data)
@@ -20,6 +20,8 @@ import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrPropertyReference
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
import org.jetbrains.kotlin.ir.expressions.typeArgumentsCount
import org.jetbrains.kotlin.ir.symbols.IrFieldSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -30,13 +32,28 @@ class IrPropertyReferenceImpl(
endOffset: Int,
type: KotlinType,
override val descriptor: PropertyDescriptor,
typeArgumentsCount: Int,
override val field: IrFieldSymbol?,
override val getter: IrFunctionSymbol?,
override val setter: IrFunctionSymbol?,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
origin: IrStatementOrigin? = null
) : IrPropertyReference,
IrNoArgumentsCallableReferenceBase(startOffset, endOffset, type, typeArguments, origin) {
) : IrNoArgumentsCallableReferenceBase(startOffset, endOffset, type, typeArgumentsCount, origin),
IrPropertyReference {
constructor(
startOffset: Int,
endOffset: Int,
type: KotlinType,
descriptor: PropertyDescriptor,
field: IrFieldSymbol?,
getter: IrFunctionSymbol?,
setter: IrFunctionSymbol?,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
origin: IrStatementOrigin? = null
) : this(startOffset, endOffset, type, descriptor, typeArguments.typeArgumentsCount, field, getter, setter, origin) {
copyTypeArgumentsFrom(typeArguments)
}
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
visitor.visitPropertyReference(this, data)
}
@@ -34,6 +34,7 @@ inline fun <reified T : IrElement> T.deepCopyOld(): T =
@Deprecated("Creates unbound symbols")
open class DeepCopyIrTree : IrElementTransformerVoid() {
protected open fun mapDeclarationOrigin(declarationOrigin: IrDeclarationOrigin) = declarationOrigin
protected open fun mapStatementOrigin(statementOrigin: IrStatementOrigin?) = statementOrigin
protected open fun mapFileEntry(fileEntry: SourceManager.FileEntry) = fileEntry
@@ -154,8 +155,9 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
}
@Deprecated("Replace with remapTypeArguments")
protected fun IrMemberAccessExpression.transformTypeArguments(newCallee: CallableDescriptor) =
remapTypeArguments(this, newCallee)
protected fun IrMemberAccessExpression.transformTypeArguments(newCallee: CallableDescriptor) {
// Do nothing: assume that type parameters of the newCallee directly correspond to the original type parameters
}
private fun FunctionDescriptor.getTypeParametersToTransform() =
when {
@@ -389,7 +391,9 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
)
override fun visitCall(expression: IrCall): IrCall =
shallowCopyCall(expression).transformValueArguments(expression)
shallowCopyCall(expression).apply {
transformValueArguments(expression)
}
protected fun shallowCopyCall(expression: IrCall) =
when (expression) {
@@ -405,30 +409,33 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.startOffset, expression.endOffset,
expression.type,
newCallee,
remapTypeArguments(expression, newCallee),
expression.typeArgumentsCount,
mapStatementOrigin(expression.origin),
mapSuperQualifier(expression.superQualifier)
)
).apply {
copyTypeArgumentsFrom(expression)
}
}
}
protected fun <T : IrMemberAccessExpression> T.transformValueArguments(original: IrMemberAccessExpression): T =
apply {
dispatchReceiver = original.dispatchReceiver?.transform()
extensionReceiver = original.extensionReceiver?.transform()
mapValueParameters { valueParameter ->
original.getValueArgument(valueParameter)?.transform()
}
Unit
protected fun <T : IrMemberAccessExpression> T.transformValueArguments(original: IrMemberAccessExpression) {
dispatchReceiver = original.dispatchReceiver?.transform()
extensionReceiver = original.extensionReceiver?.transform()
mapValueParameters { valueParameter ->
original.getValueArgument(valueParameter)?.transform()
}
}
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrDelegatingConstructorCall {
val newCallee = mapDelegatedConstructorCallee(expression.descriptor)
return IrDelegatingConstructorCallImpl(
expression.startOffset, expression.endOffset,
newCallee,
remapTypeArguments(expression, newCallee)
).transformValueArguments(expression)
expression.typeArgumentsCount
).apply {
copyTypeArgumentsFrom(expression)
transformValueArguments(expression)
}
}
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrEnumConstructorCall {
@@ -437,8 +444,11 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
return IrEnumConstructorCallImpl(
expression.startOffset, expression.endOffset,
newConstructor,
remapTypeArguments(expression, newConstructor)
).transformValueArguments(expression)
expression.typeArgumentsCount
).apply {
copyTypeArgumentsFrom(expression)
transformValueArguments(expression)
}
}
override fun visitGetClass(expression: IrGetClass): IrGetClass =
@@ -454,9 +464,12 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.startOffset, expression.endOffset,
expression.type,
newCallee.original,
remapTypeArguments(expression, newCallee),
expression.typeArgumentsCount,
mapStatementOrigin(expression.origin)
).transformValueArguments(expression)
).apply {
copyTypeArgumentsFrom(expression)
transformValueArguments(expression)
}
}
override fun visitPropertyReference(expression: IrPropertyReference): IrExpression {
@@ -466,10 +479,13 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
val newSetterSymbol = newProperty.setter?.let { IrSimpleFunctionSymbolImpl(it.original) }
return IrPropertyReferenceImpl(
expression.startOffset, expression.endOffset, expression.type,
newProperty, newFieldSymbol, newGetterSymbol, newSetterSymbol,
remapTypeArguments(expression, newProperty),
newProperty,
expression.typeArgumentsCount, newFieldSymbol, newGetterSymbol, newSetterSymbol,
mapStatementOrigin(expression.origin)
).transformValueArguments(expression)
).apply {
copyTypeArgumentsFrom(expression)
transformValueArguments(expression)
}
}
override fun visitLocalDelegatedPropertyReference(expression: IrLocalDelegatedPropertyReference): IrExpression {
@@ -633,5 +649,4 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.arguments.mapTo(arguments) { it.transform() }
}
}
@@ -315,7 +315,10 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
)
override fun visitCall(expression: IrCall): IrCall =
shallowCopyCall(expression).transformValueArguments(expression)
shallowCopyCall(expression).apply {
copyTypeArgumentsFrom(expression)
transformValueArguments(expression)
}
private fun shallowCopyCall(expression: IrCall) =
when (expression) {
@@ -332,10 +335,12 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
expression.type,
newCallee,
expression.descriptor, // TODO substitute referenced descriptor
remapTypeArguments(expression, newCallee.descriptor),
expression.typeArgumentsCount,
mapStatementOrigin(expression.origin),
symbolRemapper.getReferencedClassOrNull(expression.superQualifierSymbol)
)
).apply {
copyTypeArgumentsFrom(expression)
}
}
}
@@ -345,13 +350,12 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
extensionReceiver = original.extensionReceiver?.transform()
}
private fun <T : IrMemberAccessExpression> T.transformValueArguments(original: T): T =
apply {
transformReceiverArguments(original)
mapValueParameters { valueParameter ->
original.getValueArgument(valueParameter)?.transform()
}
private fun <T : IrMemberAccessExpression> T.transformValueArguments(original: T) {
transformReceiverArguments(original)
mapValueParameters { valueParameter ->
original.getValueArgument(valueParameter)?.transform()
}
}
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrDelegatingConstructorCall {
val newConstructor = symbolRemapper.getReferencedConstructor(expression.symbol)
@@ -359,8 +363,11 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
expression.startOffset, expression.endOffset,
newConstructor,
expression.descriptor,
remapTypeArguments(expression, newConstructor.descriptor)
).transformValueArguments(expression)
expression.typeArgumentsCount
).apply {
copyTypeArgumentsFrom(expression)
transformValueArguments(expression)
}
}
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrEnumConstructorCall {
@@ -368,8 +375,11 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
return IrEnumConstructorCallImpl(
expression.startOffset, expression.endOffset,
newConstructor,
remapTypeArguments(expression, newConstructor.descriptor)
).transformValueArguments(expression)
expression.typeArgumentsCount
).apply {
copyTypeArgumentsFrom(expression)
transformValueArguments(expression)
}
}
override fun visitGetClass(expression: IrGetClass): IrGetClass =
@@ -385,21 +395,27 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
expression.type,
symbolRemapper.getReferencedFunction(expression.symbol),
expression.descriptor, // TODO substitute referenced descriptor
expression.getTypeArgumentsMap(),
expression.typeArgumentsCount,
mapStatementOrigin(expression.origin)
).transformValueArguments(expression)
).apply {
copyTypeArgumentsFrom(expression)
transformValueArguments(expression)
}
override fun visitPropertyReference(expression: IrPropertyReference): IrPropertyReference =
IrPropertyReferenceImpl(
expression.startOffset, expression.endOffset,
expression.type,
expression.descriptor,
expression.typeArgumentsCount,
expression.field?.let { symbolRemapper.getReferencedField(it) },
expression.getter?.let { symbolRemapper.getReferencedFunction(it) },
expression.setter?.let { symbolRemapper.getReferencedFunction(it) },
expression.getTypeArgumentsMap(),
mapStatementOrigin(expression.origin)
).transformReceiverArguments(expression)
).apply {
copyTypeArgumentsFrom(expression)
transformReceiverArguments(expression)
}
override fun visitLocalDelegatedPropertyReference(expression: IrLocalDelegatedPropertyReference): IrLocalDelegatedPropertyReference =
IrLocalDelegatedPropertyReferenceImpl(
@@ -1,49 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrMemberAccessExpressionBase
import org.jetbrains.kotlin.types.KotlinType
fun remapTypeArguments(
expression: IrMemberAccessExpression,
newDescriptor: CallableDescriptor
): Map<TypeParameterDescriptor, KotlinType>? {
val oldDescriptor = expression.descriptor
val oldTypeArguments = expression.getTypeArgumentsMap()
val oldTypeParameters = oldDescriptor.original.typeParameters
val newTypeParameters = newDescriptor.original.typeParameters
assert(oldTypeParameters.size == newTypeParameters.size) {
"Mismatching type parameters: oldDescriptor: $oldDescriptor; newDescriptor: $newDescriptor"
}
return when {
oldDescriptor.original == newDescriptor.original -> oldTypeArguments
oldTypeArguments == null || oldTypeArguments.isEmpty() -> null
else -> newTypeParameters.associate { newTypeParameter ->
val oldTypeParameter = oldTypeParameters[newTypeParameter.index]
val newTypeArgument = expression.getTypeArgument(oldTypeParameter)
?: throw AssertionError("No type argument for $newTypeParameter <= $oldTypeParameter")
newTypeParameter to newTypeArgument
}
}
}
fun IrMemberAccessExpression.getTypeArgumentsMap(): Map<TypeParameterDescriptor, KotlinType>? {
if (this is IrMemberAccessExpressionBase) return typeArguments
val typeParameters = descriptor.original.typeParameters
return if (typeParameters.isEmpty())
null
else
typeParameters.associateBy({ it }, { getTypeArgument(it)!! })
}