diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedClassDescriptor.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedClassDescriptor.kt index 60dc8297f0a..c602e3d8ded 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedClassDescriptor.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedClassDescriptor.kt @@ -7,6 +7,8 @@ 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.mergedtree.ir.CirType +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeParameter import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase import org.jetbrains.kotlin.incremental.components.NoLookupLocation @@ -15,14 +17,12 @@ import org.jetbrains.kotlin.resolve.DescriptorFactory.* import org.jetbrains.kotlin.resolve.descriptorUtil.computeSealedSubclasses import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum -import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.AbstractClassTypeConstructor -import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner class CommonizedClassDescriptor( - storageManager: StorageManager, + targetComponents: TargetDeclarationsBuilderComponents, containingDeclaration: DeclarationDescriptor, override val annotations: Annotations, name: Name, @@ -36,18 +36,33 @@ class CommonizedClassDescriptor( isExternal: Boolean, private val isExpect: Boolean, private val isActual: Boolean, + cirDeclaredTypeParameters: List, companionObjectName: Name?, - supertypes: Collection -) : ClassDescriptorBase(storageManager, containingDeclaration, name, SourceElement.NO_SOURCE, isExternal) { - private lateinit var _unsubstitutedMemberScope: MemberScope + cirSupertypes: Collection +) : ClassDescriptorBase(targetComponents.storageManager, containingDeclaration, name, SourceElement.NO_SOURCE, isExternal) { + private lateinit var _unsubstitutedMemberScope: CommonizedMemberScope private lateinit var constructors: Collection private var primaryConstructor: ClassConstructorDescriptor? = null - private val staticScope = if (kind == ClassKind.ENUM_CLASS) StaticScopeForKotlinEnum(storageManager, this) else MemberScope.Empty - private lateinit var declaredTypeParameters: List - private val typeConstructor = CommonizedClassTypeConstructor(storageManager, supertypes) - private val sealedSubclasses = storageManager.createLazyValue { computeSealedSubclasses(this) } - private val companionObjectDescriptor = storageManager.createNullableLazyValue { + 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 { computeSealedSubclasses(this) } + + 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 @@ -64,18 +79,21 @@ class CommonizedClassDescriptor( override fun isExpect() = isExpect override fun isActual() = isActual - override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): MemberScope { + override fun getUnsubstitutedMemberScope(kotlinTypeRefiner: KotlinTypeRefiner): CommonizedMemberScope { check(kotlinTypeRefiner == KotlinTypeRefiner.Default) { "${kotlinTypeRefiner::class.java} is not supported in ${this::class.java}" } return _unsubstitutedMemberScope } - override fun getDeclaredTypeParameters() = declaredTypeParameters - fun setDeclaredTypeParameters(declaredTypeParameters: List) { - this.declaredTypeParameters = declaredTypeParameters + 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 @@ -83,12 +101,7 @@ class CommonizedClassDescriptor( override fun getCompanionObjectDescriptor() = companionObjectDescriptor() override fun getSealedSubclasses() = sealedSubclasses() - fun initialize( - unsubstitutedMemberScope: MemberScope, - constructors: Collection - ) { - _unsubstitutedMemberScope = unsubstitutedMemberScope - + fun initialize(constructors: Collection) { if (isExpect && kind.isSingleton) { check(constructors.isEmpty()) @@ -109,15 +122,19 @@ class CommonizedClassDescriptor( override fun toString() = (if (isExpect) "expect " else if (isActual) "actual " else "") + "class " + name.toString() private inner class CommonizedClassTypeConstructor( - storageManager: StorageManager, - private val computedSupertypes: Collection - ) : AbstractClassTypeConstructor(storageManager) { - private val parameters = storageManager.createLazyValue { + targetComponents: TargetDeclarationsBuilderComponents, + cirSupertypes: Collection + ) : 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() = computedSupertypes + override fun computeSupertypes() = supertypes() override fun isDenotable() = true override fun getDeclarationDescriptor() = this@CommonizedClassDescriptor override val supertypeLoopChecker get() = SupertypeLoopChecker.EMPTY diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedMemberScope.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedMemberScope.kt index 24c50a464fa..a23ae39a1e7 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedMemberScope.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedMemberScope.kt @@ -15,7 +15,7 @@ import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl import org.jetbrains.kotlin.utils.Printer -internal class CommonizedMemberScope : MemberScopeImpl() { +class CommonizedMemberScope : MemberScopeImpl() { private val members = ArrayList() operator fun plusAssign(member: DeclarationDescriptor) { @@ -51,7 +51,17 @@ internal class CommonizedMemberScope : MemberScopeImpl() { operator fun Array.plusAssign(members: List) { members.forEachIndexed { index, member -> - this[index] += member ?: return@forEachIndexed + if (member != null) { + this[index] += member + } + } + } + + operator fun List.plusAssign(members: List) { + members.forEachIndexed { index, member -> + if (member != null) { + this[index]?.run { this += member } + } } } } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedTypeAliasDescriptor.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedTypeAliasDescriptor.kt index 4c90a97eb66..31d0dd51080 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedTypeAliasDescriptor.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedTypeAliasDescriptor.kt @@ -8,8 +8,8 @@ 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.descriptors.impl.TypeAliasConstructorDescriptor 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 @@ -25,28 +25,33 @@ class CommonizedTypeAliasDescriptor( private val isActual: Boolean ) : AbstractTypeAliasDescriptor(containingDeclaration, annotations, name, SourceElement.NO_SOURCE, visibility) { - override lateinit var underlyingType: SimpleType - override lateinit var expandedType: SimpleType + private lateinit var underlyingTypeImpl: NotNullLazyValue + override val underlyingType get() = underlyingTypeImpl() - private lateinit var defaultType: SimpleType - override fun getDefaultType() = defaultType + private lateinit var expandedTypeImpl: NotNullLazyValue + 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 lateinit var typeConstructorParameters: List - override fun getTypeConstructorTypeParameters() = typeConstructorParameters + private val typeConstructorParametersImpl = storageManager.createLazyValue { computeConstructorTypeParameters() } + override fun getTypeConstructorTypeParameters() = typeConstructorParametersImpl() - override lateinit var constructors: Collection + private val constructorsImpl = storageManager.createLazyValue { getTypeAliasConstructors() } + override val constructors get() = constructorsImpl() override fun isActual() = isActual - fun initialize(declaredTypeParameters: List, underlyingType: SimpleType, expandedType: SimpleType) { + fun initialize( + declaredTypeParameters: List, + underlyingType: NotNullLazyValue, + expandedType: NotNullLazyValue + ) { super.initialize(declaredTypeParameters) - this.underlyingType = underlyingType - this.expandedType = expandedType - typeConstructorParameters = computeConstructorTypeParameters() - defaultType = computeDefaultType() - constructors = getTypeAliasConstructors() + underlyingTypeImpl = underlyingType + expandedTypeImpl = expandedType } override fun substitute(substitutor: TypeSubstitutor): ClassifierDescriptorWithTypeParameters { @@ -61,8 +66,8 @@ class CommonizedTypeAliasDescriptor( ) substituted.initialize( declaredTypeParameters, - substitutor.safeSubstitute(underlyingType, Variance.INVARIANT).asSimpleType(), - substitutor.safeSubstitute(expandedType, Variance.INVARIANT).asSimpleType() + storageManager.createLazyValue { substitutor.safeSubstitute(underlyingType, Variance.INVARIANT).asSimpleType() }, + storageManager.createLazyValue { substitutor.safeSubstitute(expandedType, Variance.INVARIANT).asSimpleType() } ) return substituted } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedTypeParameterDescriptor.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedTypeParameterDescriptor.kt new file mode 100644 index 00000000000..88c9d3c7cd4 --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/CommonizedTypeParameterDescriptor.kt @@ -0,0 +1,48 @@ +/* + * 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.mergedtree.ir.CirType +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 +) : AbstractLazyTypeParameterDescriptor( + targetComponents.storageManager, + containingDeclaration, + name, + variance, + isReified, + index, + SourceElement.NO_SOURCE, + SupertypeLoopChecker.EMPTY +) { + override fun resolveUpperBounds(): List { + return if (cirUpperBounds.isEmpty()) + listOf(targetComponents.builtIns.defaultBound) + else + cirUpperBounds.map { 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") +} diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor1.kt similarity index 60% rename from konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor.kt rename to konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor1.kt index f1631012f12..9df6b8300ce 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor1.kt @@ -11,17 +11,23 @@ import org.jetbrains.kotlin.descriptors.commonizer.Target 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.ir.* +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.dimension +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl -import org.jetbrains.kotlin.resolve.scopes.MemberScope -import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.utils.addIfNotNull -/** Builds and initializes the new tree of common descriptors */ -internal class DeclarationsBuilderVisitor( - private val storageManager: StorageManager, - private val collector: (Target, Collection) -> Unit +/** + * 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> { override fun visitRootNode(node: CirRootNode, data: List): List { + check(data.isEmpty()) // root node may not have containing declarations + check(components.targetComponents.size == node.dimension) + val allTargets = (node.target + node.common()!!).map { it.target } val modulesByTargets = HashMap>() @@ -41,9 +47,9 @@ internal class DeclarationsBuilderVisitor( module.setDependencies(modulesSameTarget) } - // return result (preserve platforms order): - for (target in allTargets) { - collector(target, modulesByTargets.getValue(target)) + // return result (preserving order of targets): + allTargets.forEachIndexed { index, target -> + components.cache.cache(index, modulesByTargets.getValue(target)) } return noReturningDeclarations() @@ -52,7 +58,7 @@ internal class DeclarationsBuilderVisitor( override fun visitModuleNode(node: CirModuleNode, data: List): List { // build module descriptors: val moduleDescriptorsGroup = CommonizedGroup(node.dimension) - node.buildDescriptors(moduleDescriptorsGroup, storageManager) + node.buildDescriptors(components, moduleDescriptorsGroup) val moduleDescriptors = moduleDescriptorsGroup.toList() // build package fragments: @@ -75,17 +81,11 @@ internal class DeclarationsBuilderVisitor( // build package fragments: val packageFragmentsGroup = CommonizedGroup(node.dimension) - node.buildDescriptors(packageFragmentsGroup, containingDeclarations) + node.buildDescriptors(components, packageFragmentsGroup, containingDeclarations) val packageFragments = packageFragmentsGroup.toList() // build package members: val packageMemberScopes = CommonizedMemberScope.createArray(node.dimension) - for (propertyNode in node.properties) { - packageMemberScopes += propertyNode.accept(this, packageFragments) - } - for (functionNode in node.functions) { - packageMemberScopes += functionNode.accept(this, packageFragments) - } for (classNode in node.classes) { packageMemberScopes += classNode.accept(this, packageFragments) } @@ -101,80 +101,52 @@ internal class DeclarationsBuilderVisitor( return packageFragments } - override fun visitPropertyNode(node: CirPropertyNode, data: List): List { - val propertyDescriptorsGroup = CommonizedGroup(node.dimension) - node.buildDescriptors(propertyDescriptorsGroup, data, storageManager) + override fun visitPropertyNode(node: CirPropertyNode, data: List) = + error("This method should not be called in ${this::class.java}") - return propertyDescriptorsGroup.toList() - } - - override fun visitFunctionNode(node: CirFunctionNode, data: List): List { - val functionDescriptorsGroup = CommonizedGroup(node.dimension) - node.buildDescriptors(functionDescriptorsGroup, data) - - return functionDescriptorsGroup.toList() - } + override fun visitFunctionNode(node: CirFunctionNode, data: List) = + error("This method should not be called in ${this::class.java}") override fun visitClassNode(node: CirClassNode, data: List): List { val classesGroup = CommonizedGroup(node.dimension) - node.buildDescriptors(classesGroup, data, storageManager) + node.buildDescriptors(components, classesGroup, data) val classes = classesGroup.toList().asListContaining() - // build class constructors: - val allConstructorsByTargets = Array>(node.dimension) { ArrayList() } - for (constructorNode in node.constructors) { - val constructorsByTargets = constructorNode.accept(this, classes).asListContaining() - constructorsByTargets.forEachIndexed { index, constructor -> - if (constructor != null) allConstructorsByTargets[index].add(constructor) - } - } - // build class members: val classMemberScopes = CommonizedMemberScope.createArray(node.dimension) - for (propertyNode in node.properties) { - classMemberScopes += propertyNode.accept(this, classes) - } - for (functionNode in node.functions) { - classMemberScopes += functionNode.accept(this, classes) - } for (classNode in node.classes) { classMemberScopes += classNode.accept(this, classes) } - // initialize classes + // save member scope classes.forEachIndexed { index, clazz -> - clazz?.initialize(classMemberScopes[index], allConstructorsByTargets[index]) + clazz?.unsubstitutedMemberScope = classMemberScopes[index] } return classes } - override fun visitClassConstructorNode(node: CirClassConstructorNode, data: List): List { - val containingDeclarations = data.asListContaining() - - val constructorsGroup = CommonizedGroup(node.dimension) - node.buildDescriptors(constructorsGroup, containingDeclarations) - - return constructorsGroup.toList() - } + override fun visitClassConstructorNode(node: CirClassConstructorNode, data: List) = + error("This method should not be called in ${this::class.java}") override fun visitTypeAliasNode(node: CirTypeAliasNode, data: List): List { val typeAliasesGroup = CommonizedGroup(node.dimension) - node.buildDescriptors(typeAliasesGroup, data, storageManager) + node.buildDescriptors(components, typeAliasesGroup, data) val typeAliases = typeAliasesGroup.toList() val commonClass = typeAliases[node.indexOfCommon] as CommonizedClassDescriptor? - commonClass?.initialize(MemberScope.Empty, emptyList()) + commonClass?.unsubstitutedMemberScope = CommonizedMemberScope() // empty member scope + commonClass?.initialize(emptyList()) // no constructors return typeAliases } companion object { - inline fun noContainingDeclarations() = emptyList() - inline fun noReturningDeclarations() = emptyList() + internal inline fun noContainingDeclarations() = emptyList() + internal inline fun noReturningDeclarations() = emptyList() + + @Suppress("UNCHECKED_CAST") + internal inline fun List.asListContaining(): List = + this as List } } - -@Suppress("UNCHECKED_CAST") -private inline fun List.asListContaining(): List = - this as List diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor2.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor2.kt new file mode 100644 index 00000000000..2aa7368b386 --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/DeclarationsBuilderVisitor2.kt @@ -0,0 +1,125 @@ +/* + * 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.CommonizedGroup +import org.jetbrains.kotlin.descriptors.commonizer.builder.CommonizedMemberScope.Companion.plusAssign +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.builder.DeclarationsBuilderVisitor1.Companion.asListContaining +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.* +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> { + override fun visitRootNode(node: CirRootNode, data: List): List { + check(data.isEmpty()) // root node may not have containing declarations + check(components.targetComponents.size == node.dimension) + + // visit module descriptors: + for (moduleNode in node.modules) { + moduleNode.accept(this, noContainingDeclarations()) + } + + return noReturningDeclarations() + } + + override fun visitModuleNode(node: CirModuleNode, data: List): List { + // visit package fragment descriptors: + for (packageNode in node.packages) { + packageNode.accept(this, noContainingDeclarations()) + } + + return noReturningDeclarations() + } + + override fun visitPackageNode(node: CirPackageNode, data: List): List { + val packageFragments = components.cache.getCachedPackageFragments(node.fqName) + + // build non-classifier package members: + val packageMemberScopes = packageFragments.map { it?.getMemberScope() } + for (propertyNode in node.properties) { + packageMemberScopes += propertyNode.accept(this, packageFragments) + } + for (functionNode in node.functions) { + packageMemberScopes += functionNode.accept(this, packageFragments) + } + + for (classNode in node.classes) { + classNode.accept(this, noContainingDeclarations()) + } + + return noReturningDeclarations() + } + + override fun visitPropertyNode(node: CirPropertyNode, data: List): List { + val propertyDescriptorsGroup = CommonizedGroup(node.dimension) + node.buildDescriptors(components, propertyDescriptorsGroup, data) + + return propertyDescriptorsGroup.toList() + } + + override fun visitFunctionNode(node: CirFunctionNode, data: List): List { + val functionDescriptorsGroup = CommonizedGroup(node.dimension) + node.buildDescriptors(components, functionDescriptorsGroup, data) + + return functionDescriptorsGroup.toList() + } + + override fun visitClassNode(node: CirClassNode, data: List): List { + val classes = components.cache.getCachedClasses(node.fqName) + + // build class constructors: + val allConstructorsByTargets = Array>(node.dimension) { ArrayList() } + for (constructorNode in node.constructors) { + val constructorsByTargets = constructorNode.accept(this, classes).asListContaining() + 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) { + classMemberScopes += propertyNode.accept(this, classes) + } + for (functionNode in node.functions) { + classMemberScopes += functionNode.accept(this, classes) + } + + for (classNode in node.classes) { + classNode.accept(this, noContainingDeclarations()) + } + + return noReturningDeclarations() + } + + override fun visitClassConstructorNode(node: CirClassConstructorNode, data: List): List { + val containingDeclarations = data.asListContaining() + + val constructorsGroup = CommonizedGroup(node.dimension) + node.buildDescriptors(components, constructorsGroup, containingDeclarations) + + return constructorsGroup.toList() + } + + override fun visitTypeAliasNode(node: CirTypeAliasNode, data: List) = + error("This method should not be called in ${this::class.java}") +} diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/classDescriptors.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/classDescriptors.kt index 048032a62a2..090d6235121 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/classDescriptors.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/classDescriptors.kt @@ -9,35 +9,37 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroup import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.* import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon -import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.name.FqName internal fun CirClassNode.buildDescriptors( + components: GlobalDeclarationsBuilderComponents, output: CommonizedGroup, - containingDeclarations: List, - storageManager: StorageManager + containingDeclarations: List ) { val commonClass = common() val markAsActual = commonClass != null && commonClass.kind != ClassKind.ENUM_ENTRY target.forEachIndexed { index, clazz -> - clazz?.buildDescriptor(output, index, containingDeclarations, storageManager, isActual = markAsActual) + clazz?.buildDescriptor(components, output, index, containingDeclarations, fqName, isActual = markAsActual) } - commonClass?.buildDescriptor(output, indexOfCommon, containingDeclarations, storageManager, isExpect = true) + commonClass?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, fqName, isExpect = true) } internal fun CirClass.buildDescriptor( + components: GlobalDeclarationsBuilderComponents, output: CommonizedGroup, index: Int, containingDeclarations: List, - storageManager: StorageManager, + fqName: FqName, 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( - storageManager = storageManager, + targetComponents = targetComponents, containingDeclaration = containingDeclaration, annotations = annotations, name = name, @@ -51,36 +53,41 @@ internal fun CirClass.buildDescriptor( isExternal = isExternal, isExpect = isExpect, isActual = isActual, + cirDeclaredTypeParameters = typeParameters, companionObjectName = companion?.shortName(), - supertypes = supertypes + cirSupertypes = supertypes ) - classDescriptor.declaredTypeParameters = typeParameters.buildDescriptors(classDescriptor) + // cache created class descriptor: + components.cache.cache(fqName, index, classDescriptor) output[index] = classDescriptor } internal fun CirClassConstructorNode.buildDescriptors( + components: GlobalDeclarationsBuilderComponents, output: CommonizedGroup, - containingDeclarations: List + containingDeclarations: List ) { val commonConstructor = common() val markAsActual = commonConstructor != null target.forEachIndexed { index, constructor -> - constructor?.buildDescriptor(output, index, containingDeclarations, isActual = markAsActual) + constructor?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsActual) } - commonConstructor?.buildDescriptor(output, indexOfCommon, containingDeclarations, isExpect = true) + commonConstructor?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = true) } private fun CirClassConstructor.buildDescriptor( + components: GlobalDeclarationsBuilderComponents, output: CommonizedGroup, index: Int, - containingDeclarations: List, + containingDeclarations: List, 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( @@ -96,10 +103,18 @@ private fun CirClassConstructor.buildDescriptor( constructorDescriptor.setHasStableParameterNames(hasStableParameterNames) constructorDescriptor.setHasSynthesizedParameterNames(hasSynthesizedParameterNames) + val classTypeParameters = containingDeclaration.declaredTypeParameters + val (constructorTypeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver( + targetComponents = targetComponents, + parentTypeParameterResolver = containingDeclaration.typeParameterResolver, + containingDeclaration = constructorDescriptor, + typeParametersIndexOffset = classTypeParameters.size + ) + constructorDescriptor.initialize( - valueParameters.buildDescriptors(constructorDescriptor), + valueParameters.buildDescriptors(targetComponents, typeParameterResolver, constructorDescriptor), visibility, - typeParameters.buildDescriptors(constructorDescriptor) + classTypeParameters + constructorTypeParameters ) output[index] = constructorDescriptor diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/context.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/context.kt new file mode 100644 index 00000000000..575eaee0526 --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/context.kt @@ -0,0 +1,141 @@ +/* + * 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.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroup +import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroupMap +import org.jetbrains.kotlin.descriptors.commonizer.Target +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirRootNode +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.dimension +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.storage.StorageManager + +/** + * Temporary caches for constructed descriptors. + */ +class DeclarationsBuilderCache(dimension: Int) { + init { + check(dimension > 0) + } + + private val packageFragments = CommonizedGroupMap(dimension) + private val classes = CommonizedGroupMap(dimension) + private val typeAliases = CommonizedGroupMap(dimension) + private val modules = CommonizedGroup>(dimension) + + fun getCachedPackageFragments(fqName: FqName): List = packageFragments.getOrFail(fqName) + fun getCachedClasses(fqName: FqName): List = classes.getOrFail(fqName) + + private inline fun CommonizedGroupMap.getOrFail(fqName: FqName): List = + getOrNull(fqName)?.toList() ?: error("No cached ${T::class.java} with FQ name $fqName found") + + fun cache(fqName: FqName, index: Int, descriptor: CommonizedPackageFragmentDescriptor) { + packageFragments[fqName][index] = descriptor + } + + fun cache(fqName: FqName, index: Int, descriptor: CommonizedClassDescriptor) { + classes[fqName][index] = descriptor + } + + fun cache(fqName: FqName, index: Int, descriptor: CommonizedTypeAliasDescriptor) { + typeAliases[fqName][index] = descriptor + } + + fun cache(index: Int, modules: Collection) { + this.modules[index] = modules + } + + fun getCachedClassifier(fqName: FqName, index: Int): ClassifierDescriptorWithTypeParameters? = + classes.getOrNull(fqName)?.get(index) ?: typeAliases.getOrNull(fqName)?.get(index) + + fun getCachedModules(index: Int): Collection = modules[index] ?: error("No module descriptors found for index $index") +} + +class GlobalDeclarationsBuilderComponents( + val storageManager: StorageManager, + val targetComponents: List, + val cache: DeclarationsBuilderCache +) { + init { + check(targetComponents.size > 1) + targetComponents.forEachIndexed { index, targetComponent -> check(index == targetComponent.index) } + } +} + +class TargetDeclarationsBuilderComponents( + val storageManager: StorageManager, + val target: Target, + val builtIns: KotlinBuiltIns, + val isCommon: Boolean, + val index: Int, + private val cache: DeclarationsBuilderCache +) { + // only for classes and type aliases + fun getCachedClassifier(fqName: FqName): ClassifierDescriptorWithTypeParameters? = cache.getCachedClassifier(fqName, index) +} + +fun CirRootNode.createGlobalBuilderComponents(storageManager: StorageManager): GlobalDeclarationsBuilderComponents { + val cache = DeclarationsBuilderCache(dimension) + + val targetContexts = (0 until dimension).map { index -> + val isCommon = index == indexOfCommon + val target = (if (isCommon) common()!! else target[index]).target + + val builtIns = modules.asSequence() + .mapNotNull { if (isCommon) it.common() else it.target[index] } + .first() + .builtIns + + TargetDeclarationsBuilderComponents( + storageManager = storageManager, + target = target, + builtIns = builtIns, + isCommon = isCommon, + index = index, + cache = cache + ) + } + + return GlobalDeclarationsBuilderComponents(storageManager, targetContexts, cache) +} + +interface TypeParameterResolver { + fun resolve(name: Name): TypeParameterDescriptor? + + companion object { + val EMPTY = object : TypeParameterResolver { + override fun resolve(name: Name): TypeParameterDescriptor? = null + } + } +} + +class TypeParameterResolverImpl( + storageManager: StorageManager, + ownTypeParameters: List, + private val parent: TypeParameterResolver = TypeParameterResolver.EMPTY +) : TypeParameterResolver { + + private val ownTypeParameters = storageManager.createLazyValue { + // memoize the first occurrence of descriptor with the same Name + ownTypeParameters.groupingBy { it.name }.reduce { _, accumulator, _ -> accumulator } + } + + override fun resolve(name: Name) = ownTypeParameters()[name] ?: parent.resolve(name) +} + +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 + } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/functionDescriptors.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/functionDescriptors.kt index 67a789fc275..fbdd00510ec 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/functionDescriptors.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/functionDescriptors.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl internal fun CirFunctionNode.buildDescriptors( + components: GlobalDeclarationsBuilderComponents, output: CommonizedGroup, containingDeclarations: List ) { @@ -23,19 +24,21 @@ internal fun CirFunctionNode.buildDescriptors( val markAsExpectAndActual = commonFunction != null && commonFunction.kind != CallableMemberDescriptor.Kind.SYNTHESIZED target.forEachIndexed { index, function -> - function?.buildDescriptor(output, index, containingDeclarations, isActual = markAsExpectAndActual) + function?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual) } - commonFunction?.buildDescriptor(output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual) + commonFunction?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual) } private fun CirFunction.buildDescriptor( + components: GlobalDeclarationsBuilderComponents, output: CommonizedGroup, index: Int, containingDeclarations: List, 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( @@ -59,12 +62,18 @@ private fun CirFunction.buildDescriptor( functionDescriptor.setHasStableParameterNames(hasStableParameterNames) functionDescriptor.setHasSynthesizedParameterNames(hasSynthesizedParameterNames) + val (typeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver( + targetComponents, + containingDeclaration.getTypeParameterResolver(), + functionDescriptor + ) + functionDescriptor.initialize( - extensionReceiver?.buildExtensionReceiver(functionDescriptor), + extensionReceiver?.buildExtensionReceiver(targetComponents, typeParameterResolver, functionDescriptor), buildDispatchReceiver(functionDescriptor), - typeParameters.buildDescriptors(functionDescriptor), - valueParameters.buildDescriptors(functionDescriptor), - returnType, + typeParameters, + valueParameters.buildDescriptors(targetComponents, typeParameterResolver, functionDescriptor), + returnType.buildType(targetComponents, typeParameterResolver), modality, visibility ) diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/moduleDescriptors.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/moduleDescriptors.kt index 464f71e3c9d..b9f7ad4b80b 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/moduleDescriptors.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/moduleDescriptors.kt @@ -10,27 +10,26 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirModule import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirModuleNode import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl -import org.jetbrains.kotlin.storage.StorageManager internal fun CirModuleNode.buildDescriptors( - output: CommonizedGroup, - storageManager: StorageManager + components: GlobalDeclarationsBuilderComponents, + output: CommonizedGroup ) { target.forEachIndexed { index, module -> - module?.buildDescriptor(output, index, storageManager) + module?.buildDescriptor(components, output, index) } - common()?.buildDescriptor(output, indexOfCommon, storageManager) + common()?.buildDescriptor(components, output, indexOfCommon) } private fun CirModule.buildDescriptor( + components: GlobalDeclarationsBuilderComponents, output: CommonizedGroup, - index: Int, - storageManager: StorageManager + index: Int ) { val moduleDescriptor = ModuleDescriptorImpl( moduleName = name, - storageManager = storageManager, + storageManager = components.storageManager, builtIns = builtIns, capabilities = emptyMap() // TODO: preserve capabilities from the original module descriptors, KT-33998 ) diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/packageFragments.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/packageFragments.kt index 146a1701f48..d8f3104a351 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/packageFragments.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/packageFragments.kt @@ -13,38 +13,44 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.resolve.scopes.MemberScope internal fun CirPackageNode.buildDescriptors( + components: GlobalDeclarationsBuilderComponents, output: CommonizedGroup, modules: List ) { target.forEachIndexed { index, pkg -> - pkg?.buildDescriptor(output, index, modules) + pkg?.buildDescriptor(components, output, index, modules) } - common()?.buildDescriptor(output, indexOfCommon, modules) + common()?.buildDescriptor(components, output, indexOfCommon, modules) } private fun CirPackage.buildDescriptor( + components: GlobalDeclarationsBuilderComponents, output: CommonizedGroup, index: Int, modules: List ) { val module = modules[index] ?: error("No containing declaration for package $this") + val packageFragment = CommonizedPackageFragmentDescriptor(module, fqName) + + // cache created package fragment descriptor: + components.cache.cache(fqName, index, packageFragment) + output[index] = packageFragment } -internal class CommonizedPackageFragmentDescriptor( +class CommonizedPackageFragmentDescriptor( module: ModuleDescriptor, fqName: FqName ) : PackageFragmentDescriptorImpl(module, fqName) { - private lateinit var memberScope: MemberScope + private lateinit var memberScope: CommonizedMemberScope - fun initialize(memberScope: MemberScope) { + fun initialize(memberScope: CommonizedMemberScope) { this.memberScope = memberScope } - override fun getMemberScope() = memberScope + override fun getMemberScope(): CommonizedMemberScope = memberScope } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/propertyDescriptors.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/propertyDescriptors.kt index cd08fb70f2b..257e018d3e4 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/propertyDescriptors.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/propertyDescriptors.kt @@ -16,31 +16,31 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon import org.jetbrains.kotlin.descriptors.impl.FieldDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl import org.jetbrains.kotlin.resolve.DescriptorFactory -import org.jetbrains.kotlin.storage.StorageManager internal fun CirPropertyNode.buildDescriptors( + components: GlobalDeclarationsBuilderComponents, output: CommonizedGroup, - containingDeclarations: List, - storageManager: StorageManager + containingDeclarations: List ) { val commonProperty = common() val markAsExpectAndActual = commonProperty != null && commonProperty.kind != CallableMemberDescriptor.Kind.SYNTHESIZED target.forEachIndexed { index, property -> - property?.buildDescriptor(output, index, containingDeclarations, storageManager, isActual = markAsExpectAndActual) + property?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual) } - commonProperty?.buildDescriptor(output, indexOfCommon, containingDeclarations, storageManager, isExpect = markAsExpectAndActual) + commonProperty?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual) } private fun CirProperty.buildDescriptor( + components: GlobalDeclarationsBuilderComponents, output: CommonizedGroup, index: Int, containingDeclarations: List, - storageManager: StorageManager, 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( @@ -60,11 +60,17 @@ private fun CirProperty.buildDescriptor( isDelegate ) + val (typeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver( + targetComponents, + containingDeclaration.getTypeParameterResolver(), + propertyDescriptor + ) + propertyDescriptor.setType( - returnType, - typeParameters.buildDescriptors(propertyDescriptor), + returnType.buildType(targetComponents, typeParameterResolver), + typeParameters, buildDispatchReceiver(propertyDescriptor), - extensionReceiver?.buildExtensionReceiver(propertyDescriptor) + extensionReceiver?.buildExtensionReceiver(targetComponents, typeParameterResolver, propertyDescriptor) ) val getterDescriptor = getter?.let { getter -> @@ -103,7 +109,7 @@ private fun CirProperty.buildDescriptor( ) compileTimeInitializer?.let { constantValue -> - propertyDescriptor.setCompileTimeInitializer(storageManager.createNullableLazyValue { constantValue }) + propertyDescriptor.setCompileTimeInitializer(targetComponents.storageManager.createNullableLazyValue { constantValue }) } output[index] = propertyDescriptor diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/typeAliasDescriptors.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/typeAliasDescriptors.kt index e74d554f229..d5118eac485 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/typeAliasDescriptors.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/typeAliasDescriptors.kt @@ -12,30 +12,33 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClass import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeAlias import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeAliasNode import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.indexOfCommon -import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.name.FqName internal fun CirTypeAliasNode.buildDescriptors( + components: GlobalDeclarationsBuilderComponents, output: CommonizedGroup, - containingDeclarations: List, - storageManager: StorageManager + containingDeclarations: List ) { val commonClass: CirClass? = common() val markAsActual = commonClass != null target.forEachIndexed { index, typeAlias -> - typeAlias?.buildDescriptor(output, index, containingDeclarations, storageManager, isActual = markAsActual) + typeAlias?.buildDescriptor(components, output, index, containingDeclarations, fqName, isActual = markAsActual) } - commonClass?.buildDescriptor(output, indexOfCommon, containingDeclarations, storageManager, isExpect = true) + commonClass?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, fqName, isExpect = true) } private fun CirTypeAlias.buildDescriptor( + components: GlobalDeclarationsBuilderComponents, output: CommonizedGroup, index: Int, containingDeclarations: List, - storageManager: StorageManager, + fqName: FqName, 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( @@ -47,11 +50,20 @@ private fun CirTypeAlias.buildDescriptor( isActual = isActual ) - typeAliasDescriptor.initialize( - declaredTypeParameters = typeParameters.buildDescriptors(typeAliasDescriptor), - underlyingType = underlyingType, - expandedType = expandedType + val (declaredTypeParameters, typeParameterResolver) = typeParameters.buildDescriptorsAndTypeParameterResolver( + targetComponents, + TypeParameterResolver.EMPTY, + typeAliasDescriptor ) + typeAliasDescriptor.initialize( + declaredTypeParameters = declaredTypeParameters, + underlyingType = storageManager.createLazyValue { underlyingType.buildType(targetComponents, typeParameterResolver) }, + expandedType = storageManager.createLazyValue { expandedType.buildType(targetComponents, typeParameterResolver) } + ) + + // cache created type alias descriptor: + components.cache.cache(fqName, index, typeAliasDescriptor) + output[index] = typeAliasDescriptor } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/utils.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/utils.kt index b0ae1ae07e4..49e41c30784 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/utils.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/builder/utils.kt @@ -6,60 +6,157 @@ package org.jetbrains.kotlin.descriptors.commonizer.builder import org.jetbrains.kotlin.descriptors.* -import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver -import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeParameter -import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirValueParameter -import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl +import org.jetbrains.kotlin.descriptors.annotations.Annotations +import org.jetbrains.kotlin.descriptors.commonizer.isUnderStandardKotlinPackages +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.* +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirSimpleTypeKind.Companion.areCompatible import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl +import org.jetbrains.kotlin.incremental.components.NoLookupLocation 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 +import org.jetbrains.kotlin.utils.addToStdlib.cast -internal fun List.buildDescriptors( - containingDeclaration: DeclarationDescriptor -): List { - return mapIndexed { index, param -> - val descriptor = TypeParameterDescriptorImpl.createForFurtherModification( - containingDeclaration, - param.annotations, - param.isReified, - param.variance, - param.name, - index, - SourceElement.NO_SOURCE +internal fun List.buildDescriptorsAndTypeParameterResolver( + targetComponents: TargetDeclarationsBuilderComponents, + parentTypeParameterResolver: TypeParameterResolver, + containingDeclaration: DeclarationDescriptor, + typeParametersIndexOffset: Int = 0 +): Pair, TypeParameterResolver> { + val ownTypeParameters = mutableListOf() + + val typeParameterResolver = TypeParameterResolverImpl( + storageManager = targetComponents.storageManager, + ownTypeParameters = ownTypeParameters, + parent = parentTypeParameterResolver + ) + + forEachIndexed { index, param -> + ownTypeParameters += CommonizedTypeParameterDescriptor( + targetComponents = targetComponents, + typeParameterResolver = typeParameterResolver, + containingDeclaration = containingDeclaration, + annotations = param.annotations, + name = param.name, + variance = param.variance, + isReified = param.isReified, + index = typeParametersIndexOffset + index, + cirUpperBounds = param.upperBounds ) - - param.upperBounds.forEach(descriptor::addUpperBound) - descriptor.setInitialized() - - descriptor } + + return ownTypeParameters to typeParameterResolver } + internal fun List.buildDescriptors( + targetComponents: TargetDeclarationsBuilderComponents, + typeParameterResolver: TypeParameterResolver, containingDeclaration: CallableDescriptor -) = mapIndexed { index, param -> +): List = mapIndexed { index, param -> ValueParameterDescriptorImpl( containingDeclaration, null, index, param.annotations, param.name, - param.returnType, + param.returnType.buildType(targetComponents, typeParameterResolver), param.declaresDefaultValue, param.isCrossinline, param.isNoinline, - param.varargElementType, + param.varargElementType?.buildType(targetComponents, typeParameterResolver), SourceElement.NO_SOURCE ) } internal fun CirExtensionReceiver.buildExtensionReceiver( + targetComponents: TargetDeclarationsBuilderComponents, + typeParameterResolver: TypeParameterResolver, containingDeclaration: CallableDescriptor ) = DescriptorFactory.createExtensionReceiverParameterForCallable( containingDeclaration, - type, + type.buildType(targetComponents, typeParameterResolver), annotations ) internal fun buildDispatchReceiver(callableDescriptor: CallableDescriptor) = DescriptorUtils.getDispatchReceiverParameterIfNeeded(callableDescriptor.containingDeclaration) + +internal fun CirType.buildType( + targetComponents: TargetDeclarationsBuilderComponents, + typeParameterResolver: TypeParameterResolver +): UnwrappedType = when (this) { + is CirSimpleType -> buildType(targetComponents, typeParameterResolver) + is CirFlexibleType -> flexibleType( + lowerBound = lowerBound.buildType(targetComponents, typeParameterResolver), + upperBound = upperBound.buildType(targetComponents, typeParameterResolver) + ) +} + +internal fun CirSimpleType.buildType( + targetComponents: TargetDeclarationsBuilderComponents, + typeParameterResolver: TypeParameterResolver +): SimpleType { + val classifier: ClassifierDescriptor = when (kind) { + + CirSimpleTypeKind.TYPE_PARAMETER -> { + typeParameterResolver.resolve(fqName.shortName()) + ?: error("Type parameter $fqName not found in ${typeParameterResolver::class.java}, $typeParameterResolver") + } + + CirSimpleTypeKind.CLASS, CirSimpleTypeKind.TYPE_ALIAS -> { + if (fqName.isUnderStandardKotlinPackages) { + // look up for classifier in built-ins module: + val builtInsModule = targetComponents.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.getPackage(fqName.parent()) + .memberScope + .getContributedClassifier(fqName.shortName(), NoLookupLocation.FOR_ALREADY_TRACKED) + ?.cast() + ?.also { checkClassifier(it, kind, true) } + ?: error("Classifier $fqName not found in built-ins module $builtInsModule") + } else { + // otherwise, look up in created descriptors cache: + targetComponents.getCachedClassifier(fqName) + ?.also { checkClassifier(it, kind, !targetComponents.isCommon) } + ?: error("Classifier $fqName not found in created descriptors cache") + } + } + } + + val rawType = simpleType( + annotations = Annotations.EMPTY, // TODO: support annotations + constructor = classifier.typeConstructor, + arguments = arguments.map { it.buildArgument(targetComponents, typeParameterResolver) }, + nullable = isMarkedNullable, + kotlinTypeRefiner = null + ) + + return if (isDefinitelyNotNullType) rawType.makeSimpleTypeDefinitelyNotNullOrNotNull() else rawType +} + +private fun checkClassifier(classifier: ClassifierDescriptor, kindInCir: CirSimpleTypeKind, strict: Boolean) { + val classifierKind = CirSimpleTypeKind.determineKind(classifier) + + if (strict) { + check(kindInCir == classifierKind) { + "Mismatched classifier kinds.\nFound: $classifierKind, ${classifier::class.java}, $classifier\nShould be: $kindInCir" + } + } else { + check(areCompatible(classifierKind, kindInCir)) { + "Incompatible classifier kinds.\nExpect: $classifierKind, ${classifier::class.java}, $classifier\nActual: $kindInCir" + } + } +} + +private fun CirTypeProjection.buildArgument( + targetComponents: TargetDeclarationsBuilderComponents, + typeParameterResolver: TypeParameterResolver +): TypeProjection = + if (isStarProjection) { + StarProjectionForAbsentTypeParameter(targetComponents.builtIns) + } else { + TypeProjectionImpl(projectionKind, type.buildType(targetComponents, typeParameterResolver)) + } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/commonizedGroup.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/commonizedGroup.kt index 583fc98d14b..895a45be97b 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/commonizedGroup.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/commonizedGroup.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.descriptors.commonizer -/** Fixed-size ordered collection that represents a commonized group of same-rank elements */ +/** Fixed-size ordered collection with no extra space that represents a commonized group of same-rank elements */ internal class CommonizedGroup( val size: Int, initialize: (Int) -> T? @@ -42,6 +42,7 @@ internal class CommonizedGroupMap(val size: Int) : Iterable> = HashMap() operator fun get(key: K): CommonizedGroup = wrapped.getOrPut(key) { CommonizedGroup(size) } + fun getOrNull(key: K): CommonizedGroup? = wrapped[key] override fun iterator(): Iterator>> = wrapped.iterator() } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractListCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractListCommonizer.kt index 7ce2cae2c57..c0af356144d 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractListCommonizer.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractListCommonizer.kt @@ -5,16 +5,15 @@ package org.jetbrains.kotlin.descriptors.commonizer.core -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.UnwrappedType +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType /** * Unlike [Commonizer] which commonizes only single elements, this [AbstractListCommonizer] commonizes lists of elements using * [Commonizer]s produced by [singleElementCommonizerFactory]. * * Example: - * Input: N lists of [KotlinType] - * Output: list of [UnwrappedType] + * Input: N lists of [CirType] + * Output: list of [CirType] */ abstract class AbstractListCommonizer( private val singleElementCommonizerFactory: () -> Commonizer diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CommonizationVisitor.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CommonizationVisitor.kt index 78a6a879ad4..66d8819aadf 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CommonizationVisitor.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/CommonizationVisitor.kt @@ -6,10 +6,7 @@ package org.jetbrains.kotlin.descriptors.commonizer.core import org.jetbrains.kotlin.descriptors.commonizer.CommonizedGroupMap -import org.jetbrains.kotlin.descriptors.commonizer.fqNameWithTypeParameters import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.* -import org.jetbrains.kotlin.types.KotlinType -import java.lang.IllegalStateException internal class CommonizationVisitor( private val root: CirRootNode @@ -83,7 +80,7 @@ internal class CommonizationVisitor( val companionObjectFqName = node.target.mapTo(HashSet()) { it!!.companion }.singleOrNull() if (companionObjectFqName != null) { val companionObjectNode = root.cache.classes[companionObjectFqName] - ?: throw IllegalStateException("Can't find companion object with FQ name $companionObjectFqName") + ?: error("Can't find companion object with FQ name $companionObjectFqName") if (companionObjectNode.common() != null) { // companion object has been successfully commonized @@ -92,7 +89,7 @@ internal class CommonizationVisitor( } // find out common (and commonized) supertypes - val supertypesMap = CommonizedGroupMap(node.target.size) + val supertypesMap = CommonizedGroupMap(node.target.size) node.target.forEachIndexed { index, clazz -> for (supertype in clazz!!.supertypes) { supertypesMap[supertype.fqNameWithTypeParameters][index] = supertype diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ExtensionReceiverCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ExtensionReceiverCommonizer.kt index efbdc8e675c..79581bbcf1e 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ExtensionReceiverCommonizer.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ExtensionReceiverCommonizer.kt @@ -7,10 +7,10 @@ package org.jetbrains.kotlin.descriptors.commonizer.core import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.UnwrappedType +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver.Companion.toReceiverNoAnnotations -interface ExtensionReceiverCommonizer : Commonizer { +interface ExtensionReceiverCommonizer : Commonizer { companion object { fun default(cache: CirClassifiersCache): ExtensionReceiverCommonizer = DefaultExtensionReceiverCommonizer(cache) } @@ -18,8 +18,8 @@ interface ExtensionReceiverCommonizer : Commonizer( + AbstractNullableCommonizer( wrappedCommonizerFactory = { TypeCommonizer.default(cache) }, extractor = { it.type }, - builder = { it } + builder = { it.toReceiverNoAnnotations() } ) diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/FunctionCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/FunctionCommonizer.kt index 5b99c72b975..95e9a6dba7f 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/FunctionCommonizer.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/FunctionCommonizer.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.core import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonFunction -import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver.Companion.toReceiverNoAnnotations import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirFunction class FunctionCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropertyCommonizer(cache) { @@ -20,7 +19,7 @@ class FunctionCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropert name = name, modality = modality.result, visibility = visibility.result, - extensionReceiver = extensionReceiver.result?.toReceiverNoAnnotations(), + extensionReceiver = extensionReceiver.result, returnType = returnType.result, kind = kind, modifiers = modifiers.result, diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertyCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertyCommonizer.kt index d7da3c3f3b6..107bb178aeb 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertyCommonizer.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/PropertyCommonizer.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.core import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonProperty -import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver.Companion.toReceiverNoAnnotations import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirProperty class PropertyCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropertyCommonizer(cache) { @@ -19,7 +18,7 @@ class PropertyCommonizer(cache: CirClassifiersCache) : AbstractFunctionOrPropert modality = modality.result, visibility = visibility.result, isExternal = isExternal, - extensionReceiver = extensionReceiver.result?.toReceiverNoAnnotations(), + extensionReceiver = extensionReceiver.result, returnType = returnType.result, kind = kind, setter = setter.result, diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeAliasCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeAliasCommonizer.kt index 2da498f620b..7a3b1d578a4 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeAliasCommonizer.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeAliasCommonizer.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.* import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.types.checker.isClassType class TypeAliasCommonizer(cache: CirClassifiersCache) : AbstractStandardCommonizer() { private lateinit var name: Name @@ -34,7 +33,7 @@ class TypeAliasCommonizer(cache: CirClassifiersCache) : AbstractStandardCommoniz override fun doCommonizeWith(next: CirTypeAlias) = next.typeParameters.isEmpty() // TAs with declared type parameters can't be commonized && next.underlyingType.arguments.isEmpty() // TAs with functional types or types with parameters at the right-hand side can't be commonized - && next.underlyingType.isClassType // right-hand side could have only class + && next.underlyingType.kind == CirSimpleTypeKind.CLASS // right-hand side could have only class && underlyingType.commonizeWith(next.underlyingType) && visibility.commonizeWith(next) } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizer.kt index 5a50833bf7b..cdc94092e49 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizer.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeCommonizer.kt @@ -5,14 +5,11 @@ package org.jetbrains.kotlin.descriptors.commonizer.core -import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.commonizer.isUnderStandardKotlinPackages -import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache -import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirNode -import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -import org.jetbrains.kotlin.types.* +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.* +import org.jetbrains.kotlin.types.AbstractStrictEqualityTypeChecker -interface TypeCommonizer : Commonizer { +interface TypeCommonizer : Commonizer { companion object { fun default(cache: CirClassifiersCache): TypeCommonizer = DefaultTypeCommonizer(cache) } @@ -20,45 +17,32 @@ interface TypeCommonizer : Commonizer { private class DefaultTypeCommonizer(private val cache: CirClassifiersCache) : TypeCommonizer, - AbstractStandardCommonizer() { + AbstractStandardCommonizer() { - private lateinit var temp: UnwrappedType + private lateinit var temp: CirType override fun commonizationResult() = temp - override fun initialize(first: KotlinType) { - temp = first.unwrap() + override fun initialize(first: CirType) { + temp = first } - override fun doCommonizeWith(next: KotlinType) = areTypesEqual(cache, temp, next.unwrap()) + override fun doCommonizeWith(next: CirType) = areTypesEqual(cache, temp, next) } /** * See also [AbstractStrictEqualityTypeChecker]. */ -internal fun areTypesEqual(cache: CirClassifiersCache, a: UnwrappedType, b: UnwrappedType): Boolean = when { +internal fun areTypesEqual(cache: CirClassifiersCache, a: CirType, b: CirType): Boolean = when { a === b -> true - a is SimpleType -> (b is SimpleType) && areSimpleTypesEqual(cache, a, b) - a is FlexibleType -> (b is FlexibleType) - && areSimpleTypesEqual(cache, a.lowerBound, b.lowerBound) && areSimpleTypesEqual(cache, a.upperBound, b.upperBound) + a is CirSimpleType -> (b is CirSimpleType) && areSimpleTypesEqual(cache, a, b) + a is CirFlexibleType -> (b is CirFlexibleType) + && areSimpleTypesEqual(cache, a.lowerBound, b.lowerBound) + && areSimpleTypesEqual(cache, a.upperBound, b.upperBound) else -> false } -private fun areSimpleTypesEqual(cache: CirClassifiersCache, a: SimpleType, b: SimpleType): Boolean = areAbbreviatedTypesEqual( - cache, - a = a.getAbbreviation() ?: a, - aExpanded = a, - b = b.getAbbreviation() ?: b, - bExpandedType = b -) - -private fun areAbbreviatedTypesEqual( - cache: CirClassifiersCache, - a: SimpleType, - aExpanded: SimpleType, - b: SimpleType, - bExpandedType: SimpleType -): Boolean { +private fun areSimpleTypesEqual(cache: CirClassifiersCache, a: CirSimpleType, b: CirSimpleType): Boolean { if (a.arguments.size != b.arguments.size || a.isMarkedNullable != b.isMarkedNullable || a.isDefinitelyNotNullType != b.isDefinitelyNotNullType @@ -66,41 +50,32 @@ private fun areAbbreviatedTypesEqual( return false } - val aDescriptor = requireNotNull(a.constructor.declarationDescriptor, a::nonNullDescriptorExpectedErrorMessage) - val bDescriptor = requireNotNull(b.constructor.declarationDescriptor, b::nonNullDescriptorExpectedErrorMessage) - - val aFqName = aDescriptor.fqNameSafe - val bFqName = bDescriptor.fqNameSafe - - if (aFqName != bFqName) + if (a.fqName != b.fqName) return false - val isClassOrTypeAliasUnderStandardKotlinPackages = + fun isClassOrTypeAliasUnderStandardKotlinPackages() = // N.B. only for descriptors that represent classes or type aliases, but not type parameters! - aDescriptor is ClassifierDescriptorWithTypeParameters - && bDescriptor is ClassifierDescriptorWithTypeParameters - && aFqName.isUnderStandardKotlinPackages + a.isClassOrTypeAlias && b.isClassOrTypeAlias + && a.fqName.isUnderStandardKotlinPackages // If classes are from the standard Kotlin packages, compare them only by type constructors. - // Effectively, this includes 1) comparison of FQ names and 2) number of type constructor parameters. + // Effectively, this includes comparison of 1) FQ names of underlying descriptors and 2) number of type constructor parameters. // See org.jetbrains.kotlin.types.AbstractClassTypeConstructor.equals() for details. - && aExpanded.constructor == bExpandedType.constructor + && a.expandedTypeConstructorId == b.expandedTypeConstructorId + + fun descriptorsCanBeCommonizedThemselves() = + a.kind == b.kind && when (a.kind) { + CirSimpleTypeKind.CLASS -> cache.classes[a.fqName].canBeCommonized() + CirSimpleTypeKind.TYPE_ALIAS -> cache.typeAliases[a.fqName].canBeCommonized() + CirSimpleTypeKind.TYPE_PARAMETER -> { + // Real type parameter commonization is performed in TypeParameterCommonizer. + // Here it is enough to check that FQ names are equal (which is already done above). + true + } + } val descriptorsCanBeCommonized = - /* either class or type alias from Kotlin stdlib */ isClassOrTypeAliasUnderStandardKotlinPackages - || /* or descriptors themselves can be commonized */ when (aDescriptor) { - is TypeParameterDescriptor -> { - // Real type parameter commonization is performed in TypeParameterCommonizer. - // Here it is enough to check that FQ names are equal (already done above). - bDescriptor is TypeParameterDescriptor - } - is ClassDescriptor -> { - (bDescriptor is ClassDescriptor) && cache.classes[aFqName].canBeCommonized() - } - is TypeAliasDescriptor -> { - (bDescriptor is TypeAliasDescriptor) && cache.typeAliases[aFqName].canBeCommonized() - } - else -> false - } + /* either class or type alias from Kotlin stdlib */ isClassOrTypeAliasUnderStandardKotlinPackages() + || /* or descriptors themselves can be commonized */ descriptorsCanBeCommonizedThemselves() if (!descriptorsCanBeCommonized) return false @@ -117,7 +92,7 @@ private fun areAbbreviatedTypesEqual( if (aArg.projectionKind != bArg.projectionKind) return false - if (!areTypesEqual(cache, aArg.type.unwrap(), bArg.type.unwrap())) + if (!areTypesEqual(cache, aArg.type, bArg.type)) return false } } @@ -125,10 +100,6 @@ private fun areAbbreviatedTypesEqual( return true } -@Suppress("NOTHING_TO_INLINE") -private inline fun SimpleType.nonNullDescriptorExpectedErrorMessage() = - "${TypeCommonizer::class} couldn't obtain non-null descriptor from: $this, ${this::class}" - @Suppress("NOTHING_TO_INLINE") private inline fun CirNode<*, *>?.canBeCommonized() = if (this == null) { diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeParameterCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeParameterCommonizer.kt index 0a2e584d445..c02d0ad97b0 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeParameterCommonizer.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/TypeParameterCommonizer.kt @@ -7,10 +7,9 @@ package org.jetbrains.kotlin.descriptors.commonizer.core import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonTypeParameter +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirTypeParameter import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.types.KotlinType -import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.Variance interface TypeParameterCommonizer : Commonizer { @@ -48,7 +47,7 @@ private class DefaultTypeParameterCommonizer(cache: CirClassifiersCache) : && upperBounds.commonizeWith(next.upperBounds) } -private class TypeParameterUpperBoundsCommonizer(cache: CirClassifiersCache) : AbstractListCommonizer( +private class TypeParameterUpperBoundsCommonizer(cache: CirClassifiersCache) : AbstractListCommonizer( singleElementCommonizerFactory = { TypeCommonizer.default(cache) } ) diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizer.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizer.kt index d40b7b7035b..f6d0347c59b 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizer.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/core/ValueParameterCommonizer.kt @@ -9,8 +9,8 @@ import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirCommonValueP import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirValueParameter import org.jetbrains.kotlin.descriptors.commonizer.isNull import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirClassifiersCache +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.types.UnwrappedType interface ValueParameterCommonizer : Commonizer { companion object { @@ -24,7 +24,7 @@ private class DefaultValueParameterCommonizer(cache: CirClassifiersCache) : private lateinit var name: Name private val returnType = TypeCommonizer.default(cache) - private var varargElementType: UnwrappedType? = null + private var varargElementType: CirType? = null private var isCrossinline = true private var isNoinline = true diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/facade.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/facade.kt index c5a4630ca13..436eeede244 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/facade.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/facade.kt @@ -6,7 +6,9 @@ package org.jetbrains.kotlin.descriptors.commonizer import org.jetbrains.kotlin.descriptors.ModuleDescriptor -import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor +import org.jetbrains.kotlin.descriptors.commonizer.builder.* +import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor1 +import org.jetbrains.kotlin.descriptors.commonizer.builder.DeclarationsBuilderVisitor2 import org.jetbrains.kotlin.descriptors.commonizer.core.CommonizationVisitor import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.mergeRoots import org.jetbrains.kotlin.storage.LockBasedStorageManager @@ -63,21 +65,26 @@ fun runCommonization(parameters: CommonizationParameters): CommonizationResult { if (!parameters.hasIntersection()) return NothingToCommonize - // build merged tree: val storageManager = LockBasedStorageManager("Declaration descriptors commonization") + + // build merged tree: val mergedTree = mergeRoots(storageManager, parameters.getModulesByTargets()) // commonize: mergedTree.accept(CommonizationVisitor(mergedTree), Unit) - val modulesByTargets = LinkedHashMap>() // use linked hash map to preserve order - // build resulting descriptors: - val visitor = DeclarationsBuilderVisitor(storageManager) { target, commonizedModules -> + val components = mergedTree.createGlobalBuilderComponents(storageManager) + mergedTree.accept(DeclarationsBuilderVisitor1(components), emptyList()) + mergedTree.accept(DeclarationsBuilderVisitor2(components), emptyList()) + + val modulesByTargets = LinkedHashMap>() // use linked hash map to preserve order + components.targetComponents.forEach { + val target = it.target check(target !in modulesByTargets) - modulesByTargets[target] = commonizedModules + + modulesByTargets[target] = components.cache.getCachedModules(it.index) } - mergedTree.accept(visitor, DeclarationsBuilderVisitor.noContainingDeclarations()) return CommonizationPerformed(modulesByTargets) } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirClass.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirClass.kt index 10b883f3710..6add6273311 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirClass.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirClass.kt @@ -10,7 +10,6 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe -import org.jetbrains.kotlin.types.KotlinType import kotlin.LazyThreadSafetyMode.PUBLICATION interface CirClass : CirAnnotatedDeclaration, CirNamedDeclaration, CirDeclarationWithTypeParameters, CirDeclarationWithVisibility, CirDeclarationWithModality { @@ -21,7 +20,7 @@ interface CirClass : CirAnnotatedDeclaration, CirNamedDeclaration, CirDeclaratio val isInline: Boolean val isInner: Boolean val isExternal: Boolean - val supertypes: Collection + val supertypes: Collection } interface CirClassConstructor : CirAnnotatedDeclaration, CirDeclarationWithTypeParameters, CirDeclarationWithVisibility, CirMaybeCallableMemberOfClass, CirCallableMemberWithParameters { @@ -46,7 +45,7 @@ data class CirCommonClass( override val isData get() = false override val isExternal get() = false override var companion: FqName? = null - override val supertypes: MutableCollection = ArrayList() + override val supertypes: MutableCollection = ArrayList() } data class CirCommonClassConstructor( @@ -58,10 +57,10 @@ data class CirCommonClassConstructor( override val hasStableParameterNames: Boolean, override val hasSynthesizedParameterNames: Boolean ) : CirClassConstructor { - override val annotations: Annotations get() = Annotations.EMPTY - override val containingClassKind: ClassKind get() = unsupported() - override val containingClassModality: Modality get() = unsupported() - override val containingClassIsData: Boolean get() = unsupported() + override val annotations get() = Annotations.EMPTY + override val containingClassKind get() = unsupported() + override val containingClassModality get() = unsupported() + override val containingClassIsData get() = unsupported() } class CirWrappedClass(private val wrapped: ClassDescriptor) : CirClass { @@ -77,35 +76,40 @@ class CirWrappedClass(private val wrapped: ClassDescriptor) : CirClass { override val isInline get() = wrapped.isInline override val isInner get() = wrapped.isInner override val isExternal get() = wrapped.isExternal - override val supertypes: Collection get() = wrapped.typeConstructor.supertypes + override val supertypes by lazy(PUBLICATION) { wrapped.typeConstructor.supertypes.map(CirType.Companion::create) } } class CirWrappedClassConstructor(private val wrapped: ClassConstructorDescriptor) : CirClassConstructor { - override val isPrimary: Boolean get() = wrapped.isPrimary - override val kind: CallableMemberDescriptor.Kind get() = wrapped.kind - override val containingClassKind: ClassKind get() = wrapped.containingDeclaration.kind - override val containingClassModality: Modality get() = wrapped.containingDeclaration.modality - override val containingClassIsData: Boolean get() = wrapped.containingDeclaration.isData - override val annotations: Annotations get() = wrapped.annotations - override val visibility: Visibility get() = wrapped.visibility - override val typeParameters: List by lazy(PUBLICATION) { wrapped.typeParameters.map(::CirWrappedTypeParameter) } - override val valueParameters: List by lazy(PUBLICATION) { wrapped.valueParameters.map(::CirWrappedValueParameter) } - override val hasStableParameterNames: Boolean get() = wrapped.hasStableParameterNames() - override val hasSynthesizedParameterNames: Boolean get() = wrapped.hasSynthesizedParameterNames() + override val isPrimary get() = wrapped.isPrimary + override val kind get() = wrapped.kind + override val containingClassKind get() = wrapped.containingDeclaration.kind + override val containingClassModality get() = wrapped.containingDeclaration.modality + override val containingClassIsData get() = wrapped.containingDeclaration.isData + override val annotations get() = wrapped.annotations + override val visibility get() = wrapped.visibility + override val typeParameters by lazy(PUBLICATION) { + wrapped.typeParameters.mapNotNull { typeParameter -> + // save only type parameters that are contributed by the constructor itself + typeParameter.takeIf { it.containingDeclaration == wrapped }?.let(::CirWrappedTypeParameter) + } + } + override val valueParameters by lazy(PUBLICATION) { wrapped.valueParameters.map(::CirWrappedValueParameter) } + override val hasStableParameterNames get() = wrapped.hasStableParameterNames() + override val hasSynthesizedParameterNames get() = wrapped.hasSynthesizedParameterNames() } object CirClassRecursionMarker : CirClass, CirRecursionMarker { - override val companion: FqName? get() = unsupported() - override val kind: ClassKind get() = unsupported() - override val modality: Modality get() = unsupported() - override val isCompanion: Boolean get() = unsupported() - override val isData: Boolean get() = unsupported() - override val isInline: Boolean get() = unsupported() - override val isInner: Boolean get() = unsupported() - override val isExternal: Boolean get() = unsupported() - override val supertypes: Collection get() = unsupported() - override val annotations: Annotations get() = unsupported() - override val name: Name get() = unsupported() - override val visibility: Visibility get() = unsupported() - override val typeParameters: List get() = unsupported() + override val companion get() = unsupported() + override val kind get() = unsupported() + override val modality get() = unsupported() + override val isCompanion get() = unsupported() + override val isData get() = unsupported() + override val isInline get() = unsupported() + override val isInner get() = unsupported() + override val isExternal get() = unsupported() + override val supertypes get() = unsupported() + override val annotations get() = unsupported() + override val name get() = unsupported() + override val visibility get() = unsupported() + override val typeParameters get() = unsupported() } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirFunction.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirFunction.kt index 54e3fcbb081..3560f61b31e 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirFunction.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirFunction.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.types.UnwrappedType import kotlin.LazyThreadSafetyMode.PUBLICATION interface CirFunctionModifiers { @@ -33,7 +32,7 @@ data class CirCommonFunction( override val modality: Modality, override val visibility: Visibility, override val extensionReceiver: CirExtensionReceiver?, - override val returnType: UnwrappedType, + override val returnType: CirType, override val kind: CallableMemberDescriptor.Kind, private val modifiers: CirFunctionModifiers, override val valueParameters: List, @@ -49,15 +48,15 @@ class CirWrappedFunction(wrapped: SimpleFunctionDescriptor) : CirWrappedFunction override val isTailrec get() = wrapped.isTailrec override val isSuspend get() = wrapped.isSuspend override val valueParameters by lazy(PUBLICATION) { wrapped.valueParameters.map(::CirWrappedValueParameter) } - override val hasStableParameterNames: Boolean get() = wrapped.hasStableParameterNames() - override val hasSynthesizedParameterNames: Boolean get() = wrapped.hasSynthesizedParameterNames() + override val hasStableParameterNames get() = wrapped.hasStableParameterNames() + override val hasSynthesizedParameterNames get() = wrapped.hasSynthesizedParameterNames() } interface CirValueParameter { val name: Name val annotations: Annotations - val returnType: UnwrappedType - val varargElementType: UnwrappedType? + val returnType: CirType + val varargElementType: CirType? val declaresDefaultValue: Boolean val isCrossinline: Boolean val isNoinline: Boolean @@ -65,8 +64,8 @@ interface CirValueParameter { data class CirCommonValueParameter( override val name: Name, - override val returnType: UnwrappedType, - override val varargElementType: UnwrappedType?, + override val returnType: CirType, + override val varargElementType: CirType?, override val isCrossinline: Boolean, override val isNoinline: Boolean ) : CirValueParameter { @@ -77,8 +76,8 @@ data class CirCommonValueParameter( data class CirWrappedValueParameter(private val wrapped: ValueParameterDescriptor) : CirValueParameter { override val name get() = wrapped.name override val annotations get() = wrapped.annotations - override val returnType by lazy(PUBLICATION) { wrapped.returnType!!.unwrap() } - override val varargElementType by lazy(PUBLICATION) { wrapped.varargElementType?.unwrap() } + override val returnType by lazy(PUBLICATION) { CirType.create(wrapped.returnType!!) } + override val varargElementType by lazy(PUBLICATION) { wrapped.varargElementType?.let(CirType.Companion::create) } override val declaresDefaultValue get() = wrapped.declaresDefaultValue() override val isCrossinline get() = wrapped.isCrossinline override val isNoinline get() = wrapped.isNoinline diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirFunctionOrProperty.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirFunctionOrProperty.kt index 0e10c3fd09c..cd3679459cf 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirFunctionOrProperty.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirFunctionOrProperty.kt @@ -8,13 +8,13 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver.Companion.toReceiver -import org.jetbrains.kotlin.types.UnwrappedType +import org.jetbrains.kotlin.types.KotlinType import kotlin.LazyThreadSafetyMode.PUBLICATION interface CirFunctionOrProperty : CirAnnotatedDeclaration, CirNamedDeclaration, CirDeclarationWithTypeParameters, CirDeclarationWithVisibility, CirDeclarationWithModality, CirMaybeCallableMemberOfClass { val isExternal: Boolean val extensionReceiver: CirExtensionReceiver? - val returnType: UnwrappedType + val returnType: CirType val kind: CallableMemberDescriptor.Kind } @@ -32,7 +32,7 @@ abstract class CirWrappedFunctionOrProperty(protec final override val visibility get() = wrapped.visibility final override val isExternal get() = wrapped.isExternal final override val extensionReceiver by lazy(PUBLICATION) { wrapped.extensionReceiverParameter?.toReceiver() } - final override val returnType by lazy(PUBLICATION) { wrapped.returnType!!.unwrap() } + final override val returnType by lazy(PUBLICATION) { CirType.create(wrapped.returnType!!) } final override val kind get() = wrapped.kind final override val containingClassKind: ClassKind? get() = containingClass?.kind final override val containingClassModality: Modality? get() = containingClass?.modality @@ -43,11 +43,11 @@ abstract class CirWrappedFunctionOrProperty(protec data class CirExtensionReceiver( val annotations: Annotations, - val type: UnwrappedType + val type: CirType ) { companion object { - fun UnwrappedType.toReceiverNoAnnotations() = CirExtensionReceiver(Annotations.EMPTY, this) - fun ReceiverParameterDescriptor.toReceiver() = CirExtensionReceiver(annotations, type.unwrap()) + fun CirType.toReceiverNoAnnotations() = CirExtensionReceiver(Annotations.EMPTY, this) + fun ReceiverParameterDescriptor.toReceiver() = CirExtensionReceiver(annotations, CirType.create(type)) } } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirProperty.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirProperty.kt index 56847c7f21e..c693501bd4a 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirProperty.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirProperty.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirGetter.Companion.toGetter import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirSetter.Companion.toSetter import org.jetbrains.kotlin.resolve.constants.ConstantValue @@ -32,7 +31,7 @@ data class CirCommonProperty( override val visibility: Visibility, override val isExternal: Boolean, override val extensionReceiver: CirExtensionReceiver?, - override val returnType: UnwrappedType, + override val returnType: CirType, override val kind: CallableMemberDescriptor.Kind, override val setter: CirSetter?, override val typeParameters: List diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirType.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirType.kt new file mode 100644 index 00000000000..56ebbb42815 --- /dev/null +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirType.kt @@ -0,0 +1,93 @@ +/* + * 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.mergedtree.ir + +import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.ClassifierDescriptor +import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor +import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor +import org.jetbrains.kotlin.descriptors.commonizer.declarationDescriptor +import org.jetbrains.kotlin.descriptors.commonizer.fqName +import org.jetbrains.kotlin.descriptors.commonizer.fqNameWithTypeParameters +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirSimpleTypeKind.CLASS +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirSimpleTypeKind.TYPE_ALIAS +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.types.* +import kotlin.LazyThreadSafetyMode.PUBLICATION + +sealed class CirType { + companion object { + fun create(type: KotlinType): CirType = type.unwrap().run { + when (this) { + is SimpleType -> CirSimpleType(this) + is FlexibleType -> CirFlexibleType(CirSimpleType(lowerBound), CirSimpleType(upperBound)) + } + } + } +} + +/** + * All attributes except for [expandedTypeConstructorId] are read from the abbreviation type: [AbbreviatedType.abbreviation]. + * And [expandedTypeConstructorId] is read from the expanded type: [AbbreviatedType.expandedType]. + * + * This is necessary to properly compare types for type aliases, where abbreviation type represents the type alias itself while + * expanded type represents right-hand side declaration that should be processed separately. + * + * There is no difference between [abbreviation] and [expanded] for types representing classes and type parameters. + */ +class CirSimpleType(private val wrapped: SimpleType) : CirType() { + val kind = CirSimpleTypeKind.determineKind(abbreviation.declarationDescriptor) + val fqName by lazy(PUBLICATION) { abbreviation.fqName } + val arguments by lazy(PUBLICATION) { abbreviation.arguments.map(::CirTypeProjection) } + val isMarkedNullable get() = abbreviation.isMarkedNullable + val isDefinitelyNotNullType get() = abbreviation.isDefinitelyNotNullType + val expandedTypeConstructorId by lazy(PUBLICATION) { CirTypeConstructorId(expanded) } + + inline val isClassOrTypeAlias: Boolean get() = (kind == CLASS || kind == TYPE_ALIAS) + val fqNameWithTypeParameters: String get() = wrapped.fqNameWithTypeParameters + + override fun equals(other: Any?) = wrapped == (other as? CirSimpleType)?.wrapped + override fun hashCode() = wrapped.hashCode() + + private inline val abbreviation: SimpleType get() = (wrapped as? AbbreviatedType)?.abbreviation ?: wrapped + private inline val expanded: SimpleType get() = (wrapped as? AbbreviatedType)?.expandedType ?: wrapped +} + +enum class CirSimpleTypeKind { + CLASS, + TYPE_ALIAS, + TYPE_PARAMETER; + + companion object { + fun determineKind(classifier: ClassifierDescriptor) = when (classifier) { + is ClassDescriptor -> CLASS + is TypeAliasDescriptor -> TYPE_ALIAS + is TypeParameterDescriptor -> TYPE_PARAMETER + else -> error("Unexpected classifier descriptor type: ${classifier::class.java}, $classifier") + } + + fun areCompatible(expect: CirSimpleTypeKind, actual: CirSimpleTypeKind) = + expect == actual || (expect == CLASS && actual == TYPE_ALIAS) + } +} + +data class CirTypeConstructorId(val fqName: FqName, val numberOfTypeParameters: Int) { + constructor(type: SimpleType) : this(type.fqName, type.constructor.parameters.size) +} + +class CirTypeProjection(private val wrapped: TypeProjection) { + val projectionKind get() = wrapped.projectionKind + val isStarProjection get() = wrapped.isStarProjection + val type by lazy(PUBLICATION) { CirType.create(wrapped.type) } +} + +data class CirFlexibleType(val lowerBound: CirSimpleType, val upperBound: CirSimpleType) : CirType() + +val CirType.fqNameWithTypeParameters: String + get() = when (this) { + is CirSimpleType -> fqNameWithTypeParameters + is CirFlexibleType -> lowerBound.fqNameWithTypeParameters + } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirTypeAlias.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirTypeAlias.kt index bf40446c945..3826a7fde23 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirTypeAlias.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirTypeAlias.kt @@ -6,12 +6,11 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor -import org.jetbrains.kotlin.types.SimpleType import kotlin.LazyThreadSafetyMode.PUBLICATION interface CirTypeAlias : CirAnnotatedDeclaration, CirNamedDeclaration, CirDeclarationWithTypeParameters, CirDeclarationWithVisibility { - val underlyingType: SimpleType - val expandedType: SimpleType + val underlyingType: CirSimpleType + val expandedType: CirSimpleType } class CirWrappedTypeAlias(private val wrapped: TypeAliasDescriptor) : CirTypeAlias { @@ -19,6 +18,6 @@ class CirWrappedTypeAlias(private val wrapped: TypeAliasDescriptor) : CirTypeAli override val name get() = wrapped.name override val typeParameters by lazy(PUBLICATION) { wrapped.declaredTypeParameters.map(::CirWrappedTypeParameter) } override val visibility get() = wrapped.visibility - override val underlyingType get() = wrapped.underlyingType - override val expandedType get() = wrapped.expandedType + override val underlyingType by lazy(PUBLICATION) { CirSimpleType(wrapped.underlyingType) } + override val expandedType by lazy(PUBLICATION) { CirSimpleType(wrapped.expandedType) } } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirTypeParameter.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirTypeParameter.kt index 3054cd066af..dd22072a7df 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirTypeParameter.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/CirTypeParameter.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.name.Name -import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.Variance import kotlin.LazyThreadSafetyMode.PUBLICATION @@ -17,14 +16,14 @@ interface CirTypeParameter { val name: Name val isReified: Boolean val variance: Variance - val upperBounds: List + val upperBounds: List } data class CirCommonTypeParameter( override val name: Name, override val isReified: Boolean, override val variance: Variance, - override val upperBounds: List + override val upperBounds: List ) : CirTypeParameter { override val annotations get() = Annotations.EMPTY } @@ -34,5 +33,5 @@ data class CirWrappedTypeParameter(private val wrapped: TypeParameterDescriptor) override val name get() = wrapped.name override val isReified get() = wrapped.isReified override val variance get() = wrapped.variance - override val upperBounds by lazy(PUBLICATION) { wrapped.upperBounds.map { it.unwrap() } } + override val upperBounds by lazy(PUBLICATION) { wrapped.upperBounds.map(CirType.Companion::create) } } diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/nodeBuilders.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/nodeBuilders.kt index 0989bd77c7d..279be06543e 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/nodeBuilders.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/nodeBuilders.kt @@ -50,7 +50,9 @@ internal fun buildPackageNode( commonValueProducer = { CirPackage(packageFqName) }, recursionMarker = null, nodeProducer = ::CirPackageNode -) +).also { node -> + node.fqName = packageFqName +} internal fun buildPropertyNode( storageManager: StorageManager, @@ -85,21 +87,17 @@ internal fun buildClassNode( cacheRW: ClassifiersCacheImpl, containingDeclarationCommon: NullableLazyValue<*>?, classes: List -): CirClassNode { - val fqName = classes.firstNonNull().fqNameSafe - - return buildNode( - storageManager = storageManager, - descriptors = classes, - targetDeclarationProducer = ::CirWrappedClass, - commonValueProducer = { commonize(containingDeclarationCommon, it, ClassCommonizer(cacheRW)) }, - recursionMarker = CirClassRecursionMarker, - nodeProducer = ::CirClassNode - ).also { node -> +): CirClassNode = buildNode( + storageManager = storageManager, + descriptors = classes, + targetDeclarationProducer = ::CirWrappedClass, + commonValueProducer = { commonize(containingDeclarationCommon, it, ClassCommonizer(cacheRW)) }, + recursionMarker = CirClassRecursionMarker, + nodeProducer = ::CirClassNode +).also { node -> + classes.firstNonNull().fqNameSafe.let { fqName -> node.fqName = fqName - cacheRW.classes.put(fqName, node)?.let { oldNode -> - throw IllegalStateException("Class node with FQ name $fqName has been overwritten: $oldNode") - } + cacheRW.classes.putSafe(fqName, node) } } @@ -121,21 +119,17 @@ internal fun buildTypeAliasNode( storageManager: StorageManager, cacheRW: ClassifiersCacheImpl, typeAliases: List -): CirTypeAliasNode { - val fqName = typeAliases.firstNonNull().fqNameSafe - - return buildNode( - storageManager = storageManager, - descriptors = typeAliases, - targetDeclarationProducer = ::CirWrappedTypeAlias, - commonValueProducer = { commonize(it, TypeAliasCommonizer(cacheRW)) }, - recursionMarker = CirClassRecursionMarker, - nodeProducer = ::CirTypeAliasNode - ).also { node -> +): CirTypeAliasNode = buildNode( + storageManager = storageManager, + descriptors = typeAliases, + targetDeclarationProducer = ::CirWrappedTypeAlias, + commonValueProducer = { commonize(it, TypeAliasCommonizer(cacheRW)) }, + recursionMarker = CirClassRecursionMarker, + nodeProducer = ::CirTypeAliasNode +).also { node -> + typeAliases.firstNonNull().fqNameSafe.let { fqName -> node.fqName = fqName - cacheRW.typeAliases.put(fqName, node)?.let { oldNode -> - throw IllegalStateException("Type alias node with FQ name $fqName has been overwritten: $oldNode") - } + cacheRW.typeAliases.putSafe(fqName, node) } } @@ -173,6 +167,11 @@ private fun > return nodeProducer(declarations, commonLazyValue) } +@Suppress("NOTHING_TO_INLINE") +private inline fun MutableMap.putSafe(key: K, value: V) = put(key, value)?.let { oldValue -> + error("${oldValue::class.java} with key=$key has been overwritten: $oldValue") +} + internal fun commonize(declarations: List, commonizer: Commonizer): R? { for (declaration in declarations) { if (declaration == null || !commonizer.commonizeWith(declaration)) diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/nodes.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/nodes.kt index 1a57881b2cc..5f41fc7a548 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/nodes.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/ir/nodes.kt @@ -15,6 +15,10 @@ interface CirNode { fun accept(visitor: CirNodeVisitor, data: T): R } +interface CirNodeWithFqName : CirNode { + val fqName: FqName +} + class CirRootNode( override val target: List, override val common: NullableLazyValue @@ -29,6 +33,8 @@ class CirRootNode( override fun accept(visitor: CirNodeVisitor, data: T): R = visitor.visitRootNode(this, data) + + override fun toString() = toString(this) } class CirModuleNode( @@ -39,12 +45,16 @@ class CirModuleNode( override fun accept(visitor: CirNodeVisitor, data: T) = visitor.visitModuleNode(this, data) + + override fun toString() = toString(this) } class CirPackageNode( override val target: List, override val common: NullableLazyValue -) : CirNode { +) : CirNodeWithFqName { + override lateinit var fqName: FqName + val properties: MutableList = ArrayList() val functions: MutableList = ArrayList() val classes: MutableList = ArrayList() @@ -52,6 +62,8 @@ class CirPackageNode( override fun accept(visitor: CirNodeVisitor, data: T) = visitor.visitPackageNode(this, data) + + override fun toString() = toString(this) } class CirPropertyNode( @@ -60,6 +72,8 @@ class CirPropertyNode( ) : CirNode { override fun accept(visitor: CirNodeVisitor, data: T) = visitor.visitPropertyNode(this, data) + + override fun toString() = toString(this) } class CirFunctionNode( @@ -68,13 +82,15 @@ class CirFunctionNode( ) : CirNode { override fun accept(visitor: CirNodeVisitor, data: T) = visitor.visitFunctionNode(this, data) + + override fun toString() = toString(this) } class CirClassNode( override val target: List, override val common: NullableLazyValue -) : CirNode { - lateinit var fqName: FqName +) : CirNodeWithFqName { + override lateinit var fqName: FqName val constructors: MutableList = ArrayList() val properties: MutableList = ArrayList() @@ -83,6 +99,8 @@ class CirClassNode( override fun accept(visitor: CirNodeVisitor, data: T): R = visitor.visitClassNode(this, data) + + override fun toString() = toString(this) } class CirClassConstructorNode( @@ -91,16 +109,20 @@ class CirClassConstructorNode( ) : CirNode { override fun accept(visitor: CirNodeVisitor, data: T): R = visitor.visitClassConstructorNode(this, data) + + override fun toString() = toString(this) } class CirTypeAliasNode( override val target: List, override val common: NullableLazyValue -) : CirNode { - lateinit var fqName: FqName +) : CirNodeWithFqName { + override lateinit var fqName: FqName override fun accept(visitor: CirNodeVisitor, data: T): R = visitor.visitTypeAliasNode(this, data) + + override fun toString() = toString(this) } interface CirClassifiersCache { @@ -113,3 +135,13 @@ internal inline val CirNode<*, *>.indexOfCommon: Int internal inline val CirNode<*, *>.dimension: Int get() = target.size + 1 + +private fun toString(node: CirNode<*, *>) = buildString { + if (node is CirNodeWithFqName) { + append("fqName=").append(node.fqName).append(", ") + } + append("target=") + node.target.joinTo(this) + append(", common=") + append(if (node.common.isComputed()) node.common() else "") +} diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/memberScopes.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/memberScopes.kt index 77e770888a3..b81055cecf6 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/memberScopes.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/mergedtree/memberScopes.kt @@ -15,7 +15,7 @@ internal fun MemberScope.collectMembers(vararg collectors: (DeclarationDescripto getContributedDescriptors().forEach { member -> collectors.any { it(member) } // each member must be consumed, otherwise - error - || throw IllegalStateException("Unhandled member declaration: $member") + || error("Unhandled member declaration: $member") } @Suppress("FunctionName") diff --git a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils.kt b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils.kt index 386f5e19d67..6db17a45bde 100644 --- a/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils.kt +++ b/konan/commonizer/src/org/jetbrains/kotlin/descriptors/commonizer/utils.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.descriptors.commonizer import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.ClassifierDescriptor import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe @@ -21,8 +22,11 @@ internal fun Sequence.toList(expectedCapacity: Int): List { internal inline fun Iterable.firstNonNull() = firstIsInstance() -internal val KotlinType.fqName: FqName - get() = (constructor.declarationDescriptor ?: throw IllegalStateException("No declaration descriptor found for $constructor")).fqNameSafe +internal inline val KotlinType.declarationDescriptor: ClassifierDescriptor + get() = (constructor.declarationDescriptor ?: error("No declaration descriptor found for $constructor")) + +internal inline val KotlinType.fqName: FqName + get() = declarationDescriptor.fqNameSafe internal val KotlinType.fqNameWithTypeParameters: String get() = buildString { buildFqNameWithTypeParameters(this@fqNameWithTypeParameters) } diff --git a/konan/commonizer/testData/classifierCommonization/typeParameters/commonized/common/package_root.kt b/konan/commonizer/testData/classifierCommonization/typeParameters/commonized/common/package_root.kt index 076ed8f8af8..746e8c5010a 100644 --- a/konan/commonizer/testData/classifierCommonization/typeParameters/commonized/common/package_root.kt +++ b/konan/commonizer/testData/classifierCommonization/typeParameters/commonized/common/package_root.kt @@ -124,3 +124,26 @@ expect class I>() { val property: T fun function(value: T): T } + +expect interface J1 { + fun a(): A +} +expect interface J2 { + fun a(b: B): A + fun b(a: A): B +} +expect interface J3 { + fun a(b: B, c: C): A + fun b(a: A, c: C): B + fun c(a: A, b: B): C +} + +expect class K, D : J2>() : J3 { + override fun a(b: C, c: B): D + override fun b(a: D, c: B): C + override fun c(a: D, b: C): B + inner class Inner>() { + fun dependentFunction(value: A): E + fun independentFunction(value: A): E + } +} diff --git a/konan/commonizer/testData/classifierCommonization/typeParameters/commonized/js/package_root.kt b/konan/commonizer/testData/classifierCommonization/typeParameters/commonized/js/package_root.kt index df8fb256039..cd34b0bfd89 100644 --- a/konan/commonizer/testData/classifierCommonization/typeParameters/commonized/js/package_root.kt +++ b/konan/commonizer/testData/classifierCommonization/typeParameters/commonized/js/package_root.kt @@ -634,3 +634,26 @@ actual class I> actual constructor() { actual val property: T get() = TODO() actual fun function(value: T): T = value } + +actual interface J1 { + actual fun a(): A +} +actual interface J2 { + actual fun a(b: B): A + actual fun b(a: A): B +} +actual interface J3 { + actual fun a(b: B, c: C): A + actual fun b(a: A, c: C): B + actual fun c(a: A, b: B): C +} + +actual class K, D : J2> actual constructor() : J3 { + actual override fun a(b: C, c: B): D = TODO() + actual override fun b(a: D, c: B): C = TODO() + actual override fun c(a: D, b: C): B = TODO() + actual inner class Inner> actual constructor() { + actual fun dependentFunction(value: A): E = TODO() + actual fun independentFunction(value: A): E = TODO() + } +} diff --git a/konan/commonizer/testData/classifierCommonization/typeParameters/commonized/jvm/package_root.kt b/konan/commonizer/testData/classifierCommonization/typeParameters/commonized/jvm/package_root.kt index e1f2cd081fe..93f22eb83fe 100644 --- a/konan/commonizer/testData/classifierCommonization/typeParameters/commonized/jvm/package_root.kt +++ b/konan/commonizer/testData/classifierCommonization/typeParameters/commonized/jvm/package_root.kt @@ -634,3 +634,26 @@ actual class I> actual constructor() { actual val property: T get() = TODO() actual fun function(value: T): T = value } + +actual interface J1 { + actual fun a(): A +} +actual interface J2 { + actual fun a(b: B): A + actual fun b(a: A): B +} +actual interface J3 { + actual fun a(b: B, c: C): A + actual fun b(a: A, c: C): B + actual fun c(a: A, b: B): C +} + +actual class K, D : J2> actual constructor() : J3 { + actual override fun a(b: C, c: B): D = TODO() + actual override fun b(a: D, c: B): C = TODO() + actual override fun c(a: D, b: C): B = TODO() + actual inner class Inner> actual constructor() { + actual fun dependentFunction(value: A): E = TODO() + actual fun independentFunction(value: A): E = TODO() + } +} diff --git a/konan/commonizer/testData/classifierCommonization/typeParameters/original/js/package_root.kt b/konan/commonizer/testData/classifierCommonization/typeParameters/original/js/package_root.kt index 219f02e46c8..fc3825be60c 100644 --- a/konan/commonizer/testData/classifierCommonization/typeParameters/original/js/package_root.kt +++ b/konan/commonizer/testData/classifierCommonization/typeParameters/original/js/package_root.kt @@ -634,3 +634,26 @@ class I> { val property: T get() = TODO() fun function(value: T): T = value } + +interface J1 { + actual fun a(): A +} +interface J2 { + actual fun a(b: B): A + actual fun b(a: A): B +} +interface J3 { + actual fun a(b: B, c: C): A + actual fun b(a: A, c: C): B + actual fun c(a: A, b: B): C +} + +class K, D : J2> : J3 { + override fun a(b: C, c: B): D = TODO() + override fun b(a: D, c: B): C = TODO() + override fun c(a: D, b: C): B = TODO() + inner class Inner> { + fun dependentFunction(value: A): E = TODO() + fun independentFunction(value: A): E = TODO() + } +} diff --git a/konan/commonizer/testData/classifierCommonization/typeParameters/original/jvm/package_root.kt b/konan/commonizer/testData/classifierCommonization/typeParameters/original/jvm/package_root.kt index 798e03d3c89..1b510bb34c4 100644 --- a/konan/commonizer/testData/classifierCommonization/typeParameters/original/jvm/package_root.kt +++ b/konan/commonizer/testData/classifierCommonization/typeParameters/original/jvm/package_root.kt @@ -634,3 +634,26 @@ class I> { val property: T get() = TODO() fun function(value: T): T = value } + +interface J1 { + actual fun a(): A +} +interface J2 { + actual fun a(b: B): A + actual fun b(a: A): B +} +interface J3 { + actual fun a(b: B, c: C): A + actual fun b(a: A, c: C): B + actual fun c(a: A, b: B): C +} + +class K, D : J2> : J3 { + override fun a(b: C, c: B): D = TODO() + override fun b(a: D, c: B): C = TODO() + override fun c(a: D, b: C): B = TODO() + inner class Inner> { + fun dependentFunction(value: A): E = TODO() + fun independentFunction(value: A): E = TODO() + } +} diff --git a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractCommonizerTest.kt b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractCommonizerTest.kt index 54ef580d834..c34a3723fb0 100644 --- a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractCommonizerTest.kt +++ b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/AbstractCommonizerTest.kt @@ -20,7 +20,7 @@ abstract class AbstractCommonizerTest { protected open fun isEqual(a: R?, b: R?): Boolean = a == b - protected open fun doTestSuccess(expected: R, vararg variants: T) { + protected fun doTestSuccess(expected: R, vararg variants: T) { check(variants.isNotEmpty()) val commonized = createCommonizer().apply { @@ -34,7 +34,7 @@ abstract class AbstractCommonizerTest { } // should fail on the last variant - protected open fun doTestFailure(vararg variants: T) { + protected fun doTestFailure(vararg variants: T) { check(variants.isNotEmpty()) val commonized = createCommonizer().apply { diff --git a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultExtensionReceiverCommonizerTest.kt b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultExtensionReceiverCommonizerTest.kt index ea41adf5147..5b8bbe599be 100644 --- a/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultExtensionReceiverCommonizerTest.kt +++ b/konan/commonizer/tests/org/jetbrains/kotlin/descriptors/commonizer/core/DefaultExtensionReceiverCommonizerTest.kt @@ -8,11 +8,11 @@ package org.jetbrains.kotlin.descriptors.commonizer.core import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.commonizer.utils.EMPTY_CLASSIFIERS_CACHE import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirExtensionReceiver +import org.jetbrains.kotlin.descriptors.commonizer.mergedtree.ir.CirType import org.jetbrains.kotlin.descriptors.commonizer.utils.mockClassType -import org.jetbrains.kotlin.types.UnwrappedType import org.junit.Test -class DefaultExtensionReceiverCommonizerTest : AbstractCommonizerTest() { +class DefaultExtensionReceiverCommonizerTest : AbstractCommonizerTest() { @Test fun nullReceiver() = doTestSuccess( @@ -24,7 +24,7 @@ class DefaultExtensionReceiverCommonizerTest : AbstractCommonizerTest() { +class DefaultTypeCommonizerTest : AbstractCommonizerTest() { private lateinit var cache: ClassifiersCacheImpl @@ -33,7 +33,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest) { check(variants.isNotEmpty()) val classesMap = CommonizedGroupMap(variants.size) @@ -381,7 +381,7 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest IllegalStateException("Unexpected descriptor of KotlinType: $descriptor, $type") + else -> error("Unexpected descriptor of KotlinType: $descriptor, $type") } } @@ -398,17 +398,22 @@ class DefaultTypeCommonizerTest : AbstractCommonizerTest() { @@ -153,7 +153,7 @@ class DefaultValueParameterCommonizerTest : AbstractCommonizerTest