[Commonizer] Rework CommonizedGroup API to make it more usable

This commit is contained in:
Dmitriy Dolovov
2020-06-17 21:56:43 +07:00
parent 63575582c4
commit 5cad8a793c
14 changed files with 46 additions and 60 deletions
@@ -5,10 +5,7 @@
package org.jetbrains.kotlin.descriptors.commonizer.builder
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.*
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
@@ -31,7 +28,7 @@ internal class DeclarationsBuilderVisitor1(
check(data.isEmpty()) // root node may not have containing declarations
check(components.targetComponents.size == node.dimension)
val allTargets = (node.targetDeclarations.toList() + node.commonDeclaration()!!).map { it!!.target }
val allTargets = (node.targetDeclarations + node.commonDeclaration()).map { it!!.target }
val modulesByTargets = HashMap<Target, MutableList<ModuleDescriptorImpl>>()
@@ -56,30 +53,28 @@ internal class DeclarationsBuilderVisitor1(
// build module descriptors:
val moduleDescriptorsGroup = CommonizedGroup<ModuleDescriptorImpl>(node.dimension)
node.buildDescriptors(components, moduleDescriptorsGroup)
val moduleDescriptors = moduleDescriptorsGroup.toList()
// build package fragments:
val packageFragmentProviders = CommonizedPackageFragmentProvider.createArray(node.dimension)
for (packageNode in node.packages.values) {
val packageFragments = packageNode.accept(this, moduleDescriptors).asListContaining<PackageFragmentDescriptor>()
val packageFragments = packageNode.accept(this, moduleDescriptorsGroup).asListContaining<PackageFragmentDescriptor>()
packageFragmentProviders += packageFragments
}
// initialize module descriptors:
moduleDescriptors.forEachIndexed { index, moduleDescriptor ->
moduleDescriptorsGroup.forEachIndexed { index, moduleDescriptor ->
moduleDescriptor?.initialize(packageFragmentProviders[index])
}
return moduleDescriptors
return moduleDescriptorsGroup
}
override fun visitPackageNode(node: CirPackageNode, data: List<DeclarationDescriptor?>): List<PackageFragmentDescriptor?> {
val containingDeclarations = data.asListContaining<ModuleDescriptorImpl>()
// build package fragments:
val packageFragmentsGroup = CommonizedGroup<CommonizedPackageFragmentDescriptor>(node.dimension)
node.buildDescriptors(components, packageFragmentsGroup, containingDeclarations)
val packageFragments = packageFragmentsGroup.toList()
val packageFragments = CommonizedGroup<CommonizedPackageFragmentDescriptor>(node.dimension)
node.buildDescriptors(components, packageFragments, containingDeclarations)
// build package members:
val packageMemberScopes = CommonizedMemberScope.createArray(node.dimension)
@@ -105,9 +100,9 @@ internal class DeclarationsBuilderVisitor1(
error("This method should not be called in ${this::class.java}")
override fun visitClassNode(node: CirClassNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val classesGroup = CommonizedGroup<ClassifierDescriptorWithTypeParameters>(node.dimension)
node.buildDescriptors(components, classesGroup, data)
val classes = classesGroup.toList().asListContaining<CommonizedClassDescriptor>()
val classifiers = CommonizedGroup<ClassifierDescriptorWithTypeParameters>(node.dimension)
node.buildDescriptors(components, classifiers, data)
val classes = classifiers.asListContaining<CommonizedClassDescriptor>()
// build class members:
val classMemberScopes = CommonizedMemberScope.createArray(node.dimension)
@@ -127,15 +122,14 @@ internal class DeclarationsBuilderVisitor1(
error("This method should not be called in ${this::class.java}")
override fun visitTypeAliasNode(node: CirTypeAliasNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val typeAliasesGroup = CommonizedGroup<ClassifierDescriptorWithTypeParameters>(node.dimension)
node.buildDescriptors(components, typeAliasesGroup, data)
val typeAliases = typeAliasesGroup.toList()
val classifiers = CommonizedGroup<ClassifierDescriptorWithTypeParameters>(node.dimension)
node.buildDescriptors(components, classifiers, data)
val commonClass = typeAliases[node.indexOfCommon] as? CommonizedClassDescriptor?
val commonClass = classifiers[node.indexOfCommon] as? CommonizedClassDescriptor?
commonClass?.unsubstitutedMemberScope = CommonizedMemberScope() // empty member scope
commonClass?.initialize(emptyList()) // no constructors
return typeAliases
return classifiers
}
companion object {
@@ -66,17 +66,17 @@ internal class DeclarationsBuilderVisitor2(
}
override fun visitPropertyNode(node: CirPropertyNode, data: List<DeclarationDescriptor?>): List<PropertyDescriptor?> {
val propertyDescriptorsGroup = CommonizedGroup<PropertyDescriptor>(node.dimension)
node.buildDescriptors(components, propertyDescriptorsGroup, data)
val propertyDescriptors = CommonizedGroup<PropertyDescriptor>(node.dimension)
node.buildDescriptors(components, propertyDescriptors, data)
return propertyDescriptorsGroup.toList()
return propertyDescriptors
}
override fun visitFunctionNode(node: CirFunctionNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val functionDescriptorsGroup = CommonizedGroup<SimpleFunctionDescriptor>(node.dimension)
node.buildDescriptors(components, functionDescriptorsGroup, data)
val functionDescriptors = CommonizedGroup<SimpleFunctionDescriptor>(node.dimension)
node.buildDescriptors(components, functionDescriptors, data)
return functionDescriptorsGroup.toList()
return functionDescriptors
}
override fun visitClassNode(node: CirClassNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
@@ -115,10 +115,10 @@ internal class DeclarationsBuilderVisitor2(
override fun visitClassConstructorNode(node: CirClassConstructorNode, data: List<DeclarationDescriptor?>): List<DeclarationDescriptor?> {
val containingDeclarations = data.asListContaining<CommonizedClassDescriptor>()
val constructorsGroup = CommonizedGroup<ClassConstructorDescriptor>(node.dimension)
node.buildDescriptors(components, constructorsGroup, containingDeclarations)
val constructors = CommonizedGroup<ClassConstructorDescriptor>(node.dimension)
node.buildDescriptors(components, constructors, containingDeclarations)
return constructorsGroup.toList()
return constructors
}
override fun visitTypeAliasNode(node: CirTypeAliasNode, data: List<DeclarationDescriptor?>) =
@@ -25,14 +25,14 @@ internal fun CirClassNode.buildDescriptors(
val commonClass = commonDeclaration()
val markAsActual = commonClass != null && commonClass.kind != ClassKind.ENUM_ENTRY
targetDeclarations.toList().forEachIndexed { index, clazz ->
targetDeclarations.forEachIndexed { index, clazz ->
clazz?.buildDescriptor(components, output, index, containingDeclarations, fqName, isActual = markAsActual)
}
commonClass?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, fqName, isExpect = true)
// log stats
components.statsCollector?.logStats(output.toList())
components.statsCollector?.logStats(output)
}
internal fun CirClass.buildDescriptor(
@@ -81,14 +81,14 @@ internal fun CirClassConstructorNode.buildDescriptors(
val commonConstructor = commonDeclaration()
val markAsActual = commonConstructor != null
targetDeclarations.toList().forEachIndexed { index, constructor ->
targetDeclarations.forEachIndexed { index, constructor ->
constructor?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsActual)
}
commonConstructor?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = true)
// log stats
components.statsCollector?.logStats(output.toList())
components.statsCollector?.logStats(output)
}
private fun CirClassConstructor.buildDescriptor(
@@ -110,7 +110,7 @@ class DeclarationsBuilderCache(private val dimension: Int) {
companion object {
private inline fun <reified K, reified V : DeclarationDescriptor> CommonizedGroupMap<K, V>.getOrFail(key: K): List<V?> =
getOrNull(key)?.toList() ?: error("No cached ${V::class.java} with key $key found")
getOrNull(key) ?: error("No cached ${V::class.java} with key $key found")
}
}
@@ -23,14 +23,14 @@ internal fun CirFunctionNode.buildDescriptors(
val commonFunction = commonDeclaration()
val markAsExpectAndActual = commonFunction != null && commonFunction.kind != CallableMemberDescriptor.Kind.SYNTHESIZED
targetDeclarations.toList().forEachIndexed { index, function ->
targetDeclarations.forEachIndexed { index, function ->
function?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual)
}
commonFunction?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual)
// log stats
components.statsCollector?.logStats(output.toList())
components.statsCollector?.logStats(output)
}
private fun CirFunction.buildDescriptor(
@@ -15,14 +15,14 @@ internal fun CirModuleNode.buildDescriptors(
components: GlobalDeclarationsBuilderComponents,
output: CommonizedGroup<ModuleDescriptorImpl>
) {
targetDeclarations.toList().forEachIndexed { index, module ->
targetDeclarations.forEachIndexed { index, module ->
module?.buildDescriptor(components, output, index)
}
commonDeclaration()?.buildDescriptor(components, output, indexOfCommon)
// log stats
components.statsCollector?.logStats(output.toList())
components.statsCollector?.logStats(output)
}
private fun CirModule.buildDescriptor(
@@ -19,7 +19,7 @@ internal fun CirPackageNode.buildDescriptors(
output: CommonizedGroup<CommonizedPackageFragmentDescriptor>,
modules: List<ModuleDescriptorImpl?>
) {
targetDeclarations.toList().forEachIndexed { index, pkg ->
targetDeclarations.forEachIndexed { index, pkg ->
pkg?.buildDescriptor(components, output, index, modules)
}
@@ -31,7 +31,7 @@ internal fun CirPropertyNode.buildDescriptors(
&& !isLiftedUp
if (!isLiftedUp) {
targetDeclarations.toList().forEachIndexed { index, property ->
targetDeclarations.forEachIndexed { index, property ->
property?.buildDescriptor(components, output, index, containingDeclarations, isActual = markAsExpectAndActual)
}
}
@@ -39,7 +39,7 @@ internal fun CirPropertyNode.buildDescriptors(
commonProperty?.buildDescriptor(components, output, indexOfCommon, containingDeclarations, isExpect = markAsExpectAndActual)
// log stats
components.statsCollector?.logStats(output.toList())
components.statsCollector?.logStats(output)
}
private fun CirProperty.buildDescriptor(
@@ -28,7 +28,7 @@ internal fun CirTypeAliasNode.buildDescriptors(
val markAsActual = commonClassifier != null
if (!isLiftedUp) {
targetDeclarations.toList().forEachIndexed { index, typeAlias ->
targetDeclarations.forEachIndexed { index, typeAlias ->
typeAlias?.buildDescriptor(components, output, index, containingDeclarations, fqName, isActual = markAsActual)
}
}
@@ -40,7 +40,7 @@ internal fun CirTypeAliasNode.buildDescriptors(
}
// log stats
components.statsCollector?.logStats(output.toList())
components.statsCollector?.logStats(output)
}
private fun CirTypeAlias.buildDescriptor(
@@ -78,7 +78,7 @@ internal class CommonizationVisitor(
if (commonClass != null) {
// companion object should have the same FQ name for each target class, then it could be set to common class
val companionObjectFqName = node.targetDeclarations.toList().mapTo(HashSet()) { it!!.companion }.singleOrNull()
val companionObjectFqName = node.targetDeclarations.mapTo(HashSet()) { it!!.companion }.singleOrNull()
if (companionObjectFqName != null) {
val companionObjectNode = root.cache.classes[companionObjectFqName]
?: error("Can't find companion object with FQ name $companionObjectFqName")
@@ -91,7 +91,7 @@ internal class CommonizationVisitor(
// find out common (and commonized) supertypes
val supertypesMap = CommonizedGroupMap<String, CirType>(node.targetDeclarations.size)
node.targetDeclarations.toList().forEachIndexed { index, clazz ->
node.targetDeclarations.forEachIndexed { index, clazz ->
for (supertype in clazz!!.supertypes) {
supertypesMap[supertype.fqNameWithTypeParameters][index] = supertype
}
@@ -27,7 +27,7 @@ interface CirNode<T : CirDeclaration, R : CirDeclaration> {
append("fqName=").append(node.fqName).append(", ")
}
append("target=")
node.targetDeclarations.toList().joinTo(this)
node.targetDeclarations.joinTo(this)
append(", common=")
append(if (node.commonDeclaration.isComputed()) node.commonDeclaration() else "<NOT COMPUTED>")
}
@@ -149,7 +149,7 @@ internal fun <T : Any, R> commonize(
targetDeclarations: CommonizedGroup<T>,
commonizer: Commonizer<T, R>
): R? {
for (targetDeclaration in targetDeclarations.toList()) {
for (targetDeclaration in targetDeclarations) {
if (targetDeclaration == null || !commonizer.commonizeWith(targetDeclaration))
return null
}
@@ -7,9 +7,9 @@ package org.jetbrains.kotlin.descriptors.commonizer.utils
/** Fixed-size ordered collection with no extra space that represents a commonized group of same-rank elements */
class CommonizedGroup<T : Any>(
val size: Int,
override val size: Int,
initialize: (Int) -> T?
) {
) : AbstractList<T?>() {
constructor(elements: List<T?>) : this(elements.size, elements::get)
constructor(size: Int) : this(size, { null })
@@ -18,7 +18,7 @@ class CommonizedGroup<T : Any>(
// so let's use `Any?` instead if `T` here
private val elements = Array<Any?>(size, initialize)
operator fun get(index: Int): T? {
override operator fun get(index: Int): T? {
@Suppress("UNCHECKED_CAST")
return elements[index] as T?
}
@@ -29,14 +29,6 @@ class CommonizedGroup<T : Any>(
elements[index] = value
}
// TODO: consider removing this method
fun toList(): List<T?> = object : AbstractList<T?>() {
override val size
get() = this@CommonizedGroup.size
override fun get(index: Int): T? = this@CommonizedGroup[index]
}
}
internal class CommonizedGroupMap<K, V : Any>(val size: Int) : Iterable<Map.Entry<K, CommonizedGroup<V>>> {
@@ -484,7 +484,7 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
null,
fqName
).also {
classesGroup.toList().forEachIndexed { index, clazz ->
classesGroup.forEachIndexed { index, clazz ->
if (clazz != null) {
it.targetDeclarations[index] = CirClassFactory.create(clazz)
}
@@ -499,7 +499,7 @@ class TypeCommonizerTest : AbstractCommonizerTest<CirType, CirType>() {
cache,
fqName
).also {
typeAliasesGroup.toList().forEachIndexed { index, typeAlias ->
typeAliasesGroup.forEachIndexed { index, typeAlias ->
if (typeAlias != null) {
it.targetDeclarations[index] = CirTypeAliasFactory.create(typeAlias)
}