Fix type arguments mapping

This commit is contained in:
Dmitry Petrov
2018-03-19 14:08:04 +03:00
parent eb5904ea8e
commit 135d3ab57a
33 changed files with 365 additions and 165 deletions
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.ir.builders
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrVariable
@@ -146,8 +147,12 @@ fun IrBuilderWithScope.irNotEquals(arg1: IrExpression, arg2: IrExpression) =
fun IrBuilderWithScope.irGet(receiver: IrExpression, getterSymbol: IrFunctionSymbol): IrCall =
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)
fun IrBuilderWithScope.irCall(
callee: IrFunctionSymbol,
type: KotlinType,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null
): IrCall =
IrCallImpl(startOffset, endOffset, type, callee, callee.descriptor, typeArguments)
fun IrBuilderWithScope.irCall(callee: IrFunctionSymbol): IrCall =
irCall(callee, callee.descriptor.returnType!!)
@@ -17,29 +17,34 @@
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.symbols.IrConstructorSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.KotlinType
class IrEnumConstructorCallImpl(
startOffset: Int,
endOffset: Int,
override val symbol: IrConstructorSymbol
override val symbol: IrConstructorSymbol,
typeArguments: Map<TypeParameterDescriptor, KotlinType>?
) : IrEnumConstructorCall,
IrCallWithIndexedArgumentsBase(
startOffset, endOffset,
symbol.descriptor.builtIns.unitType,
symbol.descriptor.valueParameters.size,
null
typeArguments
) {
@Deprecated("Creates unbound symbols")
constructor(
startOffset: Int,
endOffset: Int,
descriptor: ClassConstructorDescriptor
) : this(startOffset, endOffset, IrConstructorSymbolImpl(descriptor))
descriptor: ClassConstructorDescriptor,
typeArguments: Map<TypeParameterDescriptor, KotlinType>? = null
) : this(startOffset, endOffset, IrConstructorSymbolImpl(descriptor), typeArguments)
override val descriptor: ClassConstructorDescriptor get() = symbol.descriptor
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.impl.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
inline fun <reified T : IrElement> T.deepCopyOld(): T =
@@ -154,6 +153,10 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
}
}
@Deprecated("Replace with remapTypeArguments")
protected fun IrMemberAccessExpression.transformTypeArguments(newCallee: CallableDescriptor) =
remapTypeArguments(this, newCallee)
private fun FunctionDescriptor.getTypeParametersToTransform() =
when {
this is PropertyAccessorDescriptor -> correspondingProperty.typeParameters
@@ -402,7 +405,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.startOffset, expression.endOffset,
expression.type,
newCallee,
expression.transformTypeArguments(newCallee),
remapTypeArguments(expression, newCallee),
mapStatementOrigin(expression.origin),
mapSuperQualifier(expression.superQualifier)
)
@@ -419,33 +422,24 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
Unit
}
protected fun IrMemberAccessExpression.transformTypeArguments(newCallee: CallableDescriptor): Map<TypeParameterDescriptor, KotlinType>? {
if (this is IrMemberAccessExpressionBase) return typeArguments
val typeParameters = descriptor.original.typeParameters
return if (typeParameters.isEmpty())
null
else
typeParameters.associateBy(
{ newCallee.typeParameters[it.index] },
{ getTypeArgument(it)!! }
)
}
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrDelegatingConstructorCall {
val newCallee = mapDelegatedConstructorCallee(expression.descriptor)
return IrDelegatingConstructorCallImpl(
expression.startOffset, expression.endOffset,
newCallee,
expression.transformTypeArguments(newCallee)
remapTypeArguments(expression, newCallee)
).transformValueArguments(expression)
}
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrEnumConstructorCall =
IrEnumConstructorCallImpl(
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrEnumConstructorCall {
val oldConstructor = expression.descriptor
val newConstructor = mapEnumConstructorCallee(oldConstructor)
return IrEnumConstructorCallImpl(
expression.startOffset, expression.endOffset,
mapEnumConstructorCallee(expression.descriptor)
newConstructor,
remapTypeArguments(expression, newConstructor)
).transformValueArguments(expression)
}
override fun visitGetClass(expression: IrGetClass): IrGetClass =
IrGetClassImpl(
@@ -460,7 +454,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
expression.startOffset, expression.endOffset,
expression.type,
newCallee.original,
expression.transformTypeArguments(newCallee),
remapTypeArguments(expression, newCallee),
mapStatementOrigin(expression.origin)
).transformValueArguments(expression)
}
@@ -473,7 +467,7 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
return IrPropertyReferenceImpl(
expression.startOffset, expression.endOffset, expression.type,
newProperty, newFieldSymbol, newGetterSymbol, newSetterSymbol,
expression.transformTypeArguments(newProperty),
remapTypeArguments(expression, newProperty),
mapStatementOrigin(expression.origin)
).transformValueArguments(expression)
}
@@ -638,4 +632,6 @@ open class DeepCopyIrTree : IrElementTransformerVoid() {
explicitReceiver = expression.explicitReceiver?.transform()
expression.arguments.mapTo(arguments) { it.transform() }
}
}
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.*
@@ -27,7 +26,6 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
import org.jetbrains.kotlin.types.KotlinType
import java.util.*
inline fun <reified T : IrElement> T.deepCopyWithSymbols(): T {
@@ -327,16 +325,18 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
symbolRemapper.getReferencedFunction(expression.symbol),
symbolRemapper.getReferencedClassOrNull(expression.superQualifierSymbol)
)
else ->
else -> {
val newCallee = symbolRemapper.getReferencedFunction(expression.symbol)
IrCallImpl(
expression.startOffset, expression.endOffset,
expression.type,
symbolRemapper.getReferencedFunction(expression.symbol),
newCallee,
expression.descriptor, // TODO substitute referenced descriptor
expression.getTypeArgumentsMap(),
remapTypeArguments(expression, newCallee.descriptor),
mapStatementOrigin(expression.origin),
symbolRemapper.getReferencedClassOrNull(expression.superQualifierSymbol)
)
}
}
private fun <T : IrMemberAccessExpression> T.transformReceiverArguments(original: T): T =
@@ -353,29 +353,24 @@ open class DeepCopyIrTreeWithSymbols(private val symbolRemapper: SymbolRemapper)
}
}
private 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)!! })
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrDelegatingConstructorCall {
val newConstructor = symbolRemapper.getReferencedConstructor(expression.symbol)
return IrDelegatingConstructorCallImpl(
expression.startOffset, expression.endOffset,
newConstructor,
expression.descriptor,
remapTypeArguments(expression, newConstructor.descriptor)
).transformValueArguments(expression)
}
override fun visitDelegatingConstructorCall(expression: IrDelegatingConstructorCall): IrDelegatingConstructorCall =
IrDelegatingConstructorCallImpl(
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrEnumConstructorCall {
val newConstructor = symbolRemapper.getReferencedConstructor(expression.symbol)
return IrEnumConstructorCallImpl(
expression.startOffset, expression.endOffset,
symbolRemapper.getReferencedConstructor(expression.symbol),
expression.descriptor,
expression.getTypeArgumentsMap()
).transformValueArguments(expression)
override fun visitEnumConstructorCall(expression: IrEnumConstructorCall): IrEnumConstructorCall =
IrEnumConstructorCallImpl(
expression.startOffset, expression.endOffset,
symbolRemapper.getReferencedConstructor(expression.symbol)
newConstructor,
remapTypeArguments(expression, newConstructor.descriptor)
).transformValueArguments(expression)
}
override fun visitGetClass(expression: IrGetClass): IrGetClass =
IrGetClassImpl(
@@ -177,7 +177,7 @@ class DumpIrTreeVisitor(out: Appendable) : IrElementVisitor<Unit, String> {
val typeArgument = expression.getTypeArgument(typeParameter)
val renderedType = typeArgument?.let {
DescriptorRenderer.ONLY_NAMES_WITH_SHORT_TYPES.renderType(typeArgument)
} ?: "null"
} ?: "--- No type argument for $typeParameter declared in ${typeParameter.containingDeclaration}"
printer.println("$renderedParameter: $renderedType")
}
}
@@ -0,0 +1,49 @@
/*
* 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)!! })
}