diff --git a/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt b/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt index 741e0e0f2a5..d52b209566c 100644 --- a/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt +++ b/build-common/src/org/jetbrains/kotlin/incremental/JavaClassesTrackerImpl.kt @@ -35,7 +35,6 @@ import org.jetbrains.kotlin.resolve.source.PsiSourceElement import org.jetbrains.kotlin.serialization.DescriptorSerializer import org.jetbrains.kotlin.serialization.deserialization.getClassId import org.jetbrains.kotlin.util.PerformanceCounter -import org.jetbrains.kotlin.util.getExceptionMessage import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.sure import java.io.DataInput @@ -96,10 +95,8 @@ fun JavaClassDescriptor.convertToProto(): SerializedJavaClassWithSource { val file = javaSourceFile.sure { "convertToProto should only be called for source based classes" } val extension = JavaClassesSerializerExtension() - val serializer = DescriptorSerializer.createTopLevel(extension) - val classProto: ProtoBuf.Class - try { - classProto = serializer.classProto(this).build() + val classProto = try { + DescriptorSerializer.create(this, extension).classProto(this).build() } catch (e: Exception) { throw IllegalStateException( "Error during writing proto for descriptor: ${DescriptorRenderer.DEBUG_TEXT.render(this)}\n" + diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/MetadataSerializer.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/MetadataSerializer.kt index 7b97db8b215..2f8e8d393e7 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/MetadataSerializer.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/MetadataSerializer.kt @@ -158,7 +158,7 @@ open class MetadataSerializer(private val dependOnOldBuiltIns: Boolean) { } private fun serializeClass(classDescriptor: ClassDescriptor) { - val classProto = DescriptorSerializer.createTopLevel(extension).classProto(classDescriptor).build() + val classProto = DescriptorSerializer.create(classDescriptor, extension).classProto(classDescriptor).build() proto.addClass_(classProto) serializeClasses(classDescriptor.unsubstitutedInnerClassesScope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS)) diff --git a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt index d3339b2afaa..c117f9998ad 100644 --- a/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt +++ b/compiler/psi/src/org/jetbrains/kotlin/psi/stubs/KotlinStubVersions.kt @@ -36,9 +36,9 @@ object KotlinStubVersions { // BuiltIn stub version should be increased if changes are made to builtIn stub building subsystem (org.jetbrains.kotlin.idea.decompiler.builtIns) // Increasing this version will lead to reindexing of all builtIn files (see KotlinBuiltInFileType). - const val BUILTIN_STUB_VERSION = BINARY_STUB_VERSION + 1 + const val BUILTIN_STUB_VERSION = BINARY_STUB_VERSION + 2 // JS stub version should be increased if changes are made to js stub building subsystem (org.jetbrains.kotlin.idea.decompiler.js) // Increasing this version will lead to reindexing of js binary files (see KotlinJavaScriptMetaFileType). - const val JS_STUB_VERSION = BINARY_STUB_VERSION + 1 + const val JS_STUB_VERSION = BINARY_STUB_VERSION + 2 } diff --git a/compiler/testData/multiplatform/innerGenericClass/common.kt b/compiler/testData/multiplatform/innerGenericClass/common.kt new file mode 100644 index 00000000000..e0eb22ced97 --- /dev/null +++ b/compiler/testData/multiplatform/innerGenericClass/common.kt @@ -0,0 +1,9 @@ +class A { + inner class B { + fun getAE() = this@A.getAE() + fun getBT(): T? = null + fun getBE(): E? = null + } + + fun getAE(): E? = null +} diff --git a/compiler/testData/multiplatform/innerGenericClass/common2.kt b/compiler/testData/multiplatform/innerGenericClass/common2.kt new file mode 100644 index 00000000000..721c47e019a --- /dev/null +++ b/compiler/testData/multiplatform/innerGenericClass/common2.kt @@ -0,0 +1,11 @@ +fun test(): String { + val b = A().B() + val x: String? = b.getAE() + val y: Int? = b.getBT() + val z: Double? = b.getBE() + + // This line is needed to ensure that B.getAE's return type is not an error type; if it was, this line would compile with no errors + b.getAE().unresolved() + + return "$x$y$z" +} diff --git a/compiler/testData/multiplatform/innerGenericClass/output.txt b/compiler/testData/multiplatform/innerGenericClass/output.txt new file mode 100644 index 00000000000..2c52162d1d6 --- /dev/null +++ b/compiler/testData/multiplatform/innerGenericClass/output.txt @@ -0,0 +1,10 @@ +-- Common -- +Exit code: OK +Output: + +-- Common (2) -- +Exit code: COMPILATION_ERROR +Output: +compiler/testData/multiplatform/innerGenericClass/common2.kt:8:15: error: unresolved reference: unresolved + b.getAE().unresolved() + ^ diff --git a/compiler/tests/org/jetbrains/kotlin/multiplatform/AbstractMultiPlatformIntegrationTest.kt b/compiler/tests/org/jetbrains/kotlin/multiplatform/AbstractMultiPlatformIntegrationTest.kt index c3c58fa4c3f..742d4b9c338 100644 --- a/compiler/tests/org/jetbrains/kotlin/multiplatform/AbstractMultiPlatformIntegrationTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/multiplatform/AbstractMultiPlatformIntegrationTest.kt @@ -33,44 +33,57 @@ import java.nio.file.Paths abstract class AbstractMultiPlatformIntegrationTest : KtUsefulTestCase() { fun doTest(directoryPath: String) { val root = File(directoryPath).apply { assert(exists()) } - val commonSrc = File(root, "common.kt") - val jsSrc = File(root, "js.kt") - val jvmSrc = File(root, "jvm.kt") + val commonSrc = File(root, "common.kt").apply { assert(exists()) } + val jsSrc = File(root, "js.kt").takeIf(File::exists) + val jvmSrc = File(root, "jvm.kt").takeIf(File::exists) // TODO: consider inventing a more clever scheme - val jvm2Src = File(root, "jvm2.kt") + val common2Src = File(root, "common2.kt").takeIf(File::exists) + val jvm2Src = File(root, "jvm2.kt").takeIf(File::exists) val tmpdir = KotlinTestUtils.tmpDir(getTestName(true)) val optionalStdlibCommon = - if (InTextDirectivesUtils.isDirectiveDefined(commonSrc.readText(), "WITH_RUNTIME")) - arrayOf("-cp", findStdlibCommon().absolutePath) - else emptyArray() + if (InTextDirectivesUtils.isDirectiveDefined(commonSrc.readText(), "WITH_RUNTIME")) + arrayOf("-cp", findStdlibCommon().absolutePath) + else emptyArray() val commonDest = File(tmpdir, "common").absolutePath - val jvmDest = File(tmpdir, "jvm").absolutePath - val jsDest = File(File(tmpdir, "js"), "output.js").absolutePath - val jvm2Dest = File(tmpdir, "jvm2").absolutePath + val jvmDest = File(tmpdir, "jvm").absolutePath.takeIf { jvmSrc != null } + val jsDest = File(File(tmpdir, "js"), "output.js").absolutePath.takeIf { jsSrc != null } + val common2Dest = File(tmpdir, "common2").absolutePath.takeIf { common2Src != null } + val jvm2Dest = File(tmpdir, "jvm2").absolutePath.takeIf { jvm2Src != null } val result = buildString { appendln("-- Common --") appendln(K2MetadataCompiler().compile(listOf(commonSrc), "-d", commonDest, *optionalStdlibCommon)) - if (jvmSrc.exists()) { + if (jvmSrc != null) { appendln() appendln("-- JVM --") - appendln(K2JVMCompiler().compileBothWays(commonSrc, jvmSrc, "-d", jvmDest)) + appendln(K2JVMCompiler().compileBothWays(commonSrc, jvmSrc, "-d", jvmDest!!)) } - if (jsSrc.exists()) { + if (jsSrc != null) { appendln() appendln("-- JS --") - appendln(K2JSCompiler().compileBothWays(commonSrc, jsSrc, "-output", jsDest)) + appendln(K2JSCompiler().compileBothWays(commonSrc, jsSrc, "-output", jsDest!!)) } - if (jvm2Src.exists()) { + if (common2Src != null) { + appendln() + appendln("-- Common (2) --") + appendln(K2MetadataCompiler().compile(listOf(common2Src), "-d", common2Dest!!, "-cp", commonDest, *optionalStdlibCommon)) + } + + if (jvm2Src != null) { appendln() appendln("-- JVM (2) --") - appendln(K2JVMCompiler().compile(listOf(jvm2Src), "-d", jvm2Dest, "-cp", listOf(commonDest, jvmDest).joinToString(File.pathSeparator))) + appendln( + K2JVMCompiler().compile( + listOf(jvm2Src), "-d", jvm2Dest!!, + "-cp", listOfNotNull(commonDest, common2Dest, jvmDest).joinToString(File.pathSeparator) + ) + ) } } @@ -89,17 +102,17 @@ abstract class AbstractMultiPlatformIntegrationTest : KtUsefulTestCase() { private fun CLICompiler<*>.compileBothWays(commonSource: File, platformSource: File, vararg mainArguments: String): String { val configurations = listOf( - listOf(platformSource, commonSource), - listOf(commonSource, platformSource) + listOf(platformSource, commonSource), + listOf(commonSource, platformSource) ) val (platformFirst, commonFirst) = configurations.map { compile(it, *mainArguments) } if (platformFirst != commonFirst) { assertEquals( - "Compilation results are different when compiling [platform-specific, common] compared to when compiling [common, platform-specific]", - "// Compiling [platform-specific, common]\n\n$platformFirst", - "// Compiling [common, platform-specific]\n\n$commonFirst" + "Compilation results are different when compiling [platform-specific, common] compared to when compiling [common, platform-specific]", + "// Compiling [platform-specific, common]\n\n$platformFirst", + "// Compiling [common, platform-specific]\n\n$commonFirst" ) } return platformFirst @@ -107,8 +120,8 @@ abstract class AbstractMultiPlatformIntegrationTest : KtUsefulTestCase() { private fun CLICompiler<*>.compile(sources: List, vararg mainArguments: String): String = buildString { val (output, exitCode) = AbstractCliTest.executeCompilerGrabOutput( - this@compile, - sources.map(File::getAbsolutePath) + listOf("-Xmulti-platform") + mainArguments + loadExtraArguments(sources) + this@compile, + sources.map(File::getAbsolutePath) + listOf("-Xmulti-platform") + mainArguments + loadExtraArguments(sources) ) appendln("Exit code: $exitCode") appendln("Output:") diff --git a/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java index f362a8a052d..b2e18dab20f 100644 --- a/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/multiplatform/MultiPlatformIntegrationTestGenerated.java @@ -89,6 +89,11 @@ public class MultiPlatformIntegrationTestGenerated extends AbstractMultiPlatform runTest("compiler/testData/multiplatform/inlineClasses/"); } + @TestMetadata("innerGenericClass") + public void testInnerGenericClass() throws Exception { + runTest("compiler/testData/multiplatform/innerGenericClass/"); + } + @TestMetadata("jsNameClash") public void testJsNameClash() throws Exception { runTest("compiler/testData/multiplatform/jsNameClash/"); @@ -558,6 +563,19 @@ public class MultiPlatformIntegrationTestGenerated extends AbstractMultiPlatform } } + @TestMetadata("compiler/testData/multiplatform/innerGenericClass") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class InnerGenericClass extends AbstractMultiPlatformIntegrationTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath); + } + + public void testAllFilesPresentInInnerGenericClass() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/multiplatform/innerGenericClass"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + } + } + @TestMetadata("compiler/testData/multiplatform/jsNameClash") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/util/src/org/jetbrains/kotlin/utils/KotlinJavascriptMetadataUtils.kt b/compiler/util/src/org/jetbrains/kotlin/utils/KotlinJavascriptMetadataUtils.kt index a6071628106..0ad45f44f37 100644 --- a/compiler/util/src/org/jetbrains/kotlin/utils/KotlinJavascriptMetadataUtils.kt +++ b/compiler/util/src/org/jetbrains/kotlin/utils/KotlinJavascriptMetadataUtils.kt @@ -32,7 +32,7 @@ class JsMetadataVersion(vararg numbers: Int) : BinaryVersion(*numbers) { companion object { @JvmField - val INSTANCE = JsMetadataVersion(1, 2, 1) + val INSTANCE = JsMetadataVersion(1, 2, 2) @JvmField val INVALID_VERSION = JsMetadataVersion() diff --git a/core/metadata/src/org/jetbrains/kotlin/metadata/builtins/BuiltInsBinaryVersion.kt b/core/metadata/src/org/jetbrains/kotlin/metadata/builtins/BuiltInsBinaryVersion.kt index 0e1fcba9ae1..a1e16792f66 100644 --- a/core/metadata/src/org/jetbrains/kotlin/metadata/builtins/BuiltInsBinaryVersion.kt +++ b/core/metadata/src/org/jetbrains/kotlin/metadata/builtins/BuiltInsBinaryVersion.kt @@ -18,7 +18,7 @@ class BuiltInsBinaryVersion(vararg numbers: Int) : BinaryVersion(*numbers) { companion object { @JvmField - val INSTANCE = BuiltInsBinaryVersion(1, 0, 2) + val INSTANCE = BuiltInsBinaryVersion(1, 0, 3) @JvmField val INVALID_VERSION = BuiltInsBinaryVersion() diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt index 9511d51cb5c..6a3d48f04a9 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt @@ -18,7 +18,6 @@ package org.jetbrains.kotlin.serialization.js import org.jetbrains.kotlin.config.AnalysisFlag import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.config.isPreRelease import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -197,15 +196,16 @@ object KotlinJavascriptSerializationUtil { } val fileRegistry = KotlinFileRegistry() - val serializerExtension = KotlinJavascriptSerializerExtension(fileRegistry) - val serializer = DescriptorSerializer.createTopLevel(serializerExtension) + val extension = KotlinJavascriptSerializerExtension(fileRegistry) val classDescriptors = scope.filterIsInstance().sortedBy { it.fqNameSafe.asString() } fun serializeClasses(descriptors: Collection) { fun serializeClass(classDescriptor: ClassDescriptor) { if (skip(classDescriptor)) return - val classProto = serializer.classProto(classDescriptor).build() ?: error("Class not serialized: $classDescriptor") + val classProto = + DescriptorSerializer.create(classDescriptor, extension).classProto(classDescriptor).build() + ?: error("Class not serialized: $classDescriptor") builder.addClass_(classProto) serializeClasses(classDescriptor.unsubstitutedInnerClassesScope.getContributedDescriptors()) } @@ -219,10 +219,10 @@ object KotlinJavascriptSerializationUtil { serializeClasses(classDescriptors) - val stringTable = serializerExtension.stringTable + val stringTable = extension.stringTable val members = scope.filterNot(skip) - builder.`package` = serializer.packagePartProto(fqName, members).build() + builder.`package` = DescriptorSerializer.createTopLevel(extension).packagePartProto(fqName, members).build() builder.setExtension( JsProtoBuf.packageFragmentFiles,