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