From 0ce16b9d8c507e1e586741a3d8c35cc41f2cbeaf Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 31 Jan 2020 14:13:11 +0100 Subject: [PATCH] Support non-reified type parameters in typeOf in JVM and JVM_IR #KT-30279 Fixed --- .../kotlin/codegen/MemberCodegen.java | 82 +++++------ .../kotlin/codegen/inline/PsiInlineCodegen.kt | 10 +- .../inline/PsiInlineIntrinsicsSupport.kt | 60 ++++++++ .../codegen/inline/ReifiedTypeInliner.kt | 3 + .../jetbrains/kotlin/codegen/inline/typeOf.kt | 106 ++++++++++++-- .../ir/FirBlackBoxCodegenTestGenerated.java | 131 ++++++++++++++++++ .../kotlin/resolve/jvm/AsmTypes.java | 3 + .../backend/jvm/codegen/ExpressionCodegen.kt | 36 ++--- .../jvm/codegen/IrInlineIntrinsicsSupport.kt | 98 +++++++++++++ .../backend/jvm/intrinsics/SignatureString.kt | 23 +-- .../jvm/lower/FunctionReferenceLowering.kt | 27 ++-- .../jvm/lower/PropertyReferenceLowering.kt | 2 +- .../defaultUpperBound.kt | 21 +++ .../equalsOnClassParameters.kt | 41 ++++++ .../equalsOnFunctionParameters.kt | 26 ++++ .../nonReifiedTypeParameters/innerGeneric.kt | 26 ++++ .../simpleClassParameter.kt | 21 +++ .../simpleFunctionParameter.kt | 19 +++ .../simplePropertyParameter.kt | 19 +++ .../typeParameterFlags.kt | 39 ++++++ .../upperBoundUsesOuterClassParameter.kt | 26 ++++ .../nonReifiedTypeParameters/upperBounds.kt | 30 ++++ .../defaultUpperBound.kt | 21 +++ .../equalsOnClassParameters.kt | 41 ++++++ .../equalsOnClassParametersWithReflectAPI.kt | 25 ++++ .../equalsOnFunctionParameters.kt | 26 ++++ .../nonReifiedTypeParameters/innerGeneric.kt | 26 ++++ .../simpleClassParameter.kt | 21 +++ .../simpleFunctionParameter.kt | 19 +++ .../simplePropertyParameter.kt | 19 +++ .../typeParameterFlags.kt | 39 ++++++ .../upperBoundUsesOuterClassParameter.kt | 26 ++++ .../nonReifiedTypeParameters/upperBounds.kt | 30 ++++ .../reifiedTypeArgumentWithRecursion.kt | 6 +- .../codegen/BlackBoxCodegenTestGenerated.java | 131 ++++++++++++++++++ .../LightAnalysisModeTestGenerated.java | 131 ++++++++++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 131 ++++++++++++++++++ .../jvm/internal/KTypeParameterImpl.kt | 13 +- .../jvm/internal/ReflectionFactoryImpl.java | 24 +++- .../jvm/internal/ReflectionObjectRenderer.kt | 19 +-- .../IrJsCodegenBoxTestGenerated.java | 76 ++++++++++ .../semantics/JsCodegenBoxTestGenerated.java | 76 ++++++++++ .../kotlin/jvm/internal/Reflection.java | 29 +++- .../jvm/internal/ReflectionFactory.java | 11 ++ .../jvm/internal/TypeParameterReference.kt | 57 ++++++++ .../kotlin-stdlib-runtime-merged.txt | 24 ++++ 46 files changed, 1748 insertions(+), 122 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineIntrinsicsSupport.kt create mode 100644 compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineIntrinsicsSupport.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/defaultUpperBound.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnClassParameters.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnFunctionParameters.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/innerGeneric.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleClassParameter.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleFunctionParameter.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simplePropertyParameter.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/typeParameterFlags.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBounds.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/defaultUpperBound.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParameters.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParametersWithReflectAPI.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnFunctionParameters.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/innerGeneric.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleClassParameter.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleFunctionParameter.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simplePropertyParameter.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/typeParameterFlags.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt create mode 100644 compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBounds.kt create mode 100644 libraries/stdlib/jvm/runtime/kotlin/jvm/internal/TypeParameterReference.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java index 752bc8b408a..1250faf800c 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MemberCodegen.java @@ -643,59 +643,61 @@ public abstract class MemberCodegen 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(), "", - 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); - + generatePropertyReference(iv, delegatedProperties.get(i), state); iv.astore(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 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(), "", + 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() { return v.getThisName(); } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt index 85ff9f013bf..6a45b6bf228 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineCodegen.kt @@ -28,7 +28,6 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type -import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.tree.MethodNode class PsiInlineCodegen( @@ -42,15 +41,8 @@ class PsiInlineCodegen( private val actualDispatchReceiver: Type = methodOwner ) : InlineCodegen( codegen, state, function, methodOwner, signature, typeParameterMappings, sourceCompiler, - ReifiedTypeInliner(typeParameterMappings, object : ReifiedTypeInliner.IntrinsicsSupport { - 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) + ReifiedTypeInliner(typeParameterMappings, PsiInlineIntrinsicsSupport(state), codegen.typeSystem, state.languageVersionSettings), ), CallGenerator { - override fun generateAssertFieldIfNeeded(info: RootInliningContext) { if (info.generateAssertField) { codegen.parentCodegen.generateAssertField() diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineIntrinsicsSupport.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineIntrinsicsSupport.kt new file mode 100644 index 00000000000..3662688b75d --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/PsiInlineIntrinsicsSupport.kt @@ -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 { + 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, "", + 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 +} diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt index 397f3273493..98e4b9be3d8 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/ReifiedTypeInliner.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods import org.jetbrains.kotlin.codegen.optimization.common.intConstant import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.config.isReleaseCoroutines +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.resolve.jvm.AsmTypes import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext @@ -63,6 +64,8 @@ class ReifiedTypeInliner( interface IntrinsicsSupport { fun putClassInstance(v: InstructionAdapter, type: KT) + fun generateTypeParameterContainer(v: InstructionAdapter, typeParameter: TypeParameterMarker) + fun toKotlinType(type: KT): KotlinType } diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/typeOf.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/typeOf.kt index 7260232e336..7502ef7f9df 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/typeOf.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/inline/typeOf.kt @@ -16,6 +16,7 @@ import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter import org.jetbrains.org.objectweb.asm.tree.MethodNode +import kotlin.reflect.KVariance internal fun TypeSystemCommonBackendContext.createTypeOfMethodBody(typeParameter: TypeParameterMarker): MethodNode { 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 TypeSystemCommonBackendContext.generateTypeOf( v: InstructionAdapter, type: KT, intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport ) { - 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 useArray = argumentsSize >= 3 @@ -64,17 +76,87 @@ internal fun TypeSystemCommonBackendContext.generateType val methodName = if (type.isMarkedNullable()) "nullableTypeOf" else "typeOf" - val projections = when (argumentsSize) { - 0 -> emptyArray() - 1 -> arrayOf(K_TYPE_PROJECTION) - 2 -> arrayOf(K_TYPE_PROJECTION, K_TYPE_PROJECTION) - else -> arrayOf(AsmUtil.getArrayType(K_TYPE_PROJECTION)) + val signature = if (typeParameter != null) { + Type.getMethodDescriptor(K_TYPE, K_CLASSIFIER_TYPE) + } else { + val projections = when (argumentsSize) { + 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) } +private fun TypeSystemCommonBackendContext.generateNonReifiedTypeParameter( + v: InstructionAdapter, typeParameter: TypeParameterMarker, intrinsicsSupport: ReifiedTypeInliner.IntrinsicsSupport +) { + 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 = 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 TypeSystemCommonBackendContext.doGenerateTypeProjection( v: InstructionAdapter, projection: TypeArgumentMarker, @@ -91,14 +173,8 @@ private fun TypeSystemCommonBackendContext.doGenerateTyp @Suppress("UNCHECKED_CAST") val type = projection.getType() as KT val typeParameterClassifier = type.typeConstructor().getTypeParameterClassifier() - if (typeParameterClassifier != null) { - if (typeParameterClassifier.isReified()) { - putTypeOfReifiedTypeParameter(v, typeParameterClassifier, type.isMarkedNullable()) - } else { - // TODO: support non-reified type parameters in typeOf - @Suppress("UNCHECKED_CAST") - generateTypeOf(v, nullableAnyType() as KT, intrinsicsSupport) - } + if (typeParameterClassifier != null && typeParameterClassifier.isReified()) { + putTypeOfReifiedTypeParameter(v, typeParameterClassifier, type.isMarkedNullable()) } else { generateTypeOf(v, type, intrinsicsSupport) } diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index 81b47a4b539..b42479d4492 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -25656,6 +25656,137 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT public void testTypeReferenceEqualsHashCode() throws Exception { 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"); + } } } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/AsmTypes.java b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/AsmTypes.java index 79b64cd8056..a1ee0d0be09 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/AsmTypes.java +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/AsmTypes.java @@ -58,6 +58,7 @@ public class AsmTypes { 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_CLASSIFIER_TYPE = reflect("KClassifier"); public static final Type K_DECLARATION_CONTAINER_TYPE = reflect("KDeclarationContainer"); 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_PROJECTION = reflect("KTypeProjection"); 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"); diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index fd8ed0aabd0..e6e2777c9a9 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -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.jvmSignature.JvmMethodParameterKind 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.model.TypeParameterMarker import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull @@ -1084,7 +1083,7 @@ class ExpressionCodegen( putReifiedOperationMarkerIfTypeIsReifiedParameter(classType, ReifiedTypeInliner.OperationKind.JAVA_CLASS) } - generateClassInstance(mv, classType) + generateClassInstance(mv, classType, typeMapper) } else { throw AssertionError("not an IrGetClass or IrClassReference: ${classReference.dump()}") } @@ -1095,15 +1094,6 @@ class ExpressionCodegen( 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( element: IrFunctionAccessExpression, data: BlockInfo, signature: JvmMethodSignature ): IrCallGenerator { @@ -1144,13 +1134,12 @@ class ExpressionCodegen( val methodOwner = typeMapper.mapClass(callee.parentAsClass) val sourceCompiler = IrSourceCompilerForInline(state, element, callee, this, data) - val reifiedTypeInliner = ReifiedTypeInliner(mappings, object : ReifiedTypeInliner.IntrinsicsSupport { - override fun putClassInstance(v: InstructionAdapter, type: IrType) { - generateClassInstance(v, type) - } - - override fun toKotlinType(type: IrType): KotlinType = type.toKotlinType() - }, IrTypeCheckerContext(context.irBuiltIns), state.languageVersionSettings) + val reifiedTypeInliner = ReifiedTypeInliner( + mappings, + IrInlineIntrinsicsSupport(context, typeMapper), + IrTypeCheckerContext(context.irBuiltIns), + state.languageVersionSettings + ) return IrInlineCodegen(this, state, callee, methodOwner, signature, mappings, sourceCompiler, reifiedTypeInliner) } @@ -1208,4 +1197,15 @@ class ExpressionCodegen( val IrType.isReifiedTypeParameter: Boolean get() = this.classifierOrNull?.safeAs()?.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;") + } + } + } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineIntrinsicsSupport.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineIntrinsicsSupport.kt new file mode 100644 index 00000000000..97af9b0ef88 --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineIntrinsicsSupport.kt @@ -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 { + 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, "", + Type.getMethodDescriptor(VOID_TYPE, *parameterTypes.toTypedArray()), + false + ) + } + + override fun toKotlinType(type: IrType): KotlinType = type.toKotlinType() +} diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/SignatureString.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/SignatureString.kt index 28eae435167..7f1247e3ed7 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/SignatureString.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/SignatureString.kt @@ -5,18 +5,19 @@ 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.ExpressionCodegen import org.jetbrains.kotlin.backend.jvm.codegen.MaterialValue 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.expressions.IrFunctionAccessExpression 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.isSuspend 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 @@ -25,13 +26,17 @@ import org.jetbrains.org.objectweb.asm.Type object SignatureString : IntrinsicMethod() { override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue { val function = (expression.getValueArgument(0) as IrFunctionReference).symbol.owner - var resolved = if (function is IrSimpleFunction) function.collectRealOverrides().first() else function - 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) + generateSignatureString(codegen.mv, function, codegen.context) 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) + } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt index 6aeec2ec748..a3108578fc4 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/FunctionReferenceLowering.kt @@ -337,7 +337,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext) } 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() 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 = - kClassReference( - if (irContainer is IrClass) irContainer.defaultType - else { - // For built-in members (i.e. top level `toString`) we generate reference to an internal class for an owner. - // 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 - } - ) + kClassReference(getOwnerKClassType(irContainer, context)) + + internal fun getOwnerKClassType(irContainer: IrDeclarationParent, context: JvmBackendContext): IrType = + if (irContainer is IrClass) irContainer.defaultType + else { + // For built-in members (i.e. top level `toString`) we generate reference to an internal class for an owner. + // 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 } } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt index d934f30ee18..6e76d51bcd2 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt @@ -393,7 +393,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class putValueArgument(index++, kClassToJavaClass(owner, backendContext)) putValueArgument(index++, irString(expression.symbol.descriptor.name.asString())) 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) } diff --git a/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/defaultUpperBound.kt b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/defaultUpperBound.kt new file mode 100644 index 00000000000..c50e949d5bc --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/defaultUpperBound.kt @@ -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 + +fun test() = typeOf>() + +fun box(): String { + val type = test() + val x = type.arguments.single().type!!.classifier as KTypeParameter + assertEquals("java.lang.Object? (Kotlin reflection is not available)", x.upperBounds.joinToString()) + + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnClassParameters.kt b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnClassParameters.kt new file mode 100644 index 00000000000..09814866362 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnClassParameters.kt @@ -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 + +class C { + val x1 = createX() + val x2 = createXFromOtherFunction() + val xFun = createIrrelevantX() + val y = createY() + + fun createX(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter + + fun createXFromOtherFunction(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter + + fun createIrrelevantX(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter + + fun createY(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter +} + +fun box(): String { + val c = C() + assertEquals(c.x1, c.x2) + assertEquals(c.x1.hashCode(), c.x2.hashCode()) + + assertNotEquals(c.x1, c.xFun) + assertNotEquals(c.x1, c.y) + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnFunctionParameters.kt b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnFunctionParameters.kt new file mode 100644 index 00000000000..9624259d3cb --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/equalsOnFunctionParameters.kt @@ -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 + +fun createX(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter + +fun createOtherX(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter + +fun box(): String { + assertEquals(createX(), createX()) + assertEquals(createX().hashCode(), createX().hashCode()) + + assertNotEquals(createX(), createOtherX()) + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/innerGeneric.kt b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/innerGeneric.kt new file mode 100644 index 00000000000..bae963c80b5 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/innerGeneric.kt @@ -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 + +class C { + inner class D { + fun createZ(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter + } +} + +fun box(): String { + val z = C().D().createZ() + 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" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleClassParameter.kt b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleClassParameter.kt new file mode 100644 index 00000000000..9510f235cba --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleClassParameter.kt @@ -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 + +class C { + fun notNull() = typeOf>() + fun nullable() = typeOf>() +} + +fun box(): String { + assertEquals("test.Container (Kotlin reflection is not available)", C().notNull().toString()) + assertEquals("test.Container (Kotlin reflection is not available)", C().nullable().toString()) + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleFunctionParameter.kt b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleFunctionParameter.kt new file mode 100644 index 00000000000..7fe911e8808 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simpleFunctionParameter.kt @@ -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 + +fun notNull() = typeOf>() +fun nullable() = typeOf>() + +fun box(): String { + assertEquals("test.Container (Kotlin reflection is not available)", notNull().toString()) + assertEquals("test.Container (Kotlin reflection is not available)", nullable().toString()) + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simplePropertyParameter.kt b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simplePropertyParameter.kt new file mode 100644 index 00000000000..ff2e20beae1 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/simplePropertyParameter.kt @@ -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 + +val X1.notNull get() = typeOf>() +val X2.nullable get() = typeOf>() + +fun box(): String { + assertEquals("test.Container (Kotlin reflection is not available)", "".notNull.toString()) + assertEquals("test.Container (Kotlin reflection is not available)", "".nullable.toString()) + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/typeParameterFlags.kt b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/typeParameterFlags.kt new file mode 100644 index 00000000000..0be0ef84118 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/typeParameterFlags.kt @@ -0,0 +1,39 @@ +// !USE_EXPERIMENTAL: kotlin.ExperimentalStdlibApi +// TARGET_BACKEND: JVM +// WITH_RUNTIME + +package test + +import kotlin.reflect.* +import kotlin.test.assertEquals + +class Container + +class C { + fun getInv() = typeOf>().arguments.single().type!!.classifier as KTypeParameter + fun getIn() = typeOf>().arguments.single().type!!.classifier as KTypeParameter + fun getOut() = typeOf>().arguments.single().type!!.classifier as KTypeParameter +} + +inline fun getY() = typeOf>().arguments.single().type!!.classifier as KTypeParameter + +fun box(): String { + val c = C() + 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() + 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" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt new file mode 100644 index 00000000000..f433bf7d2b7 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt @@ -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 + +class B + +class C { + val B.createY: KTypeParameter where Y : X + get() = typeOf>().arguments.single().type!!.classifier as KTypeParameter +} + +fun box(): String { + with(C()) { + val y = B().createY + assertEquals("X (Kotlin reflection is not available)", y.upperBounds.joinToString()) + } + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBounds.kt b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBounds.kt new file mode 100644 index 00000000000..ffff7739d63 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/noReflect/nonReifiedTypeParameters/upperBounds.kt @@ -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 + +fun test() where X : Y?, Y : List, Z : Set + = typeOf>() + +fun box(): String { + val type = test>?, MutableList>, Set>() + assertEquals("test.Container (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 (Kotlin reflection is not available)", y.upperBounds.joinToString()) + + val z = y.upperBounds.single().arguments.single().type!!.classifier as KTypeParameter + assertEquals("java.util.Set (Kotlin reflection is not available)", z.upperBounds.joinToString()) + + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/defaultUpperBound.kt b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/defaultUpperBound.kt new file mode 100644 index 00000000000..e408ad43f4f --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/defaultUpperBound.kt @@ -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 + +fun test() = typeOf>() + +fun box(): String { + val type = test() + val x = type.arguments.single().type!!.classifier as KTypeParameter + assertEquals("kotlin.Any?", x.upperBounds.joinToString()) + + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParameters.kt b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParameters.kt new file mode 100644 index 00000000000..0ef9b673514 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParameters.kt @@ -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 + +class C { + val x1 = createX() + val x2 = createXFromOtherFunction() + val xFun = createIrrelevantX() + val y = createY() + + fun createX(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter + + fun createXFromOtherFunction(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter + + fun createIrrelevantX(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter + + fun createY(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter +} + +fun box(): String { + val c = C() + assertEquals(c.x1, c.x2) + assertEquals(c.x1.hashCode(), c.x2.hashCode()) + + assertNotEquals(c.x1, c.xFun) + assertNotEquals(c.x1, c.y) + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParametersWithReflectAPI.kt b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParametersWithReflectAPI.kt new file mode 100644 index 00000000000..4f4e7da1efc --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnClassParametersWithReflectAPI.kt @@ -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 + +class C { + fun createX(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter +} + +fun box(): String { + val tp = C::class.typeParameters + val c = C() + assertEquals(tp[0], c.createX()) + assertNotEquals(tp[1], c.createX()) + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnFunctionParameters.kt b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnFunctionParameters.kt new file mode 100644 index 00000000000..e37cf0d7c3e --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/equalsOnFunctionParameters.kt @@ -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 + +fun createX(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter + +fun createOtherX(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter + +fun box(): String { + assertEquals(createX(), createX()) + assertEquals(createX().hashCode(), createX().hashCode()) + + assertNotEquals(createX(), createOtherX()) + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/innerGeneric.kt b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/innerGeneric.kt new file mode 100644 index 00000000000..698f1c0f45b --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/innerGeneric.kt @@ -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 + +class C { + inner class D { + fun createZ(): KTypeParameter = + typeOf>().arguments.single().type!!.classifier as KTypeParameter + } +} + +fun box(): String { + val z = C().D().createZ() + assertEquals("Y", z.upperBounds.joinToString()) + val y = z.upperBounds.single().classifier as KTypeParameter + assertEquals("X", y.upperBounds.joinToString()) + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleClassParameter.kt b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleClassParameter.kt new file mode 100644 index 00000000000..7b72f674104 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleClassParameter.kt @@ -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 + +class C { + fun notNull() = typeOf>() + fun nullable() = typeOf>() +} + +fun box(): String { + assertEquals("test.Container", C().notNull().toString()) + assertEquals("test.Container", C().nullable().toString()) + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleFunctionParameter.kt b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleFunctionParameter.kt new file mode 100644 index 00000000000..2b5e12b5fed --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simpleFunctionParameter.kt @@ -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 + +fun notNull() = typeOf>() +fun nullable() = typeOf>() + +fun box(): String { + assertEquals("test.Container", notNull().toString()) + assertEquals("test.Container", nullable().toString()) + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simplePropertyParameter.kt b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simplePropertyParameter.kt new file mode 100644 index 00000000000..e0e496e7de5 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/simplePropertyParameter.kt @@ -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 + +val X1.notNull get() = typeOf>() +val X2.nullable get() = typeOf>() + +fun box(): String { + assertEquals("test.Container", "".notNull.toString()) + assertEquals("test.Container", "".nullable.toString()) + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/typeParameterFlags.kt b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/typeParameterFlags.kt new file mode 100644 index 00000000000..28f527179f9 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/typeParameterFlags.kt @@ -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 + +class C { + fun getInv() = typeOf>().arguments.single().type!!.classifier as KTypeParameter + fun getIn() = typeOf>().arguments.single().type!!.classifier as KTypeParameter + fun getOut() = typeOf>().arguments.single().type!!.classifier as KTypeParameter +} + +inline fun getY() = typeOf>().arguments.single().type!!.classifier as KTypeParameter + +fun box(): String { + val c = C() + 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() + 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" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt new file mode 100644 index 00000000000..17375113a31 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBoundUsesOuterClassParameter.kt @@ -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 + +class B + +class C { + val B.createY: KTypeParameter where Y : X + get() = typeOf>().arguments.single().type!!.classifier as KTypeParameter +} + +fun box(): String { + with(C()) { + val y = B().createY + assertEquals("X", y.upperBounds.joinToString()) + } + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBounds.kt b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBounds.kt new file mode 100644 index 00000000000..19438e26ac4 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/typeOf/nonReifiedTypeParameters/upperBounds.kt @@ -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 + +fun test() where X : Y?, Y : List, Z : Set + = typeOf>() + +fun box(): String { + val type = test>?, MutableList>, Set>() + assertEquals("test.Container", 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", y.upperBounds.joinToString()) + + val z = y.upperBounds.single().arguments.single().type!!.classifier as KTypeParameter + assertEquals("kotlin.collections.Set", z.upperBounds.joinToString()) + + return "OK" +} diff --git a/compiler/testData/codegen/box/reified/reifiedTypeArgumentWithRecursion.kt b/compiler/testData/codegen/box/reified/reifiedTypeArgumentWithRecursion.kt index f9c06193474..9e1c64a26fe 100644 --- a/compiler/testData/codegen/box/reified/reifiedTypeArgumentWithRecursion.kt +++ b/compiler/testData/codegen/box/reified/reifiedTypeArgumentWithRecursion.kt @@ -14,15 +14,17 @@ inline fun T.causeBug() { x is T x as T T::class - typeOf() Array(1) { x } + + // Non-reified type parameters with recursive bounds are not yet supported + // typeOf() } interface SomeToImplement class Y : SomeToImplement -class Something where T: SomeToImplement { +class Something where Z : SomeToImplement { fun op() = causeBug() } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 2657c3c1f65..3441a6d5db4 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -27242,6 +27242,137 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testTypeReferenceEqualsHashCode() throws Exception { 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"); + } } } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 0e641e59fa9..2e07de62225 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -26059,6 +26059,137 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testTypeReferenceEqualsHashCode() throws Exception { 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"); + } } } diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index e37f6f5aa21..5b9835aeb52 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -25656,6 +25656,137 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes public void testTypeReferenceEqualsHashCode() throws Exception { 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"); + } } } diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KTypeParameterImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KTypeParameterImpl.kt index e9795712ecd..56460e1519c 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KTypeParameterImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KTypeParameterImpl.kt @@ -50,6 +50,17 @@ internal class KTypeParameterImpl(override val descriptor: TypeParameterDescript override fun hashCode() = descriptor.hashCode() + // TODO: this temporarily duplicates TypeParameterReference.toString to prevent JPS build failure until stdlib is bootstrapped override fun toString() = - ReflectionObjectRenderer.renderTypeParameter(descriptor) + // TypeParameterReference.toString(this) + buildString { + when (variance) { + KVariance.INVARIANT -> { + } + KVariance.IN -> append("in ") + KVariance.OUT -> append("out ") + } + + append(name) + } } diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionFactoryImpl.java b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionFactoryImpl.java index 97b01a90506..7eede5b00f1 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionFactoryImpl.java +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionFactoryImpl.java @@ -28,7 +28,7 @@ import java.util.List; /** * @suppress */ -@SuppressWarnings({"UnusedDeclaration", "unchecked"}) +@SuppressWarnings({"UnusedDeclaration", "unchecked", "rawtypes"}) public class ReflectionFactoryImpl extends ReflectionFactory { @Override public KClass createKotlinClass(Class javaClass) { @@ -123,6 +123,28 @@ public class ReflectionFactoryImpl extends ReflectionFactory { return KClassifiers.createType(klass, arguments, isMarkedNullable, Collections.emptyList()); } + // TODO: this is a temporary workaround for the JPS build + // @Override + public KTypeParameter typeParameter(Object container, String name, KVariance variance, boolean isReified) { + List 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 bounds) { + // Do nothing. KTypeParameterImpl implementation will load upper bounds from the metadata. + } + // Misc public static void clearCaches() { diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionObjectRenderer.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionObjectRenderer.kt index d171c01f1b8..684e0682930 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionObjectRenderer.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionObjectRenderer.kt @@ -16,10 +16,12 @@ 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.types.KotlinType -import org.jetbrains.kotlin.types.Variance import kotlin.reflect.KParameter 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 { return renderer.renderType(type) } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 51def9310e1..fb366e8f6bd 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -20947,6 +20947,82 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { 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); } + + @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"); + } } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 25e6368646c..5a923ba16b3 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -21007,6 +21007,82 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { 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); } + + @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"); + } } } diff --git a/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Reflection.java b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Reflection.java index c51a6965828..af4492ed19d 100644 --- a/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Reflection.java +++ b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/Reflection.java @@ -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 * on any reflection-using construct. */ -@SuppressWarnings("unused") +@SuppressWarnings({"unused", "rawtypes"}) public class Reflection { private static final ReflectionFactory factory; @@ -117,6 +117,11 @@ public class Reflection { // typeOf + @SinceKotlin(version = "1.4") + public static KType typeOf(KClassifier classifier) { + return factory.typeOf(classifier, Collections.emptyList(), false); + } + @SinceKotlin(version = "1.4") public static KType typeOf(Class klass) { return factory.typeOf(getOrCreateKotlinClass(klass), Collections.emptyList(), false); @@ -137,6 +142,11 @@ public class Reflection { return factory.typeOf(getOrCreateKotlinClass(klass), ArraysKt.toList(arguments), false); } + @SinceKotlin(version = "1.4") + public static KType nullableTypeOf(KClassifier classifier) { + return factory.typeOf(classifier, Collections.emptyList(), true); + } + @SinceKotlin(version = "1.4") public static KType nullableTypeOf(Class klass) { return factory.typeOf(getOrCreateKotlinClass(klass), Collections.emptyList(), true); @@ -156,4 +166,21 @@ public class Reflection { public static KType nullableTypeOf(Class klass, KTypeProjection... arguments) { return factory.typeOf(getOrCreateKotlinClass(klass), ArraysKt.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)); + } } diff --git a/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/ReflectionFactory.java b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/ReflectionFactory.java index abd80fe57c7..33bd42d3d48 100644 --- a/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/ReflectionFactory.java +++ b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/ReflectionFactory.java @@ -10,6 +10,7 @@ import kotlin.reflect.*; import java.util.List; +@SuppressWarnings("rawtypes") public class ReflectionFactory { private static final String KOTLIN_JVM_FUNCTIONS = "kotlin.jvm.functions."; @@ -82,4 +83,14 @@ public class ReflectionFactory { public KType typeOf(KClassifier klass, List arguments, boolean 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 bounds) { + ((TypeParameterReference) typeParameter).setUpperBounds(bounds); + } } diff --git a/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/TypeParameterReference.kt b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/TypeParameterReference.kt new file mode 100644 index 00000000000..7f469e1d0fc --- /dev/null +++ b/libraries/stdlib/jvm/runtime/kotlin/jvm/internal/TypeParameterReference.kt @@ -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? = null + + @OptIn(ExperimentalStdlibApi::class) + override val upperBounds: List + get() = bounds ?: listOf(typeOf()).also { bounds = it } + + fun setUpperBounds(upperBounds: List) { + // 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) + } + } +} diff --git a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt index 39f4bac1f57..b561882f46a 100644 --- a/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt +++ b/libraries/tools/binary-compatibility-validator/reference-public-api/kotlin-stdlib-runtime-merged.txt @@ -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/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 property1 (Lkotlin/jvm/internal/PropertyReference1;)Lkotlin/reflect/KProperty1; 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/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/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 (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 { @@ -3954,7 +3959,9 @@ public class kotlin/jvm/internal/ReflectionFactory { 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/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 typeParameter (Ljava/lang/Object;Ljava/lang/String;Lkotlin/reflect/KVariance;Z)Lkotlin/reflect/KTypeParameter; } 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 final class kotlin/jvm/internal/TypeParameterReference : kotlin/reflect/KTypeParameter { + public static final field Companion Lkotlin/jvm/internal/TypeParameterReference$Companion; + public fun (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 fun (Lkotlin/reflect/KClassifier;Ljava/util/List;Z)V public fun equals (Ljava/lang/Object;)Z