KT-62859 [LL FIR] Introduce JvmStubDeserializedBuiltInsContainerSource

If deserialized declarations from built-ins have a container source
which implements `FacadeSource`, it might cause different problems
during IR compilation.

For example, IR lowering of `Any?.toString()` function call was broken
because IR assumed that this declaration belonged to a facade class
"kotlin.kotlin", which does not exist.

We introduce a special kind of container source for the built-ins
declarations, and there are in fact no real facade classes for such
declarations.

Also, `LLFirModuleWithDependenciesSymbolProvider` is modified to
correctly handle such sources. Previously it only handled
`FacadeSource`s, and now it knows about our special source for
built-ins.

^KT-62859 Fixed
This commit is contained in:
Roman Golyshev
2023-10-26 13:32:50 +02:00
committed by teamcity
parent 1a9cd81a85
commit 16608c8a1f
3 changed files with 68 additions and 3 deletions
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.analysis.low.level.api.fir.providers
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.JvmStubDeserializedBuiltInsContainerSource
import org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization.StubBasedFirDeserializedSymbolProvider
import org.jetbrains.kotlin.analysis.utils.collections.buildSmartList
import org.jetbrains.kotlin.fir.FirSession
@@ -182,7 +183,14 @@ internal class LLFirDependenciesSymbolProvider(
}
private fun FirCallableSymbol<*>.jvmClassName(): JvmClassName? {
val jvmPackagePartSource = fir.containerSource as? FacadeClassSource ?: return null
return jvmPackagePartSource.facadeClassName ?: jvmPackagePartSource.className
val containerSource = fir.containerSource
return when (containerSource) {
is JvmStubDeserializedBuiltInsContainerSource -> containerSource.facadeClassName
is FacadeClassSource -> containerSource.facadeClassName ?: containerSource.className
else -> null
}
}
}
@@ -0,0 +1,45 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.analysis.low.level.api.fir.stubBased.deserialization
import org.jetbrains.kotlin.descriptors.SourceFile
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerAbiStability
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
/**
* Container source for deserialized declarations from ".kotlin_builtins" file.
*
* [facadeClassName] points to a facade class (e.g. "kotlin/LibraryKt") and
* is used to differentiate between different builtins files.
*
* We have a dedicated container source for such declaration because we don't want
* them to be identified as belonging to a facade class.
*
* For that specific reason, this class **DOES NOT** implement
* [org.jetbrains.kotlin.load.kotlin.FacadeClassSource],
* because compiler backend might use instance checks to detect
* regular facade files.
*
* See for KTIJ-27124 for an example of an issue in IR lowerings.
*/
internal class JvmStubDeserializedBuiltInsContainerSource(val facadeClassName: JvmClassName) : DeserializedContainerSource {
override val incompatibility: IncompatibleVersionErrorData<*>?
get() = null
override val isPreReleaseInvisible: Boolean
get() = false
override val abiStability: DeserializedContainerAbiStability
get() = DeserializedContainerAbiStability.STABLE
override val presentableString: String
get() = "Declarations from ${BuiltInSerializerProtocol.BUILTINS_FILE_EXTENSION} file '${facadeClassName}'"
override fun getContainingFile(): SourceFile = SourceFile.NO_SOURCE_FILE
}
@@ -29,6 +29,8 @@ import org.jetbrains.kotlin.name.*
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.stubs.impl.*
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.deserialization.builtins.BuiltInSerializerProtocol
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
import org.jetbrains.kotlin.utils.addToStdlib.ifNotEmpty
typealias DeserializedTypeAliasPostProcessor = (FirTypeAliasSymbol) -> Unit
@@ -177,7 +179,17 @@ internal open class StubBasedFirDeserializedSymbolProvider(
}
}
private fun getFacadeContainerSource(file: KtFile, origin: KotlinStubOrigin?): JvmStubDeserializedFacadeContainerSource {
private fun getContainerSource(file: KtFile, origin: KotlinStubOrigin?): DeserializedContainerSource {
if (file.virtualFile.extension == BuiltInSerializerProtocol.BUILTINS_FILE_EXTENSION) {
require(origin is KotlinStubOrigin.Facade) {
"Expected builtins file to have Facade origin, got origin=$origin instead"
}
return JvmStubDeserializedBuiltInsContainerSource(
facadeClassName = JvmClassName.byInternalName(origin.className)
)
}
return when (origin) {
is KotlinStubOrigin.Facade -> {
val className = JvmClassName.byInternalName(origin.className)