Reflection: create synthetic classes instead of throwing UOE
... for Kotlin-generated classes which do not correspond to a "class" from the Kotlin language's point of view. For example, Kotlin lambdas, file facade classes, multifile class facade/part classes, WhenMappings, DefaultImpls. They can be distinguished from normal classes by the value of `KotlinClassHeader.Kind` (which is the same as `Metadata.kind`). Another theoretical option would be to throw exception at the point where the `::class` expression is used, if the expression's type on the left-hand side is a synthetic class. But we can't really do that since it'll affect performance of most `<expression>::class` expressions. So, construct a fake synthetic class instead, without any members except equals/hashCode/toString, and without any non-trivial modifiers. It kind of contradicts the general idea that kotlin-reflect presents anything exactly the same as the compiler sees it, but arguably it's worth it to avoid unexpected exceptions like in KT-41373. In the newly added test, Java lambda check is muted but it should work exactly the same as for Kotlin lambdas and other synthetic classes. It's fixed in a subsequent commit. #KT-41373 In Progress
This commit is contained in:
committed by
Space Team
parent
d833b732c9
commit
5dc882abf5
+16
@@ -46693,6 +46693,22 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class SyntheticClasses {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticClasses.kt")
|
||||||
|
public void testSyntheticClasses() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/syntheticClasses/syntheticClasses.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+16
@@ -46693,6 +46693,22 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class SyntheticClasses {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticClasses.kt")
|
||||||
|
public void testSyntheticClasses() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/syntheticClasses/syntheticClasses.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+124
@@ -0,0 +1,124 @@
|
|||||||
|
// TARGET_BACKEND: JVM
|
||||||
|
// WITH_REFLECT
|
||||||
|
// JVM_TARGET: 1.8
|
||||||
|
// FILE: syntheticClasses.kt
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
import kotlin.reflect.*
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
fun check(x: KClass<*>) {
|
||||||
|
assertEquals(setOf("equals", "hashCode", "toString"), x.members.mapTo(hashSetOf()) { it.name })
|
||||||
|
|
||||||
|
assertEquals(emptyList(), x.annotations)
|
||||||
|
assertEquals(emptyList(), x.constructors)
|
||||||
|
assertEquals(emptyList(), x.nestedClasses)
|
||||||
|
assertEquals(null, x.objectInstance)
|
||||||
|
assertEquals(listOf(typeOf<Any>()), x.supertypes)
|
||||||
|
assertEquals(emptyList(), x.sealedSubclasses)
|
||||||
|
|
||||||
|
assertEquals(KVisibility.PUBLIC, x.visibility)
|
||||||
|
assertTrue(x.isFinal)
|
||||||
|
assertFalse(x.isOpen)
|
||||||
|
assertFalse(x.isAbstract)
|
||||||
|
assertFalse(x.isSealed)
|
||||||
|
assertFalse(x.isData)
|
||||||
|
assertFalse(x.isInner)
|
||||||
|
assertFalse(x.isCompanion)
|
||||||
|
assertFalse(x.isFun)
|
||||||
|
assertFalse(x.isValue)
|
||||||
|
|
||||||
|
assertFalse(x.isInstance(42))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkFileClass() {
|
||||||
|
val fileClass = Class.forName("test.SyntheticClassesKt").kotlin
|
||||||
|
assertEquals("SyntheticClassesKt", fileClass.simpleName)
|
||||||
|
assertEquals("test.SyntheticClassesKt", fileClass.qualifiedName)
|
||||||
|
check(fileClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkMultifileClass() {
|
||||||
|
val klass = Class.forName("test.MultifileClass").kotlin
|
||||||
|
assertEquals("MultifileClass", klass.simpleName)
|
||||||
|
assertEquals("test.MultifileClass", klass.qualifiedName)
|
||||||
|
check(klass)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkMultifileClassPart() {
|
||||||
|
val klass = Class.forName("test.MultifileClass__Multifile1Kt").kotlin
|
||||||
|
assertEquals("MultifileClass__Multifile1Kt", klass.simpleName)
|
||||||
|
assertEquals("test.MultifileClass__Multifile1Kt", klass.qualifiedName)
|
||||||
|
check(klass)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkKotlinLambda() {
|
||||||
|
// Annotate with @JvmSerializableLambda to prevent the lambda from being generated via invokedynamic.
|
||||||
|
val lambda = @JvmSerializableLambda {}
|
||||||
|
val klass = lambda::class
|
||||||
|
|
||||||
|
// isAnonymousClass/simpleName behavior is different for Kotlin anonymous classes in JDK 1.8 and 9+, see KT-23072.
|
||||||
|
if (klass.java.isAnonymousClass) {
|
||||||
|
assertEquals(null, klass.simpleName)
|
||||||
|
} else {
|
||||||
|
assertEquals("lambda\$1", klass.simpleName)
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(null, klass.qualifiedName)
|
||||||
|
check(klass)
|
||||||
|
|
||||||
|
assertTrue(klass.isInstance(lambda))
|
||||||
|
assertNotEquals(klass, (@JvmSerializableLambda {})::class)
|
||||||
|
val equals = klass.members.single { it.name == "equals" } as KFunction<Boolean>
|
||||||
|
assertTrue(equals.call(lambda, lambda))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun checkJavaLambda() {
|
||||||
|
val lambda = JavaClass.lambda()
|
||||||
|
val klass = lambda::class
|
||||||
|
check(klass)
|
||||||
|
|
||||||
|
assertTrue(klass.isInstance(lambda))
|
||||||
|
assertNotEquals(klass, Runnable {}::class)
|
||||||
|
val equals = klass.members.single { it.name == "equals" } as KFunction<Boolean>
|
||||||
|
assertTrue(equals.call(lambda, lambda))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
checkFileClass()
|
||||||
|
checkMultifileClass()
|
||||||
|
checkMultifileClassPart()
|
||||||
|
checkKotlinLambda()
|
||||||
|
|
||||||
|
// TODO: fails with KotlinReflectionInternalError: Unresolved class: class JavaClass$$Lambda$1166/180251002 (kind = null)
|
||||||
|
// checkJavaLambda()
|
||||||
|
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: JavaClass.java
|
||||||
|
|
||||||
|
public class JavaClass {
|
||||||
|
public static Runnable lambda() {
|
||||||
|
return () -> {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Multifile1.kt
|
||||||
|
|
||||||
|
@file:JvmName("MultifileClass")
|
||||||
|
@file:JvmMultifileClass
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun f() {}
|
||||||
|
|
||||||
|
// FILE: Multifile2.kt
|
||||||
|
|
||||||
|
@file:JvmName("MultifileClass")
|
||||||
|
@file:JvmMultifileClass
|
||||||
|
|
||||||
|
package test
|
||||||
|
|
||||||
|
fun g() {}
|
||||||
+16
@@ -43987,6 +43987,22 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class SyntheticClasses {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticClasses.kt")
|
||||||
|
public void testSyntheticClasses() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/syntheticClasses/syntheticClasses.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+16
@@ -46693,6 +46693,22 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class SyntheticClasses {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticClasses.kt")
|
||||||
|
public void testSyntheticClasses() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/syntheticClasses/syntheticClasses.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+16
@@ -46693,6 +46693,22 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class SyntheticClasses {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("syntheticClasses.kt")
|
||||||
|
public void testSyntheticClasses() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/syntheticClasses/syntheticClasses.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+18
@@ -37258,6 +37258,24 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
public static class SyntheticClasses extends AbstractLightAnalysisModeTest {
|
||||||
|
private void runTest(String testDataFilePath) throws Exception {
|
||||||
|
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("syntheticClasses.kt")
|
||||||
|
public void testSyntheticClasses() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/reflection/syntheticClasses/syntheticClasses.kt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
@RunWith(JUnit3RunnerWithInners.class)
|
@RunWith(JUnit3RunnerWithInners.class)
|
||||||
|
|||||||
@@ -20,7 +20,10 @@ import org.jetbrains.kotlin.builtins.CompanionObjectMapping
|
|||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.builtins.isMappedIntrinsicCompanionObject
|
import org.jetbrains.kotlin.builtins.isMappedIntrinsicCompanionObject
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.runtime.components.ReflectKotlinClass
|
import org.jetbrains.kotlin.descriptors.runtime.components.ReflectKotlinClass
|
||||||
|
import org.jetbrains.kotlin.descriptors.runtime.components.RuntimeModuleData
|
||||||
import org.jetbrains.kotlin.descriptors.runtime.structure.functionClassArity
|
import org.jetbrains.kotlin.descriptors.runtime.structure.functionClassArity
|
||||||
import org.jetbrains.kotlin.descriptors.runtime.structure.wrapperByPrimitive
|
import org.jetbrains.kotlin.descriptors.runtime.structure.wrapperByPrimitive
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
@@ -32,6 +35,7 @@ import org.jetbrains.kotlin.name.ClassId
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.GivenFunctionsMemberScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.MemberDeserializer
|
import org.jetbrains.kotlin.serialization.deserialization.MemberDeserializer
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
|
||||||
@@ -49,6 +53,7 @@ internal class KClassImpl<T : Any>(
|
|||||||
val descriptor: ClassDescriptor by ReflectProperties.lazySoft {
|
val descriptor: ClassDescriptor by ReflectProperties.lazySoft {
|
||||||
val classId = classId
|
val classId = classId
|
||||||
val moduleData = data.value.moduleData
|
val moduleData = data.value.moduleData
|
||||||
|
val module = moduleData.module
|
||||||
|
|
||||||
val descriptor =
|
val descriptor =
|
||||||
if (classId.isLocal && jClass.isAnnotationPresent(Metadata::class.java)) {
|
if (classId.isLocal && jClass.isAnnotationPresent(Metadata::class.java)) {
|
||||||
@@ -56,10 +61,10 @@ internal class KClassImpl<T : Any>(
|
|||||||
// `module.findClassAcrossModuleDependencies`.
|
// `module.findClassAcrossModuleDependencies`.
|
||||||
moduleData.deserialization.deserializeClass(classId)
|
moduleData.deserialization.deserializeClass(classId)
|
||||||
} else {
|
} else {
|
||||||
moduleData.module.findClassAcrossModuleDependencies(classId)
|
module.findClassAcrossModuleDependencies(classId)
|
||||||
}
|
}
|
||||||
|
|
||||||
descriptor ?: reportUnresolvedClass()
|
descriptor ?: createSyntheticClassOrFail(classId, moduleData)
|
||||||
}
|
}
|
||||||
|
|
||||||
val annotations: List<Annotation> by ReflectProperties.lazySoft { descriptor.computeAnnotations() }
|
val annotations: List<Annotation> by ReflectProperties.lazySoft { descriptor.computeAnnotations() }
|
||||||
@@ -310,29 +315,38 @@ internal class KClassImpl<T : Any>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reportUnresolvedClass(): Nothing {
|
private fun createSyntheticClassOrFail(classId: ClassId, moduleData: RuntimeModuleData): ClassDescriptor {
|
||||||
when (val kind = ReflectKotlinClass.create(jClass)?.classHeader?.kind) {
|
when (val kind = ReflectKotlinClass.create(jClass)?.classHeader?.kind) {
|
||||||
KotlinClassHeader.Kind.FILE_FACADE, KotlinClassHeader.Kind.MULTIFILE_CLASS, KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
|
KotlinClassHeader.Kind.FILE_FACADE,
|
||||||
throw UnsupportedOperationException(
|
KotlinClassHeader.Kind.MULTIFILE_CLASS,
|
||||||
"Packages and file facades are not yet supported in Kotlin reflection. " +
|
KotlinClassHeader.Kind.MULTIFILE_CLASS_PART,
|
||||||
"Meanwhile please use Java reflection to inspect this class: $jClass"
|
KotlinClassHeader.Kind.SYNTHETIC_CLASS ->
|
||||||
)
|
return createSyntheticClass(classId, moduleData)
|
||||||
}
|
|
||||||
KotlinClassHeader.Kind.SYNTHETIC_CLASS -> {
|
|
||||||
throw UnsupportedOperationException(
|
|
||||||
"This class is an internal synthetic class generated by the Kotlin compiler, such as an anonymous class " +
|
|
||||||
"for a lambda, a SAM wrapper, a callable reference, etc. It's not a Kotlin class or interface, so the reflection " +
|
|
||||||
"library has no idea what declarations it has. Please use Java reflection to inspect this class: $jClass"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
KotlinClassHeader.Kind.UNKNOWN -> {
|
KotlinClassHeader.Kind.UNKNOWN -> {
|
||||||
// Should not happen since ABI-related exception must have happened earlier
|
// Should not happen since ABI-related exception must have happened earlier
|
||||||
throw KotlinReflectionInternalError("Unknown class: $jClass (kind = $kind)")
|
throw KotlinReflectionInternalError("Unknown class: $jClass (kind = $kind)")
|
||||||
}
|
}
|
||||||
KotlinClassHeader.Kind.CLASS, null -> {
|
KotlinClassHeader.Kind.CLASS, null -> {
|
||||||
// Should not happen since a proper Kotlin- or Java-class must have been resolved
|
// Should not happen since a proper Kotlin- or Java-class must have been resolved
|
||||||
throw KotlinReflectionInternalError("Unresolved class: $jClass")
|
throw KotlinReflectionInternalError("Unresolved class: $jClass (kind = $kind)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun createSyntheticClass(classId: ClassId, moduleData: RuntimeModuleData): ClassDescriptor =
|
||||||
|
ClassDescriptorImpl(
|
||||||
|
EmptyPackageFragmentDescriptor(moduleData.module, classId.packageFqName),
|
||||||
|
classId.shortClassName,
|
||||||
|
Modality.FINAL,
|
||||||
|
ClassKind.CLASS,
|
||||||
|
listOf(moduleData.module.builtIns.any.defaultType),
|
||||||
|
SourceElement.NO_SOURCE,
|
||||||
|
false,
|
||||||
|
moduleData.deserialization.storageManager,
|
||||||
|
).also { descriptor ->
|
||||||
|
descriptor.initialize(object : GivenFunctionsMemberScope(moduleData.deserialization.storageManager, descriptor) {
|
||||||
|
// Don't declare any functions in this class descriptor, only inherit equals/hashCode/toString from Any.
|
||||||
|
override fun computeDeclaredFunctions(): List<FunctionDescriptor> = emptyList()
|
||||||
|
}, emptySet(), null)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
@@ -32779,6 +32779,16 @@ public class FirJsCodegenBoxTestGenerated extends AbstractFirJsCodegenBoxTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class SyntheticClasses {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+10
@@ -32779,6 +32779,16 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class SyntheticClasses {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+10
@@ -32779,6 +32779,16 @@ public class IrJsES6CodegenBoxTestGenerated extends AbstractIrJsES6CodegenBoxTes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class SyntheticClasses {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+13
@@ -36186,6 +36186,19 @@ public class FirNativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@Tag("frontend-fir")
|
||||||
|
@FirPipeline()
|
||||||
|
@UseExtTestCaseGroupProvider()
|
||||||
|
public class SyntheticClasses {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+15
@@ -37102,6 +37102,21 @@ public class FirNativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenB
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@Tag("frontend-fir")
|
||||||
|
@FirPipeline()
|
||||||
|
@UseExtTestCaseGroupProvider()
|
||||||
|
@UsePartialLinkage(mode = Mode.DISABLED)
|
||||||
|
@Tag("no-partial-linkage-may-be-skipped")
|
||||||
|
public class SyntheticClasses {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+12
@@ -35729,6 +35729,18 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@UseExtTestCaseGroupProvider()
|
||||||
|
@DisabledTestsIfProperty(sourceLocations = { "compiler/testData/codegen/box/coroutines/featureIntersection/defaultExpect.kt", "compiler/testData/codegen/box/multiplatform/defaultArguments/*.kt", "compiler/testData/codegen/box/multiplatform/migratedOldTests/*.kt", "compiler/testData/codegen/boxInline/multiplatform/defaultArguments/receiversAndParametersInLambda.kt" }, property = ClassLevelProperty.TEST_MODE, propertyValue = "ONE_STAGE_MULTI_MODULE")
|
||||||
|
public class SyntheticClasses {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
+13
@@ -36187,6 +36187,19 @@ public class NativeCodegenBoxTestNoPLGenerated extends AbstractNativeCodegenBoxT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
@UseExtTestCaseGroupProvider()
|
||||||
|
@UsePartialLinkage(mode = Mode.DISABLED)
|
||||||
|
@Tag("no-partial-linkage-may-be-skipped")
|
||||||
|
public class SyntheticClasses {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
Generated
+10
@@ -32587,6 +32587,16 @@ public class FirWasmCodegenBoxTestGenerated extends AbstractFirWasmCodegenBoxTes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class SyntheticClasses {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
Generated
+10
@@ -32587,6 +32587,16 @@ public class K1WasmCodegenBoxTestGenerated extends AbstractK1WasmCodegenBoxTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nested
|
||||||
|
@TestMetadata("compiler/testData/codegen/box/reflection/syntheticClasses")
|
||||||
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
public class SyntheticClasses {
|
||||||
|
@Test
|
||||||
|
public void testAllFilesPresentInSyntheticClasses() throws Exception {
|
||||||
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/reflection/syntheticClasses"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||||
@TestDataPath("$PROJECT_ROOT")
|
@TestDataPath("$PROJECT_ROOT")
|
||||||
|
|||||||
Reference in New Issue
Block a user