JVM IR: fix ::class reference and type mapping for scripts

#KT-46284 Fixed
This commit is contained in:
Alexander Udalov
2021-04-26 16:59:00 +02:00
committed by TeamCityServer
parent d10f734594
commit 276ffd5a4b
15 changed files with 151 additions and 12 deletions
@@ -18,6 +18,7 @@ interface TypeMappingContext<Writer : JvmDescriptorTypeWriter<Type>> {
val typeContext: TypeSystemCommonBackendContextForTypeMapping
fun getClassInternalName(typeConstructor: TypeConstructorMarker): String
fun getScriptInternalName(typeConstructor: TypeConstructorMarker): String
fun Writer.writeGenericType(type: SimpleTypeMarker, asmType: Type, mode: TypeMappingMode)
}
@@ -117,9 +118,7 @@ object AbstractTypeMapper {
}
typeConstructor.isScript() -> {
val asmType = AsmTypes.JAVA_CLASS_TYPE
with(context) { sw?.writeGenericType(type, asmType, mode) }
return asmType
return Type.getObjectType(context.getScriptInternalName(typeConstructor))
}
typeConstructor.isTypeParameter() -> {
@@ -13,19 +13,19 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.defaultType
import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.inference.*
import org.jetbrains.kotlin.fir.resolve.symbolProvider
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.types.AbstractTypeMapper
import org.jetbrains.kotlin.types.TypeMappingContext
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
@@ -50,6 +50,9 @@ class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext<JvmSignatur
return typeConstructor.classId.asString().replace(".", "$").replace("/", ".")
}
override fun getScriptInternalName(typeConstructor: TypeConstructorMarker): String =
TODO("Not yet implemented")
override fun JvmSignatureWriter.writeGenericType(type: SimpleTypeMarker, asmType: Type, mode: TypeMappingMode) {
if (type !is ConeClassLikeType) return
if (skipGenericSignature() || hasNothingInNonContravariantPosition(type) || type.typeArguments.isEmpty()) {
@@ -38615,6 +38615,22 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/script")
@TestDataPath("$PROJECT_ROOT")
public class Script {
@Test
public void testAllFilesPresentInScript() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/script"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("classReference.kt")
public void testClassReference() throws Exception {
runTest("compiler/testData/codegen/box/script/classReference.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT")
@@ -101,6 +101,12 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas
override fun getClassInternalName(typeConstructor: TypeConstructorMarker): String =
classInternalName((typeConstructor as IrClassSymbol).owner)
override fun getScriptInternalName(typeConstructor: TypeConstructorMarker): String {
val script = (typeConstructor as IrScriptSymbol).owner
val targetClass = script.targetClass ?: error("No target class computed for script: ${script.render()}")
return classInternalName(targetClass.owner)
}
fun writeFormalTypeParameters(irParameters: List<IrTypeParameter>, sw: JvmSignatureWriter) {
if (sw.skipGenericSignature()) return
with(KotlinTypeMapper) {
@@ -66,12 +66,11 @@ fun IrType.eraseTypeParameters() = when (this) {
is IrErrorType -> this
is IrSimpleType ->
when (val owner = classifier.owner) {
is IrClass -> IrSimpleTypeImpl(
classifier,
hasQuestionMark,
arguments.map { it.eraseTypeParameters() },
annotations
)
is IrScript -> {
assert(arguments.isEmpty()) { "Script can't be generic: " + owner.render() }
IrSimpleTypeImpl(classifier, hasQuestionMark, emptyList(), annotations)
}
is IrClass -> IrSimpleTypeImpl(classifier, hasQuestionMark, arguments.map { it.eraseTypeParameters() }, annotations)
is IrTypeParameter -> {
val upperBound = owner.erasedUpperBound
IrSimpleTypeImpl(
@@ -338,6 +338,8 @@ fun ReferenceSymbolTable.referenceClassifier(classifier: ClassifierDescriptor):
when (classifier) {
is TypeParameterDescriptor ->
referenceTypeParameter(classifier)
is ScriptDescriptor ->
referenceScript(classifier)
is ClassDescriptor ->
referenceClass(classifier)
else ->
+10
View File
@@ -0,0 +1,10 @@
// TARGET_BACKEND: JVM
// IGNORE_BACKEND_FIR: JVM_IR
// IGNORE_LIGHT_ANALYSIS
// WITH_RUNTIME
// FILE: test.kt
fun box(): String =
OK::class.java.simpleName
// FILE: OK.kts
@@ -38591,6 +38591,22 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/script")
@TestDataPath("$PROJECT_ROOT")
public class Script {
@Test
public void testAllFilesPresentInScript() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/script"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@Test
@TestMetadata("classReference.kt")
public void testClassReference() throws Exception {
runTest("compiler/testData/codegen/box/script/classReference.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT")
@@ -38615,6 +38615,22 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/script")
@TestDataPath("$PROJECT_ROOT")
public class Script {
@Test
public void testAllFilesPresentInScript() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/script"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("classReference.kt")
public void testClassReference() throws Exception {
runTest("compiler/testData/codegen/box/script/classReference.kt");
}
}
@Nested
@TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT")
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.test.directives.CodegenTestDirectives.RUN_DEX_CHECKE
import org.jetbrains.kotlin.test.model.*
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.ScriptingEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.sourceProviders.AdditionalDiagnosticsSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CodegenHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
@@ -36,7 +37,8 @@ fun <R : ResultingArtifact.FrontendOutput<R>> TestConfigurationBuilder.commonCon
useConfigurators(
::CommonEnvironmentConfigurator,
::JvmEnvironmentConfigurator
::JvmEnvironmentConfigurator,
::ScriptingEnvironmentConfigurator,
)
useAdditionalSourceProviders(
@@ -30838,6 +30838,24 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
}
}
@TestMetadata("compiler/testData/codegen/box/script")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Script extends AbstractLightAnalysisModeTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
}
public void testAllFilesPresentInScript() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/script"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@TestMetadata("classReference.kt")
public void testClassReference() throws Exception {
runTest("compiler/testData/codegen/box/script/classReference.kt");
}
}
@TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -25978,6 +25978,19 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
}
}
@TestMetadata("compiler/testData/codegen/box/script")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Script extends AbstractIrJsCodegenBoxES6Test {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR_ES6, testDataFilePath);
}
public void testAllFilesPresentInScript() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/script"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
}
@TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -25389,6 +25389,19 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
}
}
@TestMetadata("compiler/testData/codegen/box/script")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Script extends AbstractIrJsCodegenBoxTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath);
}
public void testAllFilesPresentInScript() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/script"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
}
@TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -25349,6 +25349,19 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
}
}
@TestMetadata("compiler/testData/codegen/box/script")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Script extends AbstractJsCodegenBoxTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath);
}
public void testAllFilesPresentInScript() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/script"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
}
}
@TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
@@ -13810,6 +13810,19 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
}
}
@TestMetadata("compiler/testData/codegen/box/script")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)
public static class Script extends AbstractIrCodegenBoxWasmTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest0(this::doTest, TargetBackend.WASM, testDataFilePath);
}
public void testAllFilesPresentInScript() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/script"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
}
}
@TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class)