[K/N] Consolidate forward declarations handling

This is refactoring in preparation for KT-59764.
Names and layout of forward declarations related classes
was copy-pasted many times over compiler code.

Implementing KT-59764 would require copy-pasting it two more times.
So instead of doing this it was put in single place.

No behaviour changes intended in this commit.
This commit is contained in:
Pavel Kunyavskiy
2023-07-03 14:49:03 +02:00
committed by Space Team
parent 0179b45840
commit ef9413108b
16 changed files with 130 additions and 113 deletions
@@ -9,6 +9,7 @@ dependencies {
compileOnly(project(":compiler:cli-common"))
compileOnly(project(":compiler:frontend"))
compileOnly(project(":core:deserialization"))
compileOnly(project(":core:compiler.common.native"))
compileOnly(project(":compiler:serialization"))
api(kotlinStdlib())
@@ -9,8 +9,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.deserialization.PlatformDependentTypeTransformer
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.NativeForwardDeclarationKind
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.SupposititiousSimpleType
@@ -31,13 +30,6 @@ class NativeTypeTransformer : PlatformDependentTypeTransformer {
}
companion object {
private val cNames = FqName("cnames")
private val cNamesStructs = cNames.child(Name.identifier("structs"))
private val objCNames = FqName("objcnames")
private val objCNamesClasses = objCNames.child(Name.identifier("classes"))
private val objCNamesProtocols = objCNames.child(Name.identifier("protocols"))
private val forwardPackagesSet = setOf(cNamesStructs, objCNamesClasses, objCNamesProtocols)
private val forwardPackagesSet = NativeForwardDeclarationKind.entries.map { it.packageFqName }.toSet()
}
}
@@ -8,6 +8,7 @@ import org.jetbrains.kotlin.library.exportForwardDeclarations
import org.jetbrains.kotlin.library.isInterop
import org.jetbrains.kotlin.library.metadata.*
import org.jetbrains.kotlin.library.packageFqName
import org.jetbrains.kotlin.name.NativeForwardDeclarationKind
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
@@ -138,7 +139,7 @@ class ClassifierAliasingPackageFragmentDescriptor(
targets: List<KlibMetadataPackageFragment>,
module: ModuleDescriptor,
private val checker: ExportedForwardDeclarationChecker,
) : PackageFragmentDescriptorImpl(module, checker.fqName) {
) : PackageFragmentDescriptorImpl(module, checker.declKind.packageFqName) {
private val memberScope = object : MemberScopeImpl() {
override fun getContributedClassifier(name: Name, location: LookupLocation) =
targets.firstNotNullOfOrNull {
@@ -169,43 +170,14 @@ class ClassifierAliasingPackageFragmentDescriptor(
* we need to check declaration type before returning the result of lookup.
* See KT-49034.
*/
enum class ExportedForwardDeclarationChecker(val fqName: FqName) {
enum class ExportedForwardDeclarationChecker(val declKind: NativeForwardDeclarationKind) {
Struct(ForwardDeclarationsFqNames.cNamesStructs) {
override fun check(classifierDescriptor: ClassifierDescriptor): Boolean =
classifierDescriptor is ClassDescriptor && classifierDescriptor.kind.isClass &&
classifierDescriptor.isCStructVar()
},
ObjCClass(ForwardDeclarationsFqNames.objCNamesClasses) {
override fun check(classifierDescriptor: ClassifierDescriptor): Boolean =
classifierDescriptor is ClassDescriptor && classifierDescriptor.kind.isClass &&
classifierDescriptor.isObjCObjectBase()
},
ObjCProtocol(ForwardDeclarationsFqNames.objCNamesProtocols) {
override fun check(classifierDescriptor: ClassifierDescriptor): Boolean =
classifierDescriptor is ClassDescriptor && classifierDescriptor.kind.isInterface &&
classifierDescriptor.isObjCObject()
}
Struct(NativeForwardDeclarationKind.Struct),
ObjCClass(NativeForwardDeclarationKind.ObjCClass),
ObjCProtocol(NativeForwardDeclarationKind.ObjCProtocol)
;
abstract fun check(classifierDescriptor: ClassifierDescriptor): Boolean
companion object {
private val cStructVarFqName = FqName("kotlinx.cinterop.CStructVar")
private val objCObjectBaseFqName = FqName("kotlinx.cinterop.ObjCObjectBase")
private val objCObjectFqName = FqName("kotlinx.cinterop.ObjCObject")
// We can stop at ObjCObjectBase when checking Obj-C classes.
// Checking @ExternalObjCClass would be faster, but this annotation is not commonized. See KT-57541.
private fun ClassifierDescriptor.isObjCObjectBase(): Boolean =
getAllSuperClassifiers().any { it.fqNameSafe == objCObjectBaseFqName }
// For protocols, we have to go all the way up to ObjCObject.
private fun ClassifierDescriptor.isObjCObject(): Boolean =
getAllSuperClassifiers().any { it.fqNameSafe == objCObjectFqName }
private fun ClassifierDescriptor.isCStructVar(): Boolean =
getAllSuperClassifiers().any { it.fqNameSafe == cStructVarFqName }
}
fun check(classifierDescriptor: ClassifierDescriptor): Boolean = classifierDescriptor is ClassDescriptor &&
classifierDescriptor.kind == declKind.classKind &&
classifierDescriptor.getAllSuperClassifiers().any { it.fqNameSafe == declKind.matchSuperClassFqName }
}
@@ -18,7 +18,7 @@ import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.metadata.*
import org.jetbrains.kotlin.library.unresolvedDependencies
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.NativeForwardDeclarationKind
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.parentOrNull
import org.jetbrains.kotlin.platform.jvm.isJvm
@@ -194,22 +194,18 @@ class KlibMetadataModuleDescriptorFactoryImpl(
storageManager: StorageManager,
module: ModuleDescriptorImpl
): PackageFragmentProviderImpl {
fun createPackage(fqName: FqName, supertypeName: String, classKind: ClassKind) =
fun createPackage(kind: NativeForwardDeclarationKind) =
ForwardDeclarationsPackageFragmentDescriptor(
storageManager,
module,
fqName,
Name.identifier(supertypeName),
classKind,
kind.packageFqName,
kind.superClassName,
kind.classKind,
isExpect = true
)
val packageFragmentProvider = PackageFragmentProviderImpl(
listOf(
createPackage(ForwardDeclarationsFqNames.cNamesStructs, "COpaque", ClassKind.CLASS),
createPackage(ForwardDeclarationsFqNames.objCNamesClasses, "ObjCObjectBase", ClassKind.CLASS),
createPackage(ForwardDeclarationsFqNames.objCNamesProtocols, "ObjCObject", ClassKind.INTERFACE)
)
NativeForwardDeclarationKind.entries.map { createPackage(it) }
)
return packageFragmentProvider
}
@@ -17,9 +17,7 @@ import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.metadata.*
import org.jetbrains.kotlin.library.metadata.resolver.KotlinLibraryResolveResult
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.*
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
@@ -121,18 +119,18 @@ class KlibResolvedModuleDescriptorsFactoryImpl(
val module = createDescriptorOptionalBuiltsIns(FORWARD_DECLARATIONS_MODULE_NAME, storageManager, builtIns, SyntheticModulesOrigin)
fun createPackage(forwardDeclarationKind: ForwardDeclarationKind) =
fun createPackage(forwardDeclarationKind: NativeForwardDeclarationKind) =
ForwardDeclarationsPackageFragmentDescriptor(
storageManager,
module,
forwardDeclarationKind.packageFqName,
Name.identifier(forwardDeclarationKind.superClassName),
forwardDeclarationKind.superClassName,
forwardDeclarationKind.classKind,
isExpect
)
val packageFragmentProvider = PackageFragmentProviderImpl(
ForwardDeclarationKind.values().map { createPackage(it) }
NativeForwardDeclarationKind.entries.map { createPackage(it) }
)
module.initialize(packageFragmentProvider)
@@ -184,7 +182,7 @@ class ForwardDeclarationsPackageFragmentDescriptor(
private val declarations = storageManager.createMemoizedFunction(this::createDeclaration)
private val supertype by storageManager.createLazyValue {
val descriptor = builtIns.builtInsModule.getPackage(ForwardDeclarationsFqNames.cInterop)
val descriptor = builtIns.builtInsModule.getPackage(NativeStandardInteropNames.cInteropPackage)
.memberScope
.getContributedClassifier(supertypeName, NoLookupLocation.FROM_BACKEND) as ClassDescriptor
@@ -218,31 +216,18 @@ class ForwardDeclarationsPackageFragmentDescriptor(
override fun getMemberScope(): MemberScope = memberScope
}
// TODO decouple and move interop-specific logic back to Kotlin/Native.
@Deprecated(
level = DeprecationLevel.ERROR,
message = "This class was moved to org.jetbrains.kotlin.name.NativeStandardInteropNames.ForwardDeclarations",
)
object ForwardDeclarationsFqNames {
internal val cInterop = FqName("kotlinx.cinterop")
internal val cInterop = NativeStandardInteropNames.cInteropPackage
private val cNames = FqName("cnames")
internal val cNamesStructs = cNames.child(Name.identifier("structs"))
internal val cNamesStructs = NativeStandardInteropNames.ForwardDeclarations.cNamesStructsPackage
internal val objCNamesClasses = NativeStandardInteropNames.ForwardDeclarations.objCNamesClassesPackage
internal val objCNamesProtocols = NativeStandardInteropNames.ForwardDeclarations.objCNamesProtocolsPackage
private val objCNames = FqName("objcnames")
internal val objCNamesClasses = objCNames.child(Name.identifier("classes"))
internal val objCNamesProtocols = objCNames.child(Name.identifier("protocols"))
val syntheticPackages = setOf(cNames, objCNames)
}
enum class ForwardDeclarationKind(val packageFqName: FqName, val superClassName: String, val classKind: ClassKind) {
CNAMES_STRUCTS(ForwardDeclarationsFqNames.cNamesStructs, "COpaque", ClassKind.CLASS),
OBJCNAMES_CLASSES(ForwardDeclarationsFqNames.objCNamesClasses, "ObjCObjectBase", ClassKind.CLASS),
OBJCNAMES_PROTOCOLS(ForwardDeclarationsFqNames.objCNamesProtocols, "ObjCObject", ClassKind.INTERFACE)
;
val superClassId = ClassId.topLevel(ForwardDeclarationsFqNames.cInterop.child(Name.identifier(superClassName)))
companion object {
val packageFqNameToKind: Map<FqName, ForwardDeclarationKind> = ForwardDeclarationKind.values().associateBy { it.packageFqName }
}
val syntheticPackages = NativeStandardInteropNames.ForwardDeclarations.syntheticPackages
}
@@ -29,4 +29,5 @@ typealias ForwardDeclarationsPackageFragmentDescriptor = org.jetbrains.kotlin.li
"This object has been moved from package org.jetbrains.kotlin.serialization.konan.impl to package org.jetbrains.kotlin.library.metadata.impl",
ReplaceWith("org.jetbrains.kotlin.library.metadata.impl.ForwardDeclarationsFqNames")
)
@Suppress("DEPRECATION_ERROR")
typealias ForwardDeclarationsFqNames = org.jetbrains.kotlin.library.metadata.impl.ForwardDeclarationsFqNames