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
+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
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||
@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
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||
@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
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||
@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
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/typeOf")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
Reference in New Issue
Block a user