[K/N] Disable custom import for forward declarations

If forward declaration exists in a library, it was
possible to import it both by forward declaration name
and normal library name. This is strange unique behavior.
And it would also make KT-59643 changes binary incompatible.
So from now it's only possible to import forward declaration by
forward declaration name only.

^KT-59642
This commit is contained in:
Pavel Kunyavskiy
2023-07-11 14:40:29 +02:00
committed by Space Team
parent d797505f06
commit fd564d4af9
5 changed files with 1 additions and 142 deletions
@@ -13,20 +13,3 @@ package org.jetbrains.kotlin.backend.common.serialization.metadata.impl
)
typealias KlibMetadataDeserializedPackageFragmentsFactoryImpl = org.jetbrains.kotlin.library.metadata.impl.KlibMetadataDeserializedPackageFragmentsFactoryImpl
@Deprecated(
"This class has been moved from package org.jetbrains.kotlin.backend.common.serialization.metadata.impl to package org.jetbrains.kotlin.library.metadata.impl",
ReplaceWith("org.jetbrains.kotlin.library.metadata.impl.ExportedForwardDeclarationsPackageFragmentDescriptor")
)
typealias ExportedForwardDeclarationsPackageFragmentDescriptor = org.jetbrains.kotlin.library.metadata.impl.ExportedForwardDeclarationsPackageFragmentDescriptor
@Deprecated(
"This class has been moved from package org.jetbrains.kotlin.backend.common.serialization.metadata.impl to package org.jetbrains.kotlin.library.metadata.impl",
ReplaceWith("org.jetbrains.kotlin.library.metadata.impl.ClassifierAliasingPackageFragmentDescriptor")
)
typealias ClassifierAliasingPackageFragmentDescriptor = org.jetbrains.kotlin.library.metadata.impl.ClassifierAliasingPackageFragmentDescriptor
@Deprecated(
"This enum class has been moved from package org.jetbrains.kotlin.backend.common.serialization.metadata.impl to package org.jetbrains.kotlin.library.metadata.impl",
ReplaceWith("org.jetbrains.kotlin.library.metadata.impl.ExportedForwardDeclarationChecker")
)
typealias ExportedForwardDeclarationChecker = org.jetbrains.kotlin.library.metadata.impl.ExportedForwardDeclarationChecker
@@ -21,10 +21,4 @@ interface KlibMetadataDeserializedPackageFragmentsFactory {
moduleDescriptor: ModuleDescriptor,
storageManager: StorageManager
): List<KlibMetadataPackageFragment>
fun createSyntheticPackageFragments(
library: KotlinLibrary,
deserializedPackageFragments: List<KlibMetadataPackageFragment>,
moduleDescriptor: ModuleDescriptor
): List<PackageFragmentDescriptor>
}
@@ -70,114 +70,4 @@ open class KlibMetadataDeserializedPackageFragmentsFactoryImpl : KlibMetadataDes
KlibMetadataCachedPackageFragment(byteArray, storageManager, moduleDescriptor)
}
override fun createSyntheticPackageFragments(
library: KotlinLibrary,
deserializedPackageFragments: List<KlibMetadataPackageFragment>,
moduleDescriptor: ModuleDescriptor
): List<PackageFragmentDescriptor> {
if (!library.isInterop) return emptyList()
val mainPackageFqName = library.packageFqName?. let{ FqName(it) }
?: error("Inconsistent manifest: interop library ${library.libraryName} should have `package` specified")
val exportForwardDeclarations = library.exportForwardDeclarations.map{ FqName(it) }
val aliasedPackageFragments = deserializedPackageFragments.filter { it.fqName == mainPackageFqName }
val result = mutableListOf<PackageFragmentDescriptor>()
ExportedForwardDeclarationChecker.values().mapTo(result) { checker ->
ClassifierAliasingPackageFragmentDescriptor(aliasedPackageFragments, moduleDescriptor, checker)
}
result.add(ExportedForwardDeclarationsPackageFragmentDescriptor(moduleDescriptor, mainPackageFqName, exportForwardDeclarations))
return result
}
}
/**
* The package fragment to export forward declarations from interop package namespace, i.e.
* redirect "$pkg.$name" to e.g. "cnames.structs.$name".
*/
class ExportedForwardDeclarationsPackageFragmentDescriptor(
module: ModuleDescriptor,
fqName: FqName,
declarations: List<FqName>
) : PackageFragmentDescriptorImpl(module, fqName) {
private val memberScope = object : MemberScopeImpl() {
private val nameToFqName = declarations.map { it.shortName() to it }.toMap()
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
val declFqName = nameToFqName[name] ?: return null
val packageView = module.getPackage(declFqName.parent())
return packageView.memberScope.getContributedClassifier(name, location) // ?: FIXME(ddol): delegate to forward declarations synthetic module!
}
override fun printScopeStructure(p: Printer) {
p.println(this::class.java.simpleName, " {")
p.pushIndent()
p.println("declarations = $declarations")
p.popIndent()
p.println("}")
}
}
override fun getMemberScope() = memberScope
}
/**
* The package fragment that redirects all requests for classifier lookup to its targets.
*/
class ClassifierAliasingPackageFragmentDescriptor(
targets: List<KlibMetadataPackageFragment>,
module: ModuleDescriptor,
private val checker: ExportedForwardDeclarationChecker,
) : PackageFragmentDescriptorImpl(module, checker.declKind.packageFqName) {
private val memberScope = object : MemberScopeImpl() {
override fun getContributedClassifier(name: Name, location: LookupLocation) =
targets.firstNotNullOfOrNull {
if (it.hasTopLevelClassifier(name)) {
it.getMemberScope().getContributedClassifier(name, location)
?.takeIf(this@ClassifierAliasingPackageFragmentDescriptor.checker::check)
} else {
null
}
}
override fun printScopeStructure(p: Printer) {
p.println(this::class.java.simpleName, " {")
p.pushIndent()
p.println("targets = $targets")
p.popIndent()
p.println("}")
}
}
override fun getMemberScope(): MemberScope = memberScope
}
/**
* It is possible to have different C and Objective-C declarations with the same name. That's why
* we need to check declaration type before returning the result of lookup.
* See KT-49034.
*/
enum class ExportedForwardDeclarationChecker(val declKind: NativeForwardDeclarationKind) {
Struct(NativeForwardDeclarationKind.Struct),
ObjCClass(NativeForwardDeclarationKind.ObjCClass),
ObjCProtocol(NativeForwardDeclarationKind.ObjCProtocol)
;
fun check(classifierDescriptor: ClassifierDescriptor): Boolean = classifierDescriptor is ClassDescriptor &&
classifierDescriptor.kind == declKind.classKind &&
classifierDescriptor.getAllSuperClassifiers().any { it.fqNameSafe == declKind.matchSuperClassFqName }
}
@@ -108,11 +108,6 @@ class KlibMetadataModuleDescriptorFactoryImpl(
library, packageFragmentNames, moduleDescriptor, packageAccessHandler, storageManager, configuration
)
// TODO: this is native specific. Move to a child class.
val syntheticPackageFragments = packageFragmentsFactory.createSyntheticPackageFragments(
library, deserializedPackageFragments, moduleDescriptor
)
// Generate empty PackageFragmentDescriptor instances for packages that aren't mentioned in compilation units directly.
// For example, if there's `package foo.bar` directive, we'll get only PackageFragmentDescriptor for `foo.bar`, but
// none for `foo`. Various descriptor/scope code relies on presence of such package fragments, and currently we
@@ -128,7 +123,7 @@ class KlibMetadataModuleDescriptorFactoryImpl(
}
}
val provider = PackageFragmentProviderImpl(deserializedPackageFragments + syntheticPackageFragments + emptyPackageFragments)
val provider = PackageFragmentProviderImpl(deserializedPackageFragments + emptyPackageFragments)
return initializePackageFragmentProvider(provider, deserializedPackageFragments, storageManager,
moduleDescriptor, configuration, compositePackageFragmentAddend, lookupTracker)
}
@@ -27,8 +27,6 @@ import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.js.resolve.diagnostics.findPsi
import org.jetbrains.kotlin.library.SerializedMetadata
import org.jetbrains.kotlin.library.metadata.impl.ClassifierAliasingPackageFragmentDescriptor
import org.jetbrains.kotlin.library.metadata.impl.ExportedForwardDeclarationsPackageFragmentDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.CommonPlatforms
@@ -392,7 +390,6 @@ private object PatchingTestDescriptorVisitor : DeclarationDescriptorVisitorEmpty
fun recurse(packageFqName: FqName) {
val ownPackageMemberScopes = packageFragmentProvider.packageFragments(packageFqName)
.asSequence()
.filter { it !is ExportedForwardDeclarationsPackageFragmentDescriptor && it !is ClassifierAliasingPackageFragmentDescriptor }
.map { it.getMemberScope() }
.filter { it != MemberScope.Empty }
.toList()