From 8904f5652bf5aa8eafb4be062b762d2145e32dc8 Mon Sep 17 00:00:00 2001 From: Dmitriy Dolovov Date: Wed, 12 Aug 2020 14:15:13 +0700 Subject: [PATCH] [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 --- .../descriptors/commonizer/Parameters.kt | 7 +++ .../descriptors/commonizer/builder/context.kt | 57 ++++++++++++------- .../descriptors/commonizer/utils/fqName.kt | 14 +++-- .../commonizer/utils/moduleDescriptor.kt | 12 ++++ .../AbstractCommonizationFromSourcesTest.kt | 9 ++- 5 files changed, 69 insertions(+), 30 deletions(-) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/Parameters.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/Parameters.kt index b4b42d9d53f..878f0bd0e87 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/Parameters.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/Parameters.kt @@ -16,6 +16,13 @@ class Parameters( val targetProviders: List 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 diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/context.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/context.kt index 491084cffec..9bf1f5355d9 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/context.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/context.kt @@ -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) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/fqName.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/fqName.kt index 27635608544..13bfba4a171 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/fqName.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/fqName.kt @@ -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 = 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) diff --git a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/moduleDescriptor.kt b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/moduleDescriptor.kt index 45f2de06a87..2803be626f7 100644 --- a/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/moduleDescriptor.kt +++ b/native/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils/moduleDescriptor.kt @@ -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.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()) diff --git a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/AbstractCommonizationFromSourcesTest.kt b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/AbstractCommonizationFromSourcesTest.kt index 0656648bada..0645f97cfec 100644 --- a/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/AbstractCommonizationFromSourcesTest.kt +++ b/native/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/AbstractCommonizationFromSourcesTest.kt @@ -317,9 +317,14 @@ private class CommonizedCommonDependenciesContainer( override val refinesModuleInfos: List get() = listOf(commonModuleInfo) } -private fun Map.toCommonizationParameters(): Parameters = Parameters().also { +private fun Map.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,