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 val typeContext: TypeSystemCommonBackendContextForTypeMapping
fun getClassInternalName(typeConstructor: TypeConstructorMarker): String fun getClassInternalName(typeConstructor: TypeConstructorMarker): String
fun getScriptInternalName(typeConstructor: TypeConstructorMarker): String
fun Writer.writeGenericType(type: SimpleTypeMarker, asmType: Type, mode: TypeMappingMode) fun Writer.writeGenericType(type: SimpleTypeMarker, asmType: Type, mode: TypeMappingMode)
} }
@@ -117,9 +118,7 @@ object AbstractTypeMapper {
} }
typeConstructor.isScript() -> { typeConstructor.isScript() -> {
val asmType = AsmTypes.JAVA_CLASS_TYPE return Type.getObjectType(context.getScriptInternalName(typeConstructor))
with(context) { sw?.writeGenericType(type, asmType, mode) }
return asmType
} }
typeConstructor.isTypeParameter() -> { typeConstructor.isTypeParameter() -> {
@@ -13,19 +13,19 @@ import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.*
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.defaultType 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.fullyExpandedType
import org.jetbrains.kotlin.fir.resolve.inference.* 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.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag import org.jetbrains.kotlin.fir.symbols.ConeClassifierLookupTag
import org.jetbrains.kotlin.fir.symbols.ConeTypeParameterLookupTag 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.symbols.impl.*
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.types.AbstractTypeMapper import org.jetbrains.kotlin.types.AbstractTypeMapper
import org.jetbrains.kotlin.types.TypeMappingContext import org.jetbrains.kotlin.types.TypeMappingContext
import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext import org.jetbrains.kotlin.types.TypeSystemCommonBackendContext
@@ -50,6 +50,9 @@ class FirJvmTypeMapper(val session: FirSession) : TypeMappingContext<JvmSignatur
return typeConstructor.classId.asString().replace(".", "$").replace("/", ".") 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) { override fun JvmSignatureWriter.writeGenericType(type: SimpleTypeMarker, asmType: Type, mode: TypeMappingMode) {
if (type !is ConeClassLikeType) return if (type !is ConeClassLikeType) return
if (skipGenericSignature() || hasNothingInNonContravariantPosition(type) || type.typeArguments.isEmpty()) { 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 @Nested
@TestMetadata("compiler/testData/codegen/box/sealed") @TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@@ -101,6 +101,12 @@ class IrTypeMapper(private val context: JvmBackendContext) : KotlinTypeMapperBas
override fun getClassInternalName(typeConstructor: TypeConstructorMarker): String = override fun getClassInternalName(typeConstructor: TypeConstructorMarker): String =
classInternalName((typeConstructor as IrClassSymbol).owner) 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) { fun writeFormalTypeParameters(irParameters: List<IrTypeParameter>, sw: JvmSignatureWriter) {
if (sw.skipGenericSignature()) return if (sw.skipGenericSignature()) return
with(KotlinTypeMapper) { with(KotlinTypeMapper) {
@@ -66,12 +66,11 @@ fun IrType.eraseTypeParameters() = when (this) {
is IrErrorType -> this is IrErrorType -> this
is IrSimpleType -> is IrSimpleType ->
when (val owner = classifier.owner) { when (val owner = classifier.owner) {
is IrClass -> IrSimpleTypeImpl( is IrScript -> {
classifier, assert(arguments.isEmpty()) { "Script can't be generic: " + owner.render() }
hasQuestionMark, IrSimpleTypeImpl(classifier, hasQuestionMark, emptyList(), annotations)
arguments.map { it.eraseTypeParameters() }, }
annotations is IrClass -> IrSimpleTypeImpl(classifier, hasQuestionMark, arguments.map { it.eraseTypeParameters() }, annotations)
)
is IrTypeParameter -> { is IrTypeParameter -> {
val upperBound = owner.erasedUpperBound val upperBound = owner.erasedUpperBound
IrSimpleTypeImpl( IrSimpleTypeImpl(
@@ -338,6 +338,8 @@ fun ReferenceSymbolTable.referenceClassifier(classifier: ClassifierDescriptor):
when (classifier) { when (classifier) {
is TypeParameterDescriptor -> is TypeParameterDescriptor ->
referenceTypeParameter(classifier) referenceTypeParameter(classifier)
is ScriptDescriptor ->
referenceScript(classifier)
is ClassDescriptor -> is ClassDescriptor ->
referenceClass(classifier) referenceClass(classifier)
else -> 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 @Nested
@TestMetadata("compiler/testData/codegen/box/sealed") @TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT") @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 @Nested
@TestMetadata("compiler/testData/codegen/box/sealed") @TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT") @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.model.*
import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator import org.jetbrains.kotlin.test.services.configuration.CommonEnvironmentConfigurator
import org.jetbrains.kotlin.test.services.configuration.JvmEnvironmentConfigurator 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.AdditionalDiagnosticsSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CodegenHelpersSourceFilesProvider import org.jetbrains.kotlin.test.services.sourceProviders.CodegenHelpersSourceFilesProvider
import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider import org.jetbrains.kotlin.test.services.sourceProviders.CoroutineHelpersSourceFilesProvider
@@ -36,7 +37,8 @@ fun <R : ResultingArtifact.FrontendOutput<R>> TestConfigurationBuilder.commonCon
useConfigurators( useConfigurators(
::CommonEnvironmentConfigurator, ::CommonEnvironmentConfigurator,
::JvmEnvironmentConfigurator ::JvmEnvironmentConfigurator,
::ScriptingEnvironmentConfigurator,
) )
useAdditionalSourceProviders( 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") @TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @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") @TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @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") @TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @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") @TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @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") @TestMetadata("compiler/testData/codegen/box/sealed")
@TestDataPath("$PROJECT_ROOT") @TestDataPath("$PROJECT_ROOT")
@RunWith(JUnit3RunnerWithInners.class) @RunWith(JUnit3RunnerWithInners.class)