From 4ec90b18bcbcd08e78934f9d2c61731e14096366 Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Thu, 15 Oct 2020 17:01:37 +0300 Subject: [PATCH] Rework DescriptorSerializerPlugin to be a part of Project's extensions instead of statically registering it. Static registering can cause subtle errors when plugin implementation (e.g. SerializationDescriptorPluginForKotlinxSerialization) is registered from multiple classloaders: in multi-module with daemon compilation scenario #KT-41857 Fixed --- .../codegen/ImplementationBodyCodegen.java | 3 +- .../builtins/BuiltInsSerializer.kt | 9 +++- .../META-INF/extensions/compiler.xml | 2 + .../cli/jvm/compiler/KotlinCoreEnvironment.kt | 2 + .../compiler/KotlinCoreEnvironment.kt.as42 | 2 + .../cli/metadata/K2MetadataKlibSerializer.kt | 7 ++- .../kotlin/cli/metadata/MetadataSerializer.kt | 21 +++++---- .../codegen/DescriptorMetadataSerializer.kt | 11 +++-- .../KlibMetadataIncrementalSerializer.kt | 4 +- .../KlibMetadataMonolithicSerializer.kt | 4 +- .../metadata/KlibMetadataSerializer.kt | 4 +- .../jetbrains/kotlin/ir/backend/js/klib.kt | 14 +++--- compiler/serialization/build.gradle.kts | 3 ++ .../serialization/DescriptorSerializer.kt | 16 +++---- .../DescriptorSerializerPlugin.kt | 4 ++ .../org/jetbrains/kotlin/test/KlibTestUtil.kt | 3 +- .../js/KotlinJavascriptSerializerTest.kt | 3 +- .../META-INF/kotlinx-serialization.xml | 1 + .../js/KotlinJavascriptSerializationUtil.kt | 14 +++--- .../kotlin/benchmarks/GenerateIrRuntime.kt | 1 + .../kotlin/js/facade/K2JSTranslator.kt | 44 ++++++++++--------- .../konan/NativeDistributionCommonizer.kt | 3 +- .../SerializationComponentRegistrar.kt | 7 +-- 23 files changed, 115 insertions(+), 67 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index ff5e3cf1b7b..27a5e100f0b 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -125,7 +125,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { descriptor, extension, parentCodegen instanceof ImplementationBodyCodegen ? ((ImplementationBodyCodegen) parentCodegen).serializer - : DescriptorSerializer.createTopLevel(extension) + : DescriptorSerializer.createTopLevel(extension), + state.getProject() ); this.constructorCodegen = new ConstructorCodegen( diff --git a/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializer.kt b/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializer.kt index ad00e39b831..80c80e2374a 100644 --- a/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializer.kt +++ b/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.serialization.builtins +import com.intellij.openapi.project.Project import com.intellij.openapi.util.Disposer import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInClassDescriptorFactory @@ -76,7 +77,13 @@ class BuiltInsSerializer(dependOnOldBuiltIns: Boolean) : MetadataSerializer(Buil } } - override fun performSerialization(files: Collection, bindingContext: BindingContext, module: ModuleDescriptor, destDir: File) { + override fun performSerialization( + files: Collection, + bindingContext: BindingContext, + module: ModuleDescriptor, + destDir: File, + project: Project? + ) { destDir.deleteRecursively() if (!destDir.mkdirs()) { throw AssertionError("Could not make directories: " + destDir) diff --git a/compiler/cli/cli-common/resources/META-INF/extensions/compiler.xml b/compiler/cli/cli-common/resources/META-INF/extensions/compiler.xml index 45c43a722f2..43b8f776155 100644 --- a/compiler/cli/cli-common/resources/META-INF/extensions/compiler.xml +++ b/compiler/cli/cli-common/resources/META-INF/extensions/compiler.xml @@ -69,5 +69,7 @@ dynamic="true"/> + diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt index d1dddd01a88..de70bca72ad 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt @@ -99,6 +99,7 @@ import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtens import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver import org.jetbrains.kotlin.resolve.lazy.declarations.CliDeclarationProviderFactoryService import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService +import org.jetbrains.kotlin.serialization.DescriptorSerializerPlugin import org.jetbrains.kotlin.utils.PathUtil import java.io.File import java.util.zip.ZipFile @@ -555,6 +556,7 @@ class KotlinCoreEnvironment private constructor( ShellExtension.registerExtensionPoint(project) TypeResolutionInterceptor.registerExtensionPoint(project) CandidateInterceptor.registerExtensionPoint(project) + DescriptorSerializerPlugin.registerExtensionPoint(project) } internal fun registerExtensionsFromPlugins(project: MockProject, configuration: CompilerConfiguration) { diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt.as42 b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt.as42 index b2db75909f2..e2785e46e04 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt.as42 +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/KotlinCoreEnvironment.kt.as42 @@ -103,6 +103,7 @@ import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtens import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver import org.jetbrains.kotlin.resolve.lazy.declarations.CliDeclarationProviderFactoryService import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService +import org.jetbrains.kotlin.serialization.DescriptorSerializerPlugin import org.jetbrains.kotlin.utils.PathUtil import java.io.File import java.util.zip.ZipFile @@ -556,6 +557,7 @@ class KotlinCoreEnvironment private constructor( ShellExtension.registerExtensionPoint(project) TypeResolutionInterceptor.registerExtensionPoint(project) CandidateInterceptor.registerExtensionPoint(project) + DescriptorSerializerPlugin.registerExtensionPoint(project) } internal fun registerExtensionsFromPlugins(project: MockProject, configuration: CompilerConfiguration) { diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/K2MetadataKlibSerializer.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/K2MetadataKlibSerializer.kt index e2fc3a8262b..e73a20012e5 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/K2MetadataKlibSerializer.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/K2MetadataKlibSerializer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.cli.metadata +import com.intellij.openapi.project.Project import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.analyzer.common.CommonDependenciesContainer import org.jetbrains.kotlin.analyzer.common.CommonPlatformAnalyzerServices @@ -60,17 +61,19 @@ internal class K2MetadataKlibSerializer(private val metadataVersion: BuiltInsBin val (_, moduleDescriptor) = analyzer.analysisResult val destDir = checkNotNull(environment.destDir) - performSerialization(configuration, moduleDescriptor, destDir) + performSerialization(configuration, moduleDescriptor, destDir, environment.project) } private fun performSerialization( configuration: CompilerConfiguration, module: ModuleDescriptor, - destDir: File + destDir: File, + project: Project ) { val serializedMetadata: SerializedMetadata = KlibMetadataMonolithicSerializer( configuration.languageVersionSettings, metadataVersion, + project, skipExpects = false, includeOnlyModuleContent = true ).serializeModule(module) 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 3be8d18f084..bc2d56cf7bd 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/MetadataSerializer.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/metadata/MetadataSerializer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.cli.metadata +import com.intellij.openapi.project.Project import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.codegen.JvmCodegenUtil import org.jetbrains.kotlin.descriptors.ClassDescriptor @@ -45,11 +46,11 @@ open class MetadataSerializer( val (bindingContext, moduleDescriptor) = analyzer.analysisResult val destDir = checkNotNull(environment.destDir) - performSerialization(environment.getSourceFiles(), bindingContext, moduleDescriptor, destDir) + performSerialization(environment.getSourceFiles(), bindingContext, moduleDescriptor, destDir, environment.project) } protected open fun performSerialization( - files: Collection, bindingContext: BindingContext, module: ModuleDescriptor, destDir: File + files: Collection, bindingContext: BindingContext, module: ModuleDescriptor, destDir: File, project: Project? ) { val packageTable = hashMapOf() @@ -83,14 +84,14 @@ open class MetadataSerializer( val classDescriptor = bindingContext.get(BindingContext.CLASS, classOrObject) ?: error("No descriptor found for class ${classOrObject.fqName}") val destFile = File(destDir, getClassFilePath(ClassId(packageFqName, classDescriptor.name))) - PackageSerializer(listOf(classDescriptor), emptyList(), packageFqName, destFile).run() + PackageSerializer(listOf(classDescriptor), emptyList(), packageFqName, destFile, project).run() } }) } if (members.isNotEmpty()) { val destFile = File(destDir, getPackageFilePath(packageFqName, file.name)) - PackageSerializer(emptyList(), members, packageFqName, destFile).run() + PackageSerializer(emptyList(), members, packageFqName, destFile, project).run() packageTable.getOrPut(packageFqName) { PackageParts(packageFqName.asString()) @@ -123,27 +124,29 @@ open class MetadataSerializer( private val classes: Collection, private val members: Collection, private val packageFqName: FqName, - private val destFile: File + private val destFile: File, + private val project: Project? = null ) { private val proto = ProtoBuf.PackageFragment.newBuilder() private val extension = createSerializerExtension() fun run() { val serializer = DescriptorSerializer.createTopLevel(extension) - serializeClasses(classes, serializer) + serializeClasses(classes, serializer, project) serializeMembers(members, serializer) serializeStringTable() serializeBuiltInsFile() } - private fun serializeClasses(classes: Collection, parentSerializer: DescriptorSerializer) { + private fun serializeClasses(classes: Collection, parentSerializer: DescriptorSerializer, project: Project?) { for (descriptor in DescriptorSerializer.sort(classes)) { if (descriptor !is ClassDescriptor || descriptor.kind == ClassKind.ENUM_ENTRY) continue - val serializer = DescriptorSerializer.create(descriptor, extension, parentSerializer) + val serializer = DescriptorSerializer.create(descriptor, extension, parentSerializer, project) serializeClasses( descriptor.unsubstitutedInnerClassesScope.getContributedDescriptors(DescriptorKindFilter.CLASSIFIERS), - serializer + serializer, + project ) proto.addClass_(serializer.classProto(descriptor).build()) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/DescriptorMetadataSerializer.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/DescriptorMetadataSerializer.kt index 5d05790cce0..dd5b8500938 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/DescriptorMetadataSerializer.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/DescriptorMetadataSerializer.kt @@ -6,12 +6,15 @@ package org.jetbrains.kotlin.backend.jvm.codegen import org.jetbrains.kotlin.backend.jvm.JvmBackendContext -import org.jetbrains.kotlin.codegen.* import org.jetbrains.kotlin.codegen.binding.CodegenBinding +import org.jetbrains.kotlin.codegen.createFreeFakeLambdaDescriptor import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension -import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.ir.declarations.DescriptorMetadataSource +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.MetadataSource +import org.jetbrains.kotlin.ir.util.getPackageFragment +import org.jetbrains.kotlin.ir.util.isInterface import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable import org.jetbrains.kotlin.protobuf.MessageLite import org.jetbrains.kotlin.serialization.DescriptorSerializer @@ -29,7 +32,7 @@ class DescriptorMetadataSerializer( private val serializer: DescriptorSerializer? = when (val metadata = irClass.metadata) { is DescriptorMetadataSource.Class -> DescriptorSerializer.create( - metadata.descriptor, serializerExtension, (parent as? DescriptorMetadataSerializer)?.serializer + metadata.descriptor, serializerExtension, (parent as? DescriptorMetadataSerializer)?.serializer, context.state.project ) is DescriptorMetadataSource.File -> DescriptorSerializer.createTopLevel(serializerExtension) is DescriptorMetadataSource.Function -> DescriptorSerializer.createForLambda(serializerExtension) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataIncrementalSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataIncrementalSerializer.kt index 1beaa803985..d5783df4044 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataIncrementalSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataIncrementalSerializer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.backend.common.serialization.metadata +import com.intellij.openapi.project.Project import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.ClassifierDescriptor @@ -22,9 +23,10 @@ import org.jetbrains.kotlin.serialization.DescriptorSerializer class KlibMetadataIncrementalSerializer( languageVersionSettings: LanguageVersionSettings, metadataVersion: BinaryVersion, + project: Project, skipExpects: Boolean, allowErrorTypes: Boolean = false -) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, skipExpects, allowErrorTypes = allowErrorTypes) { +) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, project, skipExpects, allowErrorTypes = allowErrorTypes) { fun serializePackageFragment( module: ModuleDescriptor, diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataMonolithicSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataMonolithicSerializer.kt index 969327b6a97..ec9bdc46465 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataMonolithicSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataMonolithicSerializer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.backend.common.serialization.metadata +import com.intellij.openapi.project.Project import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.packageFragments @@ -22,10 +23,11 @@ import org.jetbrains.kotlin.serialization.DescriptorSerializer class KlibMetadataMonolithicSerializer( languageVersionSettings: LanguageVersionSettings, metadataVersion: BinaryVersion, + project: Project?, skipExpects: Boolean, includeOnlyModuleContent: Boolean = false, allowErrorTypes: Boolean = false -) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, skipExpects, includeOnlyModuleContent, allowErrorTypes) { +) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, project, skipExpects, includeOnlyModuleContent, allowErrorTypes) { private fun serializePackageFragment(fqName: FqName, module: ModuleDescriptor): List { diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializer.kt index 2b6845c7ab1..54a5f4ba343 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/metadata/KlibMetadataSerializer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.backend.common.serialization.metadata +import com.intellij.openapi.project.Project import org.jetbrains.kotlin.backend.common.serialization.isExpectMember import org.jetbrains.kotlin.backend.common.serialization.isSerializableExpectClass import org.jetbrains.kotlin.config.AnalysisFlags @@ -31,6 +32,7 @@ internal fun Iterable.maybeChunked(size: Int?, transform: (List) -> abstract class KlibMetadataSerializer( val languageVersionSettings: LanguageVersionSettings, val metadataVersion: BinaryVersion, + val project: Project?, val skipExpects: Boolean = false, val includeOnlyModuleContent: Boolean = false, private val allowErrorTypes: Boolean @@ -93,7 +95,7 @@ abstract class KlibMetadataSerializer( with(serializerContext) { val previousSerializer = classSerializer - classSerializer = DescriptorSerializer.create(classDescriptor, serializerExtension, classSerializer) + classSerializer = DescriptorSerializer.create(classDescriptor, serializerExtension, classSerializer, project) val classProto = classSerializer.classProto(classDescriptor).build() ?: error("Class not serialized: $classDescriptor") //builder.addClass(classProto) diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index e5d28ef1f1b..966fce3cbad 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.backend.common.serialization.knownBuiltins import org.jetbrains.kotlin.backend.common.serialization.mangle.ManglerChecker import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter import org.jetbrains.kotlin.backend.common.serialization.metadata.DynamicTypeDeserializer +import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataIncrementalSerializer import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataVersion import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureDescriptor import org.jetbrains.kotlin.builtins.KotlinBuiltIns @@ -33,7 +34,6 @@ import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrLinker import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsIrModuleSerializer import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerDesc import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsManglerIr -import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataIncrementalSerializer import org.jetbrains.kotlin.ir.declarations.IrFactory import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns @@ -185,6 +185,7 @@ fun generateKLib( serializeModuleIntoKlib( moduleName, + project, configuration, psi2IrContext.bindingContext, files, @@ -418,7 +419,7 @@ private class ModulesStructure( val analysisResult = analyzer.analysisResult if (IncrementalCompilation.isEnabledForJs()) { /** can throw [IncrementalNextRoundException] */ - compareMetadataAndGoToNextICRoundIfNeeded(analysisResult, compilerConfiguration, files, errorPolicy.allowErrors) + compareMetadataAndGoToNextICRoundIfNeeded(analysisResult, compilerConfiguration, project, files, errorPolicy.allowErrors) } var hasErrors = false @@ -474,6 +475,7 @@ private fun getDescriptorForElement( fun serializeModuleIntoKlib( moduleName: String, + project: Project, configuration: CompilerConfiguration, bindingContext: BindingContext, files: List, @@ -497,7 +499,7 @@ fun serializeModuleIntoKlib( ).serializedIrModule(moduleFragment) val moduleDescriptor = moduleFragment.descriptor - val metadataSerializer = KlibMetadataIncrementalSerializer(configuration, containsErrorCode) + val metadataSerializer = KlibMetadataIncrementalSerializer(configuration, project, containsErrorCode) val incrementalResultsConsumer = configuration.get(JSConfigurationKeys.INCREMENTAL_RESULTS_CONSUMER) val empty = ByteArray(0) @@ -587,12 +589,13 @@ private fun KlibMetadataIncrementalSerializer.serializeScope( private fun compareMetadataAndGoToNextICRoundIfNeeded( analysisResult: AnalysisResult, config: CompilerConfiguration, + project: Project, files: List, allowErrors: Boolean ) { val nextRoundChecker = config.get(JSConfigurationKeys.INCREMENTAL_NEXT_ROUND_CHECKER) ?: return val bindingContext = analysisResult.bindingContext - val serializer = KlibMetadataIncrementalSerializer(config, allowErrors) + val serializer = KlibMetadataIncrementalSerializer(config, project, allowErrors) for (ktFile in files) { val packageFragment = serializer.serializeScope(ktFile, bindingContext, analysisResult.moduleDescriptor) // to minimize a number of IC rounds, we should inspect all proto for changes first, @@ -603,9 +606,10 @@ private fun compareMetadataAndGoToNextICRoundIfNeeded( if (nextRoundChecker.shouldGoToNextRound()) throw IncrementalNextRoundException() } -private fun KlibMetadataIncrementalSerializer(configuration: CompilerConfiguration, allowErrors: Boolean) = KlibMetadataIncrementalSerializer( +private fun KlibMetadataIncrementalSerializer(configuration: CompilerConfiguration, project: Project, allowErrors: Boolean) = KlibMetadataIncrementalSerializer( languageVersionSettings = configuration.languageVersionSettings, metadataVersion = configuration.metadataVersion, + project = project, skipExpects = !configuration.expectActualLinker, allowErrorTypes = allowErrors ) diff --git a/compiler/serialization/build.gradle.kts b/compiler/serialization/build.gradle.kts index 6fdbea9e069..54042ad32ff 100644 --- a/compiler/serialization/build.gradle.kts +++ b/compiler/serialization/build.gradle.kts @@ -5,7 +5,10 @@ plugins { dependencies { compile(project(":compiler:resolution")) + compile(project(":compiler:frontend")) compile(project(":core:deserialization")) + + compileOnly(intellijCoreDep()) { includeJars("intellij-core", rootProject = rootProject) } } sourceSets { diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt index ac7b522f635..b228360c995 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializer.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.serialization +import com.intellij.openapi.project.Project import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.isSuspendFunctionType import org.jetbrains.kotlin.builtins.isSuspendFunctionTypeOrSubtype @@ -755,13 +756,6 @@ class DescriptorSerializer private constructor( ) companion object { - private val plugins: MutableSet = mutableSetOf() - - @JvmStatic - fun registerSerializerPlugin(plugin: DescriptorSerializerPlugin) { - plugins.add(plugin) - } - @JvmStatic fun createTopLevel(extension: SerializerExtension): DescriptorSerializer = DescriptorSerializer( @@ -778,13 +772,15 @@ class DescriptorSerializer private constructor( fun create( descriptor: ClassDescriptor, extension: SerializerExtension, - parentSerializer: DescriptorSerializer? + parentSerializer: DescriptorSerializer?, + project: Project? = null ): DescriptorSerializer { val container = descriptor.containingDeclaration val parent = if (container is ClassDescriptor) - parentSerializer ?: create(container, extension, null) + parentSerializer ?: create(container, extension, null, project) else createTopLevel(extension) + val plugins = project?.let { DescriptorSerializerPlugin.getInstances(it) }.orEmpty() // Calculate type parameter ids for the outer class beforehand, as it would've had happened if we were always // serializing outer classes before nested classes. @@ -797,7 +793,7 @@ class DescriptorSerializer private constructor( if (container is ClassDescriptor && !isVersionRequirementTableWrittenCorrectly(extension.metadataVersion)) parent.versionRequirementTable else MutableVersionRequirementTable(), serializeTypeTableToFunction = false, - plugins.toList() + plugins ) for (typeParameter in descriptor.declaredTypeParameters) { serializer.typeParameters.intern(typeParameter) diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializerPlugin.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializerPlugin.kt index 23ca0170b39..a2854c2ceff 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializerPlugin.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/DescriptorSerializerPlugin.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.serialization import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable @@ -18,4 +19,7 @@ interface DescriptorSerializerPlugin { extension: SerializerExtension ) { } + + companion object : ProjectExtensionDescriptor( + "org.jetbrains.kotlin.DescriptorSerializerPlugin", DescriptorSerializerPlugin::class.java) } \ No newline at end of file diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/test/KlibTestUtil.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/test/KlibTestUtil.kt index 91ff8f45190..d1f33273a08 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/test/KlibTestUtil.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/test/KlibTestUtil.kt @@ -72,7 +72,8 @@ object KlibTestUtil { val serializer = KlibMetadataMonolithicSerializer( languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT, metadataVersion = KlibMetadataVersion.INSTANCE, - skipExpects = false + skipExpects = false, + project = null ) val serializedMetadata = serializer.serializeModule(module) diff --git a/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt b/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt index eac0b3b9cae..ba115516889 100644 --- a/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializerTest.kt @@ -84,7 +84,8 @@ class KotlinJavascriptSerializerTest : TestCaseWithTmpdir() { ) val serializedMetadata = KotlinJavascriptSerializationUtil.serializeMetadata( analysisResult.bindingContext, description, configuration.languageVersionSettings, - configuration.get(CommonConfigurationKeys.METADATA_VERSION) as? JsMetadataVersion ?: JsMetadataVersion.INSTANCE + configuration.get(CommonConfigurationKeys.METADATA_VERSION) as? JsMetadataVersion ?: JsMetadataVersion.INSTANCE, + config.project ) FileUtil.writeToFile(metaFile, serializedMetadata.asString()) } diff --git a/idea/resources/META-INF/kotlinx-serialization.xml b/idea/resources/META-INF/kotlinx-serialization.xml index 3e2a22229ab..e07cc010ae4 100644 --- a/idea/resources/META-INF/kotlinx-serialization.xml +++ b/idea/resources/META-INF/kotlinx-serialization.xml @@ -4,6 +4,7 @@ + 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 31a88b7c942..d25699c8c90 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 @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.serialization.js +import com.intellij.openapi.project.Project import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.* @@ -61,10 +62,11 @@ object KotlinJavascriptSerializationUtil { bindingContext: BindingContext, jsDescriptor: JsModuleDescriptor, languageVersionSettings: LanguageVersionSettings, - metadataVersion: JsMetadataVersion + metadataVersion: JsMetadataVersion, + project: Project ): SerializedMetadata { val serializedFragments = - emptyMap().missingMetadata(bindingContext, jsDescriptor.data, languageVersionSettings, metadataVersion) + emptyMap().missingMetadata(bindingContext, jsDescriptor.data, languageVersionSettings, metadataVersion, project) return SerializedMetadata(serializedFragments, jsDescriptor, languageVersionSettings, metadataVersion) } @@ -160,6 +162,7 @@ object KotlinJavascriptSerializationUtil { scope: Collection, fqName: FqName, languageVersionSettings: LanguageVersionSettings, + project: Project, metadataVersion: BinaryVersion ): ProtoBuf.PackageFragment { val builder = ProtoBuf.PackageFragment.newBuilder() @@ -184,7 +187,7 @@ object KotlinJavascriptSerializationUtil { for (descriptor in descriptors) { if (descriptor !is ClassDescriptor || skip(descriptor)) continue - val serializer = DescriptorSerializer.create(descriptor, extension, parentSerializer) + val serializer = DescriptorSerializer.create(descriptor, extension, parentSerializer, project) serializeClasses(descriptor.unsubstitutedInnerClassesScope.getContributedDescriptors(), serializer) val classProto = serializer.classProto(descriptor).build() ?: error("Class not serialized: $descriptor") builder.addClass_(classProto) @@ -305,7 +308,8 @@ fun Map.missingMetadata( bindingContext: BindingContext, moduleDescriptor: ModuleDescriptor, languageVersionSettings: LanguageVersionSettings, - metadataVersion: JsMetadataVersion + metadataVersion: JsMetadataVersion, + project: Project ): Map { val serializedFragments = HashMap() @@ -317,7 +321,7 @@ fun Map.missingMetadata( moduleDescriptor.packageFragmentProviderForModuleContentWithoutDependencies.packageFragments(fqName).flatMap { it.getMemberScope().getContributedDescriptors() }, - fqName, languageVersionSettings, metadataVersion + fqName, languageVersionSettings, project, metadataVersion ) if (!fragment.isEmpty()) { diff --git a/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt b/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt index d0226cd6773..caa6b693e16 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/benchmarks/GenerateIrRuntime.kt @@ -475,6 +475,7 @@ class GenerateIrRuntime { val tmpKlibDir = createTempDir().also { it.deleteOnExit() } serializeModuleIntoKlib( moduleName, + project, configuration, bindingContext, files, diff --git a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt index 5263705b93c..e60eeb9bb8c 100644 --- a/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt +++ b/js/js.translator/src/org/jetbrains/kotlin/js/facade/K2JSTranslator.kt @@ -18,44 +18,44 @@ package org.jetbrains.kotlin.js.facade import com.intellij.openapi.vfs.VfsUtilCore import org.jetbrains.kotlin.config.CommonConfigurationKeys -import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor +import org.jetbrains.kotlin.diagnostics.DiagnosticUtils.hasError import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult -import org.jetbrains.kotlin.js.config.JSConfigurationKeys -import org.jetbrains.kotlin.js.config.JsConfig -import org.jetbrains.kotlin.js.facade.exceptions.TranslationException -import org.jetbrains.kotlin.js.inline.JsInliner -import org.jetbrains.kotlin.js.inline.clean.* -import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver -import org.jetbrains.kotlin.js.translate.general.Translation -import org.jetbrains.kotlin.js.translate.utils.* -import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus -import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil -import org.jetbrains.kotlin.serialization.js.ast.JsAstSerializer -import org.jetbrains.kotlin.utils.JsMetadataVersion - -import java.io.ByteArrayOutputStream -import java.io.IOException -import java.util.ArrayList - -import org.jetbrains.kotlin.diagnostics.DiagnosticUtils.hasError import org.jetbrains.kotlin.js.backend.ast.JsBlock import org.jetbrains.kotlin.js.backend.ast.JsName import org.jetbrains.kotlin.js.backend.ast.JsProgramFragment import org.jetbrains.kotlin.js.backend.ast.JsStatement import org.jetbrains.kotlin.js.config.ErrorTolerancePolicy +import org.jetbrains.kotlin.js.config.JSConfigurationKeys +import org.jetbrains.kotlin.js.config.JsConfig import org.jetbrains.kotlin.js.coroutine.transformCoroutines +import org.jetbrains.kotlin.js.facade.exceptions.TranslationException +import org.jetbrains.kotlin.js.inline.JsInliner +import org.jetbrains.kotlin.js.inline.clean.resolveTemporaryNames +import org.jetbrains.kotlin.js.inline.clean.transformLabeledBlockToDoWhile import org.jetbrains.kotlin.js.inline.util.collectDefinedNamesInAllScopes +import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver import org.jetbrains.kotlin.js.translate.general.SourceFileTranslationResult +import org.jetbrains.kotlin.js.translate.general.Translation +import org.jetbrains.kotlin.js.translate.utils.BindingUtils +import org.jetbrains.kotlin.js.translate.utils.expandIsCalls import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus +import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingTrace +import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil import org.jetbrains.kotlin.serialization.js.ast.JsAstProtoBuf +import org.jetbrains.kotlin.serialization.js.ast.JsAstSerializer import org.jetbrains.kotlin.serialization.js.missingMetadata +import org.jetbrains.kotlin.utils.JsMetadataVersion +import java.io.ByteArrayOutputStream +import java.io.IOException +import java.util.* /** * An entry point of translator. @@ -221,7 +221,8 @@ class K2JSTranslator @JvmOverloads constructor( bindingContext, moduleDescriptor, config.configuration.languageVersionSettings, - config.configuration.get(CommonConfigurationKeys.METADATA_VERSION) as? JsMetadataVersion ?: JsMetadataVersion.INSTANCE + config.configuration.get(CommonConfigurationKeys.METADATA_VERSION) as? JsMetadataVersion ?: JsMetadataVersion.INSTANCE, + config.project ) for ((packageName, metadata) in additionalMetadata) { @@ -248,6 +249,7 @@ class K2JSTranslator @JvmOverloads constructor( scope, packageName, config.configuration.languageVersionSettings, + config.project, metadataVersion ?: JsMetadataVersion.INSTANCE ) } diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/konan/NativeDistributionCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/konan/NativeDistributionCommonizer.kt index 0a04d57e4f4..7255c59f086 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/konan/NativeDistributionCommonizer.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/konan/NativeDistributionCommonizer.kt @@ -189,7 +189,8 @@ class NativeDistributionCommonizer( val serializer = KlibMetadataMonolithicSerializer( languageVersionSettings = LanguageVersionSettingsImpl.DEFAULT, metadataVersion = KlibMetadataVersion.INSTANCE, - skipExpects = false + skipExpects = false, + project = null ) // 'targetsToCopy' are some targets with empty set of platform libraries diff --git a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationComponentRegistrar.kt b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationComponentRegistrar.kt index 05a94d702fa..75313dd7043 100644 --- a/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationComponentRegistrar.kt +++ b/plugins/kotlin-serialization/kotlin-serialization-compiler/src/org/jetbrains/kotlinx/serialization/compiler/extensions/SerializationComponentRegistrar.kt @@ -20,7 +20,7 @@ import org.jetbrains.kotlin.library.metadata.KlibMetadataSerializerProtocol import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension -import org.jetbrains.kotlin.serialization.DescriptorSerializer +import org.jetbrains.kotlin.serialization.DescriptorSerializerPlugin import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol import org.jetbrains.kotlinx.serialization.compiler.diagnostic.SerializationPluginDeclarationChecker @@ -30,6 +30,8 @@ class SerializationComponentRegistrar : ComponentRegistrar { } companion object { + internal val serializationDescriptorSerializer = SerializationDescriptorPluginForKotlinxSerialization() + fun registerExtensions(project: Project) { SyntheticResolveExtension.registerExtension(project, SerializationResolveExtension()) @@ -39,13 +41,12 @@ class SerializationComponentRegistrar : ComponentRegistrar { StorageComponentContainerContributor.registerExtension(project, SerializationPluginComponentContainerContributor()) + DescriptorSerializerPlugin.registerExtension(project, serializationDescriptorSerializer) registerProtoExtensions() } - internal val serializationDescriptorSerializer = SerializationDescriptorPluginForKotlinxSerialization() private fun registerProtoExtensions() { - DescriptorSerializer.registerSerializerPlugin(serializationDescriptorSerializer) SerializationPluginMetadataExtensions.registerAllExtensions(JvmProtoBufUtil.EXTENSION_REGISTRY) SerializationPluginMetadataExtensions.registerAllExtensions(JsSerializerProtocol.extensionRegistry) SerializationPluginMetadataExtensions.registerAllExtensions(KlibMetadataSerializerProtocol.extensionRegistry)