Fix type arguments mapping
This commit is contained in:
+90
-19
@@ -269,6 +269,16 @@ fun StatementGenerator.pregenerateCall(resolvedCall: ResolvedCall<*>): CallBuild
|
||||
return call
|
||||
}
|
||||
|
||||
fun getTypeArguments(resolvedCall: ResolvedCall<*>?): Map<TypeParameterDescriptor, KotlinType>? {
|
||||
if (resolvedCall == null) return null
|
||||
|
||||
val descriptor = resolvedCall.resultingDescriptor
|
||||
if (descriptor.typeParameters.isEmpty()) return null
|
||||
|
||||
return resolvedCall.typeArguments
|
||||
}
|
||||
|
||||
|
||||
fun StatementGenerator.pregenerateExtensionInvokeCall(resolvedCall: ResolvedCall<*>): CallBuilder {
|
||||
val extensionInvoke = resolvedCall.resultingDescriptor
|
||||
val functionNClass = extensionInvoke.containingDeclaration as? ClassDescriptor
|
||||
@@ -278,6 +288,10 @@ fun StatementGenerator.pregenerateExtensionInvokeCall(resolvedCall: ResolvedCall
|
||||
val unsubstitutedPlainInvoke = unsubstitutedPlainInvokes.singleOrNull()
|
||||
?: throw AssertionError("There should be a single 'invoke' in FunctionN class: $unsubstitutedPlainInvokes")
|
||||
|
||||
assert(unsubstitutedPlainInvoke.typeParameters.isEmpty()) {
|
||||
"'operator fun invoke' should have no type parameters: $unsubstitutedPlainInvoke"
|
||||
}
|
||||
|
||||
val expectedValueParametersCount = extensionInvoke.valueParameters.size + 1
|
||||
assert(unsubstitutedPlainInvoke.valueParameters.size == expectedValueParametersCount) {
|
||||
"Plain 'invoke' should have $expectedValueParametersCount value parameters, got ${unsubstitutedPlainInvoke.valueParameters}"
|
||||
@@ -289,7 +303,12 @@ fun StatementGenerator.pregenerateExtensionInvokeCall(resolvedCall: ResolvedCall
|
||||
|
||||
val ktCallElement = resolvedCall.call.callElement
|
||||
|
||||
val call = CallBuilder(resolvedCall, plainInvoke, isExtensionInvokeCall = true)
|
||||
val call = CallBuilder(
|
||||
resolvedCall,
|
||||
plainInvoke,
|
||||
typeArguments = null, // FunctionN#invoke has no type parameters of its own
|
||||
isExtensionInvokeCall = true
|
||||
)
|
||||
|
||||
val functionReceiverValue = run {
|
||||
val dispatchReceiver =
|
||||
@@ -329,15 +348,6 @@ private fun ResolvedCall<*>.isExtensionInvokeCall(): Boolean {
|
||||
return extensionReceiver != null
|
||||
}
|
||||
|
||||
fun getTypeArguments(resolvedCall: ResolvedCall<*>?): Map<TypeParameterDescriptor, KotlinType>? {
|
||||
if (resolvedCall == null) return null
|
||||
|
||||
val descriptor = resolvedCall.resultingDescriptor
|
||||
if (descriptor.typeParameters.isEmpty()) return null
|
||||
|
||||
return resolvedCall.typeArguments
|
||||
}
|
||||
|
||||
private fun StatementGenerator.pregenerateValueArguments(call: CallBuilder, resolvedCall: ResolvedCall<*>) {
|
||||
resolvedCall.valueArgumentsByIndex!!.forEachIndexed { index, valueArgument ->
|
||||
val valueParameter = call.descriptor.valueParameters[index]
|
||||
@@ -346,7 +356,7 @@ private fun StatementGenerator.pregenerateValueArguments(call: CallBuilder, reso
|
||||
}
|
||||
|
||||
fun StatementGenerator.pregenerateCallReceivers(resolvedCall: ResolvedCall<*>): CallBuilder {
|
||||
val call = CallBuilder(resolvedCall, unwrapCallableDescriptor(resolvedCall.resultingDescriptor))
|
||||
val call = unwrapCallableDescriptorAndTypeArguments(resolvedCall)
|
||||
|
||||
call.callReceiver = generateCallReceiver(
|
||||
resolvedCall.call.callElement,
|
||||
@@ -361,12 +371,73 @@ fun StatementGenerator.pregenerateCallReceivers(resolvedCall: ResolvedCall<*>):
|
||||
return call
|
||||
}
|
||||
|
||||
fun unwrapCallableDescriptor(resultingDescriptor: CallableDescriptor): CallableDescriptor =
|
||||
when (resultingDescriptor) {
|
||||
is ImportedFromObjectCallableDescriptor<*> ->
|
||||
resultingDescriptor.callableFromObject
|
||||
is TypeAliasConstructorDescriptor ->
|
||||
resultingDescriptor.underlyingConstructorDescriptor
|
||||
else ->
|
||||
resultingDescriptor
|
||||
fun unwrapCallableDescriptorAndTypeArguments(resolvedCall: ResolvedCall<*>): CallBuilder {
|
||||
val originalDescriptor = resolvedCall.resultingDescriptor
|
||||
|
||||
val unwrappedDescriptor = when (originalDescriptor) {
|
||||
is ImportedFromObjectCallableDescriptor<*> -> originalDescriptor.callableFromObject
|
||||
is TypeAliasConstructorDescriptor -> originalDescriptor.underlyingConstructorDescriptor
|
||||
else -> originalDescriptor
|
||||
}
|
||||
|
||||
val originalTypeArguments = resolvedCall.typeArguments
|
||||
val unsubstitutedUnwrappedDescriptor = unwrappedDescriptor.original
|
||||
val unsubstitutedUnwrappedTypeParameters = unsubstitutedUnwrappedDescriptor.typeParameters
|
||||
|
||||
val unwrappedTypeArguments = when (originalDescriptor) {
|
||||
is ImportedFromObjectCallableDescriptor<*> -> {
|
||||
assert(originalDescriptor.typeParameters.size == unsubstitutedUnwrappedTypeParameters.size) {
|
||||
"Mismatching original / unwrapped type parameters: " +
|
||||
"originalDescriptor: $originalDescriptor; " +
|
||||
"unsubstitutedUnwrappedDescriptor: $unsubstitutedUnwrappedDescriptor"
|
||||
}
|
||||
|
||||
if (unsubstitutedUnwrappedTypeParameters.isEmpty())
|
||||
null
|
||||
else
|
||||
unsubstitutedUnwrappedTypeParameters.associate {
|
||||
val originalTypeParameter = originalDescriptor.typeParameters[it.index]
|
||||
val originalTypeArgument = originalTypeArguments[originalTypeParameter]
|
||||
?: throw AssertionError("No type argument for $originalTypeParameter")
|
||||
it to originalTypeArgument
|
||||
}
|
||||
}
|
||||
|
||||
is TypeAliasConstructorDescriptor -> {
|
||||
val substitutedType = originalDescriptor.returnType
|
||||
if (substitutedType.arguments.isEmpty())
|
||||
null
|
||||
else
|
||||
unsubstitutedUnwrappedTypeParameters.associate {
|
||||
it to substitutedType.arguments[it.index].type
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
if (originalTypeArguments.keys.all { it.containingDeclaration == unsubstitutedUnwrappedDescriptor })
|
||||
originalTypeArguments.takeIf { it.isNotEmpty() }
|
||||
else {
|
||||
assert(unsubstitutedUnwrappedTypeParameters.size == originalTypeArguments.size) {
|
||||
"Mismatching type parameters and type arguments: " +
|
||||
"unsubstitutedUnwrappedDescriptor: $unsubstitutedUnwrappedDescriptor; " +
|
||||
"originalDescriptor: $originalDescriptor; " +
|
||||
"originalTypeArguments: $originalTypeArguments"
|
||||
}
|
||||
|
||||
if (unsubstitutedUnwrappedTypeParameters.isEmpty())
|
||||
null
|
||||
else {
|
||||
originalTypeArguments.keys.associate { originalTypeParameter ->
|
||||
val unwrappedTypeParameter = unsubstitutedUnwrappedTypeParameters[originalTypeParameter.index]
|
||||
val originalTypeArgument = originalTypeArguments[originalTypeParameter]
|
||||
?: throw AssertionError("No type argument for $unwrappedTypeParameter <= $originalTypeParameter")
|
||||
unwrappedTypeParameter to originalTypeArgument
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CallBuilder(resolvedCall, unwrappedDescriptor, unwrappedTypeArguments)
|
||||
}
|
||||
|
||||
+1
@@ -176,6 +176,7 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
|
||||
|
||||
val superQualifier = getSuperQualifier(resolvedCall)
|
||||
|
||||
// TODO property imported from an object
|
||||
createPropertyLValue(ktLeft, descriptor, propertyReceiver, getTypeArguments(resolvedCall), origin, superQualifier)
|
||||
}
|
||||
|
||||
|
||||
@@ -142,8 +142,9 @@ class BodyGenerator(
|
||||
val delegatingConstructorResolvedCall = getResolvedCall(ktDelegatingConstructorCall)
|
||||
|
||||
if (delegatingConstructorResolvedCall == null) {
|
||||
if (constructorDescriptor.containingDeclaration.kind == ClassKind.ENUM_CLASS) {
|
||||
generateEnumSuperConstructorCall(irBlockBody, ktConstructor)
|
||||
val classDescriptor = constructorDescriptor.containingDeclaration
|
||||
if (classDescriptor.kind == ClassKind.ENUM_CLASS) {
|
||||
generateEnumSuperConstructorCall(irBlockBody, ktConstructor, classDescriptor)
|
||||
} else {
|
||||
generateAnySuperConstructorCall(irBlockBody, ktConstructor)
|
||||
}
|
||||
@@ -207,12 +208,14 @@ class BodyGenerator(
|
||||
val classDescriptor = getOrFail(BindingContext.CLASS, ktClassOrObject)
|
||||
|
||||
when (classDescriptor.kind) {
|
||||
ClassKind.ENUM_CLASS -> {
|
||||
generateEnumSuperConstructorCall(irBlockBody, ktClassOrObject)
|
||||
}
|
||||
ClassKind.ENUM_CLASS -> generateEnumSuperConstructorCall(irBlockBody, ktClassOrObject, classDescriptor)
|
||||
|
||||
ClassKind.ENUM_ENTRY -> {
|
||||
irBlockBody.statements.add(generateEnumEntrySuperConstructorCall(ktClassOrObject as KtEnumEntry, classDescriptor))
|
||||
irBlockBody.statements.add(
|
||||
generateEnumEntrySuperConstructorCall(ktClassOrObject as KtEnumEntry, classDescriptor)
|
||||
)
|
||||
}
|
||||
|
||||
else -> {
|
||||
val statementGenerator = createStatementGenerator()
|
||||
|
||||
@@ -252,12 +255,17 @@ class BodyGenerator(
|
||||
)
|
||||
}
|
||||
|
||||
private fun generateEnumSuperConstructorCall(irBlockBody: IrBlockBodyImpl, ktElement: KtElement) {
|
||||
private fun generateEnumSuperConstructorCall(
|
||||
irBlockBody: IrBlockBodyImpl,
|
||||
ktElement: KtElement,
|
||||
classDescriptor: ClassDescriptor
|
||||
) {
|
||||
val enumConstructor = context.builtIns.enum.constructors.single()
|
||||
irBlockBody.statements.add(
|
||||
IrEnumConstructorCallImpl(
|
||||
ktElement.startOffset, ktElement.endOffset,
|
||||
context.symbolTable.referenceConstructor(enumConstructor)
|
||||
context.symbolTable.referenceConstructor(enumConstructor),
|
||||
mapOf(enumConstructor.typeParameters.single() to classDescriptor.defaultType)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -271,7 +279,8 @@ class BodyGenerator(
|
||||
val enumEntryConstructor = enumEntryDescriptor.unsubstitutedPrimaryConstructor!!
|
||||
return IrEnumConstructorCallImpl(
|
||||
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
||||
context.symbolTable.referenceConstructor(enumEntryConstructor)
|
||||
context.symbolTable.referenceConstructor(enumEntryConstructor),
|
||||
null // enums can't be generic (so far)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -291,19 +300,8 @@ class BodyGenerator(
|
||||
}
|
||||
|
||||
val enumDefaultConstructorCall = getResolvedCall(ktEnumEntry)
|
||||
if (enumDefaultConstructorCall != null) {
|
||||
return statementGenerator.generateEnumConstructorCall(enumDefaultConstructorCall, ktEnumEntry)
|
||||
}
|
||||
|
||||
// Default enum entry constructor
|
||||
val enumClassConstructor =
|
||||
enumClassDescriptor.constructors.singleOrNull { constructor ->
|
||||
constructor.valueParameters.all(ValueParameterDescriptor::declaresDefaultValue)
|
||||
} ?: throw AssertionError("Enum class $enumClassDescriptor should have a default constructor")
|
||||
return IrEnumConstructorCallImpl(
|
||||
ktEnumEntry.startOffset, ktEnumEntry.endOffset,
|
||||
context.symbolTable.referenceConstructor(enumClassConstructor)
|
||||
)
|
||||
?: throw AssertionError("No default constructor call for enum entry $enumClassDescriptor")
|
||||
return statementGenerator.generateEnumConstructorCall(enumDefaultConstructorCall, ktEnumEntry)
|
||||
}
|
||||
|
||||
private fun StatementGenerator.generateEnumConstructorCall(
|
||||
|
||||
@@ -105,7 +105,7 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
?: throw AssertionError("Class constructor expected: ${call.descriptor}")
|
||||
val constructorSymbol = context.symbolTable.referenceConstructor(descriptor.original)
|
||||
val irCall =
|
||||
IrDelegatingConstructorCallImpl(startOffset, endOffset, constructorSymbol, descriptor, getTypeArguments(call.original))
|
||||
IrDelegatingConstructorCallImpl(startOffset, endOffset, constructorSymbol, descriptor, call.typeArguments)
|
||||
irCall.dispatchReceiver = dispatchReceiver?.load()
|
||||
irCall.extensionReceiver = extensionReceiver?.load()
|
||||
addParametersToCall(startOffset, endOffset, call, irCall, descriptor.builtIns.unitType)
|
||||
@@ -121,7 +121,11 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
if (dispatchReceiver != null) throw AssertionError("Dispatch receiver should be null: $dispatchReceiver")
|
||||
if (extensionReceiver != null) throw AssertionError("Extension receiver should be null: $extensionReceiver")
|
||||
val constructorSymbol = context.symbolTable.referenceConstructor(constructorDescriptor.original)
|
||||
val irCall = IrEnumConstructorCallImpl(startOffset, endOffset, constructorSymbol)
|
||||
val irCall = IrEnumConstructorCallImpl(
|
||||
startOffset, endOffset,
|
||||
constructorSymbol,
|
||||
call.typeArguments
|
||||
)
|
||||
addParametersToCall(startOffset, endOffset, call, irCall, constructorDescriptor.returnType)
|
||||
}
|
||||
}
|
||||
@@ -142,7 +146,7 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
startOffset, endOffset,
|
||||
getterSymbol,
|
||||
getterDescriptor,
|
||||
getTypeArguments(call.original),
|
||||
call.typeArguments,
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
IrStatementOrigin.GET_PROPERTY,
|
||||
@@ -177,7 +181,7 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
returnType,
|
||||
functionSymbol,
|
||||
functionDescriptor,
|
||||
getTypeArguments(call.original),
|
||||
call.typeArguments,
|
||||
origin,
|
||||
superQualifierSymbol
|
||||
)
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.newHashMapWithExpectedSize
|
||||
import java.lang.AssertionError
|
||||
|
||||
class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGeneratorExtension(declarationGenerator) {
|
||||
@@ -215,7 +216,7 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
startOffset, endOffset, returnType,
|
||||
context.symbolTable.referenceFunction(overridden.original),
|
||||
substitutedOverridden,
|
||||
null
|
||||
getTypeArgumentsForOverriddenDescriptorDelegatingCall(delegated, overridden)
|
||||
)
|
||||
irCall.dispatchReceiver =
|
||||
IrGetFieldImpl(
|
||||
@@ -245,13 +246,32 @@ class ClassGenerator(declarationGenerator: DeclarationGenerator) : DeclarationGe
|
||||
overridden: FunctionDescriptor
|
||||
): FunctionDescriptor {
|
||||
// TODO PropertyAccessorDescriptor doesn't support 'substitute' right now :(
|
||||
if (overridden is PropertyAccessorDescriptor) return overridden
|
||||
|
||||
val typeArguments = HashMap<TypeParameterDescriptor, KotlinType>()
|
||||
for ((i, overriddenTypeParameter) in overridden.typeParameters.withIndex()) {
|
||||
typeArguments[overriddenTypeParameter] = delegated.typeParameters[i].defaultType
|
||||
return if (overridden is PropertyAccessorDescriptor)
|
||||
overridden
|
||||
else {
|
||||
val typeArguments = zipTypeParametersToDefaultTypes(overridden, delegated)
|
||||
overridden.substitute(typeArguments)
|
||||
}
|
||||
return overridden.substitute(typeArguments)
|
||||
}
|
||||
|
||||
private fun getTypeArgumentsForOverriddenDescriptorDelegatingCall(
|
||||
delegated: FunctionDescriptor,
|
||||
overridden: FunctionDescriptor
|
||||
): Map<TypeParameterDescriptor, KotlinType>? =
|
||||
if (overridden.original.typeParameters.isEmpty())
|
||||
null
|
||||
else
|
||||
zipTypeParametersToDefaultTypes(overridden.original, delegated)
|
||||
|
||||
private fun zipTypeParametersToDefaultTypes(
|
||||
keys: FunctionDescriptor,
|
||||
values: FunctionDescriptor
|
||||
): Map<TypeParameterDescriptor, KotlinType> {
|
||||
val typeArguments = newHashMapWithExpectedSize<TypeParameterDescriptor, KotlinType>(keys.typeParameters.size)
|
||||
for ((i, overriddenTypeParameter) in keys.typeParameters.withIndex()) {
|
||||
typeArguments[overriddenTypeParameter] = values.typeParameters[i].defaultType
|
||||
}
|
||||
return typeArguments
|
||||
}
|
||||
|
||||
private fun generateAdditionalMembersForDataClass(irClass: IrClass, ktClassOrObject: KtClassOrObject) {
|
||||
|
||||
+9
-3
@@ -126,9 +126,15 @@ class DataClassMembersGenerator(declarationGenerator: DeclarationGenerator) : De
|
||||
function.valueParameters.forEach { parameter ->
|
||||
putDefault(parameter, irGet(irThis(), getPropertyGetterSymbol(parameter)))
|
||||
}
|
||||
+irReturn(irCall(constructorSymbol, dataClassConstructor.returnType).mapValueParameters {
|
||||
irGet(irFunction.valueParameters[it.index].symbol)
|
||||
})
|
||||
+irReturn(
|
||||
irCall(
|
||||
constructorSymbol,
|
||||
dataClassConstructor.returnType,
|
||||
dataClassConstructor.typeParameters.associate { it to it.defaultType }
|
||||
).mapValueParameters {
|
||||
irGet(irFunction.valueParameters[it.index].symbol)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,10 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.psi2ir.isValueArgumentReorderingRequired
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
@@ -28,6 +25,7 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
class CallBuilder(
|
||||
val original: ResolvedCall<*>, // TODO get rid of "original", sometimes we want to generate a call without ResolvedCall
|
||||
val descriptor: CallableDescriptor,
|
||||
val typeArguments: Map<TypeParameterDescriptor, KotlinType>?,
|
||||
val isExtensionInvokeCall: Boolean = false
|
||||
) {
|
||||
var superQualifier: ClassDescriptor? = null
|
||||
|
||||
@@ -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!!)
|
||||
|
||||
+9
-4
@@ -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)!! })
|
||||
}
|
||||
+1
-1
@@ -82,7 +82,7 @@ FILE fqName:<root> fileName:/classes.kt
|
||||
CONSTRUCTOR visibility:private <> () returnType:TestEnumClass flags:
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
<E : Enum<E>>: null
|
||||
<E : Enum<E>>: TestEnumClass
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnumClass'
|
||||
FUN FAKE_OVERRIDE name:clone visibility:protected modality:FINAL <> ($this:kotlin.Enum<TestEnumClass>) returnType:Any flags:
|
||||
overridden:
|
||||
|
||||
@@ -493,7 +493,7 @@ FILE fqName:<root> fileName:/dataClassWithArrayMembers.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='copy(Array<T> = ...): Test2<T>'
|
||||
CALL 'constructor Test2(Array<T>)' type=Test2<T> origin=null
|
||||
<T>: null
|
||||
<T>: T
|
||||
genericArray: GET_VAR 'value-parameter genericArray: Array<T> = ...' type=kotlin.Array<T> origin=null
|
||||
FUN GENERATED_DATA_CLASS_MEMBER name:toString visibility:public modality:OPEN <> ($this:Test2<T>) returnType:String flags:
|
||||
overridden:
|
||||
|
||||
@@ -36,7 +36,7 @@ FILE fqName:<root> fileName:/dataClassesGeneric.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='copy(T = ...): Test1<T>'
|
||||
CALL 'constructor Test1(T)' type=Test1<T> origin=null
|
||||
<T>: null
|
||||
<T>: T
|
||||
x: GET_VAR 'value-parameter x: T = ...' type=T origin=null
|
||||
FUN GENERATED_DATA_CLASS_MEMBER name:toString visibility:public modality:OPEN <> ($this:Test1<T>) returnType:String flags:
|
||||
overridden:
|
||||
|
||||
+2
-2
@@ -43,7 +43,7 @@ FILE fqName:<root> fileName:/delegatingConstructorCallToTypeAliasConstructor.kt
|
||||
CONSTRUCTOR visibility:public <> () returnType:C1 flags:
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Cell(String)'
|
||||
<T>: null
|
||||
<T>: String
|
||||
value: CONST String type=kotlin.String value=O
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='C1'
|
||||
PROPERTY FAKE_OVERRIDE name:value type:kotlin.String visibility:public modality:FINAL flags:val
|
||||
@@ -71,7 +71,7 @@ FILE fqName:<root> fileName:/delegatingConstructorCallToTypeAliasConstructor.kt
|
||||
CONSTRUCTOR visibility:public <> () returnType:C2 flags:
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Cell(String)'
|
||||
<T>: null
|
||||
<T>: String
|
||||
value: CONST String type=kotlin.String value=K
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='C2'
|
||||
PROPERTY FAKE_OVERRIDE name:value type:kotlin.String visibility:public modality:FINAL flags:val
|
||||
|
||||
+5
-5
@@ -6,7 +6,7 @@ FILE fqName:<root> fileName:/enum.kt
|
||||
CONSTRUCTOR visibility:private <> () returnType:TestEnum1 flags:
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
<E : Enum<E>>: null
|
||||
<E : Enum<E>>: TestEnum1
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnum1'
|
||||
ENUM_ENTRY name:TEST1
|
||||
init: ENUM_CONSTRUCTOR_CALL 'constructor TestEnum1()'
|
||||
@@ -65,7 +65,7 @@ FILE fqName:<root> fileName:/enum.kt
|
||||
VALUE_PARAMETER name:x index:0 type:kotlin.Int flags:
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
<E : Enum<E>>: null
|
||||
<E : Enum<E>>: TestEnum2
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnum2'
|
||||
PROPERTY name:x type:kotlin.Int visibility:public modality:FINAL flags:val
|
||||
FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:public
|
||||
@@ -138,7 +138,7 @@ FILE fqName:<root> fileName:/enum.kt
|
||||
CONSTRUCTOR visibility:private <> () returnType:TestEnum3 flags:
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
<E : Enum<E>>: null
|
||||
<E : Enum<E>>: TestEnum3
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnum3'
|
||||
ENUM_ENTRY name:TEST
|
||||
init: ENUM_CONSTRUCTOR_CALL 'constructor TEST()'
|
||||
@@ -252,7 +252,7 @@ FILE fqName:<root> fileName:/enum.kt
|
||||
VALUE_PARAMETER name:x index:0 type:kotlin.Int flags:
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
<E : Enum<E>>: null
|
||||
<E : Enum<E>>: TestEnum4
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnum4'
|
||||
PROPERTY name:x type:kotlin.Int visibility:public modality:FINAL flags:val
|
||||
FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:public
|
||||
@@ -461,7 +461,7 @@ FILE fqName:<root> fileName:/enum.kt
|
||||
CONST Int type=kotlin.Int value=0
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
<E : Enum<E>>: null
|
||||
<E : Enum<E>>: TestEnum5
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='TestEnum5'
|
||||
PROPERTY name:x type:kotlin.Int visibility:public modality:FINAL flags:val
|
||||
FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:public
|
||||
|
||||
@@ -7,7 +7,7 @@ FILE fqName:<root> fileName:/enumWithSecondaryCtor.kt
|
||||
VALUE_PARAMETER name:x index:0 type:kotlin.Int flags:
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
<E : Enum<E>>: null
|
||||
<E : Enum<E>>: Test0
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='Test0'
|
||||
PROPERTY name:x type:kotlin.Int visibility:public modality:FINAL flags:val
|
||||
FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:public
|
||||
@@ -78,7 +78,7 @@ FILE fqName:<root> fileName:/enumWithSecondaryCtor.kt
|
||||
VALUE_PARAMETER name:x index:0 type:kotlin.Int flags:
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
<E : Enum<E>>: null
|
||||
<E : Enum<E>>: Test1
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='Test1'
|
||||
PROPERTY name:x type:kotlin.Int visibility:public modality:FINAL flags:val
|
||||
FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:public
|
||||
@@ -152,7 +152,7 @@ FILE fqName:<root> fileName:/enumWithSecondaryCtor.kt
|
||||
VALUE_PARAMETER name:x index:0 type:kotlin.Int flags:
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
<E : Enum<E>>: null
|
||||
<E : Enum<E>>: Test2
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='Test2'
|
||||
PROPERTY name:x type:kotlin.Int visibility:public modality:FINAL flags:val
|
||||
FIELD PROPERTY_BACKING_FIELD name:x type:kotlin.Int visibility:public
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ FILE fqName:<root> fileName:/expectedEnumClass.kt
|
||||
CONSTRUCTOR visibility:private <> () returnType:MyEnum flags:
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
<E : Enum<E>>: null
|
||||
<E : Enum<E>>: MyEnum
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='MyEnum'
|
||||
ENUM_ENTRY name:FOO
|
||||
init: ENUM_CONSTRUCTOR_CALL 'constructor MyEnum()'
|
||||
|
||||
@@ -59,7 +59,7 @@ FILE fqName:<root> fileName:/dataClassMembers.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='copy(T = ..., String = ...): Test<T>'
|
||||
CALL 'constructor Test(T, String = ...)' type=Test<T> origin=null
|
||||
<T>: null
|
||||
<T>: T
|
||||
x: GET_VAR 'value-parameter x: T = ...' type=T origin=null
|
||||
y: GET_VAR 'value-parameter y: String = ...' type=kotlin.String origin=null
|
||||
FUN GENERATED_DATA_CLASS_MEMBER name:toString visibility:public modality:OPEN <> ($this:Test<T>) returnType:String flags:
|
||||
|
||||
@@ -58,7 +58,7 @@ FILE fqName:<root> fileName:/delegatedMembers.kt
|
||||
VALUE_PARAMETER name:x index:1 type:X flags:
|
||||
BLOCK_BODY
|
||||
CALL 'qux(TT, X): Unit' type=kotlin.Unit origin=null
|
||||
<X>: null
|
||||
<X>: X
|
||||
$this: GET_FIELD '`Test$IBase$delegate`: IBase<TT>' type=IBase<TT> origin=null
|
||||
receiver: GET_VAR 'this@Test: Test<TT>' type=Test<TT> origin=null
|
||||
t: GET_VAR 'value-parameter t: TT' type=TT origin=null
|
||||
|
||||
@@ -6,7 +6,7 @@ FILE fqName:<root> fileName:/enumEntryAsReceiver.kt
|
||||
CONSTRUCTOR visibility:private <> () returnType:X flags:
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
<E : Enum<E>>: null
|
||||
<E : Enum<E>>: X
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='X'
|
||||
ENUM_ENTRY name:B
|
||||
init: ENUM_CONSTRUCTOR_CALL 'constructor B()'
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
class GenericClass<T>(val value: T) {
|
||||
fun withNewValue(newValue: T) = GenericClass(newValue)
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
FILE fqName:<root> fileName:/memberTypeArguments.kt
|
||||
CLASS CLASS name:GenericClass modality:FINAL visibility:public flags:
|
||||
$this: VALUE_PARAMETER INSTANCE_RECEIVER name:<this> type:GenericClass<T> flags:
|
||||
superClasses:
|
||||
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
|
||||
TYPE_PARAMETER name:T index:0 variance: upperBounds:[kotlin.Any?]
|
||||
superClassifiers:
|
||||
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
|
||||
CONSTRUCTOR visibility:public <> (value:T) returnType:GenericClass<T> flags:
|
||||
VALUE_PARAMETER name:value index:0 type:T flags:
|
||||
BLOCK_BODY
|
||||
DELEGATING_CONSTRUCTOR_CALL 'constructor Any()'
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='GenericClass'
|
||||
PROPERTY name:value type:T visibility:public modality:FINAL flags:val
|
||||
FIELD PROPERTY_BACKING_FIELD name:value type:T visibility:public
|
||||
EXPRESSION_BODY
|
||||
GET_VAR 'value-parameter value: T' type=T origin=INITIALIZE_PROPERTY_FROM_PARAMETER
|
||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-value> visibility:public modality:FINAL <> ($this:GenericClass<T>) returnType:T flags:
|
||||
$this: VALUE_PARAMETER name:<this> type:GenericClass<T> flags:
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<get-value>(): T'
|
||||
GET_FIELD 'value: T' type=T origin=null
|
||||
receiver: GET_VAR 'this@GenericClass: GenericClass<T>' type=GenericClass<T> origin=null
|
||||
FUN name:withNewValue visibility:public modality:FINAL <> ($this:GenericClass<T>, newValue:T) returnType:GenericClass<T> flags:
|
||||
$this: VALUE_PARAMETER name:<this> type:GenericClass<T> flags:
|
||||
VALUE_PARAMETER name:newValue index:0 type:T flags:
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='withNewValue(T): GenericClass<T>'
|
||||
CALL 'constructor GenericClass(T)' type=GenericClass<T> origin=null
|
||||
<T>: T
|
||||
value: GET_VAR 'value-parameter newValue: T' type=T origin=null
|
||||
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:Boolean flags:
|
||||
overridden:
|
||||
FUN IR_EXTERNAL_DECLARATION_STUB name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:Boolean flags:
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
|
||||
VALUE_PARAMETER name:other index:0 type:kotlin.Any? flags:
|
||||
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:Int flags:
|
||||
overridden:
|
||||
FUN IR_EXTERNAL_DECLARATION_STUB name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:Int flags:
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
|
||||
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:String flags:
|
||||
overridden:
|
||||
FUN IR_EXTERNAL_DECLARATION_STUB name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:String flags:
|
||||
$this: VALUE_PARAMETER name:<this> type:kotlin.Any flags:
|
||||
@@ -27,7 +27,7 @@ FILE fqName:<root> fileName:/objectAsCallable.kt
|
||||
CONSTRUCTOR visibility:private <> () returnType:En flags:
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
<E : Enum<E>>: null
|
||||
<E : Enum<E>>: En
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='En'
|
||||
ENUM_ENTRY name:X
|
||||
init: ENUM_CONSTRUCTOR_CALL 'constructor En()'
|
||||
|
||||
+1
-1
@@ -39,5 +39,5 @@ FILE fqName:<root> fileName:/specializedTypeAliasConstructorCall.kt
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='test(): IntAlias /* = Cell<Int> */'
|
||||
CALL 'constructor Cell(Int)' type=Cell<kotlin.Int> origin=null
|
||||
<T>: null
|
||||
<T>: Int
|
||||
value: CONST Int type=kotlin.Int value=42
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ FILE fqName:<root> fileName:/values.kt
|
||||
CONSTRUCTOR visibility:private <> () returnType:Enum flags:
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
<E : Enum<E>>: null
|
||||
<E : Enum<E>>: Enum
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='Enum'
|
||||
ENUM_ENTRY name:A
|
||||
init: ENUM_CONSTRUCTOR_CALL 'constructor Enum()'
|
||||
|
||||
@@ -40,10 +40,10 @@ FILE fqName:<root> fileName:/typeAliasCtorForGenericClass.kt
|
||||
BLOCK_BODY
|
||||
VAR name:b type:B<kotlin.Int> /* = A<kotlin.Int> */ flags:val
|
||||
CALL 'constructor A(Int)' type=A<kotlin.Int> origin=null
|
||||
<Q>: null
|
||||
<Q>: Int
|
||||
q: CONST Int type=kotlin.Int value=2
|
||||
VAR name:b2 type:B2<kotlin.Int> /* = A<A<kotlin.Int>> */ flags:val
|
||||
CALL 'constructor A(A<Int>)' type=A<A<kotlin.Int>> origin=null
|
||||
<Q>: null
|
||||
<Q>: A<Int>
|
||||
q: GET_VAR 'b: B<Int> /* = A<Int> */' type=B<kotlin.Int> /* = A<kotlin.Int> */ origin=null
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ FILE fqName:<root> fileName:/enumEntry.kt
|
||||
CONSTRUCTOR visibility:private <> () returnType:Z flags:
|
||||
BLOCK_BODY
|
||||
ENUM_CONSTRUCTOR_CALL 'constructor Enum(String, Int)'
|
||||
<E : Enum<E>>: null
|
||||
<E : Enum<E>>: Z
|
||||
INSTANCE_INITIALIZER_CALL classDescriptor='Z'
|
||||
ENUM_ENTRY name:ENTRY
|
||||
init: ENUM_CONSTRUCTOR_CALL 'constructor ENTRY()'
|
||||
|
||||
+1
-1
@@ -2,5 +2,5 @@
|
||||
// WITH_RUNTIME
|
||||
// FULL_JDK
|
||||
|
||||
fun <K, V> Map<out K, V>.plus(pair: Pair<K, V>): Map<K, V> =
|
||||
fun <K1, V1> Map<out K1, V1>.plus(pair: Pair<K1, V1>): Map<K1, V1> =
|
||||
if (this.isEmpty()) mapOf(pair) else LinkedHashMap(this).apply { put(pair.first, pair.second) }
|
||||
+29
-30
@@ -1,43 +1,42 @@
|
||||
FILE fqName:<root> fileName:/builtinMap.kt
|
||||
FUN name:plus visibility:public modality:FINAL <K, V> ($receiver:kotlin.collections.Map<out K, V>, pair:kotlin.Pair<K, V>) returnType:Map<K, V> flags:
|
||||
TYPE_PARAMETER name:K index:0 variance: upperBounds:[kotlin.Any?]
|
||||
FUN name:plus visibility:public modality:FINAL <K1, V1> ($receiver:kotlin.collections.Map<out K1, V1>, pair:kotlin.Pair<K1, V1>) returnType:Map<K1, V1> flags:
|
||||
TYPE_PARAMETER name:K1 index:0 variance: upperBounds:[kotlin.Any?]
|
||||
superClassifiers:
|
||||
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
|
||||
TYPE_PARAMETER name:V index:1 variance: upperBounds:[kotlin.Any?]
|
||||
TYPE_PARAMETER name:V1 index:1 variance: upperBounds:[kotlin.Any?]
|
||||
superClassifiers:
|
||||
CLASS IR_EXTERNAL_DECLARATION_STUB CLASS name:Any modality:OPEN visibility:public flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.collections.Map<out K, V> flags:
|
||||
VALUE_PARAMETER name:pair index:0 type:kotlin.Pair<K, V> flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.collections.Map<out K1, V1> flags:
|
||||
VALUE_PARAMETER name:pair index:0 type:kotlin.Pair<K1, V1> flags:
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='plus(Pair<K, V>) on Map<out K, V>: Map<K, V>'
|
||||
WHEN type=kotlin.collections.Map<K, V> origin=null
|
||||
RETURN type=kotlin.Nothing from='plus(Pair<K1, V1>) on Map<out K1, V1>: Map<K1, V1>'
|
||||
WHEN type=kotlin.collections.Map<K1, V1> origin=null
|
||||
BRANCH
|
||||
if: CALL 'isEmpty(): Boolean' type=kotlin.Boolean origin=null
|
||||
$this: GET_VAR 'this@plus: Map<out K, V>' type=kotlin.collections.Map<out K, V> origin=null
|
||||
then: CALL 'mapOf(Pair<K, V>): Map<K, V>' type=kotlin.collections.Map<K, V> origin=null
|
||||
<K>: K
|
||||
<V>: V
|
||||
pair: GET_VAR 'value-parameter pair: Pair<K, V>' type=kotlin.Pair<K, V> origin=null
|
||||
$this: GET_VAR 'this@plus: Map<out K1, V1>' type=kotlin.collections.Map<out K1, V1> origin=null
|
||||
then: CALL 'mapOf(Pair<K1, V1>): Map<K1, V1>' type=kotlin.collections.Map<K1, V1> origin=null
|
||||
<K>: K1
|
||||
<V>: V1
|
||||
pair: GET_VAR 'value-parameter pair: Pair<K1, V1>' type=kotlin.Pair<K1, V1> origin=null
|
||||
BRANCH
|
||||
if: CONST Boolean type=kotlin.Boolean value=true
|
||||
then: CALL 'apply(LinkedHashMap<K!, V!> /* = LinkedHashMap<K!, V!> */.() -> Unit) on LinkedHashMap<K!, V!> /* = LinkedHashMap<K!, V!> */: LinkedHashMap<K!, V!> /* = LinkedHashMap<K!, V!> */' type=kotlin.collections.LinkedHashMap<K!, V!> /* = java.util.LinkedHashMap<K!, V!> */ origin=null
|
||||
<T>: LinkedHashMap<K!, V!> /* = LinkedHashMap<K!, V!> */
|
||||
$receiver: CALL 'constructor LinkedHashMap((MutableMap<out K!, out V!>..Map<out K!, V!>?))' type=java.util.LinkedHashMap<K!, V!> origin=null
|
||||
<K : Any!>: null
|
||||
<V : Any!>: null
|
||||
p0: GET_VAR 'this@plus: Map<out K, V>' type=kotlin.collections.Map<out K, V> origin=null
|
||||
block: BLOCK type=kotlin.collections.LinkedHashMap<K!, V!> /* = java.util.LinkedHashMap<K!, V!> */.() -> kotlin.Unit origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:kotlin.collections.LinkedHashMap<K!, V!> /* = java.util.LinkedHashMap<K!, V!> */) returnType:Unit flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.collections.LinkedHashMap<K!, V!> /* = java.util.LinkedHashMap<K!, V!> */ flags:
|
||||
then: CALL 'apply(LinkedHashMap<K1!, V1!> /* = LinkedHashMap<K1!, V1!> */.() -> Unit) on LinkedHashMap<K1!, V1!> /* = LinkedHashMap<K1!, V1!> */: LinkedHashMap<K1!, V1!> /* = LinkedHashMap<K1!, V1!> */' type=kotlin.collections.LinkedHashMap<K1!, V1!> /* = java.util.LinkedHashMap<K1!, V1!> */ origin=null
|
||||
<T>: LinkedHashMap<K1!, V1!> /* = LinkedHashMap<K1!, V1!> */
|
||||
$receiver: CALL 'constructor LinkedHashMap((MutableMap<out K1!, out V1!>..Map<out K1!, V1!>?))' type=java.util.LinkedHashMap<K1!, V1!> origin=null
|
||||
<K : Any!>: K1!
|
||||
<V : Any!>: V1!
|
||||
p0: GET_VAR 'this@plus: Map<out K1, V1>' type=kotlin.collections.Map<out K1, V1> origin=null
|
||||
block: BLOCK type=kotlin.collections.LinkedHashMap<K1!, V1!> /* = java.util.LinkedHashMap<K1!, V1!> */.() -> kotlin.Unit origin=LAMBDA
|
||||
FUN LOCAL_FUNCTION_FOR_LAMBDA name:<anonymous> visibility:local modality:FINAL <> ($receiver:kotlin.collections.LinkedHashMap<K1!, V1!> /* = java.util.LinkedHashMap<K1!, V1!> */) returnType:Unit flags:
|
||||
$receiver: VALUE_PARAMETER name:<this> type:kotlin.collections.LinkedHashMap<K1!, V1!> /* = java.util.LinkedHashMap<K1!, V1!> */ flags:
|
||||
BLOCK_BODY
|
||||
RETURN type=kotlin.Nothing from='<anonymous>() on LinkedHashMap<K!, V!> /* = LinkedHashMap<K!, V!> */: Unit'
|
||||
RETURN type=kotlin.Nothing from='<anonymous>() on LinkedHashMap<K1!, V1!> /* = LinkedHashMap<K1!, V1!> */: Unit'
|
||||
TYPE_OP type=kotlin.Unit origin=IMPLICIT_COERCION_TO_UNIT typeOperand=kotlin.Unit
|
||||
typeOperand: CLASS IR_EXTERNAL_DECLARATION_STUB OBJECT name:Unit modality:FINAL visibility:public flags:
|
||||
CALL 'put(K!, V!): V?' type=V? origin=null
|
||||
$this: GET_VAR 'this@<anonymous>: LinkedHashMap<(K..K?), (V..V?)>' type=kotlin.collections.LinkedHashMap<K!, V!> /* = java.util.LinkedHashMap<K!, V!> */ origin=null
|
||||
key: CALL '<get-first>(): K' type=K origin=GET_PROPERTY
|
||||
$this: GET_VAR 'value-parameter pair: Pair<K, V>' type=kotlin.Pair<K, V> origin=null
|
||||
value: CALL '<get-second>(): V' type=V origin=GET_PROPERTY
|
||||
$this: GET_VAR 'value-parameter pair: Pair<K, V>' type=kotlin.Pair<K, V> origin=null
|
||||
FUNCTION_REFERENCE '<anonymous>() on LinkedHashMap<K!, V!> /* = LinkedHashMap<K!, V!> */: Unit' type=kotlin.collections.LinkedHashMap<K!, V!> /* = java.util.LinkedHashMap<K!, V!> */.() -> kotlin.Unit origin=LAMBDA
|
||||
|
||||
CALL 'put(K1!, V1!): V1?' type=V1? origin=null
|
||||
$this: GET_VAR 'this@<anonymous>: LinkedHashMap<(K1..K1?), (V1..V1?)>' type=kotlin.collections.LinkedHashMap<K1!, V1!> /* = java.util.LinkedHashMap<K1!, V1!> */ origin=null
|
||||
key: CALL '<get-first>(): K1' type=K1 origin=GET_PROPERTY
|
||||
$this: GET_VAR 'value-parameter pair: Pair<K1, V1>' type=kotlin.Pair<K1, V1> origin=null
|
||||
value: CALL '<get-second>(): V1' type=V1 origin=GET_PROPERTY
|
||||
$this: GET_VAR 'value-parameter pair: Pair<K1, V1>' type=kotlin.Pair<K1, V1> origin=null
|
||||
FUNCTION_REFERENCE '<anonymous>() on LinkedHashMap<K1!, V1!> /* = LinkedHashMap<K1!, V1!> */: Unit' type=kotlin.collections.LinkedHashMap<K1!, V1!> /* = java.util.LinkedHashMap<K1!, V1!> */.() -> kotlin.Unit origin=LAMBDA
|
||||
|
||||
@@ -849,6 +849,12 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("memberTypeArguments.kt")
|
||||
public void testMemberTypeArguments() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/memberTypeArguments.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("membersImportedFromObject.kt")
|
||||
public void testMembersImportedFromObject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/ir/irText/expressions/membersImportedFromObject.kt");
|
||||
|
||||
Reference in New Issue
Block a user