[Commonizer] Implement CirUnderscoredTypeAliasSubstitutor
Try substituting TypeAlias types that start with `__` in favour of TypeAlias without the underscored prefix ^KT-48287 Verification Pending ^KT-48286 Verification Pending
This commit is contained in:
committed by
Space
parent
7d3830ba7d
commit
8aceff3641
@@ -14,6 +14,8 @@ import org.jetbrains.kotlin.commonizer.mergedtree.CirKnownClassifiers
|
|||||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirNode.Companion.indexOfCommon
|
import org.jetbrains.kotlin.commonizer.mergedtree.CirNode.Companion.indexOfCommon
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirRootNode
|
import org.jetbrains.kotlin.commonizer.mergedtree.CirRootNode
|
||||||
import org.jetbrains.kotlin.commonizer.metadata.CirTreeSerializer
|
import org.jetbrains.kotlin.commonizer.metadata.CirTreeSerializer
|
||||||
|
import org.jetbrains.kotlin.commonizer.transformer.CirAliasTypeSubstitutor
|
||||||
|
import org.jetbrains.kotlin.commonizer.transformer.CirUnderscoredTypeAliasSubstitutor
|
||||||
import org.jetbrains.kotlin.commonizer.transformer.InlineTypeAliasCirNodeTransformer
|
import org.jetbrains.kotlin.commonizer.transformer.InlineTypeAliasCirNodeTransformer
|
||||||
import org.jetbrains.kotlin.commonizer.transformer.TypeSubstitutionCirNodeTransformer
|
import org.jetbrains.kotlin.commonizer.transformer.TypeSubstitutionCirNodeTransformer
|
||||||
import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot
|
import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot
|
||||||
@@ -62,7 +64,16 @@ internal fun commonizeTarget(
|
|||||||
val mergedTree = mergeCirTree(parameters.storageManager, classifiers, availableTrees)
|
val mergedTree = mergeCirTree(parameters.storageManager, classifiers, availableTrees)
|
||||||
|
|
||||||
InlineTypeAliasCirNodeTransformer(parameters.storageManager, classifiers).invoke(mergedTree)
|
InlineTypeAliasCirNodeTransformer(parameters.storageManager, classifiers).invoke(mergedTree)
|
||||||
TypeSubstitutionCirNodeTransformer(parameters.storageManager, classifiers).invoke(mergedTree)
|
|
||||||
|
TypeSubstitutionCirNodeTransformer(
|
||||||
|
parameters.storageManager, classifiers,
|
||||||
|
CirAliasTypeSubstitutor(classifiers.commonDependencies, classifiers.classifierIndices)
|
||||||
|
).invoke(mergedTree)
|
||||||
|
|
||||||
|
TypeSubstitutionCirNodeTransformer(
|
||||||
|
parameters.storageManager, classifiers,
|
||||||
|
CirUnderscoredTypeAliasSubstitutor(classifiers.classifierIndices)
|
||||||
|
).invoke(mergedTree)
|
||||||
|
|
||||||
mergedTree.accept(CommonizationVisitor(classifiers, mergedTree), Unit)
|
mergedTree.accept(CommonizationVisitor(classifiers, mergedTree), Unit)
|
||||||
|
|
||||||
|
|||||||
+63
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* 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.CirEntityId
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirName
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirType
|
||||||
|
import org.jetbrains.kotlin.commonizer.cir.CirTypeAliasType
|
||||||
|
import org.jetbrains.kotlin.commonizer.core.expandedType
|
||||||
|
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 CirUnderscoredTypeAliasSubstitutor(
|
||||||
|
private val classifierIndices: TargetDependent<CirClassifierIndex>
|
||||||
|
) : 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
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
-7
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.commonizer.transformer
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.*
|
import org.jetbrains.kotlin.commonizer.mergedtree.*
|
||||||
import org.jetbrains.kotlin.commonizer.mergedtree.CirNodeRelationship.ParentNode
|
import org.jetbrains.kotlin.commonizer.mergedtree.CirNodeRelationship.ParentNode
|
||||||
import org.jetbrains.kotlin.commonizer.tree.CirTreeRoot
|
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
|
|
||||||
internal class TypeSubstitutionCirNodeTransformer(
|
internal class TypeSubstitutionCirNodeTransformer(
|
||||||
@@ -16,12 +15,6 @@ internal class TypeSubstitutionCirNodeTransformer(
|
|||||||
private val typeSubstitutor: CirTypeSubstitutor
|
private val typeSubstitutor: CirTypeSubstitutor
|
||||||
) : CirNodeTransformer {
|
) : CirNodeTransformer {
|
||||||
|
|
||||||
constructor(storageManager: StorageManager, classifiers: CirKnownClassifiers) : this(
|
|
||||||
storageManager = storageManager,
|
|
||||||
classifiers = classifiers,
|
|
||||||
typeSubstitutor = CirAliasTypeSubstitutor(classifiers.commonDependencies, classifiers.classifierIndices)
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun invoke(root: CirRootNode) {
|
override fun invoke(root: CirRootNode) {
|
||||||
for (index in 0 until root.targetDeclarations.size) {
|
for (index in 0 until root.targetDeclarations.size) {
|
||||||
root.modules.forEach { (_, module) -> this(module, index) }
|
root.modules.forEach { (_, module) -> this(module, index) }
|
||||||
|
|||||||
+127
@@ -0,0 +1,127 @@
|
|||||||
|
/*
|
||||||
|
* 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.AbstractInlineSourcesCommonizationTest
|
||||||
|
import org.jetbrains.kotlin.commonizer.assertCommonized
|
||||||
|
|
||||||
|
class CirUnderscoredTypeAliasSubstitutorTest : AbstractInlineSourcesCommonizationTest() {
|
||||||
|
|
||||||
|
fun `test inlined underscored typealias - single platform`() {
|
||||||
|
val result = commonize {
|
||||||
|
outputTarget("(a, b)")
|
||||||
|
simpleSingleSourceTarget(
|
||||||
|
"a", """
|
||||||
|
typealias X = Int
|
||||||
|
typealias __X = X
|
||||||
|
fun x(x: __X)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
|
simpleSingleSourceTarget(
|
||||||
|
"b", """
|
||||||
|
typealias X = Int
|
||||||
|
fun x(x: X)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.assertCommonized(
|
||||||
|
"(a, b)", """
|
||||||
|
typealias X = Int
|
||||||
|
expect fun x(x: X)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun `test inlined underscored typealias - both platforms`() {
|
||||||
|
val result = commonize {
|
||||||
|
outputTarget("(a, b)")
|
||||||
|
simpleSingleSourceTarget(
|
||||||
|
"a", """
|
||||||
|
typealias X = Int
|
||||||
|
typealias __X = X
|
||||||
|
fun x(x: __X)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
|
simpleSingleSourceTarget(
|
||||||
|
"b", """
|
||||||
|
typealias X = Int
|
||||||
|
typealias __X = X
|
||||||
|
fun x(x: X)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.assertCommonized(
|
||||||
|
"(a, b)", """
|
||||||
|
typealias X = Int
|
||||||
|
typealias __X = X
|
||||||
|
expect fun x(x: X)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun `test inlined underscored typealias - both platforms - not used in signature`() {
|
||||||
|
val result = commonize {
|
||||||
|
outputTarget("(a, b)")
|
||||||
|
simpleSingleSourceTarget(
|
||||||
|
"a", """
|
||||||
|
typealias X = Int
|
||||||
|
typealias __X = X
|
||||||
|
fun x(x: X)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
|
simpleSingleSourceTarget(
|
||||||
|
"b", """
|
||||||
|
typealias X = Int
|
||||||
|
typealias __X = X
|
||||||
|
fun x(x: X)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.assertCommonized(
|
||||||
|
"(a, b)", """
|
||||||
|
typealias X = Int
|
||||||
|
typealias __X = X
|
||||||
|
expect fun x(x: X)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fun `test inlined underscored typealias - both platforms - underscore used in both signatures`() {
|
||||||
|
val result = commonize {
|
||||||
|
outputTarget("(a, b)")
|
||||||
|
simpleSingleSourceTarget(
|
||||||
|
"a", """
|
||||||
|
typealias X = Int
|
||||||
|
typealias __X = X
|
||||||
|
fun x(x: __X)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
|
simpleSingleSourceTarget(
|
||||||
|
"b", """
|
||||||
|
typealias X = Int
|
||||||
|
typealias __X = X
|
||||||
|
fun x(x: __X)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.assertCommonized(
|
||||||
|
"(a, b)", """
|
||||||
|
typealias X = Int
|
||||||
|
typealias __X = X
|
||||||
|
expect fun x(x: __X)
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user