From dc8240c24ebd3b98f5a55fa5fbb7a166e97ae777 Mon Sep 17 00:00:00 2001 From: Alexander Gorshenev Date: Mon, 28 Oct 2019 17:34:52 +0300 Subject: [PATCH] Expect/actual support in klibs under -Xklib-mpp --- .../arguments/CommonCompilerArguments.kt | 7 + .../jetbrains/kotlin/cli/common/arguments.kt | 1 + .../jetbrains/kotlin/config/AnalysisFlags.kt | 3 + .../kotlin/config/CommonConfigurationKeys.kt | 3 + .../ExpectedActualDeclarationChecker.kt | 2 + .../backend/common/ir/descriptorBasedUtils.kt | 18 +- .../kotlin/ir/backend/js/compiler.kt | 2 + .../kotlin/backend/jvm/JvmBackendFacade.kt | 2 +- .../jetbrains/kotlin/backend/wasm/compiler.kt | 1 + .../kotlin/psi2ir/Psi2IrTranslator.kt | 12 +- .../generators/ExpectDependencyGenerator.kt | 86 ++++ .../psi2ir/generators/ModuleGenerator.kt | 6 +- .../kotlin/ir/symbols/IrDelegatingSymbol.kt | 51 ++ .../serialization.common/src/KotlinIr.proto | 6 + .../serialization/DescriptorReferenceFlags.kt | 3 +- .../DeserializeDescriptorReference.kt | 41 +- .../common/serialization/ExpectActualTable.kt | 120 +++++ .../common/serialization/IrFileSerializer.kt | 42 +- .../common/serialization/KotlinIrLinker.kt | 88 +++- .../common/serialization/KotlinMangler.kt | 7 +- .../SerializeDescriptorReference.kt | 9 +- .../KlibMetadataIncrementalSerializer.kt | 10 +- .../KlibMetadataMonolithicSerializer.kt | 10 +- .../metadata/KlibMetadataSerializer.kt | 34 +- .../common/serialization/proto/Actual.java | 428 ++++++++++++++++ .../serialization/proto/ActualOrBuilder.java | 27 + .../proto/ExpectActualTable.java | 479 ++++++++++++++++++ .../proto/ExpectActualTableOrBuilder.java | 23 + .../serialization/proto/ExpectToActual.java | 420 +++++++++++++++ .../proto/ExpectToActualOrBuilder.java | 27 + .../common/serialization/proto/IrFile.java | 208 ++++++++ .../serialization/proto/IrFileOrBuilder.java | 14 + .../jetbrains/kotlin/ir/backend/js/klib.kt | 34 +- .../serialization/ir/JsIrFileSerializer.kt | 6 +- .../serialization/ir/JsIrModuleSerializer.kt | 13 +- .../multiplatform/ExpectedActualResolver.kt | 27 +- compiler/testData/cli/js/jsExtraHelp.out | 1 + compiler/testData/cli/jvm/extraHelp.out | 1 + .../multiModule/expectActualLink.kt | 60 +++ .../multiModule/expectActualMemberLink.kt | 84 +++ .../multiModule/expectActualTypealiasLink.kt | 91 ++++ .../codegen/BlackBoxCodegenTestGenerated.java | 28 + .../LightAnalysisModeTestGenerated.java | 28 + .../ir/FirBlackBoxCodegenTestGenerated.java | 28 + .../ir/IrBlackBoxCodegenTestGenerated.java | 28 + .../DeserializedClassDescriptor.kt | 2 +- .../jetbrains/kotlin/js/test/BasicBoxTest.kt | 20 +- .../IrJsCodegenBoxTestGenerated.java | 28 + .../semantics/JsCodegenBoxTestGenerated.java | 28 + 49 files changed, 2623 insertions(+), 74 deletions(-) create mode 100644 compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ExpectDependencyGenerator.kt create mode 100644 compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/IrDelegatingSymbol.kt create mode 100644 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/ExpectActualTable.kt create mode 100644 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/Actual.java create mode 100644 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ActualOrBuilder.java create mode 100644 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectActualTable.java create mode 100644 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectActualTableOrBuilder.java create mode 100644 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectToActual.java create mode 100644 compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectToActualOrBuilder.java create mode 100644 compiler/testData/codegen/box/multiplatform/multiModule/expectActualLink.kt create mode 100644 compiler/testData/codegen/box/multiplatform/multiModule/expectActualMemberLink.kt create mode 100644 compiler/testData/codegen/box/multiplatform/multiModule/expectActualTypealiasLink.kt diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt index d15d331e2dcab..fe2f48bbaac63 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt @@ -320,6 +320,12 @@ abstract class CommonCompilerArguments : CommonToolArguments() { ) var useMixedNamedArguments: Boolean by FreezableVar(false) + @Argument( + value = "-Xklib-mpp", + description = "Enable experimental support for multi-platform klib libraries" + ) + var klibBasedMpp: Boolean by FreezableVar(false) + @Argument(value = "-Xdisable-default-scripting-plugin", description = "Do not enable scripting plugin by default") var disableDefaultScriptingPlugin: Boolean by FreezableVar(false) @@ -341,6 +347,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() { collector.report(CompilerMessageSeverity.WARNING, "'-Xexperimental' is deprecated and will be removed in a future release") } put(AnalysisFlags.useExperimental, useExperimental?.toList().orEmpty() + optIn?.toList().orEmpty()) + put(AnalysisFlags.klibBasedMpp, klibBasedMpp) put(AnalysisFlags.explicitApiVersion, apiVersion != null) put(AnalysisFlags.allowResultReturnType, allowResultReturnType) ExplicitApiMode.fromString(explicitApi)?.also { put(AnalysisFlags.explicitApiMode, it) } ?: collector.report( diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt index 9e5317fa588df..3ff837810ed3b 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt @@ -23,6 +23,7 @@ fun CompilerConfiguration.setupCommonArguments( ) { put(CommonConfigurationKeys.DISABLE_INLINE, arguments.noInline) put(CommonConfigurationKeys.USE_FIR, arguments.useFir) + put(CommonConfigurationKeys.KLIB_MPP, arguments.klibBasedMpp) putIfNotNull(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT, arguments.intellijPluginRoot) put(CommonConfigurationKeys.REPORT_OUTPUT_FILES, arguments.reportOutputFiles) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/config/AnalysisFlags.kt b/compiler/frontend/src/org/jetbrains/kotlin/config/AnalysisFlags.kt index 9b7be407f4ac5..8ee962b13ee4a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/config/AnalysisFlags.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/config/AnalysisFlags.kt @@ -12,6 +12,9 @@ object AnalysisFlags { @JvmStatic val multiPlatformDoNotCheckActual by AnalysisFlag.Delegates.Boolean + @JvmStatic + val klibBasedMpp by AnalysisFlag.Delegates.Boolean + @JvmStatic val experimental by AnalysisFlag.Delegates.ListOfStrings diff --git a/compiler/frontend/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt b/compiler/frontend/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt index 3121125bb963c..0ec525283b722 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt @@ -44,6 +44,9 @@ object CommonConfigurationKeys { @JvmField val USE_FIR = CompilerConfigurationKey.create("front-end IR") + + @JvmField + val KLIB_MPP = CompilerConfigurationKey.create("Klib based MPP") } var CompilerConfiguration.languageVersionSettings: LanguageVersionSettings diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt index caac5b873ec0f..5e5d63f257212 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt @@ -54,6 +54,8 @@ class ExpectedActualDeclarationChecker( override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) { if (!context.languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) return + // TODO: we need a klib based MPP aware ModuleStructureOracle. Just disable the checks for now. + if (context.languageVersionSettings.getFlag(AnalysisFlags.klibBasedMpp)) return // Note that this check is necessary, because for default accessors KtProperty is passed for KtDeclaration, so this // case won't be covered by the next check (also, it accidentally fixes KT-28385) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/descriptorBasedUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/descriptorBasedUtils.kt index bab7c3754a6ec..a218ebd39936e 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/descriptorBasedUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/descriptorBasedUtils.kt @@ -5,12 +5,20 @@ package org.jetbrains.kotlin.backend.common.ir -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrDeclaration -import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.declarations.IrProperty +import org.jetbrains.kotlin.ir.declarations.* val IrDeclaration.isExpect get() = this is IrClass && isExpect || this is IrFunction && isExpect || - this is IrProperty && isExpect \ No newline at end of file + this is IrProperty && isExpect + +// The original isExpect represents what user has written. +// This predicate means "there can possibly exist an 'actual' for the given declaration". +// Shouldn't it be incorporated to descriptor -> ir declaration psi2ir translation phase? +val IrDeclaration.isProperExpect + get() = this is IrClass && isExpect || + this is IrFunction && isExpect || + this is IrProperty && isExpect || + (this is IrClass || this is IrFunction || this is IrProperty || this is IrConstructor || this is IrEnumEntry) + && (this.parent as? IrDeclaration)?.isExpect ?: false + diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt index 362bb52c6ff10..f2fc1289c1c21 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/compiler.kt @@ -82,6 +82,8 @@ fun compile( ExternalDependenciesGenerator(symbolTable, irProvidersWithoutDeserializer).generateUnboundSymbolsAsDependencies() moduleFragment.patchDeclarationParents() + deserializer.finalizeExpectActualLinker() + moveBodilessDeclarationsToSeparatePlace(context, moduleFragment) jsPhases.invokeToplevel(phaseConfig, context, moduleFragment) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt index 1544bd1a1e179..b8e013818cf03 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendFacade.kt @@ -47,7 +47,7 @@ object JvmBackendFacade { psi2irContext.moduleDescriptor, psi2irContext.irBuiltIns, psi2irContext.symbolTable, extensions = extensions ) - val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files, irProviders = irProviders) + val irModuleFragment = psi2ir.generateModuleFragment(psi2irContext, files, irProviders = irProviders, expectDescriptorToSymbol = null) doGenerateFilesInternal( state, irModuleFragment, psi2irContext.symbolTable, psi2irContext.sourceManager, phaseConfig, irProviders, extensions ) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt index 210d630809406..9a77bffe90551 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/compiler.kt @@ -51,6 +51,7 @@ fun compileWasm( val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer) ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies() moduleFragment.patchDeclarationParents() + deserializer.finalizeExpectActualLinker() wasmPhases.invokeToplevel(phaseConfig, context, moduleFragment) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt index ca1b188eff4b9..7f68bd6cc3bec 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/Psi2IrTranslator.kt @@ -17,16 +17,15 @@ package org.jetbrains.kotlin.psi2ir import org.jetbrains.kotlin.config.LanguageVersionSettings +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi2ir.generators.AnnotationGenerator -import org.jetbrains.kotlin.psi2ir.generators.GeneratorContext -import org.jetbrains.kotlin.psi2ir.generators.GeneratorExtensions -import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator +import org.jetbrains.kotlin.psi2ir.generators.* import org.jetbrains.kotlin.psi2ir.transformations.insertImplicitCasts import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.utils.SmartList @@ -68,11 +67,13 @@ class Psi2IrTranslator( fun generateModuleFragment( context: GeneratorContext, ktFiles: Collection, - irProviders: List + irProviders: List, + expectDescriptorToSymbol: MutableMap? = null ): IrModuleFragment { val moduleGenerator = ModuleGenerator(context) val irModule = moduleGenerator.generateModuleFragmentWithoutDependencies(ktFiles) + expectDescriptorToSymbol ?. let { referenceExpectsForUsedActuals(it, context.symbolTable, irModule) } irModule.patchDeclarationParents() postprocess(context, irModule) // do not generate unbound symbols before postprocessing, @@ -81,6 +82,7 @@ class Psi2IrTranslator( irModule.computeUniqIdForDeclarations(context.symbolTable) moduleGenerator.generateUnboundSymbolsAsDependencies(irProviders) + return irModule } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ExpectDependencyGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ExpectDependencyGenerator.kt new file mode 100644 index 0000000000000..333ecbef1f0cb --- /dev/null +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ExpectDependencyGenerator.kt @@ -0,0 +1,86 @@ +package org.jetbrains.kotlin.psi2ir.generators + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.symbols.IrSymbol +import org.jetbrains.kotlin.ir.types.classOrNull +import org.jetbrains.kotlin.ir.util.SymbolTable +import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid +import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.resolve.multiplatform.findExpects + +// Need to create unbound symbols for expects corresponding to actuals of the currently compiled module. +// This is neccessary because there is no explicit links between expects and actuals +// neither in descriptors nor in IR. +fun referenceExpectsForUsedActuals(expectDescriptorToSymbol: MutableMap, symbolTable: SymbolTable, irModule: IrModuleFragment) { + irModule.acceptVoid(object : IrElementVisitorVoid { + + private fun T.forEachExpect(body: (DeclarationDescriptor) -> Unit) where T: IrDeclaration { + this.descriptor.findExpects().forEach { + body(it) + } + } + + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + override fun visitClass(declaration: IrClass) { + declaration.forEachExpect { + val symbol = symbolTable.referenceClass(it as ClassDescriptor) + expectDescriptorToSymbol.put(it, symbol); + it.constructors.forEach { + expectDescriptorToSymbol.put(it, symbolTable.referenceConstructor(it as ClassConstructorDescriptor)) + } + } + super.visitDeclaration(declaration) + } + override fun visitSimpleFunction(declaration: IrSimpleFunction) { + declaration.forEachExpect { + val symbol = symbolTable.referenceSimpleFunction(it as FunctionDescriptor); + expectDescriptorToSymbol.put(it, symbol); + } + super.visitDeclaration(declaration) + } + override fun visitConstructor(declaration: IrConstructor) { + declaration.forEachExpect { + val symbol = symbolTable.referenceConstructor(it as ClassConstructorDescriptor) + expectDescriptorToSymbol.put(it, symbol); + + } + super.visitDeclaration(declaration) + } + override fun visitProperty(declaration: IrProperty) { + declaration.forEachExpect { + val symbol = symbolTable.referenceProperty(it as PropertyDescriptor) + expectDescriptorToSymbol.put(it, symbol); + } + super.visitDeclaration(declaration) + } + override fun visitEnumEntry(declaration: IrEnumEntry) { + declaration.forEachExpect { + val symbol = symbolTable.referenceEnumEntry(it as ClassDescriptor) + expectDescriptorToSymbol.put(it, symbol); + + } + super.visitDeclaration(declaration) + } + override fun visitTypeAlias(declaration: IrTypeAlias) { + // Force actual type alias right hand side deserialization. + if (declaration.isActual) { + declaration.expandedType.classOrNull?.descriptor?.let { symbolTable.referenceClass(it) } + } + + declaration.forEachExpect { + val symbol = when (it) { + is ClassDescriptor -> symbolTable.referenceClass(it) + else -> error("Unexpected expect for actual type alias: $it") + } + expectDescriptorToSymbol.put(it, symbol); + + } + super.visitDeclaration(declaration) + } + }) +} diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt index 792a47d183217..0081e43fd871c 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ModuleGenerator.kt @@ -22,11 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.MetadataSource import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl -import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator -import org.jetbrains.kotlin.ir.util.IrDeserializer -import org.jetbrains.kotlin.ir.util.IrProvider -import org.jetbrains.kotlin.ir.util.StubGeneratorExtensions -import org.jetbrains.kotlin.ir.util.generateTypicalIrProviderList +import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.lazy.descriptors.findPackageFragmentForFile diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/IrDelegatingSymbol.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/IrDelegatingSymbol.kt new file mode 100644 index 0000000000000..6116ce96de89f --- /dev/null +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/symbols/IrDelegatingSymbol.kt @@ -0,0 +1,51 @@ +package org.jetbrains.kotlin.ir.symbols + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.util.UniqId + +abstract class IrDelegatingSymbol, B: IrSymbolOwner, D: DeclarationDescriptor>(var delegate: S) + : IrBindableSymbol { + override val owner: B get() = delegate.owner + override val descriptor: D get() = delegate.descriptor + override val isBound: Boolean get() = delegate.isBound + override var uniqId: UniqId + get() = delegate.uniqId + set(value: UniqId) { delegate.uniqId = value } + + override fun bind(owner: B) = delegate.bind(owner) + override fun hashCode() = delegate.hashCode() + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (this === delegate) return true + return false + } +} + +class IrDelegatingClassSymbolImpl(delegate: IrClassSymbol) : + IrClassSymbol, IrDelegatingSymbol(delegate) + +class IrDelegatingEnumEntrySymbolImpl(delegate: IrEnumEntrySymbol) : + IrEnumEntrySymbol, IrDelegatingSymbol(delegate) + +class IrDelegatingSimpleFunctionSymbolImpl(delegate: IrSimpleFunctionSymbol) : + IrSimpleFunctionSymbol, IrDelegatingSymbol(delegate) + +class IrDelegatingConstructorSymbolImpl(delegate: IrConstructorSymbol) : + IrConstructorSymbol, IrDelegatingSymbol(delegate) + +class IrDelegatingPropertySymbolImpl(delegate: IrPropertySymbol) : + IrPropertySymbol, IrDelegatingSymbol(delegate) + +class IrDelegatingTypeAliasSymbolImpl(delegate: IrTypeAliasSymbol) : + IrTypeAliasSymbol, IrDelegatingSymbol(delegate) + +fun wrapInDelegatedSymbol(delegate: IrSymbol) = when(delegate) { + is IrClassSymbol -> IrDelegatingClassSymbolImpl(delegate) + is IrEnumEntrySymbol -> IrDelegatingEnumEntrySymbolImpl(delegate) + is IrSimpleFunctionSymbol -> IrDelegatingSimpleFunctionSymbolImpl(delegate) + is IrConstructorSymbol -> IrDelegatingConstructorSymbolImpl(delegate) + is IrPropertySymbol -> IrDelegatingPropertySymbolImpl(delegate) + is IrTypeAliasSymbol -> IrDelegatingTypeAliasSymbolImpl(delegate) + else -> error("Unexpected symbol to delegate to: $delegate") +} \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/KotlinIr.proto b/compiler/ir/serialization.common/src/KotlinIr.proto index 7f73ed2a3908f..8d8aa97399039 100644 --- a/compiler/ir/serialization.common/src/KotlinIr.proto +++ b/compiler/ir/serialization.common/src/KotlinIr.proto @@ -81,6 +81,7 @@ message IrFile { repeated int32 fq_name = 3; repeated IrConstructorCall annotation = 4; repeated int32 explicitly_exported_to_compiler = 5; + repeated Actual actuals = 6; } /* ------ IrSymbols --------------------------------------------- */ @@ -113,6 +114,11 @@ message IrSymbolData { optional DescriptorReference descriptor_reference = 7; } +message Actual { + required int32 actual_symbol = 1; + required int32 expect_symbol = 2; +} + /* ------ IrTypes --------------------------------------------- */ enum IrTypeVariance { // Should we import metadata variance, or better stay separate? diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DescriptorReferenceFlags.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DescriptorReferenceFlags.kt index 8cf752f470d3c..ecf5d585fb870 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DescriptorReferenceFlags.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DescriptorReferenceFlags.kt @@ -14,7 +14,8 @@ enum class DescriptorReferenceFlags { IS_DEFAULT_CONSTRUCTOR, IS_ENUM_ENTRY, IS_ENUM_SPECIAL, - IS_TYPE_PARAMETER; + IS_TYPE_PARAMETER, + IS_EXPECT; fun encode(isSet: Boolean): Int = if (isSet) 1 shl ordinal else 0 fun decode(flags: Int): Boolean = (flags and (1 shl ordinal) != 0) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeserializeDescriptorReference.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeserializeDescriptorReference.kt index 1b12696c703a1..3b8e92ac0cc13 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeserializeDescriptorReference.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/DeserializeDescriptorReference.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe +import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor @@ -87,6 +88,21 @@ abstract class DescriptorReferenceDeserializer( return ClassMembers(classConstructorDescriptor, allMembersMap, realMembersMap) } + // TODO: the real findExpects() returns a list. + // Need to account for multiple expects here. + private fun MemberDescriptor.toExpect() = + if (this.isExpect) + this + else + ExpectedActualResolver.findExpectedForActual( + this, + currentModule, + { true } + )?.get(ExpectedActualResolver.Compatibility.Compatible)?.single() + + private fun Collection.toExpects() = this.map { (it as MemberDescriptor).toExpect() }.filterNotNull().distinct() + + open fun deserializeDescriptorReference( packageFqName: FqName, classFqName: FqName, @@ -98,10 +114,21 @@ abstract class DescriptorReferenceDeserializer( val protoIndex = index val (clazz, members) = if (classFqName.isRoot) { - Pair(null, getContributedDescriptors(packageFqName, name)) + Pair(null, + getContributedDescriptors(packageFqName, name).let { + if (DescriptorReferenceFlags.IS_EXPECT.decode(flags)) it.toExpects() else it + } + ) } else { - val clazz = currentModule.findClassAcrossModuleDependencies(ClassId(packageFqName, classFqName, false))!! - Pair(clazz, getContributedDescriptors(clazz.unsubstitutedMemberScope, name) + clazz.getConstructors()) + val classifier = (currentModule.findClassifierAcrossModuleDependencies(ClassId(packageFqName, classFqName, false)) as? MemberDescriptor) + ?: error("Could not find class across modules: $packageFqName/$classFqName") + + val expect = if (DescriptorReferenceFlags.IS_EXPECT.decode(flags)) { + classifier.toExpect() + } else null + + val expectOrActualClass = (expect as ClassDescriptor?) ?: (classifier as ClassDescriptor) // TODO: OMG!!! + Pair(expectOrActualClass, getContributedDescriptors(expectOrActualClass.unsubstitutedMemberScope, name) + expectOrActualClass.getConstructors()) } // TODO: This is still native specific. Eliminate. @@ -157,7 +184,7 @@ abstract class DescriptorReferenceDeserializer( val membersWithIndices = getMembers(members) - return when { + val result = when { DescriptorReferenceFlags.IS_DEFAULT_CONSTRUCTOR.decode(flags) -> membersWithIndices.defaultConstructor else -> { @@ -172,5 +199,11 @@ abstract class DescriptorReferenceDeserializer( } } ?: error("Could not find serialized descriptor for index: ${index} ${packageFqName},${classFqName},${name}") + + // TODO: why we don't have "expect" bit on all the expect declarations? + //if (DescriptorReferenceFlags.IS_EXPECT.decode(flags)) assert(if (result is ClassConstructorDescriptor) result.constructedClass.isExpect() else result.isExpectMember) { + // "expected expect, found $result" + //} + return result } } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/ExpectActualTable.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/ExpectActualTable.kt new file mode 100644 index 0000000000000..644f8c3690bec --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/ExpectActualTable.kt @@ -0,0 +1,120 @@ +package org.jetbrains.kotlin.backend.common.serialization + +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.symbols.IrSymbol +import org.jetbrains.kotlin.ir.types.classOrNull +import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid +import org.jetbrains.kotlin.ir.visitors.acceptVoid +import org.jetbrains.kotlin.resolve.descriptorUtil.module +import org.jetbrains.kotlin.resolve.multiplatform.findActuals +import org.jetbrains.kotlin.resolve.multiplatform.findExpects + +class ExpectActualTable(val expectDescriptorToSymbol: MutableMap) { + val table = mutableMapOf() + + private fun IrElement.recordActuals(rightHandSide: Map, inModule: ModuleDescriptor) { + this.acceptVoid(object : IrElementVisitorVoid { + + private fun recordDeclarationActuals(declaration: IrDeclaration) { + + expectDescriptorToSymbol.put(declaration.descriptor, (declaration as IrSymbolOwner).symbol) + + declaration.descriptor.findActuals(inModule).forEach { + val realActual = if (it is TypeAliasDescriptor) + it.expandedType.constructor.declarationDescriptor as? ClassDescriptor + ?: error("Unexpected actual typealias right hand side: $it") + else it + + // TODO: what to do with fake overrides??? + if (!(realActual is CallableMemberDescriptor && realActual.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE)) { + table.put( + declaration.descriptor, rightHandSide[realActual] + ?: error("Could not find actual type alias target member for: ${declaration.descriptor} -> $it") + ) + } + } + } + + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + + override fun visitFunction(declaration: IrFunction) { + recordDeclarationActuals(declaration) + super.visitFunction(declaration) + } + override fun visitClass(declaration: IrClass) { + recordDeclarationActuals(declaration) + super.visitClass(declaration) + } + override fun visitProperty(declaration: IrProperty) { + recordDeclarationActuals(declaration) + super.visitProperty(declaration) + } + override fun visitEnumEntry(declaration: IrEnumEntry) { + recordDeclarationActuals(declaration) + super.visitEnumEntry(declaration) + } + }) + } + + private fun IrDeclaration.recordRightHandSide(): Map { + val rightHandSide = mutableMapOf() + + this.acceptVoid(object : IrElementVisitorVoid { + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + override fun visitFunction(declaration: IrFunction) { + rightHandSide.put(declaration.descriptor, declaration.symbol) + super.visitFunction(declaration) + } + override fun visitClass(declaration: IrClass) { + rightHandSide.put(declaration.descriptor, declaration.symbol) + super.visitClass(declaration) + } + override fun visitProperty(declaration: IrProperty) { + rightHandSide.put(declaration.descriptor, declaration.symbol) + super.visitProperty(declaration) + } + override fun visitEnumEntry(declaration: IrEnumEntry) { + rightHandSide.put(declaration.descriptor, declaration.symbol) + super.visitEnumEntry(declaration) + } + }) + return rightHandSide + } + + fun findExpectsForActuals(declaration: IrDeclaration) { + if (declaration.descriptor !is MemberDescriptor) return + if (declaration !is IrSymbolDeclaration<*>) return + + val descriptor = declaration.symbol.descriptor + + if (declaration is IrTypeAlias && declaration.isActual) { + val rightHandSide = declaration.expandedType.classOrNull?.owner?.recordRightHandSide() + ?: error("Unexpected right hand side of actual typealias: ${declaration.descriptor}") + + + declaration.descriptor.findExpects().forEach { + expectDescriptorToSymbol[it]?.owner?.recordActuals(rightHandSide, declaration.descriptor.module) + } + return + } + + val expects: List = if (descriptor is ClassConstructorDescriptor && descriptor.isPrimary) { + (descriptor.containingDeclaration.findExpects() as List).map { + it.unsubstitutedPrimaryConstructor + }.filterNotNull() + } else { + descriptor.findExpects() + } + + expects.forEach { expect -> + table.put(expect, declaration.symbol) + } + } +} \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt index cd9c0b391cf0e..4631bd6f7b4e5 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileSerializer.kt @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.util.findTopLevelDeclaration import org.jetbrains.kotlin.ir.util.lineStartOffsets +import org.jetbrains.kotlin.ir.util.module import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid @@ -115,16 +116,22 @@ import org.jetbrains.kotlin.backend.common.serialization.proto.ModalityKind as P import org.jetbrains.kotlin.backend.common.serialization.proto.NullableIrExpression as ProtoNullableIrExpression import org.jetbrains.kotlin.backend.common.serialization.proto.TypeArguments as ProtoTypeArguments import org.jetbrains.kotlin.backend.common.serialization.proto.Visibility as ProtoVisibility +import org.jetbrains.kotlin.backend.common.serialization.proto.Actual as ProtoActual open class IrFileSerializer( val logger: LoggingContext, private val declarationTable: DeclarationTable, - private val bodiesOnlyForInlines: Boolean = false + private val expectDescriptorToSymbol: MutableMap, + private val bodiesOnlyForInlines: Boolean = false, + private val skipExpects: Boolean = false ) { - private val loopIndex = mutableMapOf() private var currentLoopIndex = 0 + // For every actual we keep a corresponding expects' uniqIds. + // The linker substitutes actual symbols when asked for an expect uniqId. + private val expectActualTable = ExpectActualTable(expectDescriptorToSymbol) + // The same symbol can be used multiple times in a file // so use this index to store symbol data only once. private val protoSymbolMap = mutableMapOf() @@ -141,7 +148,7 @@ open class IrFileSerializer( private val protoBodyArray = mutableListOf() private val descriptorReferenceSerializer = - DescriptorReferenceSerializer(declarationTable, { serializeString(it) }, { serializeFqName(it) }) + DescriptorReferenceSerializer(declarationTable, { serializeString(it) }, { serializeFqName(it) }, skipExpects) sealed class XStatementOrExpression { abstract fun toByteArray(): ByteArray @@ -984,13 +991,15 @@ open class IrFileSerializer( return proto.build() } - private fun serializeIrDeclarationBase(declaration: IrDeclaration) = - ProtoDeclarationBase.newBuilder() + private fun serializeIrDeclarationBase(declaration: IrDeclaration): ProtoDeclarationBase { + expectActualTable.findExpectsForActuals(declaration) + return ProtoDeclarationBase.newBuilder() .setSymbol(serializeIrSymbol((declaration as IrSymbolOwner).symbol)) .setCoordinates(serializeCoordinates(declaration.startOffset, declaration.endOffset)) .addAllAnnotation(serializeAnnotations(declaration.annotations)) .setOrigin(serializeIrDeclarationOrigin(declaration.origin)) .build() + } private fun serializeIrValueParameter(parameter: IrValueParameter): ProtoValueParameter { val proto = ProtoValueParameter.newBuilder() @@ -1280,7 +1289,7 @@ open class IrFileSerializer( .addAllAnnotation(serializeAnnotations(file.annotations)) file.declarations.forEach { - if (it.descriptor.isExpectMember && !it.descriptor.isSerializableExpectClass) { + if (skipExpects && it.descriptor.isExpectMember && !it.descriptor.isSerializableExpectClass) { topLevelDeclarations.add(SkippedDeclaration) return@forEach } @@ -1323,6 +1332,8 @@ open class IrFileSerializer( } }) + serializeExpectActualSubstitutionTable(proto) + return SerializedIrFile( proto.build().toByteArray(), file.fqName.asString(), @@ -1334,4 +1345,23 @@ open class IrFileSerializer( IrMemoryDeclarationWriter(topLevelDeclarations).writeIntoMemory() ) } + + fun serializeExpectActualSubstitutionTable(proto: ProtoFile.Builder) { + if (skipExpects) return + + expectActualTable.table.forEach next@{ (expect, actualSymbol) -> + val expectSymbol = expectDescriptorToSymbol[expect] + ?: error("Could not find expect symbol for expect descriptor $expect") + val expectDeclaration = expectSymbol.owner as IrDeclaration + val actualDeclaration = actualSymbol.owner as IrDeclaration + + proto.addActuals( + ProtoActual.newBuilder() + .setExpectSymbol(serializeIrSymbol(expectSymbol)) + .setActualSymbol(serializeIrSymbol(actualSymbol)) + .build() + ) + } + } } + diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt index 8732bfd091d6b..802ef2c8f9a5e 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt @@ -10,9 +10,7 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET -import org.jetbrains.kotlin.ir.declarations.IrDeclaration -import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.declarations.IrModuleFragment +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl @@ -21,8 +19,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl import org.jetbrains.kotlin.ir.expressions.impl.IrLoopBase -import org.jetbrains.kotlin.ir.symbols.IrClassSymbol -import org.jetbrains.kotlin.ir.symbols.IrSymbol +import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.impl.IrErrorTypeImpl @@ -41,6 +38,7 @@ import org.jetbrains.kotlin.backend.common.serialization.proto.IrType as ProtoTy import org.jetbrains.kotlin.backend.common.serialization.proto.IrStatement as ProtoStatement import org.jetbrains.kotlin.backend.common.serialization.proto.IrExpression as ProtoExpression import org.jetbrains.kotlin.backend.common.serialization.proto.IrConstructorCall as ProtoConstructorCall +import org.jetbrains.kotlin.backend.common.serialization.proto.Actual as ProtoActual abstract class KotlinIrLinker( val logger: LoggingContext, @@ -51,6 +49,10 @@ abstract class KotlinIrLinker( mangler: KotlinMangler ) : DescriptorUniqIdAware, IrDeserializer { + private val expectUniqIdToActualUniqId = mutableMapOf() + private val topLevelActualUniqItToDeserializer = mutableMapOf() + private val expectSymbols = mutableMapOf() + private val actualSymbols = mutableMapOf() sealed class DeserializationState { val deserializedSymbols = mutableMapOf() @@ -139,6 +141,7 @@ abstract class KotlinIrLinker( inner class IrDeserializerForFile( private var annotations: List?, + private val actuals: List, private val fileIndex: Int, onlyHeaders: Boolean ) : IrFileDeserializer(logger, builtIns, symbolTable) { @@ -161,6 +164,21 @@ abstract class KotlinIrLinker( return deserializeDeclaration(loadTopLevelDeclarationProto(key), file) } + fun deserializeExpectActualMapping() { + actuals.forEach { + val expectSymbol = loadSymbolProto(it.expectSymbol) + val actualSymbol = loadSymbolProto(it.actualSymbol) + val expect = UniqId(expectSymbol.uniqIdIndex) + val actual = UniqId(actualSymbol.uniqIdIndex) + assert(expectUniqIdToActualUniqId[expect] == null) { + "Expect uniqid ${expect.index} is already actualized by ${expectUniqIdToActualUniqId[expect]?.index}, while we try to record ${actual.index}" + } + expectUniqIdToActualUniqId.put(expect, actual) + // Non-null only for topLevel declarations. + getModuleForTopLevelId(actual)?. let { topLevelActualUniqItToDeserializer.put(actual, it) } + } + } + private fun loadTopLevelDeclarationProto(uniqId: UniqId): ProtoDeclaration { val stream = reader(moduleDescriptor, fileIndex, uniqId).codedInputStream return ProtoDeclaration.parseFrom(stream, newInstance()) @@ -323,7 +341,14 @@ abstract class KotlinIrLinker( if (it !in fdState) fdState.addUniqID(it) } - referenceDeserializedSymbol(proto, descriptor) + val symbol = referenceDeserializedSymbol(proto, descriptor).let { + if (expectUniqIdToActualUniqId[key] != null) wrapInDelegatedSymbol(it) else it + } + + if (key in expectUniqIdToActualUniqId.keys) expectSymbols.put(key, symbol) + if (key in expectUniqIdToActualUniqId.values) actualSymbols.put(key, symbol) + + symbol } if (symbol.descriptor is ClassDescriptor && symbol.descriptor !is WrappedDeclarationDescriptor<*> && @@ -402,7 +427,8 @@ abstract class KotlinIrLinker( val fileEntry = NaiveSourceBasedFileEntryImpl(fileName, fileProto.fileEntry.lineStartOffsetsList.toIntArray()) val fileDeserializer = - IrDeserializerForFile(fileProto.annotationList, fileIndex, !deserializationStrategy.needBodies).apply { + IrDeserializerForFile(fileProto.annotationList, fileProto.actualsList, fileIndex, !deserializationStrategy.needBodies).apply { + // Explicitly exported declarations (e.g. top-level initializers) must be deserialized before all other declarations. // Thus we schedule their deserialization in deserializer's constructor. fileProto.explicitlyExportedToCompilerList.forEach { @@ -555,8 +581,11 @@ abstract class KotlinIrLinker( findDeserializedDeclarationForDescriptor(symbol.descriptor) ?: return null } + // TODO: we do have serializations for those, but let's just create a stub for now. + if (!symbol.isBound && (symbol.descriptor.isExpectMember || symbol.descriptor.containingDeclaration?.isExpectMember ?: false)) return null + assert(symbol.isBound) { - "findDeserializedDeclaration: symbol ${symbol} is unbound, descriptor = ${symbol.descriptor}, hash = ${symbol.descriptor.hashCode()}" + "getDeclaration: symbol ${symbol} is unbound, descriptor = ${symbol.descriptor}, hash = ${symbol.descriptor.hashCode()}" } return symbol.owner as IrDeclaration @@ -597,6 +626,49 @@ abstract class KotlinIrLinker( } } + fun initializeExpectActualLinker() { + deserializersForModules.values.forEach { + it.fileToDeserializerMap.values.forEach { + it.deserializeExpectActualMapping() + } + } + } + + // The issue here is that an expect can not trigger its actual deserialization by reachability + // because the expect can not see the actual higher in the module dependency dag. + // So we force deserialization of actuals for all deserialized expect symbols here. + fun finalizeExpectActualLinker() { + expectUniqIdToActualUniqId.filter{ topLevelActualUniqItToDeserializer[it.value] != null}.forEach { + val expectSymbol = expectSymbols[it.key] + val actualSymbol = actualSymbols[it.value] + if (expectSymbol != null && (actualSymbol == null || !actualSymbol.isBound)) { + topLevelActualUniqItToDeserializer[it.value]!!.addModuleReachableTopLevel(it.value) + deserializeAllReachableTopLevels() + } + } + + // Now after all actuals have been deserialized, retarget delegating symbols from expects to actuals. + expectUniqIdToActualUniqId.forEach { + val expectSymbol = expectSymbols[it.key] + val actualSymbol = actualSymbols[it.value] + if (expectSymbol != null && actualSymbol != null) { + when (expectSymbol) { + is IrDelegatingClassSymbolImpl -> + expectSymbol.delegate = actualSymbol as IrClassSymbol + is IrDelegatingEnumEntrySymbolImpl -> + expectSymbol.delegate = actualSymbol as IrEnumEntrySymbol + is IrDelegatingSimpleFunctionSymbolImpl -> + expectSymbol.delegate = actualSymbol as IrSimpleFunctionSymbol + is IrDelegatingConstructorSymbolImpl -> + expectSymbol.delegate = actualSymbol as IrConstructorSymbol + is IrDelegatingPropertySymbolImpl -> + expectSymbol.delegate = actualSymbol as IrPropertySymbol + else -> error("Unexpected expect symbol kind during actualization: $expectSymbol") + } + } + } + } + fun deserializeIrModuleHeader( moduleDescriptor: ModuleDescriptor, deserializationStrategy: DeserializationStrategy = DeserializationStrategy.ONLY_REFERENCED diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinMangler.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinMangler.kt index 224b68184c27a..08cc2877d842d 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinMangler.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinMangler.kt @@ -5,6 +5,8 @@ package org.jetbrains.kotlin.backend.common.serialization +import org.jetbrains.kotlin.backend.common.ir.isExpect +import org.jetbrains.kotlin.backend.common.ir.isProperExpect import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* @@ -296,7 +298,10 @@ abstract class KotlinManglerImpl : KotlinMangler { is IrTypeParameter -> this.symbolName is IrTypeAlias -> this.symbolName else -> error("Unexpected exported declaration: $this") - } + } + expectPart + + // TODO: need to figure out the proper OptionalExpectation behavior + private val IrDeclaration.expectPart get() = if (this.isProperExpect) "#expect" else "" private val IrDeclarationParent.fqNameUnique: FqName get() = when (this) { diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/SerializeDescriptorReference.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/SerializeDescriptorReference.kt index 97d6fbeb1b256..abfd01391d93e 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/SerializeDescriptorReference.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/SerializeDescriptorReference.kt @@ -5,6 +5,8 @@ package org.jetbrains.kotlin.backend.common.serialization +import org.jetbrains.kotlin.backend.common.ir.isExpect +import org.jetbrains.kotlin.backend.common.ir.isProperExpect import org.jetbrains.kotlin.backend.common.serialization.proto.DescriptorReference as ProtoDescriptorReference import org.jetbrains.kotlin.descriptors.* @@ -20,7 +22,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.classId open class DescriptorReferenceSerializer( val declarationTable: DeclarationTable, val serializeString: (String) -> Int, - val serializeFqName: (FqName) -> List + val serializeFqName: (FqName) -> List, + val skipExpects: Boolean ) { private fun isEnumSpecialMember(descriptor: DeclarationDescriptor): Boolean { @@ -122,8 +125,8 @@ open class DescriptorReferenceSerializer( DescriptorReferenceFlags.IS_DEFAULT_CONSTRUCTOR.encode(isDefaultConstructor) or DescriptorReferenceFlags.IS_ENUM_ENTRY.encode(isEnumEntry) or DescriptorReferenceFlags.IS_ENUM_SPECIAL.encode(isEnumSpecial) or - DescriptorReferenceFlags.IS_TYPE_PARAMETER.encode(isTypeParameter) - + DescriptorReferenceFlags.IS_TYPE_PARAMETER.encode(isTypeParameter) or + DescriptorReferenceFlags.IS_EXPECT.encode(!skipExpects && declaration.isProperExpect) proto.flags = flags if (uniqId != null) proto.uniqIdIndex = uniqId.index 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 432d8fa38da41..9a4f526e7c474 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 @@ -6,8 +6,6 @@ package org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable -import org.jetbrains.kotlin.backend.common.serialization.isExpectMember -import org.jetbrains.kotlin.backend.common.serialization.isSerializableExpectClass import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataSerializer import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.CallableDescriptor @@ -26,8 +24,10 @@ import org.jetbrains.kotlin.serialization.DescriptorSerializer class KlibMetadataIncrementalSerializer( languageVersionSettings: LanguageVersionSettings, metadataVersion: BinaryVersion, - descriptorTable: DescriptorTable -) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, descriptorTable) { + moduleDescriptor: ModuleDescriptor, + descriptorTable: DescriptorTable, + skipExpects: Boolean +) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, moduleDescriptor, descriptorTable, skipExpects) { fun serializePackageFragment( module: ModuleDescriptor, @@ -41,13 +41,11 @@ class KlibMetadataIncrementalSerializer( val classifierDescriptors = allDescriptors .filterIsInstance() - .filter { !it.isExpectMember || it.isSerializableExpectClass } .sortedBy { it.fqNameSafe.asString() } val topLevelDescriptors = DescriptorSerializer.sort( allDescriptors .filterIsInstance() - .filter { !it.isExpectMember } ) // TODO: For now, in the incremental serializer, we assume 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 ad3d7c81c22b7..9148f710f04b6 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 @@ -19,8 +19,10 @@ import org.jetbrains.kotlin.serialization.DescriptorSerializer class KlibMetadataMonolithicSerializer( languageVersionSettings: LanguageVersionSettings, metadataVersion: BinaryVersion, - descriptorTable: DescriptorTable -) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, descriptorTable) { + moduleDescriptor: ModuleDescriptor, + descriptorTable: DescriptorTable, + skipExpects: Boolean +) : KlibMetadataSerializer(languageVersionSettings, metadataVersion, moduleDescriptor, descriptorTable, skipExpects) { private fun serializePackageFragment(fqName: FqName, module: ModuleDescriptor): List { @@ -33,13 +35,13 @@ class KlibMetadataMonolithicSerializer( val classifierDescriptors = DescriptorSerializer.sort( fragments.flatMap { it.getMemberScope().getDescriptorsFiltered(DescriptorKindFilter.CLASSIFIERS) - }.filter { !it.isExpectMember || it.isSerializableExpectClass } + } ) val topLevelDescriptors = DescriptorSerializer.sort( fragments.flatMap { fragment -> fragment.getMemberScope().getDescriptorsFiltered(DescriptorKindFilter.CALLABLES) - }.filter { !it.isExpectMember } + } ) return serializeDescriptors(fqName, classifierDescriptors, topLevelDescriptors) 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 798ccc944883c..c7aa24016dac0 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 @@ -6,6 +6,8 @@ package org.jetbrains.kotlin.backend.common.serialization.metadata import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable +import org.jetbrains.kotlin.backend.common.serialization.isExpectMember +import org.jetbrains.kotlin.backend.common.serialization.isSerializableExpectClass import org.jetbrains.kotlin.backend.common.serialization.newDescriptorUniqId import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.LanguageVersionSettings @@ -14,7 +16,10 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.serialization.DescriptorSerializer import org.jetbrains.kotlin.serialization.StringTableImpl @@ -28,7 +33,9 @@ internal fun Iterable.maybeChunked(size: Int?, transform: (List) -> abstract class KlibMetadataSerializer( val languageVersionSettings: LanguageVersionSettings, val metadataVersion: BinaryVersion, - val descriptorTable: DescriptorTable + val moduleDescriptor: ModuleDescriptor, + val descriptorTable: DescriptorTable, + val skipExpects: Boolean = false ) { lateinit var serializerContext: SerializerContext @@ -109,12 +116,30 @@ abstract class KlibMetadataSerializer( } } - protected fun serializeClasses(packageName: FqName, + // TODO: we filter out expects with present actuals. + // This is done because deserialized member scope doesn't give us actuals + // when it has a choice + private fun List.filterOutExpectsWithActuals(): List { + val actualClassIds = this.filter{ !it.isExpectMember }.map { ClassId.topLevel(it.fqNameSafe) } + return this.filterNot { + // TODO: this only filters classes for now. + // Need to do the same for functions etc + (it is ClassDescriptor) && it.isExpect() && ClassId.topLevel(it.fqNameSafe) in actualClassIds + } + } + + protected fun List.filterOutExpects(): List = + if (skipExpects) + this.filterNot { it.isExpectMember && !it.isSerializableExpectClass } + else + this.filterOutExpectsWithActuals() + + private fun serializeClasses(packageName: FqName, //builder: ProtoBuf.PackageFragment.Builder, descriptors: Collection): List> { return descriptors.filterIsInstance().flatMap { - serializeClass(packageName, /*builder, */it) + serializeClass(packageName, it) } } @@ -131,6 +156,9 @@ abstract class KlibMetadataSerializer( topLevelDescriptors: List ): List { + val classifierDescriptors = classifierDescriptors.filterOutExpects() + val topLevelDescriptors = topLevelDescriptors.filterOutExpects() + if (TOP_LEVEL_CLASS_DECLARATION_COUNT_PER_FILE == null && TOP_LEVEL_DECLARATION_COUNT_PER_FILE == null) { diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/Actual.java b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/Actual.java new file mode 100644 index 0000000000000..723f8ea776b9f --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/Actual.java @@ -0,0 +1,428 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: compiler/ir/serialization.common/src/KotlinIr.proto + +package org.jetbrains.kotlin.backend.common.serialization.proto; + +/** + * Protobuf type {@code org.jetbrains.kotlin.backend.common.serialization.proto.Actual} + */ +public final class Actual extends + org.jetbrains.kotlin.protobuf.GeneratedMessageLite implements + // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.backend.common.serialization.proto.Actual) + ActualOrBuilder { + // Use Actual.newBuilder() to construct. + private Actual(org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private Actual(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.ByteString.EMPTY;} + + private static final Actual defaultInstance; + public static Actual getDefaultInstance() { + return defaultInstance; + } + + public Actual getDefaultInstanceForType() { + return defaultInstance; + } + + private final org.jetbrains.kotlin.protobuf.ByteString unknownFields; + private Actual( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + org.jetbrains.kotlin.protobuf.ByteString.Output unknownFieldsOutput = + org.jetbrains.kotlin.protobuf.ByteString.newOutput(); + org.jetbrains.kotlin.protobuf.CodedOutputStream unknownFieldsCodedOutput = + org.jetbrains.kotlin.protobuf.CodedOutputStream.newInstance( + unknownFieldsOutput, 1); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFieldsCodedOutput, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + bitField0_ |= 0x00000001; + actualSymbol_ = input.readInt32(); + break; + } + case 16: { + bitField0_ |= 0x00000002; + expectSymbol_ = input.readInt32(); + break; + } + } + } + } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + try { + unknownFieldsCodedOutput.flush(); + } catch (java.io.IOException e) { + // Should not happen + } finally { + unknownFields = unknownFieldsOutput.toByteString(); + } + makeExtensionsImmutable(); + } + } + public static org.jetbrains.kotlin.protobuf.Parser PARSER = + new org.jetbrains.kotlin.protobuf.AbstractParser() { + public Actual parsePartialFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return new Actual(input, extensionRegistry); + } + }; + + @java.lang.Override + public org.jetbrains.kotlin.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + public static final int ACTUAL_SYMBOL_FIELD_NUMBER = 1; + private int actualSymbol_; + /** + * required int32 actual_symbol = 1; + */ + public boolean hasActualSymbol() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required int32 actual_symbol = 1; + */ + public int getActualSymbol() { + return actualSymbol_; + } + + public static final int EXPECT_SYMBOL_FIELD_NUMBER = 2; + private int expectSymbol_; + /** + * required int32 expect_symbol = 2; + */ + public boolean hasExpectSymbol() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required int32 expect_symbol = 2; + */ + public int getExpectSymbol() { + return expectSymbol_; + } + + private void initFields() { + actualSymbol_ = 0; + expectSymbol_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasActualSymbol()) { + memoizedIsInitialized = 0; + return false; + } + if (!hasExpectSymbol()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeInt32(1, actualSymbol_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeInt32(2, expectSymbol_); + } + output.writeRawBytes(unknownFields); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += org.jetbrains.kotlin.protobuf.CodedOutputStream + .computeInt32Size(1, actualSymbol_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += org.jetbrains.kotlin.protobuf.CodedOutputStream + .computeInt32Size(2, expectSymbol_); + } + size += unknownFields.size(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.jetbrains.kotlin.backend.common.serialization.proto.Actual parseFrom( + org.jetbrains.kotlin.protobuf.ByteString data) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.Actual parseFrom( + org.jetbrains.kotlin.protobuf.ByteString data, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.Actual parseFrom(byte[] data) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.Actual parseFrom( + byte[] data, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.Actual parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.Actual parseFrom( + java.io.InputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.Actual parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.Actual parseDelimitedFrom( + java.io.InputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.Actual parseFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.Actual parseFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.jetbrains.kotlin.backend.common.serialization.proto.Actual prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + /** + * Protobuf type {@code org.jetbrains.kotlin.backend.common.serialization.proto.Actual} + */ + public static final class Builder extends + org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder< + org.jetbrains.kotlin.backend.common.serialization.proto.Actual, Builder> + implements + // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.backend.common.serialization.proto.Actual) + org.jetbrains.kotlin.backend.common.serialization.proto.ActualOrBuilder { + // Construct using org.jetbrains.kotlin.backend.common.serialization.proto.Actual.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + actualSymbol_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + expectSymbol_ = 0; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public org.jetbrains.kotlin.backend.common.serialization.proto.Actual getDefaultInstanceForType() { + return org.jetbrains.kotlin.backend.common.serialization.proto.Actual.getDefaultInstance(); + } + + public org.jetbrains.kotlin.backend.common.serialization.proto.Actual build() { + org.jetbrains.kotlin.backend.common.serialization.proto.Actual result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.jetbrains.kotlin.backend.common.serialization.proto.Actual buildPartial() { + org.jetbrains.kotlin.backend.common.serialization.proto.Actual result = new org.jetbrains.kotlin.backend.common.serialization.proto.Actual(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.actualSymbol_ = actualSymbol_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.expectSymbol_ = expectSymbol_; + result.bitField0_ = to_bitField0_; + return result; + } + + public Builder mergeFrom(org.jetbrains.kotlin.backend.common.serialization.proto.Actual other) { + if (other == org.jetbrains.kotlin.backend.common.serialization.proto.Actual.getDefaultInstance()) return this; + if (other.hasActualSymbol()) { + setActualSymbol(other.getActualSymbol()); + } + if (other.hasExpectSymbol()) { + setExpectSymbol(other.getExpectSymbol()); + } + setUnknownFields( + getUnknownFields().concat(other.unknownFields)); + return this; + } + + public final boolean isInitialized() { + if (!hasActualSymbol()) { + + return false; + } + if (!hasExpectSymbol()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.jetbrains.kotlin.backend.common.serialization.proto.Actual parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.jetbrains.kotlin.backend.common.serialization.proto.Actual) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private int actualSymbol_ ; + /** + * required int32 actual_symbol = 1; + */ + public boolean hasActualSymbol() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required int32 actual_symbol = 1; + */ + public int getActualSymbol() { + return actualSymbol_; + } + /** + * required int32 actual_symbol = 1; + */ + public Builder setActualSymbol(int value) { + bitField0_ |= 0x00000001; + actualSymbol_ = value; + + return this; + } + /** + * required int32 actual_symbol = 1; + */ + public Builder clearActualSymbol() { + bitField0_ = (bitField0_ & ~0x00000001); + actualSymbol_ = 0; + + return this; + } + + private int expectSymbol_ ; + /** + * required int32 expect_symbol = 2; + */ + public boolean hasExpectSymbol() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * required int32 expect_symbol = 2; + */ + public int getExpectSymbol() { + return expectSymbol_; + } + /** + * required int32 expect_symbol = 2; + */ + public Builder setExpectSymbol(int value) { + bitField0_ |= 0x00000002; + expectSymbol_ = value; + + return this; + } + /** + * required int32 expect_symbol = 2; + */ + public Builder clearExpectSymbol() { + bitField0_ = (bitField0_ & ~0x00000002); + expectSymbol_ = 0; + + return this; + } + + // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.backend.common.serialization.proto.Actual) + } + + static { + defaultInstance = new Actual(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.backend.common.serialization.proto.Actual) +} diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ActualOrBuilder.java b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ActualOrBuilder.java new file mode 100644 index 0000000000000..3f38c1cf3be4c --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ActualOrBuilder.java @@ -0,0 +1,27 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: compiler/ir/serialization.common/src/KotlinIr.proto + +package org.jetbrains.kotlin.backend.common.serialization.proto; + +public interface ActualOrBuilder extends + // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.backend.common.serialization.proto.Actual) + org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder { + + /** + * required int32 actual_symbol = 1; + */ + boolean hasActualSymbol(); + /** + * required int32 actual_symbol = 1; + */ + int getActualSymbol(); + + /** + * required int32 expect_symbol = 2; + */ + boolean hasExpectSymbol(); + /** + * required int32 expect_symbol = 2; + */ + int getExpectSymbol(); +} \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectActualTable.java b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectActualTable.java new file mode 100644 index 0000000000000..cb318c3363b67 --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectActualTable.java @@ -0,0 +1,479 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: compiler/ir/serialization.common/src/KotlinIr.proto + +package org.jetbrains.kotlin.backend.common.serialization.proto; + +/** + * Protobuf type {@code org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable} + */ +public final class ExpectActualTable extends + org.jetbrains.kotlin.protobuf.GeneratedMessageLite implements + // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable) + ExpectActualTableOrBuilder { + // Use ExpectActualTable.newBuilder() to construct. + private ExpectActualTable(org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private ExpectActualTable(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.ByteString.EMPTY;} + + private static final ExpectActualTable defaultInstance; + public static ExpectActualTable getDefaultInstance() { + return defaultInstance; + } + + public ExpectActualTable getDefaultInstanceForType() { + return defaultInstance; + } + + private final org.jetbrains.kotlin.protobuf.ByteString unknownFields; + private ExpectActualTable( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + org.jetbrains.kotlin.protobuf.ByteString.Output unknownFieldsOutput = + org.jetbrains.kotlin.protobuf.ByteString.newOutput(); + org.jetbrains.kotlin.protobuf.CodedOutputStream unknownFieldsCodedOutput = + org.jetbrains.kotlin.protobuf.CodedOutputStream.newInstance( + unknownFieldsOutput, 1); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFieldsCodedOutput, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + expectToActuals_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000001; + } + expectToActuals_.add(input.readMessage(org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual.PARSER, extensionRegistry)); + break; + } + } + } + } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + if (((mutable_bitField0_ & 0x00000001) == 0x00000001)) { + expectToActuals_ = java.util.Collections.unmodifiableList(expectToActuals_); + } + try { + unknownFieldsCodedOutput.flush(); + } catch (java.io.IOException e) { + // Should not happen + } finally { + unknownFields = unknownFieldsOutput.toByteString(); + } + makeExtensionsImmutable(); + } + } + public static org.jetbrains.kotlin.protobuf.Parser PARSER = + new org.jetbrains.kotlin.protobuf.AbstractParser() { + public ExpectActualTable parsePartialFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return new ExpectActualTable(input, extensionRegistry); + } + }; + + @java.lang.Override + public org.jetbrains.kotlin.protobuf.Parser getParserForType() { + return PARSER; + } + + public static final int EXPECTTOACTUALS_FIELD_NUMBER = 1; + private java.util.List expectToActuals_; + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public java.util.List getExpectToActualsList() { + return expectToActuals_; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public java.util.List + getExpectToActualsOrBuilderList() { + return expectToActuals_; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public int getExpectToActualsCount() { + return expectToActuals_.size(); + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual getExpectToActuals(int index) { + return expectToActuals_.get(index); + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActualOrBuilder getExpectToActualsOrBuilder( + int index) { + return expectToActuals_.get(index); + } + + private void initFields() { + expectToActuals_ = java.util.Collections.emptyList(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + for (int i = 0; i < getExpectToActualsCount(); i++) { + if (!getExpectToActuals(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + for (int i = 0; i < expectToActuals_.size(); i++) { + output.writeMessage(1, expectToActuals_.get(i)); + } + output.writeRawBytes(unknownFields); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + for (int i = 0; i < expectToActuals_.size(); i++) { + size += org.jetbrains.kotlin.protobuf.CodedOutputStream + .computeMessageSize(1, expectToActuals_.get(i)); + } + size += unknownFields.size(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable parseFrom( + org.jetbrains.kotlin.protobuf.ByteString data) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable parseFrom( + org.jetbrains.kotlin.protobuf.ByteString data, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable parseFrom(byte[] data) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable parseFrom( + byte[] data, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable parseFrom( + java.io.InputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable parseDelimitedFrom( + java.io.InputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable parseFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable parseFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + /** + * Protobuf type {@code org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable} + */ + public static final class Builder extends + org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder< + org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable, Builder> + implements + // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable) + org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTableOrBuilder { + // Construct using org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + expectToActuals_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable getDefaultInstanceForType() { + return org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable.getDefaultInstance(); + } + + public org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable build() { + org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable buildPartial() { + org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable result = new org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable(this); + int from_bitField0_ = bitField0_; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + expectToActuals_ = java.util.Collections.unmodifiableList(expectToActuals_); + bitField0_ = (bitField0_ & ~0x00000001); + } + result.expectToActuals_ = expectToActuals_; + return result; + } + + public Builder mergeFrom(org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable other) { + if (other == org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable.getDefaultInstance()) return this; + if (!other.expectToActuals_.isEmpty()) { + if (expectToActuals_.isEmpty()) { + expectToActuals_ = other.expectToActuals_; + bitField0_ = (bitField0_ & ~0x00000001); + } else { + ensureExpectToActualsIsMutable(); + expectToActuals_.addAll(other.expectToActuals_); + } + + } + setUnknownFields( + getUnknownFields().concat(other.unknownFields)); + return this; + } + + public final boolean isInitialized() { + for (int i = 0; i < getExpectToActualsCount(); i++) { + if (!getExpectToActuals(i).isInitialized()) { + + return false; + } + } + return true; + } + + public Builder mergeFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private java.util.List expectToActuals_ = + java.util.Collections.emptyList(); + private void ensureExpectToActualsIsMutable() { + if (!((bitField0_ & 0x00000001) == 0x00000001)) { + expectToActuals_ = new java.util.ArrayList(expectToActuals_); + bitField0_ |= 0x00000001; + } + } + + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public java.util.List getExpectToActualsList() { + return java.util.Collections.unmodifiableList(expectToActuals_); + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public int getExpectToActualsCount() { + return expectToActuals_.size(); + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual getExpectToActuals(int index) { + return expectToActuals_.get(index); + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public Builder setExpectToActuals( + int index, org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual value) { + if (value == null) { + throw new NullPointerException(); + } + ensureExpectToActualsIsMutable(); + expectToActuals_.set(index, value); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public Builder setExpectToActuals( + int index, org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual.Builder builderForValue) { + ensureExpectToActualsIsMutable(); + expectToActuals_.set(index, builderForValue.build()); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public Builder addExpectToActuals(org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual value) { + if (value == null) { + throw new NullPointerException(); + } + ensureExpectToActualsIsMutable(); + expectToActuals_.add(value); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public Builder addExpectToActuals( + int index, org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual value) { + if (value == null) { + throw new NullPointerException(); + } + ensureExpectToActualsIsMutable(); + expectToActuals_.add(index, value); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public Builder addExpectToActuals( + org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual.Builder builderForValue) { + ensureExpectToActualsIsMutable(); + expectToActuals_.add(builderForValue.build()); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public Builder addExpectToActuals( + int index, org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual.Builder builderForValue) { + ensureExpectToActualsIsMutable(); + expectToActuals_.add(index, builderForValue.build()); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public Builder addAllExpectToActuals( + java.lang.Iterable values) { + ensureExpectToActualsIsMutable(); + org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll( + values, expectToActuals_); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public Builder clearExpectToActuals() { + expectToActuals_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000001); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + public Builder removeExpectToActuals(int index) { + ensureExpectToActualsIsMutable(); + expectToActuals_.remove(index); + + return this; + } + + // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable) + } + + static { + defaultInstance = new ExpectActualTable(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable) +} \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectActualTableOrBuilder.java b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectActualTableOrBuilder.java new file mode 100644 index 0000000000000..cd7f564512ac0 --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectActualTableOrBuilder.java @@ -0,0 +1,23 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: compiler/ir/serialization.common/src/KotlinIr.proto + +package org.jetbrains.kotlin.backend.common.serialization.proto; + +public interface ExpectActualTableOrBuilder extends + // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.backend.common.serialization.proto.ExpectActualTable) + org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder { + + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + java.util.List + getExpectToActualsList(); + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual getExpectToActuals(int index); + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual expectToActuals = 1; + */ + int getExpectToActualsCount(); +} \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectToActual.java b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectToActual.java new file mode 100644 index 0000000000000..4519e2a96f2ef --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectToActual.java @@ -0,0 +1,420 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: compiler/ir/serialization.common/src/KotlinIr.proto + +package org.jetbrains.kotlin.backend.common.serialization.proto; + +/** + * Protobuf type {@code org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual} + */ +public final class ExpectToActual extends + org.jetbrains.kotlin.protobuf.GeneratedMessageLite implements + // @@protoc_insertion_point(message_implements:org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual) + ExpectToActualOrBuilder { + // Use ExpectToActual.newBuilder() to construct. + private ExpectToActual(org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private ExpectToActual(boolean noInit) { this.unknownFields = org.jetbrains.kotlin.protobuf.ByteString.EMPTY;} + + private static final ExpectToActual defaultInstance; + public static ExpectToActual getDefaultInstance() { + return defaultInstance; + } + + public ExpectToActual getDefaultInstanceForType() { + return defaultInstance; + } + + private final org.jetbrains.kotlin.protobuf.ByteString unknownFields; + private ExpectToActual( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + org.jetbrains.kotlin.protobuf.ByteString.Output unknownFieldsOutput = + org.jetbrains.kotlin.protobuf.ByteString.newOutput(); + org.jetbrains.kotlin.protobuf.CodedOutputStream unknownFieldsCodedOutput = + org.jetbrains.kotlin.protobuf.CodedOutputStream.newInstance( + unknownFieldsOutput, 1); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFieldsCodedOutput, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + bitField0_ |= 0x00000001; + expect_ = input.readInt64(); + break; + } + case 16: { + bitField0_ |= 0x00000002; + actual_ = input.readInt64(); + break; + } + } + } + } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + try { + unknownFieldsCodedOutput.flush(); + } catch (java.io.IOException e) { + // Should not happen + } finally { + unknownFields = unknownFieldsOutput.toByteString(); + } + makeExtensionsImmutable(); + } + } + public static org.jetbrains.kotlin.protobuf.Parser PARSER = + new org.jetbrains.kotlin.protobuf.AbstractParser() { + public ExpectToActual parsePartialFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return new ExpectToActual(input, extensionRegistry); + } + }; + + @java.lang.Override + public org.jetbrains.kotlin.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + public static final int EXPECT_FIELD_NUMBER = 1; + private long expect_; + /** + * required int64 expect = 1; + */ + public boolean hasExpect() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required int64 expect = 1; + */ + public long getExpect() { + return expect_; + } + + public static final int ACTUAL_FIELD_NUMBER = 2; + private long actual_; + /** + * optional int64 actual = 2; + */ + public boolean hasActual() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional int64 actual = 2; + */ + public long getActual() { + return actual_; + } + + private void initFields() { + expect_ = 0L; + actual_ = 0L; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized == 1) return true; + if (isInitialized == 0) return false; + + if (!hasExpect()) { + memoizedIsInitialized = 0; + return false; + } + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeInt64(1, expect_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeInt64(2, actual_); + } + output.writeRawBytes(unknownFields); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += org.jetbrains.kotlin.protobuf.CodedOutputStream + .computeInt64Size(1, expect_); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += org.jetbrains.kotlin.protobuf.CodedOutputStream + .computeInt64Size(2, actual_); + } + size += unknownFields.size(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual parseFrom( + org.jetbrains.kotlin.protobuf.ByteString data) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual parseFrom( + org.jetbrains.kotlin.protobuf.ByteString data, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual parseFrom(byte[] data) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual parseFrom( + byte[] data, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual parseFrom( + java.io.InputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual parseDelimitedFrom( + java.io.InputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual parseFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual parseFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + /** + * Protobuf type {@code org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual} + */ + public static final class Builder extends + org.jetbrains.kotlin.protobuf.GeneratedMessageLite.Builder< + org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual, Builder> + implements + // @@protoc_insertion_point(builder_implements:org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual) + org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActualOrBuilder { + // Construct using org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private void maybeForceBuilderInitialization() { + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + expect_ = 0L; + bitField0_ = (bitField0_ & ~0x00000001); + actual_ = 0L; + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual getDefaultInstanceForType() { + return org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual.getDefaultInstance(); + } + + public org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual build() { + org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual buildPartial() { + org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual result = new org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.expect_ = expect_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + result.actual_ = actual_; + result.bitField0_ = to_bitField0_; + return result; + } + + public Builder mergeFrom(org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual other) { + if (other == org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual.getDefaultInstance()) return this; + if (other.hasExpect()) { + setExpect(other.getExpect()); + } + if (other.hasActual()) { + setActual(other.getActual()); + } + setUnknownFields( + getUnknownFields().concat(other.unknownFields)); + return this; + } + + public final boolean isInitialized() { + if (!hasExpect()) { + + return false; + } + return true; + } + + public Builder mergeFrom( + org.jetbrains.kotlin.protobuf.CodedInputStream input, + org.jetbrains.kotlin.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + private long expect_ ; + /** + * required int64 expect = 1; + */ + public boolean hasExpect() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * required int64 expect = 1; + */ + public long getExpect() { + return expect_; + } + /** + * required int64 expect = 1; + */ + public Builder setExpect(long value) { + bitField0_ |= 0x00000001; + expect_ = value; + + return this; + } + /** + * required int64 expect = 1; + */ + public Builder clearExpect() { + bitField0_ = (bitField0_ & ~0x00000001); + expect_ = 0L; + + return this; + } + + private long actual_ ; + /** + * optional int64 actual = 2; + */ + public boolean hasActual() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional int64 actual = 2; + */ + public long getActual() { + return actual_; + } + /** + * optional int64 actual = 2; + */ + public Builder setActual(long value) { + bitField0_ |= 0x00000002; + actual_ = value; + + return this; + } + /** + * optional int64 actual = 2; + */ + public Builder clearActual() { + bitField0_ = (bitField0_ & ~0x00000002); + actual_ = 0L; + + return this; + } + + // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual) + } + + static { + defaultInstance = new ExpectToActual(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual) +} \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectToActualOrBuilder.java b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectToActualOrBuilder.java new file mode 100644 index 0000000000000..c692fa916fa73 --- /dev/null +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/ExpectToActualOrBuilder.java @@ -0,0 +1,27 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: compiler/ir/serialization.common/src/KotlinIr.proto + +package org.jetbrains.kotlin.backend.common.serialization.proto; + +public interface ExpectToActualOrBuilder extends + // @@protoc_insertion_point(interface_extends:org.jetbrains.kotlin.backend.common.serialization.proto.ExpectToActual) + org.jetbrains.kotlin.protobuf.MessageLiteOrBuilder { + + /** + * required int64 expect = 1; + */ + boolean hasExpect(); + /** + * required int64 expect = 1; + */ + long getExpect(); + + /** + * optional int64 actual = 2; + */ + boolean hasActual(); + /** + * optional int64 actual = 2; + */ + long getActual(); +} \ No newline at end of file diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrFile.java b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrFile.java index eb1baf1409fd4..2600f975d286d 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrFile.java +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrFile.java @@ -137,6 +137,14 @@ private IrFile( input.popLimit(limit); break; } + case 50: { + if (!((mutable_bitField0_ & 0x00000020) == 0x00000020)) { + actuals_ = new java.util.ArrayList(); + mutable_bitField0_ |= 0x00000020; + } + actuals_.add(input.readMessage(org.jetbrains.kotlin.backend.common.serialization.proto.Actual.PARSER, extensionRegistry)); + break; + } } } } catch (org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException e) { @@ -157,6 +165,9 @@ private IrFile( if (((mutable_bitField0_ & 0x00000010) == 0x00000010)) { explicitlyExportedToCompiler_ = java.util.Collections.unmodifiableList(explicitlyExportedToCompiler_); } + if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) { + actuals_ = java.util.Collections.unmodifiableList(actuals_); + } try { unknownFieldsCodedOutput.flush(); } catch (java.io.IOException e) { @@ -299,12 +310,48 @@ public int getExplicitlyExportedToCompiler(int index) { return explicitlyExportedToCompiler_.get(index); } + public static final int ACTUALS_FIELD_NUMBER = 6; + private java.util.List actuals_; + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public java.util.List getActualsList() { + return actuals_; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public java.util.List + getActualsOrBuilderList() { + return actuals_; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public int getActualsCount() { + return actuals_.size(); + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public org.jetbrains.kotlin.backend.common.serialization.proto.Actual getActuals(int index) { + return actuals_.get(index); + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public org.jetbrains.kotlin.backend.common.serialization.proto.ActualOrBuilder getActualsOrBuilder( + int index) { + return actuals_.get(index); + } + private void initFields() { declarationId_ = java.util.Collections.emptyList(); fileEntry_ = org.jetbrains.kotlin.backend.common.serialization.proto.FileEntry.getDefaultInstance(); fqName_ = java.util.Collections.emptyList(); annotation_ = java.util.Collections.emptyList(); explicitlyExportedToCompiler_ = java.util.Collections.emptyList(); + actuals_ = java.util.Collections.emptyList(); } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -326,6 +373,12 @@ public final boolean isInitialized() { return false; } } + for (int i = 0; i < getActualsCount(); i++) { + if (!getActuals(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } memoizedIsInitialized = 1; return true; } @@ -348,6 +401,9 @@ public void writeTo(org.jetbrains.kotlin.protobuf.CodedOutputStream output) for (int i = 0; i < explicitlyExportedToCompiler_.size(); i++) { output.writeInt32(5, explicitlyExportedToCompiler_.get(i)); } + for (int i = 0; i < actuals_.size(); i++) { + output.writeMessage(6, actuals_.get(i)); + } output.writeRawBytes(unknownFields); } @@ -392,6 +448,10 @@ public int getSerializedSize() { size += dataSize; size += 1 * getExplicitlyExportedToCompilerList().size(); } + for (int i = 0; i < actuals_.size(); i++) { + size += org.jetbrains.kotlin.protobuf.CodedOutputStream + .computeMessageSize(6, actuals_.get(i)); + } size += unknownFields.size(); memoizedSerializedSize = size; return size; @@ -496,6 +556,8 @@ public Builder clear() { bitField0_ = (bitField0_ & ~0x00000008); explicitlyExportedToCompiler_ = java.util.Collections.emptyList(); bitField0_ = (bitField0_ & ~0x00000010); + actuals_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000020); return this; } @@ -543,6 +605,11 @@ public org.jetbrains.kotlin.backend.common.serialization.proto.IrFile buildParti bitField0_ = (bitField0_ & ~0x00000010); } result.explicitlyExportedToCompiler_ = explicitlyExportedToCompiler_; + if (((bitField0_ & 0x00000020) == 0x00000020)) { + actuals_ = java.util.Collections.unmodifiableList(actuals_); + bitField0_ = (bitField0_ & ~0x00000020); + } + result.actuals_ = actuals_; result.bitField0_ = to_bitField0_; return result; } @@ -591,6 +658,16 @@ public Builder mergeFrom(org.jetbrains.kotlin.backend.common.serialization.proto explicitlyExportedToCompiler_.addAll(other.explicitlyExportedToCompiler_); } + } + if (!other.actuals_.isEmpty()) { + if (actuals_.isEmpty()) { + actuals_ = other.actuals_; + bitField0_ = (bitField0_ & ~0x00000020); + } else { + ensureActualsIsMutable(); + actuals_.addAll(other.actuals_); + } + } setUnknownFields( getUnknownFields().concat(other.unknownFields)); @@ -612,6 +689,12 @@ public final boolean isInitialized() { return false; } } + for (int i = 0; i < getActualsCount(); i++) { + if (!getActuals(i).isInitialized()) { + + return false; + } + } return true; } @@ -1017,6 +1100,131 @@ public Builder clearExplicitlyExportedToCompiler() { return this; } + private java.util.List actuals_ = + java.util.Collections.emptyList(); + private void ensureActualsIsMutable() { + if (!((bitField0_ & 0x00000020) == 0x00000020)) { + actuals_ = new java.util.ArrayList(actuals_); + bitField0_ |= 0x00000020; + } + } + + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public java.util.List getActualsList() { + return java.util.Collections.unmodifiableList(actuals_); + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public int getActualsCount() { + return actuals_.size(); + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public org.jetbrains.kotlin.backend.common.serialization.proto.Actual getActuals(int index) { + return actuals_.get(index); + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public Builder setActuals( + int index, org.jetbrains.kotlin.backend.common.serialization.proto.Actual value) { + if (value == null) { + throw new NullPointerException(); + } + ensureActualsIsMutable(); + actuals_.set(index, value); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public Builder setActuals( + int index, org.jetbrains.kotlin.backend.common.serialization.proto.Actual.Builder builderForValue) { + ensureActualsIsMutable(); + actuals_.set(index, builderForValue.build()); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public Builder addActuals(org.jetbrains.kotlin.backend.common.serialization.proto.Actual value) { + if (value == null) { + throw new NullPointerException(); + } + ensureActualsIsMutable(); + actuals_.add(value); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public Builder addActuals( + int index, org.jetbrains.kotlin.backend.common.serialization.proto.Actual value) { + if (value == null) { + throw new NullPointerException(); + } + ensureActualsIsMutable(); + actuals_.add(index, value); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public Builder addActuals( + org.jetbrains.kotlin.backend.common.serialization.proto.Actual.Builder builderForValue) { + ensureActualsIsMutable(); + actuals_.add(builderForValue.build()); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public Builder addActuals( + int index, org.jetbrains.kotlin.backend.common.serialization.proto.Actual.Builder builderForValue) { + ensureActualsIsMutable(); + actuals_.add(index, builderForValue.build()); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public Builder addAllActuals( + java.lang.Iterable values) { + ensureActualsIsMutable(); + org.jetbrains.kotlin.protobuf.AbstractMessageLite.Builder.addAll( + values, actuals_); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public Builder clearActuals() { + actuals_ = java.util.Collections.emptyList(); + bitField0_ = (bitField0_ & ~0x00000020); + + return this; + } + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + public Builder removeActuals(int index) { + ensureActualsIsMutable(); + actuals_.remove(index); + + return this; + } + // @@protoc_insertion_point(builder_scope:org.jetbrains.kotlin.backend.common.serialization.proto.IrFile) } diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrFileOrBuilder.java b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrFileOrBuilder.java index 092a14e33021f..ad87d8a380214 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrFileOrBuilder.java +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/proto/IrFileOrBuilder.java @@ -68,4 +68,18 @@ public interface IrFileOrBuilder extends * repeated int32 explicitly_exported_to_compiler = 5; */ int getExplicitlyExportedToCompiler(int index); + + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + java.util.List + getActualsList(); + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + org.jetbrains.kotlin.backend.common.serialization.proto.Actual getActuals(int index); + /** + * repeated .org.jetbrains.kotlin.backend.common.serialization.proto.Actual actuals = 6; + */ + int getActualsCount(); } \ No newline at end of file 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 9665d13226df3..694c26835a9b7 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 @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir.JsMangler import org.jetbrains.kotlin.ir.backend.js.lower.serialization.metadata.KlibMetadataIncrementalSerializer import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns +import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.util.ExpectDeclarationRemover import org.jetbrains.kotlin.ir.util.IrDeserializer import org.jetbrains.kotlin.ir.util.SymbolTable @@ -80,6 +81,9 @@ val emptyLoggingContext = object : LoggingContext { private val CompilerConfiguration.metadataVersion get() = get(CommonConfigurationKeys.METADATA_VERSION) as? KlibMetadataVersion ?: KlibMetadataVersion.INSTANCE +private val CompilerConfiguration.klibMpp: Boolean + get() = get(CommonConfigurationKeys.KLIB_MPP) ?: false + class KotlinFileSerializedData(val metadata: ByteArray, val irData: SerializedIrFile) fun generateKLib( @@ -124,11 +128,16 @@ fun generateKLib( val psi2IrContext = runAnalysisAndPreparePsi2Ir(depsDescriptors) - val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, files) + val expectDescriptorToSymbol = mutableMapOf() + + val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, files, + deserializer = null, expectDescriptorToSymbol = expectDescriptorToSymbol) val moduleName = configuration[CommonConfigurationKeys.MODULE_NAME]!! - moduleFragment.acceptVoid(ExpectDeclarationRemover(psi2IrContext.symbolTable, false)) + if (!configuration.klibMpp) { + moduleFragment.acceptVoid(ExpectDeclarationRemover(psi2IrContext.symbolTable, false)) + } serializeModuleIntoKlib( moduleName, @@ -138,6 +147,7 @@ fun generateKLib( outputKlibPath, allDependencies.getFullList(), moduleFragment, + expectDescriptorToSymbol, icData, nopack ) @@ -181,6 +191,8 @@ fun loadIr( deserializer.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it))!! } + deserializer.initializeExpectActualLinker() + val moduleFragment = psi2IrContext.generateModuleFragmentWithPlugins(project, files, deserializer) return IrModuleInfo(moduleFragment, deserializedModuleFragments, irBuiltIns, symbolTable, deserializer) @@ -202,7 +214,8 @@ private fun runAnalysisAndPreparePsi2Ir(depsDescriptors: ModulesStructure): Gene fun GeneratorContext.generateModuleFragmentWithPlugins( project: Project, files: List, - deserializer: IrDeserializer? = null + deserializer: IrDeserializer? = null, + expectDescriptorToSymbol: MutableMap? = null ): IrModuleFragment { val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer) val psi2Ir = Psi2IrTranslator(languageVersionSettings, configuration, mangler = JsMangler) @@ -227,16 +240,17 @@ fun GeneratorContext.generateModuleFragmentWithPlugins( psi2Ir.generateModuleFragment( this, files, - irProviders + irProviders, + expectDescriptorToSymbol ) return moduleFragment } -fun GeneratorContext.generateModuleFragment(files: List, deserializer: IrDeserializer? = null): IrModuleFragment { +fun GeneratorContext.generateModuleFragment(files: List, deserializer: IrDeserializer? = null, expectDescriptorToSymbol: MutableMap? = null): IrModuleFragment { val irProviders = generateTypicalIrProviderList(moduleDescriptor, irBuiltIns, symbolTable, deserializer) return Psi2IrTranslator( languageVersionSettings, configuration, mangler = JsMangler - ).generateModuleFragment(this, files, irProviders) + ).generateModuleFragment(this, files, irProviders, expectDescriptorToSymbol) } @@ -358,6 +372,7 @@ fun serializeModuleIntoKlib( klibPath: String, dependencies: List, moduleFragment: IrModuleFragment, + expectDescriptorToSymbol: MutableMap, cleanFiles: List, nopack: Boolean ) { @@ -365,7 +380,7 @@ fun serializeModuleIntoKlib( val descriptorTable = DescriptorTable.createDefault() val serializedIr = - JsIrModuleSerializer(emptyLoggingContext, moduleFragment.irBuiltins, descriptorTable).serializedIrModule(moduleFragment) + JsIrModuleSerializer(emptyLoggingContext, moduleFragment.irBuiltins, descriptorTable, skipExpects = !configuration.klibMpp, expectDescriptorToSymbol = expectDescriptorToSymbol).serializedIrModule(moduleFragment) val moduleDescriptor = moduleFragment.descriptor @@ -375,7 +390,10 @@ fun serializeModuleIntoKlib( val metadataSerializer = KlibMetadataIncrementalSerializer( languageVersionSettings, metadataVersion, - descriptorTable) + moduleDescriptor, + descriptorTable, + skipExpects = !configuration.klibMpp + ) fun serializeScope(fqName: FqName, memberScope: Collection): ByteArray { return metadataSerializer.serializePackageFragment( diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrFileSerializer.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrFileSerializer.kt index 625b6892f2d98..df33d3314c5fb 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrFileSerializer.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrFileSerializer.kt @@ -9,12 +9,16 @@ import org.jetbrains.kotlin.backend.common.LoggingContext import org.jetbrains.kotlin.backend.common.serialization.IrFileSerializer import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable import org.jetbrains.kotlin.ir.declarations.IrProperty +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.ir.symbols.IrSymbol class JsIrFileSerializer( logger: LoggingContext, declarationTable: DeclarationTable, + private val expectDescriptorToSymbol: MutableMap, + skipExpects: Boolean, bodiesOnlyForInlines: Boolean = false -) : IrFileSerializer(logger, declarationTable, bodiesOnlyForInlines) { +) : IrFileSerializer(logger, declarationTable, expectDescriptorToSymbol, bodiesOnlyForInlines = bodiesOnlyForInlines, skipExpects = skipExpects) { // Temporary keep order of any property, even of constants override fun keepOrderOfProperties(property: IrProperty): Boolean = true diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrModuleSerializer.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrModuleSerializer.kt index 7c4e5eec1b7cd..64f7c2f3da8a6 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrModuleSerializer.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrModuleSerializer.kt @@ -9,14 +9,21 @@ import org.jetbrains.kotlin.backend.common.LoggingContext import org.jetbrains.kotlin.backend.common.serialization.DeclarationTable import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable import org.jetbrains.kotlin.backend.common.serialization.IrModuleSerializer +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns +import org.jetbrains.kotlin.ir.symbols.IrSymbol -class JsIrModuleSerializer(logger: LoggingContext, irBuiltIns: IrBuiltIns, private val descriptorTable: DescriptorTable) : - IrModuleSerializer(logger) { +class JsIrModuleSerializer( + logger: LoggingContext, + irBuiltIns: IrBuiltIns, + private val descriptorTable: DescriptorTable, + private val expectDescriptorToSymbol: MutableMap, + val skipExpects: Boolean +) : IrModuleSerializer(logger) { private val globalDeclarationTable = JsGlobalDeclarationTable(irBuiltIns) override fun createSerializerForFile(file: IrFile): JsIrFileSerializer = - JsIrFileSerializer(logger, DeclarationTable(descriptorTable, globalDeclarationTable, 0)) + JsIrFileSerializer(logger, DeclarationTable(descriptorTable, globalDeclarationTable, 0), expectDescriptorToSymbol, skipExpects = skipExpects) } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt index 26092d71b77b5..3367db01c672a 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/multiplatform/ExpectedActualResolver.kt @@ -18,6 +18,8 @@ import org.jetbrains.kotlin.resolve.multiplatform.ExpectedActualResolver.Compati import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor +import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedMemberDescriptor import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.types.TypeConstructorSubstitution @@ -55,7 +57,7 @@ object ExpectedActualResolver { // TODO: use some other way to determine that the declaration is from Kotlin. // This way behavior differs between fast and PSI-based Java class reading mode // TODO: support non-source definitions (e.g. from Java) - actual.source.containingFile != SourceFile.NO_SOURCE_FILE + actual.couldHaveASource }.groupBy { actual -> areCompatibleCallables(expected, actual, platformModule) } @@ -63,7 +65,7 @@ object ExpectedActualResolver { is ClassDescriptor -> { expected.findClassifiersFromModule(platformModule, moduleVisibilityFilter).filter { actual -> expected != actual && !actual.isExpect && - actual.source.containingFile != SourceFile.NO_SOURCE_FILE + actual.couldHaveASource }.groupBy { actual -> areCompatibleClassifiers(expected, actual) } @@ -560,3 +562,24 @@ object ExpectedActualResolver { } } +fun DeclarationDescriptor.findExpects(inModule: ModuleDescriptor = this.module): List { + return ExpectedActualResolver.findExpectedForActual( + this as MemberDescriptor, + inModule, + { true } + )?.get(Compatible).orEmpty() +} + +fun DeclarationDescriptor.findActuals(inModule: ModuleDescriptor = this.module): List { + return ExpectedActualResolver.findActualForExpected( + (this as MemberDescriptor), + inModule, + { true } + )?.get(Compatible).orEmpty() +} + +// TODO: Klibs still need to better handle source in deserialized descriptors. +val DeclarationDescriptorWithSource.couldHaveASource: Boolean get() = + this.source.containingFile != SourceFile.NO_SOURCE_FILE || + this is DeserializedMemberDescriptor || + this is DeserializedClassDescriptor \ No newline at end of file diff --git a/compiler/testData/cli/js/jsExtraHelp.out b/compiler/testData/cli/js/jsExtraHelp.out index 799be8f426337..49dc369cc6e9f 100644 --- a/compiler/testData/cli/js/jsExtraHelp.out +++ b/compiler/testData/cli/js/jsExtraHelp.out @@ -34,6 +34,7 @@ where advanced options include: Use 'warning' level to issue warnings instead of errors. -Xinline-classes Enable experimental inline classes -Xintellij-plugin-root= Path to the kotlin-compiler.jar or directory where IntelliJ configuration files can be found + -Xklib-mpp Enable experimental support for multi-platform klib libraries -Xlegacy-smart-cast-after-try Allow var smart casts despite assignment in try block -Xlist-phases List backend phases -Xmetadata-version Change metadata version of the generated binary files diff --git a/compiler/testData/cli/jvm/extraHelp.out b/compiler/testData/cli/jvm/extraHelp.out index 7cca178f79237..7f06790b607ce 100644 --- a/compiler/testData/cli/jvm/extraHelp.out +++ b/compiler/testData/cli/jvm/extraHelp.out @@ -91,6 +91,7 @@ where advanced options include: Use 'warning' level to issue warnings instead of errors. -Xinline-classes Enable experimental inline classes -Xintellij-plugin-root= Path to the kotlin-compiler.jar or directory where IntelliJ configuration files can be found + -Xklib-mpp Enable experimental support for multi-platform klib libraries -Xlegacy-smart-cast-after-try Allow var smart casts despite assignment in try block -Xlist-phases List backend phases -Xmetadata-version Change metadata version of the generated binary files diff --git a/compiler/testData/codegen/box/multiplatform/multiModule/expectActualLink.kt b/compiler/testData/codegen/box/multiplatform/multiModule/expectActualLink.kt new file mode 100644 index 0000000000000..61facc1faced6 --- /dev/null +++ b/compiler/testData/codegen/box/multiplatform/multiModule/expectActualLink.kt @@ -0,0 +1,60 @@ +// !LANGUAGE: +MultiPlatformProjects +// KJS_WITH_FULL_RUNTIME +// KLIB_BASED_MPP +// IGNORE_BACKEND: JS +// IGNORE_BACKEND: JVM +// IGNORE_BACKEND: JVM_IR + +// MODULE: A +// FILE: a.kt +@file:Suppress("NO_ACTUAL_FOR_EXPECT") +package foo + +expect fun foo1(): String +expect fun foo2(): String +expect fun foo3(): String +expect fun foo4(): String +expect fun foo5(): String +expect fun foo6(): String + +actual fun foo1() = "1" +actual fun foo2() = "2" + +fun use1() = foo1() +fun use3() = foo3() + + +// MODULE: B(A) +// FILE: b.kt +@file:Suppress("ACTUAL_WITHOUT_EXPECT") +package foo + +actual fun foo3() = "3" +actual fun foo4() = "4" +actual fun foo5() = "5" + +fun use2() = foo2() +fun use4() = foo4() +fun use6() = foo6() + + +// MODULE: C(B) +// FILE: c.kt +@file:Suppress("ACTUAL_WITHOUT_EXPECT") +package foo + +actual fun foo6() = "6" + +fun use5() = foo5() + + +// MODULE: main(C) +// FILE: main.kt +package main + +import foo.* + +fun box(): String { + return if (use1() + use2() + use3() + use4() + use5() + use6() == "123456") "OK" else "FAIL" +} + diff --git a/compiler/testData/codegen/box/multiplatform/multiModule/expectActualMemberLink.kt b/compiler/testData/codegen/box/multiplatform/multiModule/expectActualMemberLink.kt new file mode 100644 index 0000000000000..8da012cce1bc9 --- /dev/null +++ b/compiler/testData/codegen/box/multiplatform/multiModule/expectActualMemberLink.kt @@ -0,0 +1,84 @@ +// !LANGUAGE: +MultiPlatformProjects +// KJS_WITH_FULL_RUNTIME +// KLIB_BASED_MPP +// IGNORE_BACKEND: JS +// IGNORE_BACKEND: JVM +// IGNORE_BACKEND: JVM_IR + +// MODULE: A +// FILE: a.kt +@file:Suppress("NO_ACTUAL_FOR_EXPECT") +package foo + +expect class C1() { + fun foo1(): String +} +expect class C2() { + fun foo2(): String +} +expect class C3() { + fun foo3(): String +} +expect class C4() { + fun foo4(): String +} +expect class C5() { + fun foo5(): String +} +expect class C6() { + fun foo6(): String +} + +actual class C1 { + actual fun foo1() = "1" +} +actual class C2 { + actual fun foo2() = "2" +} + +fun use1() = C1().foo1() +fun use3() = C3().foo3() + + +// MODULE: B(A) +// FILE: b.kt +@file:Suppress("ACTUAL_WITHOUT_EXPECT") +package foo + +actual class C3 { + actual fun foo3() = "3" +} +actual class C4 { + actual fun foo4() = "4" +} +actual class C5 { + actual fun foo5() = "5" +} + +fun use2() = C2().foo2() +fun use4() = C4().foo4() +fun use6() = C6().foo6() + + +// MODULE: C(B) +// FILE: c.kt +@file:Suppress("ACTUAL_WITHOUT_EXPECT") +package foo + +actual class C6 { + actual fun foo6() = "6" +} + +fun use5() = C5().foo5() + + +// MODULE: main(C) +// FILE: main.kt +package main + +import foo.* + +fun box(): String { + return if (use1() + use2() + use3() + use4() + use5() + use6() == "123456") "OK" else "FAIL" +} + diff --git a/compiler/testData/codegen/box/multiplatform/multiModule/expectActualTypealiasLink.kt b/compiler/testData/codegen/box/multiplatform/multiModule/expectActualTypealiasLink.kt new file mode 100644 index 0000000000000..9eedfabdd3b81 --- /dev/null +++ b/compiler/testData/codegen/box/multiplatform/multiModule/expectActualTypealiasLink.kt @@ -0,0 +1,91 @@ +// !LANGUAGE: +MultiPlatformProjects +// KJS_WITH_FULL_RUNTIME +// KLIB_BASED_MPP +// IGNORE_BACKEND: JS +// IGNORE_BACKEND: JVM +// IGNORE_BACKEND: JVM_IR + +// MODULE: A +// FILE: a.kt +@file:Suppress("NO_ACTUAL_FOR_EXPECT") +package foo + +expect class C1() { + fun foo1(): String +} +expect class C2() { + fun foo2(): String +} +expect class C3() { + fun foo3(): String +} +expect class C4() { + fun foo4(): String +} +expect class C5() { + fun foo5(): String +} +expect class C6() { + fun foo6(): String +} + +class D1 { + fun foo1() = "1" +} +class D2 { + fun foo2() = "2" +} + +fun use1() = C1().foo1() +fun use3() = C3().foo3() + + +// MODULE: B(A) +// FILE: b.kt +@file:Suppress("ACTUAL_WITHOUT_EXPECT") +package foo + +class D3 { + fun foo3() = "3" +} +class D4 { + fun foo4() = "4" +} +class D5 { + fun foo5() = "5" +} + +fun use2() = C2().foo2() +fun use4() = C4().foo4() +fun use6() = C6().foo6() + + +// MODULE: C(B) +// FILE: c.kt +@file:Suppress("ACTUAL_WITHOUT_EXPECT") +package foo + +class D6 { + fun foo6() = "6" +} + +fun use5() = C5().foo5() + +actual typealias C1 = D1 +actual typealias C2 = D2 +actual typealias C3 = D3 +actual typealias C4 = D4 +actual typealias C5 = D5 +actual typealias C6 = D6 + + +// MODULE: main(C) +// FILE: main.kt +package main + +import foo.* + +fun box(): String { + return if (use1() + use2() + use3() + use4() + use5() + use6() == "123456") "OK" else "FAIL" +} + diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index b384c7608c65f..233649a049ea3 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -16936,6 +16936,34 @@ public void testTypeAlias() throws Exception { runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/typeAlias.kt"); } } + + @TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class MultiModule extends AbstractBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInMultiModule() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/multiModule"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("expectActualLink.kt") + public void testExpectActualLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualLink.kt"); + } + + @TestMetadata("expectActualMemberLink.kt") + public void testExpectActualMemberLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualMemberLink.kt"); + } + + @TestMetadata("expectActualTypealiasLink.kt") + public void testExpectActualTypealiasLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualTypealiasLink.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/nonLocalReturns") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index a4e1794a3fbc0..e61f18c135037 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -16936,6 +16936,34 @@ public void testTypeAlias() throws Exception { runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/typeAlias.kt"); } } + + @TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class MultiModule extends AbstractLightAnalysisModeTest { + @TestMetadata("expectActualLink.kt") + public void ignoreExpectActualLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualLink.kt"); + } + + @TestMetadata("expectActualMemberLink.kt") + public void ignoreExpectActualMemberLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualMemberLink.kt"); + } + + @TestMetadata("expectActualTypealiasLink.kt") + public void ignoreExpectActualTypealiasLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualTypealiasLink.kt"); + } + + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInMultiModule() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/multiModule"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + } } @TestMetadata("compiler/testData/codegen/box/nonLocalReturns") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index e0dfebc885178..4ee9fe6892162 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -15786,6 +15786,34 @@ public void testTypeAlias() throws Exception { runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/typeAlias.kt"); } } + + @TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class MultiModule extends AbstractFirBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTestWithCustomIgnoreDirective(this::doTest, TargetBackend.JVM_IR, testDataFilePath, "// IGNORE_BACKEND_FIR: "); + } + + public void testAllFilesPresentInMultiModule() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/multiModule"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); + } + + @TestMetadata("expectActualLink.kt") + public void testExpectActualLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualLink.kt"); + } + + @TestMetadata("expectActualMemberLink.kt") + public void testExpectActualMemberLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualMemberLink.kt"); + } + + @TestMetadata("expectActualTypealiasLink.kt") + public void testExpectActualTypealiasLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualTypealiasLink.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/nonLocalReturns") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index dc63f8270013d..a94b23811ac0f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -15786,6 +15786,34 @@ public void testTypeAlias() throws Exception { runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/typeAlias.kt"); } } + + @TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class MultiModule extends AbstractIrBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInMultiModule() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/multiModule"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); + } + + @TestMetadata("expectActualLink.kt") + public void testExpectActualLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualLink.kt"); + } + + @TestMetadata("expectActualMemberLink.kt") + public void testExpectActualMemberLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualMemberLink.kt"); + } + + @TestMetadata("expectActualTypealiasLink.kt") + public void testExpectActualTypealiasLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualTypealiasLink.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/nonLocalReturns") diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index 63ce78e153d62..349744290b2b3 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -164,7 +164,7 @@ class DeserializedClassDescriptor( override fun getSealedSubclasses() = sealedSubclasses() - override fun toString() = "deserialized class $name" // not using descriptor render to preserve laziness + override fun toString() = "deserialized ${if (isExpect()) "expect" else ""} class $name" // not using descriptor render to preserve laziness override fun getSource() = sourceElement diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt index ba0e6ca26194a..b3fabbfd63864 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/BasicBoxTest.kt @@ -119,6 +119,7 @@ abstract class BasicBoxTest( val runPlainBoxFunction = RUN_PLAIN_BOX_FUNCTION.matcher(fileContent).find() val inferMainModule = INFER_MAIN_MODULE.matcher(fileContent).find() + val klibBasedMpp = KLIB_BASED_MPP.matcher(fileContent).find() TestFileFactoryImpl(coroutinesPackage).use { testFactory -> val inputFiles = TestFiles.createTestFiles( @@ -162,7 +163,7 @@ abstract class BasicBoxTest( testFactory.tmpDir, file.parent, module, outputFileName, dceOutputFileName, dependencies, allDependencies, friends, modules.size > 1, !SKIP_SOURCEMAP_REMAPPING.matcher(fileContent).find(), outputPrefixFile, outputPostfixFile, - actualMainCallParameters, testPackage, testFunction, needsFullIrRuntime, isMainModule + actualMainCallParameters, testPackage, testFunction, needsFullIrRuntime, isMainModule, klibBasedMpp ) when { @@ -362,7 +363,8 @@ abstract class BasicBoxTest( testPackage: String?, testFunction: String, needsFullIrRuntime: Boolean, - isMainModule: Boolean + isMainModule: Boolean, + klibBasedMpp: Boolean ) { val kotlinFiles = module.files.filter { it.fileName.endsWith(".kt") } val testFiles = kotlinFiles.map { it.fileName } @@ -378,7 +380,7 @@ abstract class BasicBoxTest( val psiFiles = createPsiFiles(allSourceFiles.sortedBy { it.canonicalPath }.map { it.canonicalPath }) val sourceDirs = (testFiles + additionalFiles).map { File(it).parent }.distinct() - val config = createConfig(sourceDirs, module, dependencies, allDependencies, friends, multiModule, tmpDir, incrementalData = null) + val config = createConfig(sourceDirs, module, dependencies, allDependencies, friends, multiModule, tmpDir, incrementalData = null, klibBasedMpp = klibBasedMpp) val outputFile = File(outputFileName) val dceOutputFile = File(dceOutputFileName) @@ -391,7 +393,7 @@ abstract class BasicBoxTest( if (incrementalCompilationChecksEnabled && module.hasFilesToRecompile) { checkIncrementalCompilation( sourceDirs, module, kotlinFiles, dependencies, allDependencies, friends, multiModule, tmpDir, remap, - outputFile, outputPrefixFile, outputPostfixFile, mainCallParameters, incrementalData, testPackage, testFunction, needsFullIrRuntime + outputFile, outputPrefixFile, outputPostfixFile, mainCallParameters, incrementalData, testPackage, testFunction, needsFullIrRuntime, klibBasedMpp ) } } @@ -413,7 +415,8 @@ abstract class BasicBoxTest( incrementalData: IncrementalData, testPackage: String?, testFunction: String, - needsFullIrRuntime: Boolean + needsFullIrRuntime: Boolean, + klibBasedMpp: Boolean ) { val sourceToTranslationUnit = hashMapOf() for (testFile in kotlinFiles) { @@ -431,7 +434,7 @@ abstract class BasicBoxTest( .sortedBy { it.canonicalPath } .map { sourceToTranslationUnit[it]!! } - val recompiledConfig = createConfig(sourceDirs, module, dependencies, allDependencies, friends, multiModule, tmpDir, incrementalData) + val recompiledConfig = createConfig(sourceDirs, module, dependencies, allDependencies, friends, multiModule, tmpDir, incrementalData, klibBasedMpp) val recompiledOutputFile = File(outputFile.parentFile, outputFile.nameWithoutExtension + "-recompiled.js") translateFiles( @@ -644,7 +647,7 @@ abstract class BasicBoxTest( private fun createConfig( sourceDirs: List, module: TestModule, dependencies: List, allDependencies: List, friends: List, - multiModule: Boolean, tmpDir: File, incrementalData: IncrementalData? + multiModule: Boolean, tmpDir: File, incrementalData: IncrementalData?, klibBasedMpp: Boolean ): JsConfig { val configuration = environment.configuration.copy() @@ -696,6 +699,8 @@ abstract class BasicBoxTest( ) ) + configuration.put(CommonConfigurationKeys.KLIB_MPP, klibBasedMpp) + return JsConfig(project, configuration, METADATA_CACHE, (JsConfig.JS_STDLIB + JsConfig.JS_KOTLIN_TEST).toSet()) } @@ -889,6 +894,7 @@ abstract class BasicBoxTest( private val SOURCE_MAP_SOURCE_EMBEDDING = Regex("^// *SOURCE_MAP_EMBED_SOURCES: ([A-Z]+)*\$", RegexOption.MULTILINE) private val CALL_MAIN_PATTERN = Pattern.compile("^// *CALL_MAIN *$", Pattern.MULTILINE) private val KJS_WITH_FULL_RUNTIME = Pattern.compile("^// *KJS_WITH_FULL_RUNTIME *\$", Pattern.MULTILINE) + private val KLIB_BASED_MPP = Pattern.compile("^// KLIB_BASED_MPP *$", Pattern.MULTILINE) @JvmStatic protected val runTestInNashorn = getBoolean("kotlin.js.useNashorn") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index 745f98153ce11..aead34dab57a4 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -12911,6 +12911,34 @@ public void testTypeAlias() throws Exception { runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/typeAlias.kt"); } } + + @TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class MultiModule extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInMultiModule() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/multiModule"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true); + } + + @TestMetadata("expectActualLink.kt") + public void testExpectActualLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualLink.kt"); + } + + @TestMetadata("expectActualMemberLink.kt") + public void testExpectActualMemberLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualMemberLink.kt"); + } + + @TestMetadata("expectActualTypealiasLink.kt") + public void testExpectActualTypealiasLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualTypealiasLink.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/nonLocalReturns") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index 7dfaf05289273..1c0da14f0da3f 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -14051,6 +14051,34 @@ public void testTypeAlias() throws Exception { runTest("compiler/testData/codegen/box/multiplatform/defaultArguments/typeAlias.kt"); } } + + @TestMetadata("compiler/testData/codegen/box/multiplatform/multiModule") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class MultiModule extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInMultiModule() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/multiplatform/multiModule"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + + @TestMetadata("expectActualLink.kt") + public void testExpectActualLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualLink.kt"); + } + + @TestMetadata("expectActualMemberLink.kt") + public void testExpectActualMemberLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualMemberLink.kt"); + } + + @TestMetadata("expectActualTypealiasLink.kt") + public void testExpectActualTypealiasLink() throws Exception { + runTest("compiler/testData/codegen/box/multiplatform/multiModule/expectActualTypealiasLink.kt"); + } + } } @TestMetadata("compiler/testData/codegen/box/nonLocalReturns")