Support non-reified type parameters in typeOf in JVM and JVM_IR
#KT-30279 Fixed
This commit is contained in:
committed by
Alexander Udalov
parent
6fb40878c4
commit
0ce16b9d8c
@@ -643,59 +643,61 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
|||||||
|
|
||||||
if (!state.getClassBuilderMode().generateBodies) return;
|
if (!state.getClassBuilderMode().generateBodies) return;
|
||||||
|
|
||||||
boolean generateClassIntCtorCall = state.getGenerateOptimizedCallableReferenceSuperClasses();
|
|
||||||
|
|
||||||
InstructionAdapter iv = createOrGetClInitCodegen().v;
|
InstructionAdapter iv = createOrGetClInitCodegen().v;
|
||||||
iv.iconst(delegatedProperties.size());
|
iv.iconst(delegatedProperties.size());
|
||||||
iv.newarray(K_PROPERTY_TYPE);
|
iv.newarray(K_PROPERTY_TYPE);
|
||||||
|
|
||||||
for (int i = 0, size = delegatedProperties.size(); i < size; i++) {
|
for (int i = 0, size = delegatedProperties.size(); i < size; i++) {
|
||||||
VariableDescriptorWithAccessors property = delegatedProperties.get(i);
|
|
||||||
|
|
||||||
iv.dup();
|
iv.dup();
|
||||||
iv.iconst(i);
|
iv.iconst(i);
|
||||||
|
generatePropertyReference(iv, delegatedProperties.get(i), state);
|
||||||
int receiverCount = (property.getDispatchReceiverParameter() != null ? 1 : 0) +
|
|
||||||
(property.getExtensionReceiverParameter() != null ? 1 : 0);
|
|
||||||
Type implType = property.isVar() ? MUTABLE_PROPERTY_REFERENCE_IMPL[receiverCount] : PROPERTY_REFERENCE_IMPL[receiverCount];
|
|
||||||
iv.anew(implType);
|
|
||||||
iv.dup();
|
|
||||||
|
|
||||||
List<Type> superCtorArgTypes = new ArrayList<>();
|
|
||||||
if (generateClassIntCtorCall) {
|
|
||||||
CallableReferenceUtilKt.generateCallableReferenceDeclarationContainerClass(iv, property, state);
|
|
||||||
superCtorArgTypes.add(JAVA_CLASS_TYPE);
|
|
||||||
} else {
|
|
||||||
// TODO: generate the container once and save to a local field instead (KT-10495)
|
|
||||||
CallableReferenceUtilKt.generateCallableReferenceDeclarationContainer(iv, property, state);
|
|
||||||
superCtorArgTypes.add(K_DECLARATION_CONTAINER_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
iv.aconst(property.getName().asString());
|
|
||||||
CallableReferenceUtilKt.generateCallableReferenceSignature(iv, property, state);
|
|
||||||
superCtorArgTypes.add(JAVA_STRING_TYPE);
|
|
||||||
superCtorArgTypes.add(JAVA_STRING_TYPE);
|
|
||||||
|
|
||||||
if (generateClassIntCtorCall) {
|
|
||||||
iv.aconst(CallableReferenceUtilKt.getCallableReferenceTopLevelFlag(property));
|
|
||||||
superCtorArgTypes.add(Type.INT_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
iv.invokespecial(
|
|
||||||
implType.getInternalName(), "<init>",
|
|
||||||
Type.getMethodDescriptor(Type.VOID_TYPE, superCtorArgTypes.toArray(new Type[0])), false
|
|
||||||
);
|
|
||||||
Method wrapper = PropertyReferenceCodegen.getWrapperMethodForPropertyReference(property, receiverCount);
|
|
||||||
iv.invokestatic(REFLECTION, wrapper.getName(), wrapper.getDescriptor(), false);
|
|
||||||
|
|
||||||
StackValue.onStack(implType).put(K_PROPERTY_TYPE, iv);
|
|
||||||
|
|
||||||
iv.astore(K_PROPERTY_TYPE);
|
iv.astore(K_PROPERTY_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
iv.putstatic(thisAsmType.getInternalName(), JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME, "[" + K_PROPERTY_TYPE);
|
iv.putstatic(thisAsmType.getInternalName(), JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME, "[" + K_PROPERTY_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void generatePropertyReference(
|
||||||
|
@NotNull InstructionAdapter iv,
|
||||||
|
@NotNull VariableDescriptorWithAccessors property,
|
||||||
|
@NotNull GenerationState state
|
||||||
|
) {
|
||||||
|
int receiverCount = (property.getDispatchReceiverParameter() != null ? 1 : 0) +
|
||||||
|
(property.getExtensionReceiverParameter() != null ? 1 : 0);
|
||||||
|
Type implType = property.isVar() ? MUTABLE_PROPERTY_REFERENCE_IMPL[receiverCount] : PROPERTY_REFERENCE_IMPL[receiverCount];
|
||||||
|
iv.anew(implType);
|
||||||
|
iv.dup();
|
||||||
|
|
||||||
|
List<Type> superCtorArgTypes = new ArrayList<>();
|
||||||
|
if (state.getGenerateOptimizedCallableReferenceSuperClasses()) {
|
||||||
|
CallableReferenceUtilKt.generateCallableReferenceDeclarationContainerClass(iv, property, state);
|
||||||
|
superCtorArgTypes.add(JAVA_CLASS_TYPE);
|
||||||
|
} else {
|
||||||
|
// TODO: generate the container once and save to a local field instead (KT-10495)
|
||||||
|
CallableReferenceUtilKt.generateCallableReferenceDeclarationContainer(iv, property, state);
|
||||||
|
superCtorArgTypes.add(K_DECLARATION_CONTAINER_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
iv.aconst(property.getName().asString());
|
||||||
|
CallableReferenceUtilKt.generateCallableReferenceSignature(iv, property, state);
|
||||||
|
superCtorArgTypes.add(JAVA_STRING_TYPE);
|
||||||
|
superCtorArgTypes.add(JAVA_STRING_TYPE);
|
||||||
|
|
||||||
|
if (state.getGenerateOptimizedCallableReferenceSuperClasses()) {
|
||||||
|
iv.aconst(CallableReferenceUtilKt.getCallableReferenceTopLevelFlag(property));
|
||||||
|
superCtorArgTypes.add(Type.INT_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
iv.invokespecial(
|
||||||
|
implType.getInternalName(), "<init>",
|
||||||
|
Type.getMethodDescriptor(Type.VOID_TYPE, superCtorArgTypes.toArray(new Type[0])), false
|
||||||
|
);
|
||||||
|
Method wrapper = PropertyReferenceCodegen.getWrapperMethodForPropertyReference(property, receiverCount);
|
||||||
|
iv.invokestatic(REFLECTION, wrapper.getName(), wrapper.getDescriptor(), false);
|
||||||
|
|
||||||
|
StackValue.onStack(implType).put(K_PROPERTY_TYPE, iv);
|
||||||
|
}
|
||||||
|
|
||||||
public String getClassName() {
|
public String getClassName() {
|
||||||
return v.getThisName();
|
return v.getThisName();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
|
||||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||||
|
|
||||||
class PsiInlineCodegen(
|
class PsiInlineCodegen(
|
||||||
@@ -42,15 +41,8 @@ class PsiInlineCodegen(
|
|||||||
private val actualDispatchReceiver: Type = methodOwner
|
private val actualDispatchReceiver: Type = methodOwner
|
||||||
) : InlineCodegen<ExpressionCodegen>(
|
) : InlineCodegen<ExpressionCodegen>(
|
||||||
codegen, state, function, methodOwner, signature, typeParameterMappings, sourceCompiler,
|
codegen, state, function, methodOwner, signature, typeParameterMappings, sourceCompiler,
|
||||||
ReifiedTypeInliner(typeParameterMappings, object : ReifiedTypeInliner.IntrinsicsSupport<KotlinType> {
|
ReifiedTypeInliner(typeParameterMappings, PsiInlineIntrinsicsSupport(state), codegen.typeSystem, state.languageVersionSettings),
|
||||||
override fun putClassInstance(v: InstructionAdapter, type: KotlinType) {
|
|
||||||
AsmUtil.putJavaLangClassInstance(v, state.typeMapper.mapType(type), type, state.typeMapper)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toKotlinType(type: KotlinType): KotlinType = type
|
|
||||||
}, codegen.typeSystem, state.languageVersionSettings)
|
|
||||||
), CallGenerator {
|
), CallGenerator {
|
||||||
|
|
||||||
override fun generateAssertFieldIfNeeded(info: RootInliningContext) {
|
override fun generateAssertFieldIfNeeded(info: RootInliningContext) {
|
||||||
if (info.generateAssertField) {
|
if (info.generateAssertField) {
|
||||||
codegen.parentCodegen.generateAssertField()
|
codegen.parentCodegen.generateAssertField()
|
||||||
|
|||||||
+60
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* 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.codegen.inline
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.codegen.*
|
||||||
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type.INT_TYPE
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type.VOID_TYPE
|
||||||
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
|
|
||||||
|
class PsiInlineIntrinsicsSupport(private val state: GenerationState) : ReifiedTypeInliner.IntrinsicsSupport<KotlinType> {
|
||||||
|
override fun putClassInstance(v: InstructionAdapter, type: KotlinType) {
|
||||||
|
AsmUtil.putJavaLangClassInstance(v, state.typeMapper.mapType(type), type, state.typeMapper)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun generateTypeParameterContainer(v: InstructionAdapter, typeParameter: TypeParameterMarker) {
|
||||||
|
require(typeParameter is TypeParameterDescriptor)
|
||||||
|
|
||||||
|
when (val container = typeParameter.containingDeclaration) {
|
||||||
|
is ClassDescriptor -> putClassInstance(v, container.defaultType).also { AsmUtil.wrapJavaClassIntoKClass(v) }
|
||||||
|
is FunctionDescriptor -> generateFunctionReference(v, container)
|
||||||
|
is PropertyDescriptor -> MemberCodegen.generatePropertyReference(v, container, state)
|
||||||
|
else -> error("Unknown container of type parameter: $container (${typeParameter.name})")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateFunctionReference(v: InstructionAdapter, descriptor: FunctionDescriptor) {
|
||||||
|
check(state.generateOptimizedCallableReferenceSuperClasses) {
|
||||||
|
"typeOf() of a non-reified type parameter is only allowed if optimized callable references are enabled.\n" +
|
||||||
|
"Please make sure API version is set to 1.4, and -Xno-optimized-callable-references is NOT used.\n" +
|
||||||
|
"Container: $descriptor"
|
||||||
|
}
|
||||||
|
|
||||||
|
v.anew(FUNCTION_REFERENCE_IMPL)
|
||||||
|
v.dup()
|
||||||
|
v.aconst(descriptor.arity)
|
||||||
|
generateCallableReferenceDeclarationContainerClass(v, descriptor, state)
|
||||||
|
v.aconst(descriptor.name.asString())
|
||||||
|
generateCallableReferenceSignature(v, descriptor, state)
|
||||||
|
v.aconst(getCallableReferenceTopLevelFlag(descriptor))
|
||||||
|
v.invokespecial(
|
||||||
|
FUNCTION_REFERENCE_IMPL.internalName, "<init>",
|
||||||
|
Type.getMethodDescriptor(VOID_TYPE, INT_TYPE, JAVA_CLASS_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE, INT_TYPE),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toKotlinType(type: KotlinType): KotlinType = type
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
|||||||
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
|
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
|
||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
import org.jetbrains.kotlin.config.isReleaseCoroutines
|
||||||
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||||
@@ -63,6 +64,8 @@ class ReifiedTypeInliner<KT : KotlinTypeMarker>(
|
|||||||
interface IntrinsicsSupport<KT : KotlinTypeMarker> {
|
interface IntrinsicsSupport<KT : KotlinTypeMarker> {
|
||||||
fun putClassInstance(v: InstructionAdapter, type: KT)
|
fun putClassInstance(v: InstructionAdapter, type: KT)
|
||||||
|
|
||||||
|
fun generateTypeParameterContainer(v: InstructionAdapter, typeParameter: TypeParameterMarker)
|
||||||
|
|
||||||
fun toKotlinType(type: KT): KotlinType
|
fun toKotlinType(type: KT): KotlinType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes
|
|||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||||
|
import kotlin.reflect.KVariance
|
||||||
|
|
||||||
internal fun TypeSystemCommonBackendContext.createTypeOfMethodBody(typeParameter: TypeParameterMarker): MethodNode {
|
internal fun TypeSystemCommonBackendContext.createTypeOfMethodBody(typeParameter: TypeParameterMarker): MethodNode {
|
||||||
val node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", Type.getMethodDescriptor(K_TYPE), null, null)
|
val node = MethodNode(Opcodes.API_VERSION, Opcodes.ACC_STATIC, "fake", Type.getMethodDescriptor(K_TYPE), null, null)
|
||||||
@@ -39,7 +40,18 @@ private fun TypeSystemCommonBackendContext.putTypeOfReifiedTypeParameter(
|
|||||||
internal fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateTypeOf(
|
internal fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateTypeOf(
|
||||||
v: InstructionAdapter, type: KT, intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport<KT>
|
v: InstructionAdapter, type: KT, intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport<KT>
|
||||||
) {
|
) {
|
||||||
intrinsicsSupport.putClassInstance(v, type)
|
val typeParameter = type.typeConstructor().getTypeParameterClassifier()
|
||||||
|
if (typeParameter != null) {
|
||||||
|
if (!doesTypeContainTypeParametersWithRecursiveBounds(type)) {
|
||||||
|
throw UnsupportedOperationException(
|
||||||
|
"Non-reified type parameters with recursive bounds are not supported yet: ${typeParameter.getName()}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
generateNonReifiedTypeParameter(v, typeParameter, intrinsicsSupport)
|
||||||
|
} else {
|
||||||
|
intrinsicsSupport.putClassInstance(v, type)
|
||||||
|
}
|
||||||
|
|
||||||
val argumentsSize = type.argumentsCount()
|
val argumentsSize = type.argumentsCount()
|
||||||
val useArray = argumentsSize >= 3
|
val useArray = argumentsSize >= 3
|
||||||
@@ -64,17 +76,87 @@ internal fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateType
|
|||||||
|
|
||||||
val methodName = if (type.isMarkedNullable()) "nullableTypeOf" else "typeOf"
|
val methodName = if (type.isMarkedNullable()) "nullableTypeOf" else "typeOf"
|
||||||
|
|
||||||
val projections = when (argumentsSize) {
|
val signature = if (typeParameter != null) {
|
||||||
0 -> emptyArray()
|
Type.getMethodDescriptor(K_TYPE, K_CLASSIFIER_TYPE)
|
||||||
1 -> arrayOf(K_TYPE_PROJECTION)
|
} else {
|
||||||
2 -> arrayOf(K_TYPE_PROJECTION, K_TYPE_PROJECTION)
|
val projections = when (argumentsSize) {
|
||||||
else -> arrayOf(AsmUtil.getArrayType(K_TYPE_PROJECTION))
|
0 -> emptyArray()
|
||||||
|
1 -> arrayOf(K_TYPE_PROJECTION)
|
||||||
|
2 -> arrayOf(K_TYPE_PROJECTION, K_TYPE_PROJECTION)
|
||||||
|
else -> arrayOf(AsmUtil.getArrayType(K_TYPE_PROJECTION))
|
||||||
|
}
|
||||||
|
Type.getMethodDescriptor(K_TYPE, JAVA_CLASS_TYPE, *projections)
|
||||||
}
|
}
|
||||||
val signature = Type.getMethodDescriptor(K_TYPE, JAVA_CLASS_TYPE, *projections)
|
|
||||||
|
|
||||||
v.invokestatic(REFLECTION, methodName, signature, false)
|
v.invokestatic(REFLECTION, methodName, signature, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.generateNonReifiedTypeParameter(
|
||||||
|
v: InstructionAdapter, typeParameter: TypeParameterMarker, intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport<KT>
|
||||||
|
) {
|
||||||
|
intrinsicsSupport.generateTypeParameterContainer(v, typeParameter)
|
||||||
|
|
||||||
|
v.aconst(typeParameter.getName().asString())
|
||||||
|
val variance = when (typeParameter.getVariance()) {
|
||||||
|
TypeVariance.INV -> KVariance.INVARIANT
|
||||||
|
TypeVariance.IN -> KVariance.IN
|
||||||
|
TypeVariance.OUT -> KVariance.OUT
|
||||||
|
}
|
||||||
|
v.getstatic(K_VARIANCE.internalName, variance.name, K_VARIANCE.descriptor)
|
||||||
|
v.aconst(typeParameter.isReified())
|
||||||
|
v.invokestatic(
|
||||||
|
REFLECTION, "typeParameter",
|
||||||
|
Type.getMethodDescriptor(K_TYPE_PARAMETER, OBJECT_TYPE, JAVA_STRING_TYPE, K_VARIANCE, Type.BOOLEAN_TYPE),
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
val bounds = (0 until typeParameter.upperBoundCount()).map { typeParameter.getUpperBound(it) as KT }
|
||||||
|
if (bounds.isEmpty()) return
|
||||||
|
|
||||||
|
v.dup()
|
||||||
|
|
||||||
|
if (bounds.size == 1) {
|
||||||
|
generateTypeOf(v, bounds.single(), intrinsicsSupport)
|
||||||
|
} else {
|
||||||
|
v.aconst(bounds.size)
|
||||||
|
v.newarray(K_TYPE)
|
||||||
|
for ((i, bound) in bounds.withIndex()) {
|
||||||
|
v.dup()
|
||||||
|
v.aconst(i)
|
||||||
|
generateTypeOf(v, bound, intrinsicsSupport)
|
||||||
|
v.astore(K_TYPE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
v.invokestatic(
|
||||||
|
REFLECTION, "setUpperBounds", Type.getMethodDescriptor(
|
||||||
|
Type.VOID_TYPE, K_TYPE_PARAMETER,
|
||||||
|
if (bounds.size == 1) K_TYPE else AsmUtil.getArrayType(K_TYPE)
|
||||||
|
),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun TypeSystemCommonBackendContext.doesTypeContainTypeParametersWithRecursiveBounds(
|
||||||
|
type: KotlinTypeMarker,
|
||||||
|
used: MutableSet<TypeParameterMarker> = linkedSetOf()
|
||||||
|
): Boolean {
|
||||||
|
val typeParameter = type.typeConstructor().getTypeParameterClassifier()
|
||||||
|
if (typeParameter != null) {
|
||||||
|
if (!used.add(typeParameter)) return false
|
||||||
|
for (i in 0 until typeParameter.upperBoundCount()) {
|
||||||
|
if (!doesTypeContainTypeParametersWithRecursiveBounds(typeParameter.getUpperBound(i), used)) return false
|
||||||
|
}
|
||||||
|
used.remove(typeParameter)
|
||||||
|
} else {
|
||||||
|
for (i in 0 until type.argumentsCount()) {
|
||||||
|
if (!doesTypeContainTypeParametersWithRecursiveBounds(type.getArgument(i).getType(), used)) return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
private fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.doGenerateTypeProjection(
|
private fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.doGenerateTypeProjection(
|
||||||
v: InstructionAdapter,
|
v: InstructionAdapter,
|
||||||
projection: TypeArgumentMarker,
|
projection: TypeArgumentMarker,
|
||||||
@@ -91,14 +173,8 @@ private fun <KT : KotlinTypeMarker> TypeSystemCommonBackendContext.doGenerateTyp
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val type = projection.getType() as KT
|
val type = projection.getType() as KT
|
||||||
val typeParameterClassifier = type.typeConstructor().getTypeParameterClassifier()
|
val typeParameterClassifier = type.typeConstructor().getTypeParameterClassifier()
|
||||||
if (typeParameterClassifier != null) {
|
if (typeParameterClassifier != null && typeParameterClassifier.isReified()) {
|
||||||
if (typeParameterClassifier.isReified()) {
|
putTypeOfReifiedTypeParameter(v, typeParameterClassifier, type.isMarkedNullable())
|
||||||
putTypeOfReifiedTypeParameter(v, typeParameterClassifier, type.isMarkedNullable())
|
|
||||||
} else {
|
|
||||||
// TODO: support non-reified type parameters in typeOf
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
generateTypeOf(v, nullableAnyType() as KT, intrinsicsSupport)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
generateTypeOf(v, type, intrinsicsSupport)
|
generateTypeOf(v, type, intrinsicsSupport)
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+131
@@ -25656,6 +25656,137 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
public void testTypeReferenceEqualsHashCode() throws Exception {
|
public void testTypeReferenceEqualsHashCode() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/typeReferenceEqualsHashCode.kt");
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/typeReferenceEqualsHashCode.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NonReifiedTypeParameters extends AbstractFirBlackBoxCodegenTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNonReifiedTypeParameters() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultUpperBound.kt")
|
||||||
|
public void testDefaultUpperBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/defaultUpperBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnClassParameters.kt")
|
||||||
|
public void testEqualsOnClassParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnClassParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnFunctionParameters.kt")
|
||||||
|
public void testEqualsOnFunctionParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnFunctionParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerGeneric.kt")
|
||||||
|
public void testInnerGeneric() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/innerGeneric.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleClassParameter.kt")
|
||||||
|
public void testSimpleClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleFunctionParameter.kt")
|
||||||
|
public void testSimpleFunctionParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleFunctionParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simplePropertyParameter.kt")
|
||||||
|
public void testSimplePropertyParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simplePropertyParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterFlags.kt")
|
||||||
|
public void testTypeParameterFlags() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/typeParameterFlags.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBoundUsesOuterClassParameter.kt")
|
||||||
|
public void testUpperBoundUsesOuterClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBounds.kt")
|
||||||
|
public void testUpperBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBounds.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NonReifiedTypeParameters extends AbstractFirBlackBoxCodegenTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: ");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNonReifiedTypeParameters() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultUpperBound.kt")
|
||||||
|
public void testDefaultUpperBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/defaultUpperBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnClassParameters.kt")
|
||||||
|
public void testEqualsOnClassParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnClassParametersWithReflectAPI.kt")
|
||||||
|
public void testEqualsOnClassParametersWithReflectAPI() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParametersWithReflectAPI.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnFunctionParameters.kt")
|
||||||
|
public void testEqualsOnFunctionParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnFunctionParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerGeneric.kt")
|
||||||
|
public void testInnerGeneric() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/innerGeneric.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleClassParameter.kt")
|
||||||
|
public void testSimpleClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleFunctionParameter.kt")
|
||||||
|
public void testSimpleFunctionParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleFunctionParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simplePropertyParameter.kt")
|
||||||
|
public void testSimplePropertyParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simplePropertyParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterFlags.kt")
|
||||||
|
public void testTypeParameterFlags() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/typeParameterFlags.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBoundUsesOuterClassParameter.kt")
|
||||||
|
public void testUpperBoundUsesOuterClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBounds.kt")
|
||||||
|
public void testUpperBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBounds.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ public class AsmTypes {
|
|||||||
|
|
||||||
public static final Type K_CLASS_TYPE = reflect("KClass");
|
public static final Type K_CLASS_TYPE = reflect("KClass");
|
||||||
public static final Type K_CLASS_ARRAY_TYPE = Type.getObjectType("[" + K_CLASS_TYPE.getDescriptor());
|
public static final Type K_CLASS_ARRAY_TYPE = Type.getObjectType("[" + K_CLASS_TYPE.getDescriptor());
|
||||||
|
public static final Type K_CLASSIFIER_TYPE = reflect("KClassifier");
|
||||||
public static final Type K_DECLARATION_CONTAINER_TYPE = reflect("KDeclarationContainer");
|
public static final Type K_DECLARATION_CONTAINER_TYPE = reflect("KDeclarationContainer");
|
||||||
|
|
||||||
public static final Type K_FUNCTION = reflect("KFunction");
|
public static final Type K_FUNCTION = reflect("KFunction");
|
||||||
@@ -73,6 +74,8 @@ public class AsmTypes {
|
|||||||
public static final Type K_TYPE = reflect("KType");
|
public static final Type K_TYPE = reflect("KType");
|
||||||
public static final Type K_TYPE_PROJECTION = reflect("KTypeProjection");
|
public static final Type K_TYPE_PROJECTION = reflect("KTypeProjection");
|
||||||
public static final Type K_TYPE_PROJECTION_COMPANION = reflect("KTypeProjection$Companion");
|
public static final Type K_TYPE_PROJECTION_COMPANION = reflect("KTypeProjection$Companion");
|
||||||
|
public static final Type K_TYPE_PARAMETER = reflect("KTypeParameter");
|
||||||
|
public static final Type K_VARIANCE = reflect("KVariance");
|
||||||
|
|
||||||
public static final Type SUSPEND_FUNCTION_TYPE = Type.getObjectType("kotlin/coroutines/jvm/internal/SuspendFunction");
|
public static final Type SUSPEND_FUNCTION_TYPE = Type.getObjectType("kotlin/coroutines/jvm/internal/SuspendFunction");
|
||||||
|
|
||||||
|
|||||||
+18
-18
@@ -47,7 +47,6 @@ import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
|
||||||
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
|
||||||
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||||
@@ -1084,7 +1083,7 @@ class ExpressionCodegen(
|
|||||||
putReifiedOperationMarkerIfTypeIsReifiedParameter(classType, ReifiedTypeInliner.OperationKind.JAVA_CLASS)
|
putReifiedOperationMarkerIfTypeIsReifiedParameter(classType, ReifiedTypeInliner.OperationKind.JAVA_CLASS)
|
||||||
}
|
}
|
||||||
|
|
||||||
generateClassInstance(mv, classType)
|
generateClassInstance(mv, classType, typeMapper)
|
||||||
} else {
|
} else {
|
||||||
throw AssertionError("not an IrGetClass or IrClassReference: ${classReference.dump()}")
|
throw AssertionError("not an IrGetClass or IrClassReference: ${classReference.dump()}")
|
||||||
}
|
}
|
||||||
@@ -1095,15 +1094,6 @@ class ExpressionCodegen(
|
|||||||
return classReference.onStack
|
return classReference.onStack
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateClassInstance(v: InstructionAdapter, classType: IrType) {
|
|
||||||
val asmType = typeMapper.mapType(classType)
|
|
||||||
if (classType.getClass()?.isInline == true || !isPrimitive(asmType)) {
|
|
||||||
v.aconst(typeMapper.boxType(classType))
|
|
||||||
} else {
|
|
||||||
v.getstatic(boxType(asmType).internalName, "TYPE", "Ljava/lang/Class;")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getOrCreateCallGenerator(
|
private fun getOrCreateCallGenerator(
|
||||||
element: IrFunctionAccessExpression, data: BlockInfo, signature: JvmMethodSignature
|
element: IrFunctionAccessExpression, data: BlockInfo, signature: JvmMethodSignature
|
||||||
): IrCallGenerator {
|
): IrCallGenerator {
|
||||||
@@ -1144,13 +1134,12 @@ class ExpressionCodegen(
|
|||||||
val methodOwner = typeMapper.mapClass(callee.parentAsClass)
|
val methodOwner = typeMapper.mapClass(callee.parentAsClass)
|
||||||
val sourceCompiler = IrSourceCompilerForInline(state, element, callee, this, data)
|
val sourceCompiler = IrSourceCompilerForInline(state, element, callee, this, data)
|
||||||
|
|
||||||
val reifiedTypeInliner = ReifiedTypeInliner(mappings, object : ReifiedTypeInliner.IntrinsicsSupport<IrType> {
|
val reifiedTypeInliner = ReifiedTypeInliner(
|
||||||
override fun putClassInstance(v: InstructionAdapter, type: IrType) {
|
mappings,
|
||||||
generateClassInstance(v, type)
|
IrInlineIntrinsicsSupport(context, typeMapper),
|
||||||
}
|
IrTypeCheckerContext(context.irBuiltIns),
|
||||||
|
state.languageVersionSettings
|
||||||
override fun toKotlinType(type: IrType): KotlinType = type.toKotlinType()
|
)
|
||||||
}, IrTypeCheckerContext(context.irBuiltIns), state.languageVersionSettings)
|
|
||||||
|
|
||||||
return IrInlineCodegen(this, state, callee, methodOwner, signature, mappings, sourceCompiler, reifiedTypeInliner)
|
return IrInlineCodegen(this, state, callee, methodOwner, signature, mappings, sourceCompiler, reifiedTypeInliner)
|
||||||
}
|
}
|
||||||
@@ -1208,4 +1197,15 @@ class ExpressionCodegen(
|
|||||||
|
|
||||||
val IrType.isReifiedTypeParameter: Boolean
|
val IrType.isReifiedTypeParameter: Boolean
|
||||||
get() = this.classifierOrNull?.safeAs<IrTypeParameterSymbol>()?.owner?.isReified == true
|
get() = this.classifierOrNull?.safeAs<IrTypeParameterSymbol>()?.owner?.isReified == true
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
internal fun generateClassInstance(v: InstructionAdapter, classType: IrType, typeMapper: IrTypeMapper) {
|
||||||
|
val asmType = typeMapper.mapType(classType)
|
||||||
|
if (classType.getClass()?.isInline == true || !isPrimitive(asmType)) {
|
||||||
|
v.aconst(typeMapper.boxType(classType))
|
||||||
|
} else {
|
||||||
|
v.getstatic(boxType(asmType).internalName, "TYPE", "Ljava/lang/Class;")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+98
@@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* 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.backend.jvm.codegen
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.ir.allParameters
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.intrinsics.SignatureString
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.lower.FunctionReferenceLowering
|
||||||
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
|
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||||
|
import org.jetbrains.kotlin.ir.util.defaultType
|
||||||
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.*
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeParameterMarker
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type.INT_TYPE
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type.VOID_TYPE
|
||||||
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
|
|
||||||
|
class IrInlineIntrinsicsSupport(
|
||||||
|
private val context: JvmBackendContext,
|
||||||
|
private val typeMapper: IrTypeMapper
|
||||||
|
) : ReifiedTypeInliner.IntrinsicsSupport<IrType> {
|
||||||
|
override fun putClassInstance(v: InstructionAdapter, type: IrType) {
|
||||||
|
ExpressionCodegen.generateClassInstance(v, type, typeMapper)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun generateTypeParameterContainer(v: InstructionAdapter, typeParameter: TypeParameterMarker) {
|
||||||
|
require(typeParameter is IrTypeParameterSymbol)
|
||||||
|
|
||||||
|
when (val parent = typeParameter.owner.parent) {
|
||||||
|
is IrClass -> putClassInstance(v, parent.defaultType).also { AsmUtil.wrapJavaClassIntoKClass(v) }
|
||||||
|
is IrSimpleFunction -> {
|
||||||
|
check(context.state.generateOptimizedCallableReferenceSuperClasses) {
|
||||||
|
"typeOf() of a non-reified type parameter is only allowed if optimized callable references are enabled.\n" +
|
||||||
|
"Please make sure API version is set to 1.4, and -Xno-optimized-callable-references is NOT used.\n" +
|
||||||
|
"Container: $parent"
|
||||||
|
}
|
||||||
|
val property = parent.correspondingPropertySymbol
|
||||||
|
if (property != null) {
|
||||||
|
generatePropertyReference(v, property.owner)
|
||||||
|
} else {
|
||||||
|
generateFunctionReference(v, parent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> error("Unknown parent of type parameter: ${parent.render()} ${typeParameter.owner.name})")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateFunctionReference(v: InstructionAdapter, function: IrFunction) {
|
||||||
|
generateCallableReference(v, function, function, FUNCTION_REFERENCE_IMPL, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generatePropertyReference(v: InstructionAdapter, property: IrProperty) {
|
||||||
|
// We're sure that this property has a getter because if a property is generic, it necessarily has extension receiver and
|
||||||
|
// thus cannot have a backing field, and is required to have a getter.
|
||||||
|
val getter = property.getter
|
||||||
|
?: error("Property without getter: ${property.render()}")
|
||||||
|
val arity = getter.allParameters.size
|
||||||
|
val implClass = (if (property.isVar) MUTABLE_PROPERTY_REFERENCE_IMPL else PROPERTY_REFERENCE_IMPL).getOrNull(arity)
|
||||||
|
?: error("No property reference impl class with arity $arity (${property.render()}")
|
||||||
|
|
||||||
|
generateCallableReference(v, property, getter, implClass, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateCallableReference(
|
||||||
|
v: InstructionAdapter, declaration: IrDeclarationWithName, function: IrFunction, implClass: Type, withArity: Boolean
|
||||||
|
) {
|
||||||
|
v.anew(implClass)
|
||||||
|
v.dup()
|
||||||
|
if (withArity) {
|
||||||
|
v.aconst(function.allParameters.size)
|
||||||
|
}
|
||||||
|
putClassInstance(v, FunctionReferenceLowering.getOwnerKClassType(declaration.parent, context))
|
||||||
|
v.aconst(declaration.name.asString())
|
||||||
|
// TODO: generate correct signature for functions and property accessors which have inline class types in the signature.
|
||||||
|
SignatureString.generateSignatureString(v, function, context)
|
||||||
|
v.aconst(FunctionReferenceLowering.getCallableReferenceTopLevelFlag(declaration))
|
||||||
|
val parameterTypes =
|
||||||
|
(if (withArity) listOf(INT_TYPE) else emptyList()) +
|
||||||
|
listOf(JAVA_CLASS_TYPE, JAVA_STRING_TYPE, JAVA_STRING_TYPE, INT_TYPE)
|
||||||
|
v.invokespecial(
|
||||||
|
implClass.internalName, "<init>",
|
||||||
|
Type.getMethodDescriptor(VOID_TYPE, *parameterTypes.toTypedArray()),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun toKotlinType(type: IrType): KotlinType = type.toKotlinType()
|
||||||
|
}
|
||||||
+14
-9
@@ -5,18 +5,19 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
|
import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.MaterialValue
|
import org.jetbrains.kotlin.backend.jvm.codegen.MaterialValue
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.PromisedValue
|
import org.jetbrains.kotlin.backend.jvm.codegen.PromisedValue
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
|
||||||
import org.jetbrains.kotlin.ir.util.collectRealOverrides
|
import org.jetbrains.kotlin.ir.util.collectRealOverrides
|
||||||
import org.jetbrains.kotlin.ir.util.isSuspend
|
import org.jetbrains.kotlin.ir.util.isSuspend
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the JVM signature of a given IrFunction. The function is passed as an IrFunctionReference
|
* Computes the JVM signature of a given IrFunction. The function is passed as an IrFunctionReference
|
||||||
@@ -25,13 +26,17 @@ import org.jetbrains.org.objectweb.asm.Type
|
|||||||
object SignatureString : IntrinsicMethod() {
|
object SignatureString : IntrinsicMethod() {
|
||||||
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue {
|
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue {
|
||||||
val function = (expression.getValueArgument(0) as IrFunctionReference).symbol.owner
|
val function = (expression.getValueArgument(0) as IrFunctionReference).symbol.owner
|
||||||
var resolved = if (function is IrSimpleFunction) function.collectRealOverrides().first() else function
|
generateSignatureString(codegen.mv, function, codegen.context)
|
||||||
if (resolved.isSuspend) {
|
|
||||||
resolved = codegen.context.suspendFunctionOriginalToView[resolved] ?: resolved
|
|
||||||
}
|
|
||||||
val method = codegen.context.methodSignatureMapper.mapAsmMethod(resolved)
|
|
||||||
val descriptor = method.name + method.descriptor
|
|
||||||
codegen.mv.aconst(descriptor)
|
|
||||||
return MaterialValue(codegen, AsmTypes.JAVA_STRING_TYPE, codegen.context.irBuiltIns.stringType)
|
return MaterialValue(codegen, AsmTypes.JAVA_STRING_TYPE, codegen.context.irBuiltIns.stringType)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal fun generateSignatureString(v: InstructionAdapter, function: IrFunction, context: JvmBackendContext) {
|
||||||
|
var resolved = if (function is IrSimpleFunction) function.collectRealOverrides().first() else function
|
||||||
|
if (resolved.isSuspend) {
|
||||||
|
resolved = context.suspendFunctionOriginalToView[resolved] ?: resolved
|
||||||
|
}
|
||||||
|
val method = context.methodSignatureMapper.mapAsmMethod(resolved)
|
||||||
|
val descriptor = method.name + method.descriptor
|
||||||
|
v.aconst(descriptor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+17
-10
@@ -337,7 +337,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getFunctionReferenceFlags(callableReferenceTarget: IrFunction): Int {
|
private fun getFunctionReferenceFlags(callableReferenceTarget: IrFunction): Int {
|
||||||
val isTopLevelBit = if (callableReferenceTarget.parent.let { it is IrClass && it.isFileClass }) 1 else 0
|
val isTopLevelBit = getCallableReferenceTopLevelFlag(callableReferenceTarget)
|
||||||
val adaptedCallableReferenceFlags = getAdaptedCallableReferenceFlags()
|
val adaptedCallableReferenceFlags = getAdaptedCallableReferenceFlags()
|
||||||
return isTopLevelBit + (adaptedCallableReferenceFlags shl 1)
|
return isTopLevelBit + (adaptedCallableReferenceFlags shl 1)
|
||||||
}
|
}
|
||||||
@@ -518,14 +518,21 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun IrBuilderWithScope.calculateOwnerKClass(irContainer: IrDeclarationParent, context: JvmBackendContext): IrExpression =
|
internal fun IrBuilderWithScope.calculateOwnerKClass(irContainer: IrDeclarationParent, context: JvmBackendContext): IrExpression =
|
||||||
kClassReference(
|
kClassReference(getOwnerKClassType(irContainer, context))
|
||||||
if (irContainer is IrClass) irContainer.defaultType
|
|
||||||
else {
|
internal fun getOwnerKClassType(irContainer: IrDeclarationParent, context: JvmBackendContext): IrType =
|
||||||
// For built-in members (i.e. top level `toString`) we generate reference to an internal class for an owner.
|
if (irContainer is IrClass) irContainer.defaultType
|
||||||
// This allows kotlin-reflect to understand that this is a built-in intrinsic which has no real declaration,
|
else {
|
||||||
// and construct a special KCallable object.
|
// For built-in members (i.e. top level `toString`) we generate reference to an internal class for an owner.
|
||||||
context.ir.symbols.intrinsicsKotlinClass.defaultType
|
// This allows kotlin-reflect to understand that this is a built-in intrinsic which has no real declaration,
|
||||||
}
|
// and construct a special KCallable object.
|
||||||
)
|
context.ir.symbols.intrinsicsKotlinClass.defaultType
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun getCallableReferenceTopLevelFlag(declaration: IrDeclaration): Int =
|
||||||
|
if (isCallableReferenceTopLevel(declaration)) 1 else 0
|
||||||
|
|
||||||
|
internal fun isCallableReferenceTopLevel(declaration: IrDeclaration): Boolean =
|
||||||
|
declaration.parent.let { it is IrClass && it.isFileClass }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -393,7 +393,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
|
|||||||
putValueArgument(index++, kClassToJavaClass(owner, backendContext))
|
putValueArgument(index++, kClassToJavaClass(owner, backendContext))
|
||||||
putValueArgument(index++, irString(expression.symbol.descriptor.name.asString()))
|
putValueArgument(index++, irString(expression.symbol.descriptor.name.asString()))
|
||||||
putValueArgument(index++, computeSignatureString(expression))
|
putValueArgument(index++, computeSignatureString(expression))
|
||||||
putValueArgument(index, irInt(if (callee.parent.let { it is IrClass && it.isFileClass }) 1 else 0))
|
putValueArgument(index, irInt(FunctionReferenceLowering.getCallableReferenceTopLevelFlag(callee)))
|
||||||
}
|
}
|
||||||
+IrInstanceInitializerCallImpl(startOffset, endOffset, referenceClass.symbol, context.irBuiltIns.unitType)
|
+IrInstanceInitializerCallImpl(startOffset, endOffset, referenceClass.symbol, context.irBuiltIns.unitType)
|
||||||
}
|
}
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.reflect.KTypeParameter
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
fun <X> test() = typeOf<Container<X>>()
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val type = test<Any>()
|
||||||
|
val x = type.arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
assertEquals("java.lang.Object? (Kotlin reflection is not available)", x.upperBounds.joinToString())
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.reflect.KTypeParameter
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNotEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
class C<X, Y> {
|
||||||
|
val x1 = createX()
|
||||||
|
val x2 = createXFromOtherFunction()
|
||||||
|
val xFun = createIrrelevantX<Any>()
|
||||||
|
val y = createY()
|
||||||
|
|
||||||
|
fun createX(): KTypeParameter =
|
||||||
|
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
|
||||||
|
fun createXFromOtherFunction(): KTypeParameter =
|
||||||
|
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
|
||||||
|
fun <X> createIrrelevantX(): KTypeParameter =
|
||||||
|
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
|
||||||
|
fun createY(): KTypeParameter =
|
||||||
|
typeOf<Container<Y>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val c = C<Any, Any>()
|
||||||
|
assertEquals(c.x1, c.x2)
|
||||||
|
assertEquals(c.x1.hashCode(), c.x2.hashCode())
|
||||||
|
|
||||||
|
assertNotEquals(c.x1, c.xFun)
|
||||||
|
assertNotEquals(c.x1, c.y)
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.reflect.KTypeParameter
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNotEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
fun <X> createX(): KTypeParameter =
|
||||||
|
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
|
||||||
|
fun <X> createOtherX(): KTypeParameter =
|
||||||
|
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals(createX<Any>(), createX<Any>())
|
||||||
|
assertEquals(createX<Any>().hashCode(), createX<Any>().hashCode())
|
||||||
|
|
||||||
|
assertNotEquals(createX<Any>(), createOtherX<Any>())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+26
@@ -0,0 +1,26 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.KTypeParameter
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
class C<X> {
|
||||||
|
inner class D<Y : X> {
|
||||||
|
fun <Z : Y> createZ(): KTypeParameter =
|
||||||
|
typeOf<Container<Z>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val z = C<Any>().D<Any>().createZ<Any>()
|
||||||
|
assertEquals("Y (Kotlin reflection is not available)", z.upperBounds.joinToString())
|
||||||
|
val y = z.upperBounds.single().classifier as KTypeParameter
|
||||||
|
assertEquals("X (Kotlin reflection is not available)", y.upperBounds.joinToString())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
class C<X> {
|
||||||
|
fun notNull() = typeOf<Container<X>>()
|
||||||
|
fun nullable() = typeOf<Container<X?>>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals("test.Container<X> (Kotlin reflection is not available)", C<Any>().notNull().toString())
|
||||||
|
assertEquals("test.Container<X?> (Kotlin reflection is not available)", C<Any>().nullable().toString())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
fun <X1> notNull() = typeOf<Container<X1>>()
|
||||||
|
fun <X2> nullable() = typeOf<Container<X2?>>()
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals("test.Container<X1> (Kotlin reflection is not available)", notNull<Any>().toString())
|
||||||
|
assertEquals("test.Container<X2?> (Kotlin reflection is not available)", nullable<Any>().toString())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
val <X1> X1.notNull get() = typeOf<Container<X1>>()
|
||||||
|
val <X2> X2.nullable get() = typeOf<Container<X2?>>()
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals("test.Container<X1> (Kotlin reflection is not available)", "".notNull.toString())
|
||||||
|
assertEquals("test.Container<X2?> (Kotlin reflection is not available)", "".nullable.toString())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.*
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
class C<INV, in IN, out OUT> {
|
||||||
|
fun getInv() = typeOf<Container<INV>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
fun getIn() = typeOf<Container<IN>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
fun getOut() = typeOf<Container<OUT>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified X, Y : X> getY() = typeOf<Container<Y>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val c = C<Any, Any, Any>()
|
||||||
|
assertEquals(KVariance.INVARIANT, c.getInv().variance)
|
||||||
|
assertEquals(KVariance.IN, c.getIn().variance)
|
||||||
|
assertEquals(KVariance.OUT, c.getOut().variance)
|
||||||
|
assertEquals(false, c.getInv().isReified)
|
||||||
|
|
||||||
|
val y = getY<Any, Any>()
|
||||||
|
assertEquals(false, y.isReified)
|
||||||
|
val x = y.upperBounds.single().classifier as KTypeParameter
|
||||||
|
assertEquals(true, x.isReified)
|
||||||
|
assertEquals(KVariance.INVARIANT, x.variance)
|
||||||
|
|
||||||
|
assertEquals("INV", c.getInv().toString())
|
||||||
|
assertEquals("in IN", c.getIn().toString())
|
||||||
|
assertEquals("out OUT", c.getOut().toString())
|
||||||
|
assertEquals("X", x.toString())
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.reflect.KTypeParameter
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
class B<W>
|
||||||
|
|
||||||
|
class C<X> {
|
||||||
|
val <Y> B<Y>.createY: KTypeParameter where Y : X
|
||||||
|
get() = typeOf<Container<Y>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
with(C<Any>()) {
|
||||||
|
val y = B<Any>().createY
|
||||||
|
assertEquals("X (Kotlin reflection is not available)", y.upperBounds.joinToString())
|
||||||
|
}
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+30
@@ -0,0 +1,30 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.reflect.KTypeParameter
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
fun <X, Y, Z> test() where X : Y?, Y : List<Z>, Z : Set<String>
|
||||||
|
= typeOf<Container<X>>()
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val type = test<MutableList<Set<String>>?, MutableList<Set<String>>, Set<String>>()
|
||||||
|
assertEquals("test.Container<X> (Kotlin reflection is not available)", type.toString())
|
||||||
|
|
||||||
|
val x = type.arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
assertEquals("Y? (Kotlin reflection is not available)", x.upperBounds.joinToString())
|
||||||
|
|
||||||
|
val y = x.upperBounds.single().classifier as KTypeParameter
|
||||||
|
assertEquals("java.util.List<Z> (Kotlin reflection is not available)", y.upperBounds.joinToString())
|
||||||
|
|
||||||
|
val z = y.upperBounds.single().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
assertEquals("java.util.Set<java.lang.String> (Kotlin reflection is not available)", z.upperBounds.joinToString())
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+21
@@ -0,0 +1,21 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.reflect.KTypeParameter
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
fun <X> test() = typeOf<Container<X>>()
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val type = test<Any>()
|
||||||
|
val x = type.arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
assertEquals("kotlin.Any?", x.upperBounds.joinToString())
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+41
@@ -0,0 +1,41 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.reflect.KTypeParameter
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNotEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
class C<X, Y> {
|
||||||
|
val x1 = createX()
|
||||||
|
val x2 = createXFromOtherFunction()
|
||||||
|
val xFun = createIrrelevantX<Any>()
|
||||||
|
val y = createY()
|
||||||
|
|
||||||
|
fun createX(): KTypeParameter =
|
||||||
|
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
|
||||||
|
fun createXFromOtherFunction(): KTypeParameter =
|
||||||
|
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
|
||||||
|
fun <X> createIrrelevantX(): KTypeParameter =
|
||||||
|
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
|
||||||
|
fun createY(): KTypeParameter =
|
||||||
|
typeOf<Container<Y>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val c = C<Any, Any>()
|
||||||
|
assertEquals(c.x1, c.x2)
|
||||||
|
assertEquals(c.x1.hashCode(), c.x2.hashCode())
|
||||||
|
|
||||||
|
assertNotEquals(c.x1, c.xFun)
|
||||||
|
assertNotEquals(c.x1, c.y)
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.reflect.KTypeParameter
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNotEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
class C<X, Y> {
|
||||||
|
fun createX(): KTypeParameter =
|
||||||
|
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val tp = C::class.typeParameters
|
||||||
|
val c = C<Any, Any>()
|
||||||
|
assertEquals(tp[0], c.createX())
|
||||||
|
assertNotEquals(tp[1], c.createX())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.reflect.KTypeParameter
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertNotEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
fun <X> createX(): KTypeParameter =
|
||||||
|
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
|
||||||
|
fun <X> createOtherX(): KTypeParameter =
|
||||||
|
typeOf<Container<X>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals(createX<Any>(), createX<Any>())
|
||||||
|
assertEquals(createX<Any>().hashCode(), createX<Any>().hashCode())
|
||||||
|
|
||||||
|
assertNotEquals(createX<Any>(), createOtherX<Any>())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.KTypeParameter
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
class C<X> {
|
||||||
|
inner class D<Y : X> {
|
||||||
|
fun <Z : Y> createZ(): KTypeParameter =
|
||||||
|
typeOf<Container<Z>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val z = C<Any>().D<Any>().createZ<Any>()
|
||||||
|
assertEquals("Y", z.upperBounds.joinToString())
|
||||||
|
val y = z.upperBounds.single().classifier as KTypeParameter
|
||||||
|
assertEquals("X", y.upperBounds.joinToString())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+21
@@ -0,0 +1,21 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
class C<X> {
|
||||||
|
fun notNull() = typeOf<Container<X>>()
|
||||||
|
fun nullable() = typeOf<Container<X?>>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals("test.Container<X>", C<Any>().notNull().toString())
|
||||||
|
assertEquals("test.Container<X?>", C<Any>().nullable().toString())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
fun <X1> notNull() = typeOf<Container<X1>>()
|
||||||
|
fun <X2> nullable() = typeOf<Container<X2?>>()
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals("test.Container<X1>", notNull<Any>().toString())
|
||||||
|
assertEquals("test.Container<X2?>", nullable<Any>().toString())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
val <X1> X1.notNull get() = typeOf<Container<X1>>()
|
||||||
|
val <X2> X2.nullable get() = typeOf<Container<X2?>>()
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
assertEquals("test.Container<X1>", "".notNull.toString())
|
||||||
|
assertEquals("test.Container<X2?>", "".nullable.toString())
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
Vendored
+39
@@ -0,0 +1,39 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.*
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
class C<INV, in IN, out OUT> {
|
||||||
|
fun getInv() = typeOf<Container<INV>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
fun getIn() = typeOf<Container<IN>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
fun getOut() = typeOf<Container<OUT>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <reified X, Y : X> getY() = typeOf<Container<Y>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val c = C<Any, Any, Any>()
|
||||||
|
assertEquals(KVariance.INVARIANT, c.getInv().variance)
|
||||||
|
assertEquals(KVariance.IN, c.getIn().variance)
|
||||||
|
assertEquals(KVariance.OUT, c.getOut().variance)
|
||||||
|
assertEquals(false, c.getInv().isReified)
|
||||||
|
|
||||||
|
val y = getY<Any, Any>()
|
||||||
|
assertEquals(false, y.isReified)
|
||||||
|
val x = y.upperBounds.single().classifier as KTypeParameter
|
||||||
|
assertEquals(true, x.isReified)
|
||||||
|
assertEquals(KVariance.INVARIANT, x.variance)
|
||||||
|
|
||||||
|
assertEquals("INV", c.getInv().toString())
|
||||||
|
assertEquals("in IN", c.getIn().toString())
|
||||||
|
assertEquals("out OUT", c.getOut().toString())
|
||||||
|
assertEquals("X", x.toString())
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.reflect.KTypeParameter
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
class B<W>
|
||||||
|
|
||||||
|
class C<X> {
|
||||||
|
val <Y> B<Y>.createY: KTypeParameter where Y : X
|
||||||
|
get() = typeOf<Container<Y>>().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
with(C<Any>()) {
|
||||||
|
val y = B<Any>().createY
|
||||||
|
assertEquals("X", y.upperBounds.joinToString())
|
||||||
|
}
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi
|
||||||
|
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||||
|
// WITH_REFLECT
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
import kotlin.reflect.KTypeParameter
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
class Container<T>
|
||||||
|
|
||||||
|
fun <X, Y, Z> test() where X : Y?, Y : List<Z>, Z : Set<String>
|
||||||
|
= typeOf<Container<X>>()
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val type = test<MutableList<Set<String>>?, MutableList<Set<String>>, Set<String>>()
|
||||||
|
assertEquals("test.Container<X>", type.toString())
|
||||||
|
|
||||||
|
val x = type.arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
assertEquals("Y?", x.upperBounds.joinToString())
|
||||||
|
|
||||||
|
val y = x.upperBounds.single().classifier as KTypeParameter
|
||||||
|
assertEquals("kotlin.collections.List<Z>", y.upperBounds.joinToString())
|
||||||
|
|
||||||
|
val z = y.upperBounds.single().arguments.single().type!!.classifier as KTypeParameter
|
||||||
|
assertEquals("kotlin.collections.Set<kotlin.String>", z.upperBounds.joinToString())
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
@@ -14,15 +14,17 @@ inline fun <reified T> T.causeBug() {
|
|||||||
x is T
|
x is T
|
||||||
x as T
|
x as T
|
||||||
T::class
|
T::class
|
||||||
typeOf<T>()
|
|
||||||
Array<T>(1) { x }
|
Array<T>(1) { x }
|
||||||
|
|
||||||
|
// Non-reified type parameters with recursive bounds are not yet supported
|
||||||
|
// typeOf<T>()
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SomeToImplement<SELF_TVAR>
|
interface SomeToImplement<SELF_TVAR>
|
||||||
|
|
||||||
class Y : SomeToImplement<Y>
|
class Y : SomeToImplement<Y>
|
||||||
|
|
||||||
class Something<T> where T: SomeToImplement<T> {
|
class Something<Z> where Z : SomeToImplement<Z> {
|
||||||
fun op() = causeBug()
|
fun op() = causeBug()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+131
@@ -27242,6 +27242,137 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
public void testTypeReferenceEqualsHashCode() throws Exception {
|
public void testTypeReferenceEqualsHashCode() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/typeReferenceEqualsHashCode.kt");
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/typeReferenceEqualsHashCode.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NonReifiedTypeParameters extends AbstractBlackBoxCodegenTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNonReifiedTypeParameters() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultUpperBound.kt")
|
||||||
|
public void testDefaultUpperBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/defaultUpperBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnClassParameters.kt")
|
||||||
|
public void testEqualsOnClassParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnClassParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnFunctionParameters.kt")
|
||||||
|
public void testEqualsOnFunctionParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnFunctionParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerGeneric.kt")
|
||||||
|
public void testInnerGeneric() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/innerGeneric.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleClassParameter.kt")
|
||||||
|
public void testSimpleClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleFunctionParameter.kt")
|
||||||
|
public void testSimpleFunctionParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleFunctionParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simplePropertyParameter.kt")
|
||||||
|
public void testSimplePropertyParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simplePropertyParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterFlags.kt")
|
||||||
|
public void testTypeParameterFlags() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/typeParameterFlags.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBoundUsesOuterClassParameter.kt")
|
||||||
|
public void testUpperBoundUsesOuterClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBounds.kt")
|
||||||
|
public void testUpperBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBounds.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NonReifiedTypeParameters extends AbstractBlackBoxCodegenTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNonReifiedTypeParameters() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultUpperBound.kt")
|
||||||
|
public void testDefaultUpperBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/defaultUpperBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnClassParameters.kt")
|
||||||
|
public void testEqualsOnClassParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnClassParametersWithReflectAPI.kt")
|
||||||
|
public void testEqualsOnClassParametersWithReflectAPI() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParametersWithReflectAPI.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnFunctionParameters.kt")
|
||||||
|
public void testEqualsOnFunctionParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnFunctionParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerGeneric.kt")
|
||||||
|
public void testInnerGeneric() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/innerGeneric.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleClassParameter.kt")
|
||||||
|
public void testSimpleClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleFunctionParameter.kt")
|
||||||
|
public void testSimpleFunctionParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleFunctionParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simplePropertyParameter.kt")
|
||||||
|
public void testSimplePropertyParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simplePropertyParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterFlags.kt")
|
||||||
|
public void testTypeParameterFlags() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/typeParameterFlags.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBoundUsesOuterClassParameter.kt")
|
||||||
|
public void testUpperBoundUsesOuterClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBounds.kt")
|
||||||
|
public void testUpperBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBounds.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+131
@@ -26059,6 +26059,137 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
public void testTypeReferenceEqualsHashCode() throws Exception {
|
public void testTypeReferenceEqualsHashCode() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/typeReferenceEqualsHashCode.kt");
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/typeReferenceEqualsHashCode.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NonReifiedTypeParameters extends AbstractLightAnalysisModeTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNonReifiedTypeParameters() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultUpperBound.kt")
|
||||||
|
public void testDefaultUpperBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/defaultUpperBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnClassParameters.kt")
|
||||||
|
public void testEqualsOnClassParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnClassParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnFunctionParameters.kt")
|
||||||
|
public void testEqualsOnFunctionParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnFunctionParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerGeneric.kt")
|
||||||
|
public void testInnerGeneric() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/innerGeneric.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleClassParameter.kt")
|
||||||
|
public void testSimpleClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleFunctionParameter.kt")
|
||||||
|
public void testSimpleFunctionParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleFunctionParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simplePropertyParameter.kt")
|
||||||
|
public void testSimplePropertyParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simplePropertyParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterFlags.kt")
|
||||||
|
public void testTypeParameterFlags() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/typeParameterFlags.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBoundUsesOuterClassParameter.kt")
|
||||||
|
public void testUpperBoundUsesOuterClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBounds.kt")
|
||||||
|
public void testUpperBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBounds.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NonReifiedTypeParameters extends AbstractLightAnalysisModeTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNonReifiedTypeParameters() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultUpperBound.kt")
|
||||||
|
public void testDefaultUpperBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/defaultUpperBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnClassParameters.kt")
|
||||||
|
public void testEqualsOnClassParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnClassParametersWithReflectAPI.kt")
|
||||||
|
public void testEqualsOnClassParametersWithReflectAPI() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParametersWithReflectAPI.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnFunctionParameters.kt")
|
||||||
|
public void testEqualsOnFunctionParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnFunctionParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerGeneric.kt")
|
||||||
|
public void testInnerGeneric() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/innerGeneric.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleClassParameter.kt")
|
||||||
|
public void testSimpleClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleFunctionParameter.kt")
|
||||||
|
public void testSimpleFunctionParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleFunctionParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simplePropertyParameter.kt")
|
||||||
|
public void testSimplePropertyParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simplePropertyParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterFlags.kt")
|
||||||
|
public void testTypeParameterFlags() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/typeParameterFlags.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBoundUsesOuterClassParameter.kt")
|
||||||
|
public void testUpperBoundUsesOuterClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBounds.kt")
|
||||||
|
public void testUpperBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBounds.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+131
@@ -25656,6 +25656,137 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
public void testTypeReferenceEqualsHashCode() throws Exception {
|
public void testTypeReferenceEqualsHashCode() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/typeReferenceEqualsHashCode.kt");
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/typeReferenceEqualsHashCode.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NonReifiedTypeParameters extends AbstractIrBlackBoxCodegenTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNonReifiedTypeParameters() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultUpperBound.kt")
|
||||||
|
public void testDefaultUpperBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/defaultUpperBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnClassParameters.kt")
|
||||||
|
public void testEqualsOnClassParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnClassParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnFunctionParameters.kt")
|
||||||
|
public void testEqualsOnFunctionParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnFunctionParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerGeneric.kt")
|
||||||
|
public void testInnerGeneric() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/innerGeneric.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleClassParameter.kt")
|
||||||
|
public void testSimpleClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleFunctionParameter.kt")
|
||||||
|
public void testSimpleFunctionParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleFunctionParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simplePropertyParameter.kt")
|
||||||
|
public void testSimplePropertyParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simplePropertyParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterFlags.kt")
|
||||||
|
public void testTypeParameterFlags() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/typeParameterFlags.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBoundUsesOuterClassParameter.kt")
|
||||||
|
public void testUpperBoundUsesOuterClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBounds.kt")
|
||||||
|
public void testUpperBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBounds.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NonReifiedTypeParameters extends AbstractIrBlackBoxCodegenTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNonReifiedTypeParameters() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultUpperBound.kt")
|
||||||
|
public void testDefaultUpperBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/defaultUpperBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnClassParameters.kt")
|
||||||
|
public void testEqualsOnClassParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnClassParametersWithReflectAPI.kt")
|
||||||
|
public void testEqualsOnClassParametersWithReflectAPI() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParametersWithReflectAPI.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnFunctionParameters.kt")
|
||||||
|
public void testEqualsOnFunctionParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnFunctionParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerGeneric.kt")
|
||||||
|
public void testInnerGeneric() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/innerGeneric.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleClassParameter.kt")
|
||||||
|
public void testSimpleClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleFunctionParameter.kt")
|
||||||
|
public void testSimpleFunctionParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleFunctionParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simplePropertyParameter.kt")
|
||||||
|
public void testSimplePropertyParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simplePropertyParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterFlags.kt")
|
||||||
|
public void testTypeParameterFlags() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/typeParameterFlags.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBoundUsesOuterClassParameter.kt")
|
||||||
|
public void testUpperBoundUsesOuterClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBounds.kt")
|
||||||
|
public void testUpperBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBounds.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,17 @@ internal class KTypeParameterImpl(override val descriptor: TypeParameterDescript
|
|||||||
override fun hashCode() =
|
override fun hashCode() =
|
||||||
descriptor.hashCode()
|
descriptor.hashCode()
|
||||||
|
|
||||||
|
// TODO: this temporarily duplicates TypeParameterReference.toString to prevent JPS build failure until stdlib is bootstrapped
|
||||||
override fun toString() =
|
override fun toString() =
|
||||||
ReflectionObjectRenderer.renderTypeParameter(descriptor)
|
// TypeParameterReference.toString(this)
|
||||||
|
buildString {
|
||||||
|
when (variance) {
|
||||||
|
KVariance.INVARIANT -> {
|
||||||
|
}
|
||||||
|
KVariance.IN -> append("in ")
|
||||||
|
KVariance.OUT -> append("out ")
|
||||||
|
}
|
||||||
|
|
||||||
|
append(name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import java.util.List;
|
|||||||
/**
|
/**
|
||||||
* @suppress
|
* @suppress
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings({"UnusedDeclaration", "unchecked"})
|
@SuppressWarnings({"UnusedDeclaration", "unchecked", "rawtypes"})
|
||||||
public class ReflectionFactoryImpl extends ReflectionFactory {
|
public class ReflectionFactoryImpl extends ReflectionFactory {
|
||||||
@Override
|
@Override
|
||||||
public KClass createKotlinClass(Class javaClass) {
|
public KClass createKotlinClass(Class javaClass) {
|
||||||
@@ -123,6 +123,28 @@ public class ReflectionFactoryImpl extends ReflectionFactory {
|
|||||||
return KClassifiers.createType(klass, arguments, isMarkedNullable, Collections.<Annotation>emptyList());
|
return KClassifiers.createType(klass, arguments, isMarkedNullable, Collections.<Annotation>emptyList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this is a temporary workaround for the JPS build
|
||||||
|
// @Override
|
||||||
|
public KTypeParameter typeParameter(Object container, String name, KVariance variance, boolean isReified) {
|
||||||
|
List<KTypeParameter> typeParameters;
|
||||||
|
if (container instanceof KClass) {
|
||||||
|
typeParameters = ((KClass<?>) container).getTypeParameters();
|
||||||
|
} else if (container instanceof KCallable) {
|
||||||
|
typeParameters = ((KCallable<?>) container).getTypeParameters();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Type parameter container must be a class or a callable: " + container);
|
||||||
|
}
|
||||||
|
for (KTypeParameter typeParameter : typeParameters) {
|
||||||
|
if (typeParameter.getName().equals(name)) return typeParameter;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Type parameter " + name + " is not found in container: " + container);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Override
|
||||||
|
public void setUpperBounds(KTypeParameter typeParameter, List<KType> bounds) {
|
||||||
|
// Do nothing. KTypeParameterImpl implementation will load upper bounds from the metadata.
|
||||||
|
}
|
||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
|
|
||||||
public static void clearCaches() {
|
public static void clearCaches() {
|
||||||
|
|||||||
@@ -16,10 +16,12 @@
|
|||||||
|
|
||||||
package kotlin.reflect.jvm.internal
|
package kotlin.reflect.jvm.internal
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.Variance
|
|
||||||
import kotlin.reflect.KParameter
|
import kotlin.reflect.KParameter
|
||||||
|
|
||||||
internal object ReflectionObjectRenderer {
|
internal object ReflectionObjectRenderer {
|
||||||
@@ -105,19 +107,6 @@ internal object ReflectionObjectRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun renderTypeParameter(typeParameter: TypeParameterDescriptor): String {
|
|
||||||
return buildString {
|
|
||||||
when (typeParameter.variance) {
|
|
||||||
Variance.INVARIANT -> {
|
|
||||||
}
|
|
||||||
Variance.IN_VARIANCE -> append("in ")
|
|
||||||
Variance.OUT_VARIANCE -> append("out ")
|
|
||||||
}
|
|
||||||
|
|
||||||
append(typeParameter.name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun renderType(type: KotlinType): String {
|
fun renderType(type: KotlinType): String {
|
||||||
return renderer.renderType(type)
|
return renderer.renderType(type)
|
||||||
}
|
}
|
||||||
|
|||||||
Generated
+76
@@ -20947,6 +20947,82 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
public void testAllFilesPresentInNoReflect() throws Exception {
|
public void testAllFilesPresentInNoReflect() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/noReflect"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/noReflect"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NonReifiedTypeParameters extends AbstractIrJsCodegenBoxTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNonReifiedTypeParameters() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NonReifiedTypeParameters extends AbstractIrJsCodegenBoxTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNonReifiedTypeParameters() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultUpperBound.kt")
|
||||||
|
public void testDefaultUpperBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/defaultUpperBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnClassParameters.kt")
|
||||||
|
public void testEqualsOnClassParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnFunctionParameters.kt")
|
||||||
|
public void testEqualsOnFunctionParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnFunctionParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerGeneric.kt")
|
||||||
|
public void testInnerGeneric() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/innerGeneric.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleClassParameter.kt")
|
||||||
|
public void testSimpleClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleFunctionParameter.kt")
|
||||||
|
public void testSimpleFunctionParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleFunctionParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simplePropertyParameter.kt")
|
||||||
|
public void testSimplePropertyParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simplePropertyParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterFlags.kt")
|
||||||
|
public void testTypeParameterFlags() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/typeParameterFlags.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBoundUsesOuterClassParameter.kt")
|
||||||
|
public void testUpperBoundUsesOuterClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBounds.kt")
|
||||||
|
public void testUpperBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBounds.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+76
@@ -21007,6 +21007,82 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
public void testAllFilesPresentInNoReflect() throws Exception {
|
public void testAllFilesPresentInNoReflect() throws Exception {
|
||||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/noReflect"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/noReflect"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NonReifiedTypeParameters extends AbstractJsCodegenBoxTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNonReifiedTypeParameters() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class NonReifiedTypeParameters extends AbstractJsCodegenBoxTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInNonReifiedTypeParameters() throws Exception {
|
||||||
|
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("defaultUpperBound.kt")
|
||||||
|
public void testDefaultUpperBound() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/defaultUpperBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnClassParameters.kt")
|
||||||
|
public void testEqualsOnClassParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("equalsOnFunctionParameters.kt")
|
||||||
|
public void testEqualsOnFunctionParameters() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnFunctionParameters.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("innerGeneric.kt")
|
||||||
|
public void testInnerGeneric() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/innerGeneric.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleClassParameter.kt")
|
||||||
|
public void testSimpleClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simpleFunctionParameter.kt")
|
||||||
|
public void testSimpleFunctionParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleFunctionParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("simplePropertyParameter.kt")
|
||||||
|
public void testSimplePropertyParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simplePropertyParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("typeParameterFlags.kt")
|
||||||
|
public void testTypeParameterFlags() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/typeParameterFlags.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBoundUsesOuterClassParameter.kt")
|
||||||
|
public void testUpperBoundUsesOuterClassParameter() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("upperBounds.kt")
|
||||||
|
public void testUpperBounds() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBounds.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import java.util.Collections;
|
|||||||
* This class serves as a facade to the actual reflection implementation. JVM back-end generates calls to static methods of this class
|
* This class serves as a facade to the actual reflection implementation. JVM back-end generates calls to static methods of this class
|
||||||
* on any reflection-using construct.
|
* on any reflection-using construct.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings({"unused", "rawtypes"})
|
||||||
public class Reflection {
|
public class Reflection {
|
||||||
private static final ReflectionFactory factory;
|
private static final ReflectionFactory factory;
|
||||||
|
|
||||||
@@ -117,6 +117,11 @@ public class Reflection {
|
|||||||
|
|
||||||
// typeOf
|
// typeOf
|
||||||
|
|
||||||
|
@SinceKotlin(version = "1.4")
|
||||||
|
public static KType typeOf(KClassifier classifier) {
|
||||||
|
return factory.typeOf(classifier, Collections.<KTypeProjection>emptyList(), false);
|
||||||
|
}
|
||||||
|
|
||||||
@SinceKotlin(version = "1.4")
|
@SinceKotlin(version = "1.4")
|
||||||
public static KType typeOf(Class klass) {
|
public static KType typeOf(Class klass) {
|
||||||
return factory.typeOf(getOrCreateKotlinClass(klass), Collections.<KTypeProjection>emptyList(), false);
|
return factory.typeOf(getOrCreateKotlinClass(klass), Collections.<KTypeProjection>emptyList(), false);
|
||||||
@@ -137,6 +142,11 @@ public class Reflection {
|
|||||||
return factory.typeOf(getOrCreateKotlinClass(klass), ArraysKt.<KTypeProjection>toList(arguments), false);
|
return factory.typeOf(getOrCreateKotlinClass(klass), ArraysKt.<KTypeProjection>toList(arguments), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SinceKotlin(version = "1.4")
|
||||||
|
public static KType nullableTypeOf(KClassifier classifier) {
|
||||||
|
return factory.typeOf(classifier, Collections.<KTypeProjection>emptyList(), true);
|
||||||
|
}
|
||||||
|
|
||||||
@SinceKotlin(version = "1.4")
|
@SinceKotlin(version = "1.4")
|
||||||
public static KType nullableTypeOf(Class klass) {
|
public static KType nullableTypeOf(Class klass) {
|
||||||
return factory.typeOf(getOrCreateKotlinClass(klass), Collections.<KTypeProjection>emptyList(), true);
|
return factory.typeOf(getOrCreateKotlinClass(klass), Collections.<KTypeProjection>emptyList(), true);
|
||||||
@@ -156,4 +166,21 @@ public class Reflection {
|
|||||||
public static KType nullableTypeOf(Class klass, KTypeProjection... arguments) {
|
public static KType nullableTypeOf(Class klass, KTypeProjection... arguments) {
|
||||||
return factory.typeOf(getOrCreateKotlinClass(klass), ArraysKt.<KTypeProjection>toList(arguments), true);
|
return factory.typeOf(getOrCreateKotlinClass(klass), ArraysKt.<KTypeProjection>toList(arguments), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Support of non-reified type parameters for typeOf
|
||||||
|
|
||||||
|
@SinceKotlin(version = "1.4")
|
||||||
|
public static KTypeParameter typeParameter(Object container, String name, KVariance variance, boolean isReified) {
|
||||||
|
return factory.typeParameter(container, name, variance, isReified);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SinceKotlin(version = "1.4")
|
||||||
|
public static void setUpperBounds(KTypeParameter typeParameter, KType bound) {
|
||||||
|
factory.setUpperBounds(typeParameter, Collections.singletonList(bound));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SinceKotlin(version = "1.4")
|
||||||
|
public static void setUpperBounds(KTypeParameter typeParameter, KType... bounds) {
|
||||||
|
factory.setUpperBounds(typeParameter, ArraysKt.toList(bounds));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import kotlin.reflect.*;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
public class ReflectionFactory {
|
public class ReflectionFactory {
|
||||||
private static final String KOTLIN_JVM_FUNCTIONS = "kotlin.jvm.functions.";
|
private static final String KOTLIN_JVM_FUNCTIONS = "kotlin.jvm.functions.";
|
||||||
|
|
||||||
@@ -82,4 +83,14 @@ public class ReflectionFactory {
|
|||||||
public KType typeOf(KClassifier klass, List<KTypeProjection> arguments, boolean isMarkedNullable) {
|
public KType typeOf(KClassifier klass, List<KTypeProjection> arguments, boolean isMarkedNullable) {
|
||||||
return new TypeReference(klass, arguments, isMarkedNullable);
|
return new TypeReference(klass, arguments, isMarkedNullable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SinceKotlin(version = "1.4")
|
||||||
|
public KTypeParameter typeParameter(Object container, String name, KVariance variance, boolean isReified) {
|
||||||
|
return new TypeParameterReference(container, name, variance, isReified);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SinceKotlin(version = "1.4")
|
||||||
|
public void setUpperBounds(KTypeParameter typeParameter, List<KType> bounds) {
|
||||||
|
((TypeParameterReference) typeParameter).setUpperBounds(bounds);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.jvm.internal
|
||||||
|
|
||||||
|
import kotlin.reflect.KType
|
||||||
|
import kotlin.reflect.KTypeParameter
|
||||||
|
import kotlin.reflect.KVariance
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
|
||||||
|
@SinceKotlin("1.4")
|
||||||
|
class TypeParameterReference(
|
||||||
|
private val container: Any?, // Either ClassReference or CallableReference
|
||||||
|
override val name: String,
|
||||||
|
override val variance: KVariance,
|
||||||
|
override val isReified: Boolean,
|
||||||
|
) : KTypeParameter {
|
||||||
|
@Volatile
|
||||||
|
private var bounds: List<KType>? = null
|
||||||
|
|
||||||
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
|
override val upperBounds: List<KType>
|
||||||
|
get() = bounds ?: listOf(typeOf<Any?>()).also { bounds = it }
|
||||||
|
|
||||||
|
fun setUpperBounds(upperBounds: List<KType>) {
|
||||||
|
// This assertion is only checking that the typeOf compiler implementation didn't generate some nonsense in bytecode.
|
||||||
|
// Since this class is not used anywhere else, we don't use any locks to prevent double initialization here intentionally.
|
||||||
|
if (bounds != null) {
|
||||||
|
error("Upper bounds of type parameter '$this' have already been initialized.")
|
||||||
|
}
|
||||||
|
bounds = upperBounds
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean =
|
||||||
|
other is TypeParameterReference && container == other.container && name == other.name
|
||||||
|
|
||||||
|
override fun hashCode(): Int =
|
||||||
|
container.hashCode() * 31 + name.hashCode()
|
||||||
|
|
||||||
|
override fun toString(): String = toString(this)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun toString(typeParameter: KTypeParameter): String =
|
||||||
|
buildString {
|
||||||
|
when (typeParameter.variance) {
|
||||||
|
KVariance.INVARIANT -> {
|
||||||
|
}
|
||||||
|
KVariance.IN -> append("in ")
|
||||||
|
KVariance.OUT -> append("out ")
|
||||||
|
}
|
||||||
|
|
||||||
|
append(typeParameter.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+24
@@ -3927,15 +3927,20 @@ public class kotlin/jvm/internal/Reflection {
|
|||||||
public static fun nullableTypeOf (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;
|
public static fun nullableTypeOf (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;
|
||||||
public static fun nullableTypeOf (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;
|
public static fun nullableTypeOf (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;
|
||||||
public static fun nullableTypeOf (Ljava/lang/Class;[Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;
|
public static fun nullableTypeOf (Ljava/lang/Class;[Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;
|
||||||
|
public static fun nullableTypeOf (Lkotlin/reflect/KClassifier;)Lkotlin/reflect/KType;
|
||||||
public static fun property0 (Lkotlin/jvm/internal/PropertyReference0;)Lkotlin/reflect/KProperty0;
|
public static fun property0 (Lkotlin/jvm/internal/PropertyReference0;)Lkotlin/reflect/KProperty0;
|
||||||
public static fun property1 (Lkotlin/jvm/internal/PropertyReference1;)Lkotlin/reflect/KProperty1;
|
public static fun property1 (Lkotlin/jvm/internal/PropertyReference1;)Lkotlin/reflect/KProperty1;
|
||||||
public static fun property2 (Lkotlin/jvm/internal/PropertyReference2;)Lkotlin/reflect/KProperty2;
|
public static fun property2 (Lkotlin/jvm/internal/PropertyReference2;)Lkotlin/reflect/KProperty2;
|
||||||
public static fun renderLambdaToString (Lkotlin/jvm/internal/FunctionBase;)Ljava/lang/String;
|
public static fun renderLambdaToString (Lkotlin/jvm/internal/FunctionBase;)Ljava/lang/String;
|
||||||
public static fun renderLambdaToString (Lkotlin/jvm/internal/Lambda;)Ljava/lang/String;
|
public static fun renderLambdaToString (Lkotlin/jvm/internal/Lambda;)Ljava/lang/String;
|
||||||
|
public static fun setUpperBounds (Lkotlin/reflect/KTypeParameter;Lkotlin/reflect/KType;)V
|
||||||
|
public static fun setUpperBounds (Lkotlin/reflect/KTypeParameter;[Lkotlin/reflect/KType;)V
|
||||||
public static fun typeOf (Ljava/lang/Class;)Lkotlin/reflect/KType;
|
public static fun typeOf (Ljava/lang/Class;)Lkotlin/reflect/KType;
|
||||||
public static fun typeOf (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;
|
public static fun typeOf (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;
|
||||||
public static fun typeOf (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;
|
public static fun typeOf (Ljava/lang/Class;Lkotlin/reflect/KTypeProjection;Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;
|
||||||
public static fun typeOf (Ljava/lang/Class;[Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;
|
public static fun typeOf (Ljava/lang/Class;[Lkotlin/reflect/KTypeProjection;)Lkotlin/reflect/KType;
|
||||||
|
public static fun typeOf (Lkotlin/reflect/KClassifier;)Lkotlin/reflect/KType;
|
||||||
|
public static fun typeParameter (Ljava/lang/Object;Ljava/lang/String;Lkotlin/reflect/KVariance;Z)Lkotlin/reflect/KTypeParameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class kotlin/jvm/internal/ReflectionFactory {
|
public class kotlin/jvm/internal/ReflectionFactory {
|
||||||
@@ -3954,7 +3959,9 @@ public class kotlin/jvm/internal/ReflectionFactory {
|
|||||||
public fun property2 (Lkotlin/jvm/internal/PropertyReference2;)Lkotlin/reflect/KProperty2;
|
public fun property2 (Lkotlin/jvm/internal/PropertyReference2;)Lkotlin/reflect/KProperty2;
|
||||||
public fun renderLambdaToString (Lkotlin/jvm/internal/FunctionBase;)Ljava/lang/String;
|
public fun renderLambdaToString (Lkotlin/jvm/internal/FunctionBase;)Ljava/lang/String;
|
||||||
public fun renderLambdaToString (Lkotlin/jvm/internal/Lambda;)Ljava/lang/String;
|
public fun renderLambdaToString (Lkotlin/jvm/internal/Lambda;)Ljava/lang/String;
|
||||||
|
public fun setUpperBounds (Lkotlin/reflect/KTypeParameter;Ljava/util/List;)V
|
||||||
public fun typeOf (Lkotlin/reflect/KClassifier;Ljava/util/List;Z)Lkotlin/reflect/KType;
|
public fun typeOf (Lkotlin/reflect/KClassifier;Ljava/util/List;Z)Lkotlin/reflect/KType;
|
||||||
|
public fun typeParameter (Ljava/lang/Object;Ljava/lang/String;Lkotlin/reflect/KVariance;Z)Lkotlin/reflect/KTypeParameter;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class kotlin/jvm/internal/ShortCompanionObject {
|
public final class kotlin/jvm/internal/ShortCompanionObject {
|
||||||
@@ -4027,6 +4034,23 @@ public class kotlin/jvm/internal/TypeIntrinsics {
|
|||||||
public static fun throwCce (Ljava/lang/String;)V
|
public static fun throwCce (Ljava/lang/String;)V
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class kotlin/jvm/internal/TypeParameterReference : kotlin/reflect/KTypeParameter {
|
||||||
|
public static final field Companion Lkotlin/jvm/internal/TypeParameterReference$Companion;
|
||||||
|
public fun <init> (Ljava/lang/Object;Ljava/lang/String;Lkotlin/reflect/KVariance;Z)V
|
||||||
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
public fun getName ()Ljava/lang/String;
|
||||||
|
public fun getUpperBounds ()Ljava/util/List;
|
||||||
|
public fun getVariance ()Lkotlin/reflect/KVariance;
|
||||||
|
public fun hashCode ()I
|
||||||
|
public fun isReified ()Z
|
||||||
|
public final fun setUpperBounds (Ljava/util/List;)V
|
||||||
|
public fun toString ()Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class kotlin/jvm/internal/TypeParameterReference$Companion {
|
||||||
|
public final fun toString (Lkotlin/reflect/KTypeParameter;)Ljava/lang/String;
|
||||||
|
}
|
||||||
|
|
||||||
public final class kotlin/jvm/internal/TypeReference : kotlin/reflect/KType {
|
public final class kotlin/jvm/internal/TypeReference : kotlin/reflect/KType {
|
||||||
public fun <init> (Lkotlin/reflect/KClassifier;Ljava/util/List;Z)V
|
public fun <init> (Lkotlin/reflect/KClassifier;Ljava/util/List;Z)V
|
||||||
public fun equals (Ljava/lang/Object;)Z
|
public fun equals (Ljava/lang/Object;)Z
|
||||||
|
|||||||
Reference in New Issue
Block a user