[K2] Support legacy serialization for custom function type extensions.

For Compose libraries, it is important that libraries built with
K2 in version 2.0 can be read and used by a version 1.9 K1
compiler. That is not possible if custom function types are
in the metadata.

^KT-58456 Fixed
This commit is contained in:
Mads Ager
2023-05-10 13:39:51 +02:00
committed by teamcity
parent fb476612af
commit 089928ba2b
12 changed files with 114 additions and 2 deletions
@@ -9,6 +9,7 @@ import com.intellij.openapi.vfs.StandardFileSystems
import com.intellij.openapi.vfs.VirtualFileManager
import org.jetbrains.kotlin.cli.common.prepareJvmSessions
import org.jetbrains.kotlin.cli.jvm.compiler.VfsBasedProjectEnvironment
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl
import org.jetbrains.kotlin.fir.BinaryModuleData
import org.jetbrains.kotlin.fir.DependencyListForCliModule
@@ -26,7 +27,9 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices
import org.jetbrains.kotlin.test.backend.handlers.JvmBinaryArtifactHandler
import org.jetbrains.kotlin.test.directives.LanguageSettingsDirectives.LANGUAGE_VERSION
import org.jetbrains.kotlin.test.directives.model.RegisteredDirectives
import org.jetbrains.kotlin.test.directives.model.singleOrZeroValue
import org.jetbrains.kotlin.test.frontend.classic.ClassicFrontendOutputArtifact
import org.jetbrains.kotlin.test.frontend.fir.FirOutputArtifact
import org.jetbrains.kotlin.test.model.*
@@ -42,11 +45,17 @@ class LoadedMetadataDumpHandler(testServices: TestServices) : JvmBinaryArtifactH
override fun processModule(module: TestModule, info: BinaryArtifacts.Jvm) {
if (testServices.loadedMetadataSuppressionDirective in module.directives) return
val languageVersion = module.directives.singleOrZeroValue(LANGUAGE_VERSION)
val languageVersionSettings = if (languageVersion != null) {
LanguageVersionSettingsImpl(languageVersion, ApiVersion.createByLanguageVersion(languageVersion))
} else {
LanguageVersionSettingsImpl.DEFAULT
}
val emptyModule = TestModule(
name = "empty", JvmPlatforms.defaultJvmPlatform, TargetBackend.JVM_IR, FrontendKinds.FIR,
BackendKinds.IrBackend, ArtifactKinds.Jvm, files = emptyList(),
allDependencies = listOf(DependencyDescription(module.name, DependencyKind.Binary, DependencyRelation.RegularDependency)),
RegisteredDirectives.Empty, LanguageVersionSettingsImpl.DEFAULT
RegisteredDirectives.Empty, languageVersionSettings
)
val configuration = testServices.compilerConfigurationProvider.getCompilerConfiguration(emptyModule)
val environment = VfsBasedProjectEnvironment(
@@ -7,7 +7,9 @@ package org.jetbrains.kotlin.fir.serialization
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.builtins.functions.FunctionTypeKind
import org.jetbrains.kotlin.builtins.functions.isBuiltin
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.constant.EnumValue
import org.jetbrains.kotlin.constant.IntValue
@@ -823,7 +825,8 @@ class FirElementSerializer private constructor(
return lowerBound
}
is ConeClassLikeType -> {
if (type.functionTypeKind(session) == FunctionTypeKind.SuspendFunction) {
val functionTypeKind = type.functionTypeKind(session)
if (functionTypeKind == FunctionTypeKind.SuspendFunction) {
val runtimeFunctionType = type.suspendFunctionTypeToFunctionTypeWithContinuation(
session, StandardClassIds.Continuation
)
@@ -831,6 +834,13 @@ class FirElementSerializer private constructor(
functionType.flags = Flags.getTypeFlags(true, false)
return functionType
}
if (functionTypeKind?.isBuiltin == false) {
val legacySerializationUntil =
LanguageVersion.fromVersionString(functionTypeKind.serializeAsFunctionWithAnnotationUntil)
if (legacySerializationUntil != null && languageVersionSettings.languageVersion < legacySerializationUntil) {
return typeProto(type.customFunctionTypeToSimpleFunctionType(session))
}
}
fillFromPossiblyInnerType(builder, type)
if (type.hasContextReceivers) {
typeAnnotations.addIfNotNull(