From 5c7ac614ceebadd21bd61b8f195912a13d271457 Mon Sep 17 00:00:00 2001 From: "sebastian.sellmair" Date: Fri, 10 Sep 2021 11:52:03 +0200 Subject: [PATCH] [Commonizer] Remove old implementations for type commonization Removed AliasedTypeSubstitutor: Covered by ClassOrTypeAliasTypeCommonizer Removed ClassTypeCommonizer: Covered by ClassOrTypeAliasTypeCommonizer Removed type alias substitution transformers: Covered by CirCommonClassifierId ^KT-48288 --- .../commonizer/core/ClassTypeCommonizer.kt | 66 --------- .../core/TypeAliasTypeCommonizer.kt | 138 ------------------ .../transformer/AliasedTypeSubstitutor.kt | 109 -------------- .../TypeSubstitutionCirNodeTransformer.kt | 71 --------- .../UnderscoredTypeAliasTypeSubstitutor.kt | 59 -------- 5 files changed, 443 deletions(-) delete mode 100644 native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassTypeCommonizer.kt delete mode 100644 native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeAliasTypeCommonizer.kt delete mode 100644 native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/AliasedTypeSubstitutor.kt delete mode 100644 native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/TypeSubstitutionCirNodeTransformer.kt delete mode 100644 native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/UnderscoredTypeAliasTypeSubstitutor.kt diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassTypeCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassTypeCommonizer.kt deleted file mode 100644 index de470c85973..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/ClassTypeCommonizer.kt +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2010-2021 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.commonizer.core - -import org.jetbrains.kotlin.commonizer.cir.CirClassType -import org.jetbrains.kotlin.commonizer.cir.CirEntityId -import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers -import org.jetbrains.kotlin.commonizer.utils.isUnderKotlinNativeSyntheticPackages -import org.jetbrains.kotlin.commonizer.utils.singleDistinctValueOrNull - -class ClassTypeCommonizer internal constructor( - private val classifiers: CirKnownClassifiers, - private val typeCommonizer: TypeCommonizer, - private val isMarkedNullableCommonizer: TypeNullabilityCommonizer -) : NullableSingleInvocationCommonizer { - override fun invoke(values: List): CirClassType? { - if (values.isEmpty()) return null - val classId = values.singleDistinctValueOrNull { it.classifierId } ?: return null - val isMarkedNullable = isMarkedNullableCommonizer.commonize(values.map { it.isMarkedNullable }) ?: return null - - if (values.any { !isClassifierAvailableInCommon(classifiers, it.classifierId) }) { - return null - } - - val outerType = if (values.all { it.outerType == null }) null - else if (values.any { it.outerType == null }) return null - else invoke(values.map { checkNotNull(it.outerType) }) ?: return null - - // Commonizer is stateful: Needs to be created per invocation! - val arguments = TypeArgumentListCommonizer(typeCommonizer).commonize(values.map { it.arguments }) ?: return null - - return CirClassType.createInterned( - classId = classId, - outerType = outerType, - - // N.B. The 'visibility' field in class types is needed ONLY for TA commonization. The class type constructed here is - // intended to be used in "common" target. It could not participate in TA commonization. So, it does not matter which - // exactly visibility will be recorded for commonized class type. Passing the visibility of the first class type - // to reach better interning rate. - visibility = values.first().visibility, - arguments = arguments, - isMarkedNullable = isMarkedNullable - ) - } -} - -private fun isClassifierAvailableInCommon(classifiers: CirKnownClassifiers, classId: CirEntityId): Boolean { - if (classifiers.commonDependencies.hasClassifier(classId)) { - // The class is from common fragment of dependency library (ex: stdlib). Already commonized. - return true - } else if (classId.packageName.isUnderKotlinNativeSyntheticPackages) { - // C/Obj-C forward declarations are: - // - Either resolved to real classes/interfaces from other interop libraries (which are generated by C-interop tool and - // are known to have modality/visibility/other attributes to successfully pass commonization). - // - Or resolved to the same synthetic classes/interfaces. - // ... and therefore are considered as successfully commonized. - return true - } - - // Looking for a a node that provides a non-null (successfully commonized) classifier declaration - return (classifiers.commonizedNodes.classNode(classId)?.commonDeclaration?.invoke() - ?: classifiers.commonizedNodes.typeAliasNode(classId)?.commonDeclaration?.invoke()) != null -} diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeAliasTypeCommonizer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeAliasTypeCommonizer.kt deleted file mode 100644 index a086120e55c..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/core/TypeAliasTypeCommonizer.kt +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright 2010-2021 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.commonizer.core - -import org.jetbrains.kotlin.commonizer.cir.* -import org.jetbrains.kotlin.commonizer.core.CommonizedTypeAliasAnswer.Companion.FAILURE_MISSING_IN_SOME_TARGET -import org.jetbrains.kotlin.commonizer.core.CommonizedTypeAliasAnswer.Companion.SUCCESS_FROM_DEPENDENCY_LIBRARY -import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers - -internal class TypeAliasTypeCommonizer( - private val typeCommonizer: TypeCommonizer, - private val classifiers: CirKnownClassifiers, -) : AbstractStandardCommonizer() { - - private lateinit var typeAliasId: CirEntityId - private val arguments = TypeArgumentListCommonizer(typeCommonizer) - private val underlyingTypeArguments = TypeArgumentListCommonizer(typeCommonizer) - private val isMarkedNullable = TypeNullabilityCommonizer(typeCommonizer.options).asCommonizer() - private var commonizedTypeBuilder: CommonizedTypeAliasTypeBuilder? = null // null means not selected yet - - override fun commonizationResult() = - (commonizedTypeBuilder ?: failInEmptyState()).build( - typeAliasId = typeAliasId, - arguments = arguments.result, - underlyingTypeArguments = underlyingTypeArguments.result, - isMarkedNullable = isMarkedNullable.result - ) - - override fun initialize(first: CirTypeAliasType) { - typeAliasId = first.classifierId - } - - override fun doCommonizeWith(next: CirTypeAliasType): Boolean { - if (typeAliasId != next.classifierId) return false - if (!isMarkedNullable.commonizeWith(next.expandedType().isMarkedNullable)) return false - - if (commonizedTypeBuilder == null) { - val answer = commonizeTypeAlias(typeAliasId, classifiers) - if (!answer.isCommon) - return false - - commonizedTypeBuilder = when (val commonClassifier = answer.commonClassifier) { - is CirClass -> CommonizedTypeAliasTypeBuilder.forClass(commonClassifier) - is CirTypeAlias -> CommonizedTypeAliasTypeBuilder.forTypeAlias(commonClassifier) - null -> { - val underlyingType = computeSuitableUnderlyingType(classifiers, typeCommonizer, next.underlyingType) ?: return false - CommonizedTypeAliasTypeBuilder.forKnownUnderlyingType(underlyingType) - } - else -> error("Unexpected common classifier type: ${commonClassifier::class.java}, $commonClassifier") - } - } - - return arguments.commonizeWith(next.arguments) && - underlyingTypeArguments.commonizeWith(next.underlyingType.arguments) - } - - // builds a new type for "common" library fragment for the given combination of type alias types in "platform" fragments - internal interface CommonizedTypeAliasTypeBuilder { - fun build( - typeAliasId: CirEntityId, - arguments: List, - underlyingTypeArguments: List, - isMarkedNullable: Boolean - ): CirClassOrTypeAliasType - - companion object { - // type alias has been commonized to expect class, need to build type for expect class - fun forClass(commonClass: CirClass) = object : CommonizedTypeAliasTypeBuilder { - override fun build( - typeAliasId: CirEntityId, - arguments: List, - underlyingTypeArguments: List, - isMarkedNullable: Boolean - ) = CirClassType.createInterned( - classId = typeAliasId, - outerType = null, // there can't be outer type - visibility = commonClass.visibility, - arguments = arguments, - isMarkedNullable = isMarkedNullable - ) - } - - // type alias has been commonized to another type alias with the different underlying type, need to build type for - // new type alias - fun forTypeAlias(modifiedTypeAlias: CirTypeAlias) = forKnownUnderlyingType(modifiedTypeAlias.underlyingType) - - // type alias don't needs to be commonized because it is from the standard library - fun forKnownUnderlyingType(underlyingType: CirClassOrTypeAliasType) = object : CommonizedTypeAliasTypeBuilder { - override fun build( - typeAliasId: CirEntityId, - arguments: List, - underlyingTypeArguments: List, - isMarkedNullable: Boolean - ): CirTypeAliasType { - val underlyingTypeWithProperNullability = underlyingType - .makeNullableIfNecessary(isMarkedNullable) - .withArguments(underlyingTypeArguments) - - return CirTypeAliasType.createInterned( - typeAliasId = typeAliasId, - underlyingType = underlyingTypeWithProperNullability, - arguments = arguments, - isMarkedNullable = isMarkedNullable - ) - } - } - } - } -} - -private fun commonizeTypeAlias(typeAliasId: CirEntityId, classifiers: CirKnownClassifiers): CommonizedTypeAliasAnswer { - if (classifiers.commonDependencies.hasClassifier(typeAliasId)) { - // The type alias is from common fragment of dependency library (ex: stdlib). Already commonized. - return SUCCESS_FROM_DEPENDENCY_LIBRARY - } - - val typeAliasNode = classifiers.commonizedNodes.typeAliasNode(typeAliasId) - val classNode = classifiers.commonizedNodes.classNode(typeAliasId) - - if (typeAliasNode == null && classNode == null) { - return FAILURE_MISSING_IN_SOME_TARGET - } - - return CommonizedTypeAliasAnswer.create(typeAliasNode?.commonDeclaration?.invoke() ?: classNode?.commonDeclaration?.invoke()) -} - -private class CommonizedTypeAliasAnswer(val isCommon: Boolean, val commonClassifier: CirClassifier?) { - companion object { - val SUCCESS_FROM_DEPENDENCY_LIBRARY = CommonizedTypeAliasAnswer(true, null) - val FAILURE_MISSING_IN_SOME_TARGET = CommonizedTypeAliasAnswer(false, null) - - fun create(commonClassifier: CirClassifier?) = - if (commonClassifier != null) CommonizedTypeAliasAnswer(true, commonClassifier) else FAILURE_MISSING_IN_SOME_TARGET - } -} diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/AliasedTypeSubstitutor.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/AliasedTypeSubstitutor.kt deleted file mode 100644 index d4ed25fa52e..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/AliasedTypeSubstitutor.kt +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2010-2021 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.commonizer.transformer - -import org.jetbrains.kotlin.commonizer.TargetDependent -import org.jetbrains.kotlin.commonizer.cir.* -import org.jetbrains.kotlin.commonizer.cir.CirClassType.Companion.copyInterned -import org.jetbrains.kotlin.commonizer.cir.CirTypeAliasType.Companion.copyInterned -import org.jetbrains.kotlin.commonizer.mergedtree.CirClassifierIndex -import org.jetbrains.kotlin.commonizer.mergedtree.CirProvidedClassifiers -import org.jetbrains.kotlin.commonizer.mergedtree.CirTypeSubstitutor -import org.jetbrains.kotlin.commonizer.tree.CirTreeTypeAlias - -internal class AliasedTypeSubstitutor( - private val commonDependencies: CirProvidedClassifiers, - private val classifierIndices: TargetDependent -) : CirTypeSubstitutor { - - override fun substitute(targetIndex: Int, type: CirType): CirType { - return when (type) { - is CirFlexibleType -> type - is CirTypeParameterType -> type - is CirClassOrTypeAliasType -> substituteClassOrTypeAliasType(targetIndex, type) - } - } - - private fun substituteTypeProjection(targetIndex: Int, projection: CirTypeProjection): CirTypeProjection { - return when (projection) { - is CirRegularTypeProjection -> { - val newType = substitute(targetIndex, projection.type) - if (newType != projection.type) projection.copy(type = newType) else projection - } - is CirStarTypeProjection -> projection - } - } - - private fun substituteClassOrTypeAliasType(targetIndex: Int, type: CirClassOrTypeAliasType): CirClassOrTypeAliasType { - /* - Classifier id is available in all platforms or is provided by common dependencies. - The classifier itself does not require substitution, but type arguments potentially do! - */ - if (isCommon(type.classifierId)) { - val newArguments = type.arguments.map { argument -> substituteTypeProjection(targetIndex, argument) } - return if (newArguments != type.arguments) when (type) { - is CirTypeAliasType -> type.copyInterned(arguments = newArguments) - is CirClassType -> type.copyInterned(arguments = newArguments) - } else type - } - - /** - * Yet, we do not have any evidence that it is worth trying to substitute types with arguments when the type itself is - * not common at all. This substitutor could try to substitute the type & it's arguments. - * - * Without any evidence of libraries that would benefit from this higher effort, we will just skip this case. - */ - if (type.arguments.isNotEmpty()) { - return type - } - - return when (type) { - is CirClassType -> substituteClassType(targetIndex, type) - is CirTypeAliasType -> substituteClassType(targetIndex, type.unabbreviate()) - } - } - - /** - * Tries to find a suitable type alias pointing to the given class [type] which is available in 'common' - * This function does *not* support types with arguments! - */ - private fun substituteClassType(targetIndex: Int, type: CirClassType): CirClassOrTypeAliasType { - if (type.arguments.isNotEmpty()) return type - if (type.outerType != null) return type - if (isCommon(type.classifierId)) return type - val classifierIndex = classifierIndices[targetIndex] - - val typeAliases = classifierIndex.findTypeAliasesWithUnderlyingType(type.classifierId) - val commonTypeAlias = findSuitableCommonTypeAlias(classifierIndex, typeAliases) ?: return type - - return CirTypeAliasType.createInterned( - typeAliasId = commonTypeAlias.id, - underlyingType = commonTypeAlias.typeAlias.underlyingType, - arguments = emptyList(), - isMarkedNullable = type.isMarkedNullable - ) - } - - private tailrec fun findSuitableCommonTypeAlias( - index: CirClassifierIndex, - typeAliases: List - ): CirTreeTypeAlias? { - if (typeAliases.isEmpty()) return null - - val commonTypeAlias = typeAliases.firstOrNull { (id, typeAlias) -> typeAlias.typeParameters.isEmpty() && isCommon(id) } - if (commonTypeAlias != null) { - return commonTypeAlias - } - - return findSuitableCommonTypeAlias( - index, typeAliases.flatMap { (id, _) -> index.findTypeAliasesWithUnderlyingType(id) } - ) - } - - private fun isCommon(id: CirEntityId): Boolean = - commonDependencies.hasClassifier(id) || classifierIndices.all { index -> id in index.allClassifierIds } -} - diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/TypeSubstitutionCirNodeTransformer.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/TypeSubstitutionCirNodeTransformer.kt deleted file mode 100644 index 97af82c54a4..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/TypeSubstitutionCirNodeTransformer.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 2010-2021 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.commonizer.transformer - -import org.jetbrains.kotlin.commonizer.mergedtree.* -import org.jetbrains.kotlin.commonizer.mergedtree.CirNodeRelationship.ParentNode -import org.jetbrains.kotlin.commonizer.utils.fastForEach -import org.jetbrains.kotlin.storage.StorageManager - -internal class TypeSubstitutionCirNodeTransformer( - private val storageManager: StorageManager, - private val classifiers: CirKnownClassifiers, - private val typeSubstitutor: CirTypeSubstitutor, -) : CirNodeTransformer { - - private val commonClassifierIdResolver = classifiers.commonClassifierIdResolver - - override fun invoke(root: CirRootNode) { - for (index in 0 until root.targetDeclarations.size) { - root.modules.forEach { (_, module) -> this(module, index) } - } - } - - private operator fun invoke(module: CirModuleNode, index: Int) { - module.packages.forEach { (_, pkg) -> this(pkg, index) } - } - - private operator fun invoke(pkg: CirPackageNode, index: Int) { - pkg.functions.values.toTypedArray().fastForEach { function -> this(pkg, function, index, CirMemberContext.empty) } - pkg.properties.values.toTypedArray().fastForEach { property -> this(pkg, property, index, CirMemberContext.empty) } - pkg.classes.values.toTypedArray().fastForEach { clazz -> this(clazz, index, CirMemberContext.empty) } - } - - private operator fun invoke(clazz: CirClassNode, index: Int, context: CirMemberContext) { - val contextWithClass = context.withContextOf(clazz.targetDeclarations[index] ?: return) - clazz.functions.values.toTypedArray().fastForEach { function -> this(clazz, function, index, contextWithClass) } - clazz.properties.values.toTypedArray().fastForEach { property -> this(clazz, property, index, contextWithClass) } - clazz.classes.values.toTypedArray().fastForEach { innerClass -> this(innerClass, index, contextWithClass) } - } - - private operator fun invoke(parent: CirNodeWithMembers<*, *>, function: CirFunctionNode, index: Int, context: CirMemberContext) { - /* Only perform type substitution to nodes that are not 'complete' */ - if (function.targetDeclarations.none { it == null }) return - val originalFunction = function.targetDeclarations[index] ?: return - val newFunction = typeSubstitutor.substitute(index, originalFunction) - if (originalFunction == newFunction) return - - val approximationKey = FunctionApproximationKey.create(context, commonClassifierIdResolver, newFunction) - val newNode = parent.functions.getOrPut(approximationKey) { - buildFunctionNode(storageManager, parent.targetDeclarations.size, classifiers, ParentNode(parent)) - } - - newNode.targetDeclarations.setAllowingOverride(index, newFunction) - } - - private operator fun invoke(parent: CirNodeWithMembers<*, *>, property: CirPropertyNode, index: Int, context: CirMemberContext) { - val originalProperty = property.targetDeclarations[index] ?: return - val newProperty = typeSubstitutor.substitute(index, originalProperty) - if (originalProperty == newProperty) return - - val approximationKey = PropertyApproximationKey.create(context, commonClassifierIdResolver, newProperty) - val newNode = parent.properties.getOrPut(approximationKey) { - buildPropertyNode(storageManager, parent.targetDeclarations.size, classifiers, ParentNode(parent)) - } - - newNode.targetDeclarations.setAllowingOverride(index, newProperty) - } -} \ No newline at end of file diff --git a/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/UnderscoredTypeAliasTypeSubstitutor.kt b/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/UnderscoredTypeAliasTypeSubstitutor.kt deleted file mode 100644 index 34f1752fa75..00000000000 --- a/native/commonizer/src/org/jetbrains/kotlin/commonizer/transformer/UnderscoredTypeAliasTypeSubstitutor.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2010-2021 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.commonizer.transformer - -import org.jetbrains.kotlin.commonizer.TargetDependent -import org.jetbrains.kotlin.commonizer.cir.* -import org.jetbrains.kotlin.commonizer.mergedtree.CirClassifierIndex -import org.jetbrains.kotlin.commonizer.mergedtree.CirTypeSubstitutor -import org.jetbrains.kotlin.commonizer.mergedtree.findTypeAlias - -/** - * Explicitly substitute [CirTypeAliasType]s whose classifier name is prefixed with a double underscore: "__" - * with a type using a classifier without the prefix if - * 1) Such a TypeAlias exists on the platform - * 2) Such a TypeAlias expands to the same type - * - * Example from platform.posix.mkdir: - * This function uses the following parameter: - * linux: `platform/posix/__mode_t -> kotlin/UInt` - * apple: `platform/posix/mode_t -> platform/posix/__darwin_mode_t -> platform/posix/__uint16_t -> kotlin/UShort` - * - * However, on linux a corresponding type alias - * `platform/posix/mode_t -> platform/posix/__mode_t -> kotlin/UInt` - * exists which is preferable - */ -internal class UnderscoredTypeAliasTypeSubstitutor( - private val classifierIndices: TargetDependent -) : CirTypeSubstitutor { - - override fun substitute(targetIndex: Int, type: CirType): CirType { - if (type !is CirTypeAliasType) return type - - /* TypeAliases cannot be nested and therefore are expected to have only a single name segment */ - val name = type.classifierId.relativeNameSegments.singleOrNull() ?: return type - if (!name.name.startsWith("__")) return type - - /* Argument substitution not implemented. No real world cases known that would benefit */ - if (type.arguments.isNotEmpty()) return type - - val preferredClassifierId = CirEntityId.create( - type.classifierId.packageName, - CirName.create(name.name.removePrefix("__")) - ) - - val preferredTypeAlias = classifierIndices[targetIndex].findTypeAlias(preferredClassifierId) ?: return type - val expandedType = type.expandedType() - if (preferredTypeAlias.expandedType != expandedType) return type - - return CirTypeAliasType.createInterned( - typeAliasId = preferredClassifierId, - underlyingType = preferredTypeAlias.underlyingType, - arguments = emptyList(), - isMarkedNullable = expandedType.isMarkedNullable - ) - } -}