[Commonizer] Allow extended lookup for classifiers in test mode

Only for commonizer tests!

Allow to look up classifiers from the standard Kotlin packages (kotlin, kotlinx)
both in the default built-ins module and in test data sources. This is necessary
to write tests that refer to C-interop classifiers that are not available without
Kotlin/Native distribution.

^KT-34602
This commit is contained in:
Dmitriy Dolovov
2020-08-12 14:15:13 +07:00
parent 3b398ed57f
commit 8904f5652b
5 changed files with 69 additions and 30 deletions
@@ -16,6 +16,13 @@ class Parameters(
val targetProviders: List<TargetProvider> get() = _targetProviders.values.toList()
// only for test purposes
internal var extendedLookupForBuiltInsClassifiers: Boolean = false
set(value) {
check(!field || value)
field = value
}
fun addTarget(targetProvider: TargetProvider): Parameters {
require(targetProvider.target !in _targetProviders) { "Target ${targetProvider.target} is already added" }
_targetProviders[targetProvider.target] = targetProvider
@@ -138,6 +138,9 @@ class TargetDeclarationsBuilderComponents(
val index: Int,
private val cache: DeclarationsBuilderCache
) {
// only for test purposes
internal var extendedLookupForBuiltInsClassifiers: Boolean = false
// N.B. this function may create new classifiers for types from Kotlin/Native forward declarations packages
fun findClassOrTypeAlias(classId: ClassId): ClassifierDescriptorWithTypeParameters {
return when {
@@ -146,8 +149,16 @@ class TargetDeclarationsBuilderComponents(
val builtInsModule = builtIns.builtInsModule
// TODO: this works fine for Native as far as built-ins module contains full Native stdlib, but this is not enough for JVM and JS
builtInsModule.resolveClassOrTypeAlias(classId)
?: error("Classifier ${classId.asString()} not found in built-ins module $builtInsModule for $target")
val classifier = builtInsModule.resolveClassOrTypeAlias(classId)
if (classifier != null)
return classifier
if (extendedLookupForBuiltInsClassifiers) {
return findOriginalClassOrTypeAlias(classId)
?: error("Classifier ${classId.asString()} not found neither in built-ins module $builtInsModule nor in original modules for $target")
}
error("Classifier ${classId.asString()} not found in built-ins module $builtInsModule for $target")
}
classId.packageFqName.isUnderKotlinNativeSyntheticPackages -> {
// that's a synthetic Kotlin/Native classifier that was exported as forward declaration in one or more modules,
@@ -162,29 +173,29 @@ class TargetDeclarationsBuilderComponents(
?: error("Classifier ${classId.asString()} not found for $target")
}
else -> {
// look up in created descriptors cache
val fromCache = cache.getCachedClassifier(classId, index)
fromCache
?: run {
// attempt to load the original classifier
if (!classId.packageFqName.isRoot) {
// first, guess containing module and look up in it
val classifier = lazyModulesLookupTable()
.guessModuleByPackageFqName(classId.packageFqName)
?.resolveClassOrTypeAlias(classId)
// if failed, then look up though all modules
classifier
?: lazyModulesLookupTable().values
.asSequence()
.mapNotNull { it?.resolveClassOrTypeAlias(classId) }
.firstOrNull()
} else null
}
cache.getCachedClassifier(classId, index) // first, look up in created descriptors cache
?: findOriginalClassOrTypeAlias(classId) // then, attempt to load the original classifier
?: error("Classifier ${classId.asString()} not found for $target")
}
}
}
private fun findOriginalClassOrTypeAlias(classId: ClassId): ClassifierDescriptorWithTypeParameters? {
if (classId.packageFqName.isRoot)
return null
// first, guess containing module and look up in it
val classifier = lazyModulesLookupTable()
.guessModuleByPackageFqName(classId.packageFqName)
?.resolveClassOrTypeAlias(classId)
// if failed, then look up though all modules
return classifier
?: lazyModulesLookupTable().values
.asSequence()
.mapNotNull { it?.resolveClassOrTypeAlias(classId) }
.firstOrNull()
}
}
fun CirRootNode.createGlobalBuilderComponents(
@@ -217,7 +228,9 @@ fun CirRootNode.createGlobalBuilderComponents(
isCommon = isCommon,
index = index,
cache = cache
)
).also {
it.extendedLookupForBuiltInsClassifiers = parameters.extendedLookupForBuiltInsClassifiers
}
}
return GlobalDeclarationsBuilderComponents(storageManager, targetContexts, cache, parameters.statsCollector)
@@ -13,12 +13,14 @@ import org.jetbrains.kotlin.serialization.konan.impl.ForwardDeclarationsFqNames
internal val DEPRECATED_ANNOTATION_FQN: FqName = FqName(Deprecated::class.java.name).intern()
internal val DEPRECATED_ANNOTATION_CID: ClassId = internedClassId(DEPRECATED_ANNOTATION_FQN)
private val STANDARD_KOTLIN_PACKAGE_PREFIXES = listOf(
KotlinBuiltIns.BUILT_INS_PACKAGE_NAME.asString(),
"kotlinx"
internal val STANDARD_KOTLIN_PACKAGE_FQNS: List<FqName> = listOf(
KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.intern(),
FqName("kotlinx").intern()
)
private val KOTLIN_NATIVE_SYNTHETIC_PACKAGES_PREFIXES = ForwardDeclarationsFqNames.syntheticPackages
private val STANDARD_KOTLIN_PACKAGES = STANDARD_KOTLIN_PACKAGE_FQNS.map { it.asString() }
private val KOTLIN_NATIVE_SYNTHETIC_PACKAGES = ForwardDeclarationsFqNames.syntheticPackages
.map { fqName ->
check(!fqName.isRoot)
fqName.asString()
@@ -27,10 +29,10 @@ private val KOTLIN_NATIVE_SYNTHETIC_PACKAGES_PREFIXES = ForwardDeclarationsFqNam
private const val DARWIN_PACKAGE_PREFIX = "platform.darwin"
internal val FqName.isUnderStandardKotlinPackages: Boolean
get() = hasAnyPrefix(STANDARD_KOTLIN_PACKAGE_PREFIXES)
get() = hasAnyPrefix(STANDARD_KOTLIN_PACKAGES)
internal val FqName.isUnderKotlinNativeSyntheticPackages: Boolean
get() = hasAnyPrefix(KOTLIN_NATIVE_SYNTHETIC_PACKAGES_PREFIXES)
get() = hasAnyPrefix(KOTLIN_NATIVE_SYNTHETIC_PACKAGES)
internal val FqName.isUnderDarwinPackage: Boolean
get() = asString().hasPrefix(DARWIN_PACKAGE_PREFIX)
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.descriptors.commonizer.utils
import org.jetbrains.kotlin.backend.common.serialization.metadata.impl.ExportedForwardDeclarationsPackageFragmentDescriptor
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
@@ -98,4 +99,15 @@ internal fun MutableMap<String, ModuleDescriptor?>.guessModuleByPackageFqName(pa
return candidate
}
internal val ModuleDescriptor.hasSomethingUnderStandardKotlinPackages: Boolean
get() {
val packageFragmentProvider = packageFragmentProvider
return STANDARD_KOTLIN_PACKAGE_FQNS.any { fqName ->
packageFragmentProvider.getPackageFragments(fqName).any { packageFragment ->
packageFragment !is ExportedForwardDeclarationsPackageFragmentDescriptor
&& packageFragment.getMemberScope() != MemberScope.Empty
}
}
}
internal val NativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer, NativeTypeTransformer())
@@ -317,9 +317,14 @@ private class CommonizedCommonDependenciesContainer(
override val refinesModuleInfos: List<ModuleInfo> get() = listOf(commonModuleInfo)
}
private fun Map<InputTarget, ModuleDescriptor>.toCommonizationParameters(): Parameters = Parameters().also {
private fun Map<InputTarget, ModuleDescriptor>.toCommonizationParameters(): Parameters = Parameters().also { parameters ->
forEach { (target, moduleDescriptor) ->
it.addTarget(
if (!parameters.extendedLookupForBuiltInsClassifiers) {
if (moduleDescriptor.hasSomethingUnderStandardKotlinPackages)
parameters.extendedLookupForBuiltInsClassifiers = true
}
parameters.addTarget(
TargetProvider(
target = target,
builtInsClass = moduleDescriptor.builtIns::class.java,