[Commonizer] Drop descriptors for commonized declarations

This commit is contained in:
Dmitriy Dolovov
2021-01-29 14:00:27 +03:00
parent 5ff6b5ef42
commit 585cd64b9a
25 changed files with 70 additions and 1935 deletions
@@ -24,9 +24,6 @@ class CommonizerParameters(
field = value
}
// To be removed. Used only for tests now.
internal var generateDescriptors: Boolean = false
fun addTarget(targetProvider: TargetProvider): CommonizerParameters {
require(targetProvider.target !in _targetProviders) { "Target ${targetProvider.target} is already added" }
_targetProviders[targetProvider.target] = targetProvider
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.descriptors.commonizer
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.library.SerializedMetadata
import java.io.File
@@ -21,16 +20,11 @@ sealed class CommonizerResult {
}
sealed class ModuleResult {
class Missing(val originalLocation: File) : ModuleResult()
abstract val libraryName: String
class Commonized(
@Deprecated("To be removed. Used only for tests now.")
internal val module: ModuleDescriptor?,
val metadata: LibraryMetadata
) : ModuleResult()
class Missing(val originalLocation: File) : ModuleResult() {
override val libraryName: String get() = originalLocation.name
}
class Commonized(override val libraryName: String, val metadata: SerializedMetadata) : ModuleResult()
}
class LibraryMetadata(
val libraryName: String,
val metadata: SerializedMetadata
)
@@ -1,31 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirAnnotation
import org.jetbrains.kotlin.descriptors.commonizer.utils.compactConcat
import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMapValues
import org.jetbrains.kotlin.resolve.constants.AnnotationValue
import org.jetbrains.kotlin.storage.getValue
class CommonizedAnnotationDescriptor(
targetComponents: TargetDeclarationsBuilderComponents,
cirAnnotation: CirAnnotation
) : AnnotationDescriptor {
override val type by targetComponents.storageManager.createLazyValue {
cirAnnotation.type.buildType(targetComponents, TypeParameterResolver.EMPTY, expandTypeAliases = true)
}
override val allValueArguments by targetComponents.storageManager.createLazyValue {
cirAnnotation.constantValueArguments compactConcat cirAnnotation.annotationValueArguments.compactMapValues { (_, nestedCirAnnotation) ->
AnnotationValue(CommonizedAnnotationDescriptor(targetComponents, nestedCirAnnotation))
}
}
override val source: SourceElement get() = SourceElement.NO_SOURCE
}
@@ -1,166 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeParameter
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.DescriptorFactory.createPrimaryConstructorForObject
import org.jetbrains.kotlin.resolve.CliSealedClassInheritorsProvider
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum
import org.jetbrains.kotlin.types.AbstractClassTypeConstructor
import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
class CommonizedClassDescriptor(
targetComponents: TargetDeclarationsBuilderComponents,
containingDeclaration: DeclarationDescriptor,
override val annotations: Annotations,
name: Name,
private val kind: ClassKind,
private val modality: Modality,
private val visibility: DescriptorVisibility,
private val isCompanion: Boolean,
private val isData: Boolean,
private val isInline: Boolean,
private val isInner: Boolean,
isExternal: Boolean,
private val isExpect: Boolean,
private val isActual: Boolean,
cirDeclaredTypeParameters: List<CirTypeParameter>,
companionObjectName: Name?,
cirSupertypes: Collection<CirType>
) : ClassDescriptorBase(targetComponents.storageManager, containingDeclaration, name, SourceElement.NO_SOURCE, isExternal) {
private lateinit var _unsubstitutedMemberScope: CommonizedMemberScope
private lateinit var constructors: Collection<ClassConstructorDescriptor>
private var primaryConstructor: ClassConstructorDescriptor? = null
private val staticScope = if (kind == ClassKind.ENUM_CLASS)
StaticScopeForKotlinEnum(targetComponents.storageManager, this)
else
MemberScope.Empty
private val typeConstructor = CommonizedClassTypeConstructor(targetComponents, cirSupertypes)
private val sealedSubclasses = targetComponents.storageManager.createLazyValue {
// TODO: pass proper language version settings
if (modality == Modality.SEALED) {
CliSealedClassInheritorsProvider.computeSealedSubclasses(this, allowSealedInheritorsInDifferentFilesOfSamePackage = false)
} else {
emptyList()
}
}
private val declaredTypeParametersAndTypeParameterResolver = targetComponents.storageManager.createLazyValue {
val parent = if (isInner) (containingDeclaration as? ClassDescriptor)?.getTypeParameterResolver() else null
cirDeclaredTypeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents,
parent ?: TypeParameterResolver.EMPTY,
this
)
}
private val companionObjectDescriptor = targetComponents.storageManager.createNullableLazyValue {
if (companionObjectName != null)
unsubstitutedMemberScope.getContributedClassifier(companionObjectName, NoLookupLocation.FOR_ALREADY_TRACKED) as? ClassDescriptor
else
null
}
override fun getKind() = kind
override fun getModality() = modality
override fun getVisibility() = visibility
override fun isCompanionObject() = isCompanion
override fun isData() = isData
override fun isInline() = isInline
override fun isInner() = isInner
override fun isExpect() = isExpect
override fun isActual() = isActual
override fun isFun() = false // TODO: modifier "fun" should be accessible from here too
override fun isValue() = false // TODO: modifier "value" should be accessible from here too
override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): CommonizedMemberScope {
check(kotlinTypeRefiner == KotlinTypeRefiner.Default) {
"${kotlinTypeRefiner::class.java} is not supported in ${this::class.java}"
}
return _unsubstitutedMemberScope
}
override fun getUnsubstitutedMemberScope(): CommonizedMemberScope = super.getUnsubstitutedMemberScope() as CommonizedMemberScope
fun setUnsubstitutedMemberScope(unsubstitutedMemberScope: CommonizedMemberScope) {
_unsubstitutedMemberScope = unsubstitutedMemberScope
}
override fun getDeclaredTypeParameters() = declaredTypeParametersAndTypeParameterResolver().first
val typeParameterResolver: TypeParameterResolver get() = declaredTypeParametersAndTypeParameterResolver().second
override fun getConstructors() = constructors
override fun getUnsubstitutedPrimaryConstructor() = primaryConstructor
override fun getStaticScope(): MemberScope = staticScope
override fun getTypeConstructor(): TypeConstructor = typeConstructor
override fun getCompanionObjectDescriptor() = companionObjectDescriptor()
override fun getSealedSubclasses() = sealedSubclasses()
fun initialize(constructors: Collection<CommonizedClassConstructorDescriptor>) {
if (isExpect && kind.isSingleton) {
check(constructors.isEmpty())
primaryConstructor = if (kind == ClassKind.ENUM_ENTRY)
createPrimaryConstructorForObject(this, SourceElement.NO_SOURCE).apply { returnType = getDefaultType() }
else
null
this.constructors = listOfNotNull(primaryConstructor)
} else {
constructors.forEach { it.returnType = getDefaultType() }
primaryConstructor = constructors.firstOrNull { it.isPrimary }
this.constructors = constructors
}
}
override fun toString() = (if (isExpect) "expect " else if (isActual) "actual " else "") + "class " + name.toString()
private inner class CommonizedClassTypeConstructor(
targetComponents: TargetDeclarationsBuilderComponents,
cirSupertypes: Collection<CirType>
) : AbstractClassTypeConstructor(targetComponents.storageManager) {
private val parameters = targetComponents.storageManager.createLazyValue {
this@CommonizedClassDescriptor.computeConstructorTypeParameters()
}
private val supertypes = targetComponents.storageManager.createLazyValue {
cirSupertypes.map { it.buildType(targetComponents, this@CommonizedClassDescriptor.typeParameterResolver) }
}
override fun getParameters() = parameters()
override fun computeSupertypes() = supertypes()
override fun isDenotable() = true
override fun getDeclarationDescriptor() = this@CommonizedClassDescriptor
override val supertypeLoopChecker get() = SupertypeLoopChecker.EMPTY
override fun toString() = declarationDescriptor.fqNameSafe.asString()
}
}
class CommonizedClassConstructorDescriptor(
containingDeclaration: ClassDescriptor,
annotations: Annotations,
isPrimary: Boolean
) : ClassConstructorDescriptorImpl(
containingDeclaration,
null,
annotations,
isPrimary,
CallableMemberDescriptor.Kind.DECLARATION,
SourceElement.NO_SOURCE
)
@@ -1,107 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import gnu.trove.THashMap
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.utils.Printer
class CommonizedMemberScope : MemberScope {
private val functions = THashMap<Name, MutableList<SimpleFunctionDescriptor>>()
private val variables = THashMap<Name, MutableList<PropertyDescriptor>>()
private val classifiers = THashMap<Name, ClassifierDescriptorWithTypeParameters>()
private fun addMember(member: DeclarationDescriptor) {
when (member) {
is SimpleFunctionDescriptor -> functions.getOrPut(member.name) { ArrayList(INITIAL_CAPACITY_FOR_CALLABLES) } += member
is PropertyDescriptor -> variables.getOrPut(member.name) { ArrayList(INITIAL_CAPACITY_FOR_CALLABLES) } += member
is ClassifierDescriptorWithTypeParameters -> classifiers[member.name] = member
else -> error("Unsupported member type: ${member::class.java}, $member")
}
}
override fun getFunctionNames(): Set<Name> = functions.keys
override fun getVariableNames(): Set<Name> = variables.keys
override fun getClassifierNames(): Set<Name> = classifiers.keys
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<SimpleFunctionDescriptor> =
functions[name].orEmpty()
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<PropertyDescriptor> =
variables[name].orEmpty()
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? =
classifiers[name]
override fun getContributedDescriptors(
kindFilter: DescriptorKindFilter,
nameFilter: (Name) -> Boolean
): Collection<DeclarationDescriptor> {
val result = ArrayList<DeclarationDescriptor>(INITIAL_CAPACITY_FOR_CONTRIBUTED_DESCRIPTORS)
if (kindFilter.acceptsKinds(DescriptorKindFilter.CLASSIFIERS_MASK)) {
classifiers.values.filterTo(result) { nameFilter(it.name) }
}
if (kindFilter.acceptsKinds(DescriptorKindFilter.FUNCTIONS_MASK)) {
functions.forEach { (name, callables) ->
if (nameFilter(name))
result.addAll(callables)
}
}
if (kindFilter.acceptsKinds(DescriptorKindFilter.VARIABLES_MASK)) {
variables.forEach { (name, callables) ->
if (nameFilter(name))
result.addAll(callables)
}
}
return result
}
override fun printScopeStructure(p: Printer) {
p.println(this::class.java.simpleName, " {")
p.pushIndent()
p.println("functions = $functions")
p.println("variables = $variables")
p.println("classifiers = $classifiers")
p.popIndent()
p.println("}")
}
companion object {
fun createArray(size: Int) = Array(size) { CommonizedMemberScope() }
operator fun Array<CommonizedMemberScope>.plusAssign(members: List<DeclarationDescriptor?>) {
members.forEachIndexed { index, member ->
if (member != null)
this[index].addMember(member)
}
}
operator fun List<CommonizedMemberScope?>.plusAssign(members: List<DeclarationDescriptor?>) {
members.forEachIndexed { index, member ->
if (member != null)
this[index]?.addMember(member)
}
}
// Heuristic memory usage optimization. During commonization of ios_x64 and ios_arm64 only about 3% of functions are overloaded
// (and therefore have the same name in the same scope). For the remaining 97% the capacity of 1 is enough.
private const val INITIAL_CAPACITY_FOR_CALLABLES = 1
// Heuristic memory usage optimization. During commonization of ios_x64 and ios_arm64 the getContributedDescriptors() call
// returns empty list in 27% times and list of size 1 in 63% times. The default capacity of 0 looks reasonable.
private const val INITIAL_CAPACITY_FOR_CONTRIBUTED_DESCRIPTORS = 0
}
}
@@ -1,43 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
import org.jetbrains.kotlin.descriptors.PackageFragmentProviderOptimized
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
internal class CommonizedPackageFragmentProvider : PackageFragmentProviderOptimized {
private val packageFragments = ArrayList<PackageFragmentDescriptor>()
operator fun plusAssign(packageFragment: PackageFragmentDescriptor) {
this.packageFragments += packageFragment
}
override fun collectPackageFragments(fqName: FqName, packageFragments: MutableCollection<PackageFragmentDescriptor>) {
this.packageFragments.filterTo(packageFragments) { it.fqName == fqName }
}
override fun getPackageFragments(fqName: FqName): List<PackageFragmentDescriptor> =
packageFragments.filter { it.fqName == fqName }
override fun getSubPackagesOf(fqName: FqName, nameFilter: (Name) -> Boolean): Collection<FqName> =
packageFragments.asSequence()
.map { it.fqName }
.filter { !it.isRoot && it.parent() == fqName }
.toList()
companion object {
fun createArray(size: Int) = Array(size) { CommonizedPackageFragmentProvider() }
operator fun Array<CommonizedPackageFragmentProvider>.plusAssign(packageFragments: List<PackageFragmentDescriptor?>) {
packageFragments.forEachIndexed { index, packageFragment ->
this[index] += packageFragment ?: return@forEachIndexed
}
}
}
}
@@ -1,74 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.asSimpleType
class CommonizedTypeAliasDescriptor(
override val storageManager: StorageManager,
containingDeclaration: DeclarationDescriptor,
annotations: Annotations,
name: Name,
visibility: DescriptorVisibility,
private val isActual: Boolean
) : AbstractTypeAliasDescriptor(containingDeclaration, annotations, name, SourceElement.NO_SOURCE, visibility) {
private lateinit var underlyingTypeImpl: NotNullLazyValue<SimpleType>
override val underlyingType get() = underlyingTypeImpl()
private lateinit var expandedTypeImpl: NotNullLazyValue<SimpleType>
override val expandedType: SimpleType get() = expandedTypeImpl()
private val defaultTypeImpl = storageManager.createLazyValue { computeDefaultType() }
override fun getDefaultType() = defaultTypeImpl()
override val classDescriptor get() = expandedType.constructor.declarationDescriptor as? ClassDescriptor
private val typeConstructorParametersImpl = storageManager.createLazyValue { computeConstructorTypeParameters() }
override fun getTypeConstructorTypeParameters() = typeConstructorParametersImpl()
private val constructorsImpl = storageManager.createLazyValue { getTypeAliasConstructors() }
override val constructors get() = constructorsImpl()
override fun isActual() = isActual
fun initialize(
declaredTypeParameters: List<TypeParameterDescriptor>,
underlyingType: NotNullLazyValue<SimpleType>,
expandedType: NotNullLazyValue<SimpleType>
) {
super.initialize(declaredTypeParameters)
underlyingTypeImpl = underlyingType
expandedTypeImpl = expandedType
}
override fun substitute(substitutor: TypeSubstitutor): ClassifierDescriptorWithTypeParameters {
if (substitutor.isEmpty) return this
val substituted = CommonizedTypeAliasDescriptor(
storageManager = storageManager,
containingDeclaration = containingDeclaration,
annotations = annotations,
name = name,
visibility = visibility,
isActual = isActual
)
substituted.initialize(
declaredTypeParameters,
storageManager.createLazyValue { substitutor.safeSubstitute(underlyingType, Variance.INVARIANT).asSimpleType() },
storageManager.createLazyValue { substitutor.safeSubstitute(expandedType, Variance.INVARIANT).asSimpleType() }
)
return substituted
}
}
@@ -1,49 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirType
import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap
import org.jetbrains.kotlin.descriptors.impl.AbstractLazyTypeParameterDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.Variance
class CommonizedTypeParameterDescriptor(
private val targetComponents: TargetDeclarationsBuilderComponents,
private val typeParameterResolver: TypeParameterResolver,
containingDeclaration: DeclarationDescriptor,
override val annotations: Annotations,
name: Name,
variance: Variance,
isReified: Boolean,
index: Int,
private val cirUpperBounds: List<CirType>
) : AbstractLazyTypeParameterDescriptor(
targetComponents.storageManager,
containingDeclaration,
name,
variance,
isReified,
index,
SourceElement.NO_SOURCE,
SupertypeLoopChecker.EMPTY
) {
override fun resolveUpperBounds(): List<UnwrappedType> {
return if (cirUpperBounds.isEmpty())
listOf(targetComponents.builtIns.defaultBound)
else
cirUpperBounds.compactMap { it.buildType(targetComponents, typeParameterResolver) }
}
override fun reportSupertypeLoopError(type: KotlinType) =
error("There should be no cycles for commonized type parameters, but found for: $type in $this")
}
@@ -1,144 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.CommonizerTarget
import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedMemberScope.Companion.plusAssign
import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedPackageFragmentProvider.Companion.plusAssign
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.dimension
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
/**
* Serves two goals:
* 1. Builds and initializes descriptors that do not depend on Kotlin types, such as [ModuleDescriptor], [PackageFragmentDescriptor], etc.
* 2. Builds BUT not initializes classifier descriptors, so that they can be used during the next phase for construction of Kotlin types.
*/
internal class DeclarationsBuilderVisitor1(
private val components: GlobalDeclarationsBuilderComponents
) : CirNodeVisitor<List<DeclarationDescriptor?>, List<DeclarationDescriptor?>> {
override fun visitRootNode(node: CirRootNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
check(data.isEmpty()) // root node may not have containing declarations
check(components.targetComponents.size == node.dimension)
val allTargets: List<CommonizerTarget> = (node.targetDeclarations + node.commonDeclaration()).map { it!!.target }
val modulesByTargets: Map<CommonizerTarget, MutableList<ModuleDescriptorImpl>> =
allTargets.associateWithTo(HashMap()) { mutableListOf() }
// collect module descriptors:
for (moduleNode in node.modules.values) {
val modules = moduleNode.accept(this, noContainingDeclarations()).asListContaining<ModuleDescriptorImpl>()
modules.forEachIndexed { index, module ->
if (module != null) {
val target = allTargets[index]
modulesByTargets.getValue(target) += module
}
}
}
// return result (preserving order of targets):
allTargets.forEachIndexed { index, target ->
components.cache.cache(index, modulesByTargets.getValue(target))
}
return noReturningDeclarations()
}
override fun visitModuleNode(node: CirModuleNode, data: List<DeclarationDescriptor?>): List<ModuleDescriptorImpl?> {
// build module descriptors:
val moduleDescriptorsGroup = CommonizedGroup<ModuleDescriptorImpl>(node.dimension)
node.buildDescriptors(components, moduleDescriptorsGroup)
// build package fragments:
val packageFragmentProviders = CommonizedPackageFragmentProvider.createArray(node.dimension)
for (packageNode in node.packages.values) {
val packageFragments = packageNode.accept(this, moduleDescriptorsGroup).asListContaining<PackageFragmentDescriptor>()
packageFragmentProviders += packageFragments
}
// initialize module descriptors:
moduleDescriptorsGroup.forEachIndexed { index, moduleDescriptor ->
moduleDescriptor?.initialize(packageFragmentProviders[index])
}
return moduleDescriptorsGroup
}
override fun visitPackageNode(node: CirPackageNode, data: List<DeclarationDescriptor?>): List<PackageFragmentDescriptor?> {
val containingDeclarations = data.asListContaining<ModuleDescriptorImpl>()
// build package fragments:
val packageFragments = CommonizedGroup<CommonizedPackageFragmentDescriptor>(node.dimension)
node.buildDescriptors(components, packageFragments, containingDeclarations)
// build package members:
val packageMemberScopes = CommonizedMemberScope.createArray(node.dimension)
for (classNode in node.classes.values) {
packageMemberScopes += classNode.accept(this, packageFragments)
}
for (typeAliasNode in node.typeAliases.values) {
packageMemberScopes += typeAliasNode.accept(this, packageFragments)
}
// initialize package fragments:
packageFragments.forEachIndexed { index, packageFragment ->
packageFragment?.initialize(packageMemberScopes[index])
}
return packageFragments
}
override fun visitPropertyNode(node: CirPropertyNode, data: List<DeclarationDescriptor?>) =
error("This method should not be called in ${this::class.java}")
override fun visitFunctionNode(node: CirFunctionNode, data: List<DeclarationDescriptor?>) =
error("This method should not be called in ${this::class.java}")
override fun visitClassNode(node: CirClassNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val classifiers = CommonizedGroup<ClassifierDescriptorWithTypeParameters>(node.dimension)
node.buildDescriptors(components, classifiers, data)
val classes = classifiers.asListContaining<CommonizedClassDescriptor>()
// build class members:
val classMemberScopes = CommonizedMemberScope.createArray(node.dimension)
for (classNode in node.classes.values) {
classMemberScopes += classNode.accept(this, classes)
}
// save member scope
classes.forEachIndexed { index, clazz ->
clazz?.unsubstitutedMemberScope = classMemberScopes[index]
}
return classes
}
override fun visitClassConstructorNode(node: CirClassConstructorNode, data: List<DeclarationDescriptor?>) =
error("This method should not be called in ${this::class.java}")
override fun visitTypeAliasNode(node: CirTypeAliasNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val classifiers = CommonizedGroup<ClassifierDescriptorWithTypeParameters>(node.dimension)
node.buildDescriptors(components, classifiers, data)
val commonClass = classifiers[node.indexOfCommon] as? CommonizedClassDescriptor?
commonClass?.unsubstitutedMemberScope = CommonizedMemberScope() // empty member scope
commonClass?.initialize(emptyList()) // no constructors
return classifiers
}
companion object {
internal inline fun <reified T : DeclarationDescriptor> noContainingDeclarations() = emptyList<T?>()
internal inline fun <reified T : DeclarationDescriptor> noReturningDeclarations() = emptyList<T?>()
@Suppress("UNCHECKED_CAST")
internal inline fun <reified T : DeclarationDescriptor> List<DeclarationDescriptor?>.asListContaining(): List<T?> =
this as List<T?>
}
}
@@ -1,126 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedMemberScope.Companion.plusAssign
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1.Companion.asListContaining
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1.Companion.noContainingDeclarations
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1.Companion.noReturningDeclarations
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.dimension
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
/** Builds and initializes the new tree of common descriptors */
/**
* This visitor should be applied right after [DeclarationsBuilderVisitor1]. It does the following:
* 1. Builds and initializes descriptors that depend on Kotlin types, such as [PropertyDescriptor], [SimpleFunctionDescriptor], etc.
* 2. Initializes classifier descriptors.
*/
internal class DeclarationsBuilderVisitor2(
private val components: GlobalDeclarationsBuilderComponents
) : CirNodeVisitor<List<DeclarationDescriptor?>, List<DeclarationDescriptor?>> {
override fun visitRootNode(node: CirRootNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
check(data.isEmpty()) // root node may not have containing declarations
check(components.targetComponents.size == node.dimension)
// visit module descriptors:
for (moduleNode in node.modules.values) {
moduleNode.accept(this, noContainingDeclarations())
}
return noReturningDeclarations()
}
override fun visitModuleNode(node: CirModuleNode, data: List<DeclarationDescriptor?>): List<ModuleDescriptorImpl?> {
// visit package fragment descriptors:
for (packageNode in node.packages.values) {
packageNode.accept(this, noContainingDeclarations())
}
return noReturningDeclarations()
}
override fun visitPackageNode(node: CirPackageNode, data: List<DeclarationDescriptor?>): List<PackageFragmentDescriptor?> {
val packageFragments = components.cache.getCachedPackageFragments(node.moduleName, node.fqName)
// build non-classifier package members:
val packageMemberScopes = packageFragments.map { it?.getMemberScope() }
for (propertyNode in node.properties.values) {
packageMemberScopes += propertyNode.accept(this, packageFragments)
}
for (functionNode in node.functions.values) {
packageMemberScopes += functionNode.accept(this, packageFragments)
}
for (classNode in node.classes.values) {
classNode.accept(this, noContainingDeclarations())
}
return noReturningDeclarations()
}
override fun visitPropertyNode(node: CirPropertyNode, data: List<DeclarationDescriptor?>): List<PropertyDescriptor?> {
val propertyDescriptors = CommonizedGroup<PropertyDescriptor>(node.dimension)
node.buildDescriptors(components, propertyDescriptors, data)
return propertyDescriptors
}
override fun visitFunctionNode(node: CirFunctionNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val functionDescriptors = CommonizedGroup<SimpleFunctionDescriptor>(node.dimension)
node.buildDescriptors(components, functionDescriptors, data)
return functionDescriptors
}
override fun visitClassNode(node: CirClassNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val classes = components.cache.getCachedClasses(node.classId)
// build class constructors:
val allConstructorsByTargets = Array<MutableList<CommonizedClassConstructorDescriptor>>(node.dimension) { ArrayList() }
for (constructorNode in node.constructors.values) {
val constructorsByTargets = constructorNode.accept(this, classes).asListContaining<CommonizedClassConstructorDescriptor>()
constructorsByTargets.forEachIndexed { index, constructor ->
if (constructor != null) allConstructorsByTargets[index].add(constructor)
}
}
// initialize classes
classes.forEachIndexed { index, clazz ->
clazz?.initialize(allConstructorsByTargets[index])
}
// build class members:
val classMemberScopes = classes.map { it?.unsubstitutedMemberScope }
for (propertyNode in node.properties.values) {
classMemberScopes += propertyNode.accept(this, classes)
}
for (functionNode in node.functions.values) {
classMemberScopes += functionNode.accept(this, classes)
}
for (classNode in node.classes.values) {
classNode.accept(this, noContainingDeclarations())
}
return noReturningDeclarations()
}
override fun visitClassConstructorNode(node: CirClassConstructorNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val containingDeclarations = data.asListContaining<CommonizedClassDescriptor>()
val constructors = CommonizedGroup<ClassConstructorDescriptor>(node.dimension)
node.buildDescriptors(components, constructors, containingDeclarations)
return constructors
}
override fun visitTypeAliasNode(node: CirTypeAliasNode, data: List<DeclarationDescriptor?>) =
error("This method should not be called in ${this::class.java}")
}
@@ -1,198 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.cir.*
import org.jetbrains.kotlin.descriptors.commonizer.utils.compact
import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMap
import org.jetbrains.kotlin.descriptors.commonizer.utils.compactMapIndexed
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.KotlinTypeFactory.flexibleType
import org.jetbrains.kotlin.types.KotlinTypeFactory.simpleType
internal fun List<CirTypeParameter>.buildDescriptorsAndTypeParameterResolver(
targetComponents: TargetDeclarationsBuilderComponents,
parentTypeParameterResolver: TypeParameterResolver,
containingDeclaration: DeclarationDescriptor,
typeParametersIndexOffset: Int = 0
): Pair<List<TypeParameterDescriptor>, TypeParameterResolver> {
val ownTypeParameters = ArrayList<TypeParameterDescriptor>(size)
val typeParameterResolver = TypeParameterResolverImpl(
ownTypeParameters = ownTypeParameters,
parent = parentTypeParameterResolver
)
forEachIndexed { index, param ->
ownTypeParameters += CommonizedTypeParameterDescriptor(
targetComponents = targetComponents,
typeParameterResolver = typeParameterResolver,
containingDeclaration = containingDeclaration,
annotations = param.annotations.buildDescriptors(targetComponents),
name = param.name,
variance = param.variance,
isReified = param.isReified,
index = typeParametersIndexOffset + index,
cirUpperBounds = param.upperBounds
)
}
return ownTypeParameters to typeParameterResolver
}
internal fun List<CirValueParameter>.buildDescriptors(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver,
containingDeclaration: CallableDescriptor
): List<ValueParameterDescriptor> = compactMapIndexed { index, param ->
ValueParameterDescriptorImpl(
containingDeclaration,
null,
index,
param.annotations.buildDescriptors(targetComponents),
param.name,
param.returnType.buildType(targetComponents, typeParameterResolver),
param.declaresDefaultValue,
param.isCrossinline,
param.isNoinline,
param.varargElementType?.buildType(targetComponents, typeParameterResolver),
SourceElement.NO_SOURCE
)
}
internal fun List<CirAnnotation>.buildDescriptors(targetComponents: TargetDeclarationsBuilderComponents): Annotations =
Annotations.create(compactMap { CommonizedAnnotationDescriptor(targetComponents, it) })
internal fun CirExtensionReceiver.buildExtensionReceiver(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver,
containingDeclaration: CallableDescriptor
) = DescriptorFactory.createExtensionReceiverParameterForCallable(
containingDeclaration,
type.buildType(targetComponents, typeParameterResolver),
annotations.buildDescriptors(targetComponents)
)
internal fun buildDispatchReceiver(callableDescriptor: CallableDescriptor) =
DescriptorUtils.getDispatchReceiverParameterIfNeeded(callableDescriptor.containingDeclaration)
internal fun CirType.buildType(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver,
expandTypeAliases: Boolean = true
): UnwrappedType = when (this) {
is CirSimpleType -> buildType(targetComponents, typeParameterResolver, expandTypeAliases)
is CirFlexibleType -> flexibleType(
lowerBound = lowerBound.buildType(targetComponents, typeParameterResolver, expandTypeAliases),
upperBound = upperBound.buildType(targetComponents, typeParameterResolver, expandTypeAliases)
)
}
internal fun CirSimpleType.buildType(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver,
expandTypeAliases: Boolean
): SimpleType = when (this) {
is CirClassType -> buildSimpleType(
classifier = targetComponents.findClassOrTypeAlias(classifierId).checkClassifierType<ClassDescriptor>(),
arguments = collectArguments(targetComponents, typeParameterResolver, expandTypeAliases),
isMarkedNullable = isMarkedNullable
)
is CirTypeAliasType -> {
val typeAliasDescriptor = targetComponents.findClassOrTypeAlias(classifierId).checkClassifierType<TypeAliasDescriptor>()
val arguments = this.arguments.compactMap { it.buildArgument(targetComponents, typeParameterResolver, expandTypeAliases) }
if (expandTypeAliases)
buildExpandedType(typeAliasDescriptor, arguments, isMarkedNullable)
else
buildSimpleType(typeAliasDescriptor, arguments, isMarkedNullable)
}
is CirTypeParameterType -> buildSimpleType(
classifier = typeParameterResolver.resolve(index)
?: error("Type parameter with index=$index not found in ${typeParameterResolver::class.java}, $typeParameterResolver for ${targetComponents.target}"),
arguments = emptyList(),
isMarkedNullable = isMarkedNullable
)
}
private fun buildSimpleType(classifier: ClassifierDescriptor, arguments: List<TypeProjection>, isMarkedNullable: Boolean): SimpleType {
val reorderedArguments = if (arguments.isNotEmpty() && classifier is ClassDescriptor && classifier.isInner) {
val totalArguments = arguments.size
var remainingArguments = totalArguments
ArrayList<TypeProjection>(totalArguments).also { reorderedArguments ->
var currentClassifier: ClassDescriptor = classifier
while (true) {
val argumentsForCurrentClassifier = currentClassifier.declaredTypeParameters.size
for (i in 0 until argumentsForCurrentClassifier) {
reorderedArguments += arguments[remainingArguments - argumentsForCurrentClassifier + i]
}
remainingArguments -= argumentsForCurrentClassifier
if (remainingArguments == 0) break
currentClassifier = currentClassifier.containingDeclaration as ClassDescriptor
}
}
} else arguments
return simpleType(
annotations = Annotations.EMPTY,
constructor = classifier.typeConstructor,
arguments = reorderedArguments,
nullable = isMarkedNullable,
kotlinTypeRefiner = null
)
}
private fun buildExpandedType(classifier: TypeAliasDescriptor, arguments: List<TypeProjection>, isMarkedNullable: Boolean): SimpleType {
return TypeAliasExpander.NON_REPORTING.expand(
TypeAliasExpansion.create(null, classifier, arguments),
Annotations.EMPTY
).makeNullableAsSpecified(isMarkedNullable)
}
private inline fun <reified T : ClassifierDescriptorWithTypeParameters> ClassifierDescriptorWithTypeParameters.checkClassifierType(): T {
check(this is T) { "Mismatched classifier kinds.\nFound: ${this::class.java}, $this\nShould be: ${T::class.java}" }
return this
}
private fun CirClassType.collectArguments(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver,
expandTypeAliases: Boolean
): List<TypeProjection> {
return if (outerType == null) {
arguments.compactMap { it.buildArgument(targetComponents, typeParameterResolver, expandTypeAliases) }
} else {
val allTypes = generateSequence(this) { it.outerType }.toList()
val arguments = mutableListOf<TypeProjection>()
for (index in allTypes.size - 1 downTo 0) {
allTypes[index].arguments.mapTo(arguments) { it.buildArgument(targetComponents, typeParameterResolver, expandTypeAliases) }
}
arguments.compact()
}
}
private fun CirTypeProjection.buildArgument(
targetComponents: TargetDeclarationsBuilderComponents,
typeParameterResolver: TypeParameterResolver,
expandTypeAliases: Boolean
): TypeProjection = when (this) {
is CirStarTypeProjection -> StarProjectionForAbsentTypeParameter(targetComponents.builtIns)
is CirTypeProjectionImpl -> TypeProjectionImpl(
projectionKind,
type.buildType(targetComponents, typeParameterResolver, expandTypeAliases)
)
}
@@ -1,125 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.ClassConstructorDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassConstructor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassConstructorNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirClassNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.name.ClassId
internal fun CirClassNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>,
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonClass = commonDeclaration()
val markAsActual = commonClass != null && commonClass.kind != ClassKind.ENUM_ENTRY
targetDeclarations.forEachIndexed { index, clazz ->
clazz?.buildDescriptor(components, output, index, containingDeclarations, classId, isActual = markAsActual)
}
commonClass?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, classId, isExpect = true)
}
internal fun CirClass.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<in ClassifierDescriptorWithTypeParameters>,
index: Int,
containingDeclarations: List<DeclarationDescriptor?>,
classId: ClassId,
isExpect: Boolean = false,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for class $this")
val classDescriptor = CommonizedClassDescriptor(
targetComponents = targetComponents,
containingDeclaration = containingDeclaration,
annotations = annotations.buildDescriptors(targetComponents),
name = name,
kind = kind,
modality = modality,
visibility = visibility,
isCompanion = isCompanion,
isData = isData,
isInline = isInline,
isInner = isInner,
isExternal = isExternal,
isExpect = isExpect,
isActual = isActual,
cirDeclaredTypeParameters = typeParameters,
companionObjectName = companion,
cirSupertypes = supertypes
)
// cache created class descriptor:
components.cache.cache(classId, index, classDescriptor)
output[index] = classDescriptor
}
internal fun CirClassConstructorNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassConstructorDescriptor>,
containingDeclarations: List<CommonizedClassDescriptor?>
) {
val commonConstructor = commonDeclaration()
val markAsActual = commonConstructor != null
targetDeclarations.forEachIndexed { index, constructor ->
constructor?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsActual)
}
commonConstructor?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = true)
}
private fun CirClassConstructor.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassConstructorDescriptor>,
index: Int,
containingDeclarations: List<CommonizedClassDescriptor?>,
isExpect: Boolean = false,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for constructor $this")
val constructorDescriptor = CommonizedClassConstructorDescriptor(
containingDeclaration = containingDeclaration,
annotations = annotations.buildDescriptors(targetComponents),
isPrimary = isPrimary
)
constructorDescriptor.isExpect = isExpect
constructorDescriptor.isActual = isActual
constructorDescriptor.setHasStableParameterNames(hasStableParameterNames)
val classTypeParameters = containingDeclaration.declaredTypeParameters
val (constructorTypeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents = targetComponents,
parentTypeParameterResolver = containingDeclaration.typeParameterResolver,
containingDeclaration = constructorDescriptor,
typeParametersIndexOffset = classTypeParameters.size
)
constructorDescriptor.initialize(
valueParameters.buildDescriptors(targetComponents, typeParameterResolver, constructorDescriptor),
visibility,
classTypeParameters + constructorTypeParameters
)
output[index] = constructorDescriptor
}
@@ -1,319 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import gnu.trove.THashMap
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.commonizer.CommonizerParameters
import org.jetbrains.kotlin.descriptors.commonizer.CommonizerTarget
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.dimension
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirRootNode
import org.jetbrains.kotlin.descriptors.commonizer.utils.*
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroupMap
import org.jetbrains.kotlin.descriptors.commonizer.utils.createKotlinNativeForwardDeclarationsModule
import org.jetbrains.kotlin.descriptors.commonizer.utils.isUnderKotlinNativeSyntheticPackages
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.NotNullLazyValue
import org.jetbrains.kotlin.storage.StorageManager
/**
* Temporary caches for constructed descriptors.
*/
class DeclarationsBuilderCache(private val dimension: Int) {
init {
check(dimension > 0)
}
private val modules = CommonizedGroup<List<ModuleDescriptorImpl>>(dimension)
private val packageFragments = CommonizedGroupMap<Pair<Name, FqName>, CommonizedPackageFragmentDescriptor>(dimension)
private val classes = CommonizedGroupMap<ClassId, CommonizedClassDescriptor>(dimension)
private val typeAliases = CommonizedGroupMap<ClassId, CommonizedTypeAliasDescriptor>(dimension)
private val forwardDeclarationsModules = CommonizedGroup<ModuleDescriptorImpl>(dimension)
private val allModulesWithDependencies = CommonizedGroup<List<ModuleDescriptor>>(dimension)
fun getCachedPackageFragments(moduleName: Name, packageFqName: FqName): List<CommonizedPackageFragmentDescriptor?> =
packageFragments.getOrFail(moduleName to packageFqName)
fun getCachedClasses(classId: ClassId): List<CommonizedClassDescriptor?> = classes.getOrFail(classId)
fun getCachedClassifier(classId: ClassId, index: Int): ClassifierDescriptorWithTypeParameters? {
// first, look up for class
val classes: CommonizedGroup<CommonizedClassDescriptor>? = classes.getOrNull(classId)
classes?.get(index)?.let { return it }
// then, for type alias
val typeAliases: CommonizedGroup<CommonizedTypeAliasDescriptor>? = typeAliases.getOrNull(classId)
typeAliases?.get(index)?.let { return it }
val indexOfCommon = dimension - 1
if (indexOfCommon != index) {
// then, for class from the common fragment
classes?.get(indexOfCommon)?.let { return it }
// then, for type alias from the common fragment
typeAliases?.get(indexOfCommon)?.let { return it }
}
return null
}
fun cache(index: Int, modules: List<ModuleDescriptorImpl>) {
this.modules[index] = modules
}
fun cache(moduleName: Name, packageFqName: FqName, index: Int, descriptor: CommonizedPackageFragmentDescriptor) {
packageFragments[moduleName to packageFqName][index] = descriptor
}
fun cache(classId: ClassId, index: Int, descriptor: CommonizedClassDescriptor) {
classes[classId][index] = descriptor
}
fun cache(classId: ClassId, index: Int, descriptor: CommonizedTypeAliasDescriptor) {
typeAliases[classId][index] = descriptor
}
fun getOrPutForwardDeclarationsModule(index: Int, computable: () -> ModuleDescriptorImpl): ModuleDescriptorImpl {
forwardDeclarationsModules[index]?.let { return it }
val module = computable()
forwardDeclarationsModules[index] = module
return module
}
fun getAllModules(index: Int): List<ModuleDescriptor> {
allModulesWithDependencies[index]?.let { return it }
val modulesForTarget = modules[index] ?: error("No module descriptors found for index $index")
val forwardDeclarationsModule = forwardDeclarationsModules[index]
// forward declarations module is created on demand (and only when commonizing Kotlin/Native target)
// so, don't return it if it's not necessary
val allModules = if (forwardDeclarationsModule != null)
modulesForTarget + forwardDeclarationsModule
else
modulesForTarget
// set dependencies for target modules and cache them
modulesForTarget.forEach { it.setDependencies(allModules) }
allModulesWithDependencies[index] = allModules
return allModules
}
companion object {
private inline fun <reified K, reified V : DeclarationDescriptor> CommonizedGroupMap<K, V>.getOrFail(key: K): List<V?> =
getOrNull(key) ?: error("No cached ${V::class.java} with key $key found")
}
}
class GlobalDeclarationsBuilderComponents(
val storageManager: StorageManager,
val targetComponents: List<TargetDeclarationsBuilderComponents>,
val cache: DeclarationsBuilderCache
) {
init {
check(targetComponents.size > 1)
targetComponents.forEachIndexed { index, targetComponent -> check(index == targetComponent.index) }
}
}
class TargetDeclarationsBuilderComponents(
val storageManager: StorageManager,
val target: CommonizerTarget,
val builtIns: KotlinBuiltIns,
val lazyClassifierLookupTable: NotNullLazyValue<LazyClassifierLookupTable>,
val index: Int,
private val cache: DeclarationsBuilderCache
) {
// N.B. this function may create new classifiers for types from Kotlin/Native forward declarations packages
fun findClassOrTypeAlias(classifierId: ClassId): ClassifierDescriptorWithTypeParameters {
return if (classifierId.packageFqName.isUnderKotlinNativeSyntheticPackages) {
// that's a synthetic Kotlin/Native classifier that was exported as forward declaration in one or more modules,
// but did not match any existing class or typealias
cache.getOrPutForwardDeclarationsModule(index) {
// N.B. forward declarations module is created only on demand
createKotlinNativeForwardDeclarationsModule(
storageManager = storageManager,
builtIns = builtIns
)
}.resolveClassOrTypeAlias(classifierId)
?: error("Classifier ${classifierId.asString()} not found for $target")
} else {
cache.getCachedClassifier(classifierId, index) // first, look up in created descriptors cache
?: lazyClassifierLookupTable().resolveClassOrTypeAlias(classifierId) // then, attempt to load the original classifier
?: error("Classifier ${classifierId.asString()} not found for $target")
}
}
}
class LazyClassifierLookupTable(lazyModules: Map<String, List<ModuleDescriptor>>) {
private val table = THashMap<String, List<ModuleDescriptor>>()
private val allModules: Collection<ModuleDescriptor>
init {
// add "module:" prefix for each key representing a module name, not a package name
lazyModules.forEach { (moduleName, modules) -> table[MODULE_NAME_PREFIX + moduleName.toLowerCase()] = modules }
allModules = lazyModules.values.flatten()
}
fun resolveClassOrTypeAlias(classifierId: ClassId): ClassifierDescriptorWithTypeParameters? {
if (table.isEmpty) return null
val packageFqName = classifierId.packageFqName
if (packageFqName.isRoot) return null
val packageFqNameRaw = packageFqName.asString()
table[packageFqNameRaw]?.let { modules ->
for (module in modules)
return module.resolveClassOrTypeAlias(classifierId) ?: continue
}
val packageFqNameFragments = packageFqNameRaw.split('.')
val moduleNameForLookup = when (packageFqNameFragments[0]) {
"kotlin" -> "kotlin"
"platform" -> if (packageFqNameFragments.size == 2) packageFqNameFragments[1].toLowerCase() else null
else -> null
}
// try to find the classifier by guessing its container module
if (moduleNameForLookup != null) {
table[MODULE_NAME_PREFIX + moduleNameForLookup]?.let { modules ->
for (module in modules) {
val classifier = module.resolveClassOrTypeAlias(classifierId) ?: continue
table[packageFqNameRaw] = modules // cache to speed-up the further look-ups
return classifier
}
}
}
// last resort: brute force
for (module in allModules) {
val classifier = module.resolveClassOrTypeAlias(classifierId) ?: continue
table[packageFqNameRaw] = listOf(module) // cache to speed-up the further look-ups
return classifier
}
table[packageFqNameRaw] = null // cache to speed-up the further look-ups
return null
}
companion object {
private const val MODULE_NAME_PREFIX = "module:"
}
}
fun CirRootNode.createGlobalBuilderComponents(
storageManager: StorageManager,
parameters: CommonizerParameters
): GlobalDeclarationsBuilderComponents? {
if (!parameters.generateDescriptors)
return null
val cache = DeclarationsBuilderCache(dimension)
val lazyCommonDependeeModules = storageManager.createLazyValue {
parameters.dependeeModulesProvider?.loadModules(emptyList()).orEmpty()
}
val targetContexts = (0 until dimension).map { index ->
val isCommon = index == indexOfCommon
// do not leak root inside of createLazyValue {} closures!!
val root = if (isCommon) commonDeclaration()!! else targetDeclarations[index]!!
val builtIns = root.builtInsProvider.loadBuiltIns()
check(builtIns::class.java.name == root.builtInsClass) {
"Unexpected built-ins class: ${builtIns::class.java}, $builtIns\nExpected: ${root.builtInsClass}"
}
val lazyModulesLookupTable = storageManager.createLazyValue {
val result = mutableMapOf<String, MutableList<ModuleDescriptor>>()
val commonDependeeModules: Map<String, ModuleDescriptor> = lazyCommonDependeeModules()
if (!isCommon) {
with(parameters.targetProviders[index]) {
val targetDependeeModules: Map<String, ModuleDescriptor> =
dependeeModulesProvider?.loadModules(commonDependeeModules.values).orEmpty()
val targetModules: Map<String, ModuleDescriptor> =
modulesProvider.loadModules(targetDependeeModules.values + commonDependeeModules.values)
targetModules.forEach { (moduleName, module) -> result.getOrPut(moduleName) { mutableListOf() } += module }
targetDependeeModules.forEach { (moduleName, module) -> result.getOrPut(moduleName) { mutableListOf() } += module }
}
}
commonDependeeModules.forEach { (moduleName, module) -> result.getOrPut(moduleName) { mutableListOf() } += module }
result.getOrPut(StandardNames.BUILT_INS_PACKAGE_FQ_NAME.asString()) { mutableListOf() } += builtIns.builtInsModule
LazyClassifierLookupTable(result)
}
TargetDeclarationsBuilderComponents(
storageManager = storageManager,
target = root.target,
builtIns = builtIns,
lazyClassifierLookupTable = lazyModulesLookupTable,
index = index,
cache = cache
)
}
return GlobalDeclarationsBuilderComponents(storageManager, targetContexts, cache)
}
interface TypeParameterResolver {
val parametersCount: Int
fun resolve(index: Int): TypeParameterDescriptor?
companion object {
val EMPTY = object : TypeParameterResolver {
override val parametersCount get() = 0
override fun resolve(index: Int): TypeParameterDescriptor? = null
}
}
}
class TypeParameterResolverImpl(
private val ownTypeParameters: List<TypeParameterDescriptor>,
private val parent: TypeParameterResolver = TypeParameterResolver.EMPTY
) : TypeParameterResolver {
override val parametersCount: Int
get() = ownTypeParameters.size + parent.parametersCount
@Suppress("ConvertTwoComparisonsToRangeCheck")
override fun resolve(index: Int): TypeParameterDescriptor? {
val parentParametersCount = parent.parametersCount
if (index >= 0 && index < parentParametersCount)
return parent.resolve(index)
val localIndex = index - parentParametersCount
if (localIndex < ownTypeParameters.size)
return ownTypeParameters[localIndex]
error("Illegal type parameter index: $index. Should be between 0 and ${parametersCount - 1}")
}
}
fun DeclarationDescriptor.getTypeParameterResolver(): TypeParameterResolver =
when (this) {
is CommonizedClassDescriptor -> typeParameterResolver
is ClassDescriptor -> {
// all class descriptors must be instances of CommonizedClassDescriptor, and therefore must implement ContainerWithTypeParameterResolver
error("Class descriptor that is not instance of ${CommonizedClassDescriptor::class.java}: ${this::class.java}, $this")
}
else -> TypeParameterResolver.EMPTY
}
@@ -1,81 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirFunction
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirFunctionNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
internal fun CirFunctionNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<SimpleFunctionDescriptor>,
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonFunction = commonDeclaration()
val markAsExpectAndActual = commonFunction != null && commonFunction.kind != CallableMemberDescriptor.Kind.SYNTHESIZED
targetDeclarations.forEachIndexed { index, function ->
function?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual)
}
commonFunction?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual)
}
private fun CirFunction.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<SimpleFunctionDescriptor>,
index: Int,
containingDeclarations: List<DeclarationDescriptor?>,
isExpect: Boolean = false,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for function $this")
val functionDescriptor = SimpleFunctionDescriptorImpl.create(
containingDeclaration,
annotations.buildDescriptors(targetComponents),
name,
kind,
SourceElement.NO_SOURCE
)
functionDescriptor.isOperator = modifiers.isOperator
functionDescriptor.isInfix = modifiers.isInfix
functionDescriptor.isInline = modifiers.isInline
functionDescriptor.isTailrec = modifiers.isTailrec
functionDescriptor.isSuspend = modifiers.isSuspend
functionDescriptor.isExternal = modifiers.isExternal
functionDescriptor.isExpect = isExpect
functionDescriptor.isActual = isActual
functionDescriptor.setHasStableParameterNames(hasStableParameterNames)
val (typeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents,
containingDeclaration.getTypeParameterResolver(),
functionDescriptor
)
functionDescriptor.initialize(
extensionReceiver?.buildExtensionReceiver(targetComponents, typeParameterResolver, functionDescriptor),
buildDispatchReceiver(functionDescriptor),
typeParameters,
valueParameters.buildDescriptors(targetComponents, typeParameterResolver, functionDescriptor),
returnType.buildType(targetComponents, typeParameterResolver),
modality,
visibility
)
output[index] = functionDescriptor
}
@@ -1,38 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirModule
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirModuleNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
internal fun CirModuleNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ModuleDescriptorImpl>
) {
targetDeclarations.forEachIndexed { index, module ->
module?.buildDescriptor(components, output, index)
}
commonDeclaration()?.buildDescriptor(components, output, indexOfCommon)
}
private fun CirModule.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ModuleDescriptorImpl>,
index: Int
) {
val moduleDescriptor = ModuleDescriptorImpl(
moduleName = name,
storageManager = components.storageManager,
builtIns = components.targetComponents[index].builtIns,
capabilities = emptyMap() // TODO: preserve capabilities from the original module descriptors, KT-33998
)
output[index] = moduleDescriptor
}
@@ -1,56 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirPackage
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirPackageNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
import org.jetbrains.kotlin.name.FqName
internal fun CirPackageNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<CommonizedPackageFragmentDescriptor>,
modules: List<ModuleDescriptorImpl?>
) {
targetDeclarations.forEachIndexed { index, pkg ->
pkg?.buildDescriptor(components, output, index, modules)
}
commonDeclaration()?.buildDescriptor(components, output, indexOfCommon, modules)
}
private fun CirPackage.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<CommonizedPackageFragmentDescriptor>,
index: Int,
modules: List<ModuleDescriptorImpl?>
) {
val module = modules[index] ?: error("No containing declaration for package $this")
val packageFragment = CommonizedPackageFragmentDescriptor(module, fqName)
// cache created package fragment descriptor:
components.cache.cache(module.name, fqName, index, packageFragment)
output[index] = packageFragment
}
class CommonizedPackageFragmentDescriptor(
module: ModuleDescriptor,
fqName: FqName
) : PackageFragmentDescriptorImpl(module, fqName) {
private lateinit var memberScope: CommonizedMemberScope
fun initialize(memberScope: CommonizedMemberScope) {
this.memberScope = memberScope
}
override fun getMemberScope(): CommonizedMemberScope = memberScope
}
@@ -1,131 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirProperty
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirPropertyNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.descriptors.impl.FieldDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.constants.AnnotationValue
internal fun CirPropertyNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<PropertyDescriptor>,
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonProperty = commonDeclaration()
val isLiftedUp = commonProperty?.isLiftedUp == true
val markAsExpectAndActual = commonProperty != null
&& commonProperty.kind != CallableMemberDescriptor.Kind.SYNTHESIZED
&& !isLiftedUp
if (!isLiftedUp) {
targetDeclarations.forEachIndexed { index, property ->
property?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual)
}
}
commonProperty?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual)
}
private fun CirProperty.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<PropertyDescriptor>,
index: Int,
containingDeclarations: List<DeclarationDescriptor?>,
isExpect: Boolean = false,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for property $this")
val propertyDescriptor = PropertyDescriptorImpl.create(
containingDeclaration,
annotations.buildDescriptors(targetComponents),
modality,
visibility,
isVar,
name,
kind,
SourceElement.NO_SOURCE,
isLateInit,
isConst,
isExpect,
isActual,
isExternal,
isDelegate
)
val (typeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents,
containingDeclaration.getTypeParameterResolver(),
propertyDescriptor
)
propertyDescriptor.setType(
returnType.buildType(targetComponents, typeParameterResolver),
typeParameters,
buildDispatchReceiver(propertyDescriptor),
extensionReceiver?.buildExtensionReceiver(targetComponents, typeParameterResolver, propertyDescriptor)
)
val getterDescriptor = getter?.let { getter ->
DescriptorFactory.createGetter(
propertyDescriptor,
getter.annotations.buildDescriptors(targetComponents),
getter.isDefault,
getter.isExternal,
getter.isInline
).apply {
initialize(null) // use return type from the property descriptor
}
}
val setterDescriptor = setter?.let { setter ->
DescriptorFactory.createSetter(
propertyDescriptor,
setter.annotations.buildDescriptors(targetComponents),
setter.parameterAnnotations.buildDescriptors(targetComponents),
setter.isDefault,
setter.isExternal,
setter.isInline,
setter.visibility,
SourceElement.NO_SOURCE
)
}
val backingField = backingFieldAnnotations?.let { annotations ->
FieldDescriptorImpl(annotations.buildDescriptors(targetComponents), propertyDescriptor)
}
val delegateField = delegateFieldAnnotations?.let { annotations ->
FieldDescriptorImpl(annotations.buildDescriptors(targetComponents), propertyDescriptor)
}
propertyDescriptor.initialize(
getterDescriptor,
setterDescriptor,
backingField,
delegateField
)
compileTimeInitializer?.let { constantValue ->
check(constantValue !is AnnotationValue) {
"Unexpected type of compile time constant: ${constantValue::class.java}, $constantValue"
}
propertyDescriptor.setCompileTimeInitializer(targetComponents.storageManager.createNullableLazyValue { constantValue })
}
output[index] = propertyDescriptor
}
@@ -1,94 +0,0 @@
/*
* Copyright 2010-2019 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.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClass
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirClassifier
import org.jetbrains.kotlin.descriptors.commonizer.cir.CirTypeAlias
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirTypeAliasNode
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.indexOfCommon
import org.jetbrains.kotlin.descriptors.commonizer.utils.CommonizedGroup
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.types.TypeAliasExpander
import org.jetbrains.kotlin.types.TypeAliasExpansion
internal fun CirTypeAliasNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>,
containingDeclarations: List<DeclarationDescriptor?>
) {
val commonClassifier: CirClassifier? = commonDeclaration()
// Note: 'expect class' and lifted up 'typealias' both can't be non-null
val commonTypeAlias: CirTypeAlias? = commonClassifier as? CirTypeAlias?
val isLiftedUp = commonTypeAlias?.isLiftedUp == true
val markAsActual = commonClassifier != null
if (!isLiftedUp) {
targetDeclarations.forEachIndexed { index, typeAlias ->
typeAlias?.buildDescriptor(components, output, index, containingDeclarations, classId, isActual = markAsActual)
}
}
if (commonTypeAlias != null) {
commonTypeAlias.buildDescriptor(components, output, indexOfCommon, containingDeclarations, classId)
} else if (commonClassifier != null && commonClassifier is CirClass) {
commonClassifier.buildDescriptor(components, output, indexOfCommon, containingDeclarations, classId, isExpect = true)
}
}
private fun CirTypeAlias.buildDescriptor(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ClassifierDescriptorWithTypeParameters>,
index: Int,
containingDeclarations: List<DeclarationDescriptor?>,
classId: ClassId,
isActual: Boolean = false
) {
val targetComponents = components.targetComponents[index]
val storageManager = targetComponents.storageManager
val containingDeclaration = containingDeclarations[index] ?: error("No containing declaration for type alias $this")
val typeAliasDescriptor = CommonizedTypeAliasDescriptor(
storageManager = storageManager,
containingDeclaration = containingDeclaration,
annotations = annotations.buildDescriptors(targetComponents),
name = name,
visibility = visibility,
isActual = isActual
)
val (declaredTypeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver(
targetComponents,
TypeParameterResolver.EMPTY,
typeAliasDescriptor
)
val lazyUnderlyingType = storageManager.createLazyValue {
underlyingType.buildType(targetComponents, typeParameterResolver, expandTypeAliases = false)
}
val lazyExpandedType = storageManager.createLazyValue {
TypeAliasExpander.NON_REPORTING.expandWithoutAbbreviation(
TypeAliasExpansion.createWithFormalArguments(typeAliasDescriptor),
Annotations.EMPTY
)
}
typeAliasDescriptor.initialize(
declaredTypeParameters = declaredTypeParameters,
underlyingType = lazyUnderlyingType,
expandedType = lazyExpandedType
)
// cache created type alias descriptor:
components.cache.cache(classId, index, typeAliasDescriptor)
output[index] = typeAliasDescriptor
}
@@ -6,18 +6,12 @@
package org.jetbrains.kotlin.descriptors.commonizer
import kotlinx.metadata.klib.ChunkedKlibModuleFragmentWriteStrategy
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1
import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor2
import org.jetbrains.kotlin.descriptors.commonizer.builder.createGlobalBuilderComponents
import org.jetbrains.kotlin.descriptors.commonizer.core.CommonizationVisitor
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.*
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirNode.Companion.dimension
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.CirTreeMerger.CirTreeMergeResult
import org.jetbrains.kotlin.descriptors.commonizer.metadata.MetadataBuilder
import org.jetbrains.kotlin.descriptors.commonizer.utils.strip
import org.jetbrains.kotlin.library.SerializedMetadata
import org.jetbrains.kotlin.serialization.konan.impl.KlibResolvedModuleDescriptorsFactoryImpl.Companion.FORWARD_DECLARATIONS_MODULE_NAME
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager
@@ -25,50 +19,25 @@ fun runCommonization(parameters: CommonizerParameters): CommonizerResult {
if (!parameters.hasAnythingToCommonize())
return CommonizerResult.NothingToDo
val storageManager = LockBasedStorageManager("Declaration descriptors commonization")
val storageManager = LockBasedStorageManager("Declarations commonization")
val mergeResult = mergeAndCommonize(storageManager, parameters)
val mergedTree = mergeResult.root
// build resulting descriptors:
// build resulting declarations:
val modulesByTargets = LinkedHashMap<CommonizerTarget, Collection<ModuleResult>>() // use linked hash map to preserve order
val klibFragmentWriteStrategy = ChunkedKlibModuleFragmentWriteStrategy()
// optional part for generating descriptors: begin
val components = mergedTree.createGlobalBuilderComponents(storageManager, parameters)
if (components != null) {
mergedTree.accept(DeclarationsBuilderVisitor1(components), emptyList())
mergedTree.accept(DeclarationsBuilderVisitor2(components), emptyList())
}
// optional part for generating descriptors: end
for (targetIndex in 0 until mergedTree.dimension) {
val (target, metadataModules) = MetadataBuilder.build(mergedTree, targetIndex, parameters.statsCollector)
// optional part for generating descriptors: begin
val moduleDescriptors: Map<String, ModuleDescriptor>? = components?.targetComponents?.get(targetIndex)?.let { component ->
check(component.target == target)
check(component.index == targetIndex)
components.cache.getAllModules(targetIndex)
.filter { it.name != FORWARD_DECLARATIONS_MODULE_NAME }
.associateBy { it.name.strip() }
}
// optional part for generating descriptors: end
val commonizedModules: List<ModuleResult.Commonized> = metadataModules.map { metadataModule ->
val libraryName = metadataModule.name
val serializedMetadata = with(metadataModule.write(klibFragmentWriteStrategy)) {
SerializedMetadata(header, fragments, fragmentNames)
}
val libraryMetadata = LibraryMetadata(libraryName, serializedMetadata)
// optional part for generating descriptors: begin
val moduleDescriptor = moduleDescriptors?.get(libraryName)
// optional part for generating descriptors: end
ModuleResult.Commonized(moduleDescriptor, libraryMetadata)
ModuleResult.Commonized(libraryName, serializedMetadata)
}
parameters.progressLogger?.invoke("Built metadata for ${target.prettyCommonizedName(parameters.sharedTarget)}")
@@ -192,25 +192,14 @@ class NativeDistributionCommonizer(
val targetsToSerialize = result.leafTargets + result.sharedTarget
targetsToSerialize.forEach { target ->
val moduleResults: Collection<ModuleResult> = result.modulesByTargets.getValue(target)
val newLibraries: Collection<LibraryMetadata> = moduleResults.mapNotNull { (it as? ModuleResult.Commonized)?.metadata }
val missingModuleLocations: List<File> =
moduleResults.mapNotNull { (it as? ModuleResult.Missing)?.originalLocation }
val prettyTargetName = target.prettyCommonizedName(result.sharedTarget)
val manifestProvider: NativeManifestDataProvider
val starredTarget: String?
when (target) {
is LeafTarget -> {
manifestProvider = originalLibraries.librariesByTargets.getValue(target)
starredTarget = target.name
}
is SharedTarget -> {
manifestProvider = CommonNativeManifestDataProvider(originalLibraries.librariesByTargets.values)
starredTarget = null
}
val manifestProvider = when (target) {
is LeafTarget -> originalLibraries.librariesByTargets.getValue(target)
is SharedTarget -> CommonNativeManifestDataProvider(originalLibraries.librariesByTargets.values)
}
val prettyTargetName = target.prettyCommonizedName(result.sharedTarget)
serializeTarget(target, prettyTargetName, newLibraries, missingModuleLocations, manifestProvider)
serializeTarget(target, prettyTargetName, moduleResults, manifestProvider)
}
}
}
@@ -254,25 +243,29 @@ class NativeDistributionCommonizer(
private fun serializeTarget(
target: CommonizerTarget,
prettyTargetName: String,
newLibraries: Collection<LibraryMetadata>,
missingModuleLocations: List<File>,
moduleResults: Collection<ModuleResult>,
manifestProvider: NativeManifestDataProvider
) {
val librariesDestination = target.librariesDestination
librariesDestination.mkdirs() // always create an empty directory even if there is nothing to copy
for (newLibrary in newLibraries) {
val libraryName = newLibrary.libraryName
for (moduleResult in moduleResults) {
when (moduleResult) {
is ModuleResult.Commonized -> {
val libraryName = moduleResult.libraryName
val manifestData = manifestProvider.getManifest(libraryName)
val libraryDestination = librariesDestination.resolve(libraryName)
val manifestData = manifestProvider.getManifest(libraryName)
val libraryDestination = librariesDestination.resolve(libraryName)
writeLibrary(newLibrary.metadata, manifestData, libraryDestination)
}
writeLibrary(moduleResult.metadata, manifestData, libraryDestination)
}
is ModuleResult.Missing -> {
val libraryName = moduleResult.libraryName
val missingModuleLocation = moduleResult.originalLocation
for (missingModuleLocation in missingModuleLocations) {
val libraryName = missingModuleLocation.name
missingModuleLocation.copyRecursively(librariesDestination.resolve(libraryName))
missingModuleLocation.copyRecursively(librariesDestination.resolve(libraryName))
}
}
}
logProgress("Written libraries for $prettyTargetName")
@@ -5,8 +5,6 @@
package org.jetbrains.kotlin.descriptors.commonizer.utils
import gnu.trove.THashMap
/** Fixed-size ordered collection with no extra space that represents a commonized group of same-rank elements */
class CommonizedGroup<T : Any>(
override val size: Int,
@@ -32,13 +30,3 @@ class CommonizedGroup<T : Any>(
elements[index] = value
}
}
internal class CommonizedGroupMap<K, V : Any>(val size: Int) : Iterable<Map.Entry<K, CommonizedGroup<V>>> {
private val wrapped: MutableMap<K, CommonizedGroup<V>> = THashMap()
operator fun get(key: K): CommonizedGroup<V> = wrapped.getOrPut(key) { CommonizedGroup(size) }
fun getOrNull(key: K): CommonizedGroup<V>? = wrapped[key]
override fun iterator(): Iterator<Map.Entry<K, CommonizedGroup<V>>> = wrapped.iterator()
}
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.konan.util.KlibMetadataFactories
import org.jetbrains.kotlin.library.metadata.NativeTypeTransformer
import org.jetbrains.kotlin.library.metadata.NullFlexibleTypeDeserializer
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.konan.impl.KlibResolvedModuleDescriptorsFactoryImpl
@@ -32,17 +31,6 @@ internal fun createKotlinNativeForwardDeclarationsModule(
storageManager = storageManager
)
// similar to org.jetbrains.kotlin.descriptors.DescriptorUtilKt#resolveClassByFqName, but resolves also type aliases
internal fun ModuleDescriptor.resolveClassOrTypeAlias(classId: ClassId): ClassifierDescriptorWithTypeParameters? {
val relativeClassName: FqName = classId.relativeClassName
if (relativeClassName.isRoot)
return null
return packageFragmentProvider.packageFragments(classId.packageFqName).asSequence().mapNotNull { packageFragment ->
packageFragment.getMemberScope().resolveClassOrTypeAlias(relativeClassName)
}.firstOrNull()
}
internal fun MemberScope.resolveClassOrTypeAlias(relativeClassName: FqName): ClassifierDescriptorWithTypeParameters? {
var memberScope: MemberScope = this
if (memberScope is MemberScope.Empty)
@@ -68,6 +56,4 @@ internal fun MemberScope.resolveClassOrTypeAlias(relativeClassName: FqName): Cla
) as? ClassifierDescriptorWithTypeParameters
}
internal const val MODULE_NAME_PREFIX = "module:"
internal val NativeFactories = KlibMetadataFactories(::KonanBuiltIns, NullFlexibleTypeDeserializer, NativeTypeTransformer())
@@ -80,7 +80,7 @@ abstract class AbstractCommonizationFromSourcesTest : KtUsefulTestCase() {
val sharedModuleAsExpected: SerializedMetadata = analyzedModules.commonizedModules.getValue(sharedTarget)
val sharedModuleByCommonizer: SerializedMetadata =
(result.modulesByTargets.getValue(sharedTarget).single() as ModuleResult.Commonized).metadata.metadata
(result.modulesByTargets.getValue(sharedTarget).single() as ModuleResult.Commonized).metadata
assertModulesAreEqual(sharedModuleAsExpected, sharedModuleByCommonizer, sharedTarget)
@@ -90,7 +90,7 @@ abstract class AbstractCommonizationFromSourcesTest : KtUsefulTestCase() {
for (leafTarget in leafTargets) {
val leafTargetModuleAsExpected: SerializedMetadata = analyzedModules.commonizedModules.getValue(leafTarget)
val leafTargetModuleByCommonizer: SerializedMetadata =
(result.modulesByTargets.getValue(leafTarget).single() as ModuleResult.Commonized).metadata.metadata
(result.modulesByTargets.getValue(leafTarget).single() as ModuleResult.Commonized).metadata
assertModulesAreEqual(leafTargetModuleAsExpected, leafTargetModuleByCommonizer, leafTarget)
}
@@ -205,7 +205,6 @@ private class AnalyzedModules(
fun toCommonizationParameters(): CommonizerParameters {
val parameters = CommonizerParameters()
parameters.generateDescriptors = true
leafTargets.forEach { leafTarget ->
val originalModule = originalModules.getValue(leafTarget)
@@ -120,12 +120,8 @@ class CommonizerFacadeTest {
actualModuleResults.forEach { moduleResult ->
when (moduleResult) {
is ModuleResult.Commonized -> {
actualCommonizedModuleNames += moduleResult.metadata.libraryName
}
is ModuleResult.Missing -> {
actualMissingModuleNames += moduleResult.originalLocation.name
}
is ModuleResult.Commonized -> actualCommonizedModuleNames += moduleResult.libraryName
is ModuleResult.Missing -> actualMissingModuleNames += moduleResult.libraryName
}
}
@@ -5,17 +5,16 @@
package org.jetbrains.kotlin.descriptors.commonizer.utils
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.commonizer.BuiltInsProvider
import org.jetbrains.kotlin.descriptors.commonizer.LeafTarget
import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider
import org.jetbrains.kotlin.descriptors.commonizer.ModulesProvider.ModuleInfo
import org.jetbrains.kotlin.descriptors.commonizer.builder.*
import org.jetbrains.kotlin.descriptors.commonizer.cir.factory.CirClassFactory
import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.*
import org.jetbrains.kotlin.descriptors.impl.AbstractTypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
@@ -26,6 +25,7 @@ import org.jetbrains.kotlin.test.KotlinTestUtils
import org.jetbrains.kotlin.types.*
import java.io.File
import kotlin.random.Random
import org.jetbrains.kotlin.storage.getValue
// expected special name for module
internal fun mockEmptyModule(moduleName: String): ModuleDescriptor {
@@ -40,39 +40,23 @@ internal fun mockClassType(
): KotlinType = LazyWrappedType(LockBasedStorageManager.NO_LOCKS) {
val classFqName = FqName(fqName)
val targetComponents = TargetDeclarationsBuilderComponents(
storageManager = LockBasedStorageManager.NO_LOCKS,
target = LeafTarget("Arbitrary target"),
builtIns = DefaultBuiltIns.Instance,
lazyClassifierLookupTable = LockBasedStorageManager.NO_LOCKS.createLazyValue { LazyClassifierLookupTable(emptyMap()) },
index = 0,
cache = DeclarationsBuilderCache(1)
val classDescriptor = ClassDescriptorImpl(
/* containingDeclaration = */ createPackageFragmentForClassifier(classFqName),
/* name = */ classFqName.shortName(),
/* modality = */ Modality.FINAL,
/* classKind = */ ClassKind.CLASS,
/* supertypes = */ emptyList(),
/* source = */ SourceElement.NO_SOURCE,
/* isExternal = */ false,
/* storageManager = */ LockBasedStorageManager.NO_LOCKS
)
val classDescriptor = CommonizedClassDescriptor(
targetComponents = targetComponents,
containingDeclaration = createPackageFragmentForClassifier(classFqName),
annotations = Annotations.EMPTY,
name = classFqName.shortName(),
kind = ClassKind.CLASS,
modality = Modality.FINAL,
visibility = DescriptorVisibilities.PUBLIC,
isCompanion = false,
isData = false,
isInline = false,
isInner = false,
isExternal = false,
isExpect = false,
isActual = false,
cirDeclaredTypeParameters = emptyList(),
companionObjectName = null,
cirSupertypes = emptyList()
classDescriptor.initialize(
/* unsubstitutedMemberScope = */ MemberScope.Empty,
/* constructors = */ emptySet(),
/* primaryConstructor = */ null
)
classDescriptor.unsubstitutedMemberScope = CommonizedMemberScope()
classDescriptor.initialize(constructors = emptyList())
classDescriptor.defaultType.makeNullableAsSpecified(nullable)
}
@@ -85,20 +69,31 @@ internal fun mockTAType(
val rightHandSideType = rightHandSideTypeProvider().lowerIfFlexible()
val typeAliasDescriptor = CommonizedTypeAliasDescriptor(
storageManager = LockBasedStorageManager.NO_LOCKS,
val typeAliasDescriptor = object : AbstractTypeAliasDescriptor(
containingDeclaration = createPackageFragmentForClassifier(typeAliasFqName),
annotations = Annotations.EMPTY,
name = typeAliasFqName.shortName(),
visibility = DescriptorVisibilities.PUBLIC,
isActual = false
)
sourceElement = SourceElement.NO_SOURCE,
visibilityImpl = DescriptorVisibilities.PUBLIC
) {
override val storageManager get() = LockBasedStorageManager.NO_LOCKS
typeAliasDescriptor.initialize(
declaredTypeParameters = emptyList(),
underlyingType = LockBasedStorageManager.NO_LOCKS.createLazyValue { rightHandSideType.getAbbreviation() ?: rightHandSideType },
expandedType = LockBasedStorageManager.NO_LOCKS.createLazyValue { rightHandSideType }
)
private val defaultTypeImpl = storageManager.createLazyValue { computeDefaultType() }
override fun getDefaultType() = defaultTypeImpl()
override val underlyingType by storageManager.createLazyValue { rightHandSideType.getAbbreviation() ?: rightHandSideType }
override val expandedType by storageManager.createLazyValue { rightHandSideType }
override val classDescriptor get() = expandedType.constructor.declarationDescriptor as? ClassDescriptor
override val constructors by storageManager.createLazyValue { getTypeAliasConstructors() }
private val typeConstructorTypeParametersImpl by storageManager.createLazyValue { computeConstructorTypeParameters() }
override fun getTypeConstructorTypeParameters() = typeConstructorTypeParametersImpl
override fun substitute(substitutor: TypeSubstitutor) = error("Unsupported")
}
typeAliasDescriptor.initialize(declaredTypeParameters = emptyList())
(rightHandSideType.getAbbreviatedType()?.expandedType ?: rightHandSideType)
.withAbbreviation(typeAliasDescriptor.defaultType)