[MPP] Add preliminary version of platform integer commonizer

Doesn't take target's size_t alias into account just yet

KT-41509
This commit is contained in:
Pavel Kirpichenkov
2022-02-02 12:03:00 +03:00
committed by teamcity
parent b8ee473107
commit 8f4d04dad2
13 changed files with 749 additions and 30 deletions
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.gradle.plugin.KotlinJsCompilerType.Companion.jsCompi
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_CINTEROP_COMMONIZATION
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_GRANULAR_SOURCE_SETS_METADATA
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_OPTIMISTIC_NUMBER_COMMONIZATION
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_ENABLE_PLATFORM_INTEGER_COMMONIZATION
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_HIERARCHICAL_STRUCTURE_BY_DEFAULT
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_MPP_HIERARCHICAL_STRUCTURE_SUPPORT
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider.PropertyNames.KOTLIN_NATIVE_DEPENDENCY_PROPAGATION
@@ -221,6 +222,9 @@ internal class PropertiesProvider private constructor(private val project: Proje
val mppEnableOptimisticNumberCommonization: Boolean
get() = booleanProperty(KOTLIN_MPP_ENABLE_OPTIMISTIC_NUMBER_COMMONIZATION) ?: true
val mppEnablePlatformIntegerCommonization: Boolean
get() = booleanProperty(KOTLIN_MPP_ENABLE_PLATFORM_INTEGER_COMMONIZATION) ?: false
val wasmStabilityNoWarn: Boolean
get() = booleanProperty("kotlin.wasm.stability.nowarn") ?: false
@@ -498,6 +502,7 @@ internal class PropertiesProvider private constructor(private val project: Proje
const val KOTLIN_NATIVE_DEPENDENCY_PROPAGATION = "kotlin.native.enableDependencyPropagation"
const val KOTLIN_MPP_ENABLE_OPTIMISTIC_NUMBER_COMMONIZATION = "kotlin.mpp.enableOptimisticNumberCommonization"
const val KOTLIN_KPM_EXPERIMENTAL_MODEL_MAPPING = "kotlin.kpm.experimentalModelMapping"
const val KOTLIN_MPP_ENABLE_PLATFORM_INTEGER_COMMONIZATION = "kotlin.mpp.enablePlatformIntegerCommonization"
}
companion object {
@@ -6,10 +6,7 @@
package org.jetbrains.kotlin.gradle.targets.native.internal
import org.gradle.api.Project
import org.jetbrains.kotlin.commonizer.AdditionalCommonizerSetting
import org.jetbrains.kotlin.commonizer.CommonizerLogLevel
import org.jetbrains.kotlin.commonizer.OptimisticNumberCommonizationEnabledKey
import org.jetbrains.kotlin.commonizer.setTo
import org.jetbrains.kotlin.commonizer.*
import org.jetbrains.kotlin.gradle.plugin.PropertiesProvider
internal val Project.commonizerLogLevel: CommonizerLogLevel
@@ -24,5 +21,6 @@ internal val Project.commonizerLogLevel: CommonizerLogLevel
internal val Project.additionalCommonizerSettings: List<AdditionalCommonizerSetting<*>>
get() = listOf(
OptimisticNumberCommonizationEnabledKey setTo isOptimisticNumberCommonizationEnabled
OptimisticNumberCommonizationEnabledKey setTo isOptimisticNumberCommonizationEnabled,
PlatformIntegerCommonizationEnabledKey setTo isPlatformIntegerCommonizationEnabled,
)
@@ -25,6 +25,9 @@ internal val Project.isIntransitiveMetadataConfigurationEnabled: Boolean
internal val Project.isOptimisticNumberCommonizationEnabled: Boolean
get() = PropertiesProvider(this).mppEnableOptimisticNumberCommonization
internal val Project.isPlatformIntegerCommonizationEnabled: Boolean
get() = PropertiesProvider(this).mppEnablePlatformIntegerCommonization
internal val Project.commonizeTask: TaskProvider<Task>
get() = locateOrRegisterTask(
"commonize",
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.commonizer
import org.jetbrains.kotlin.commonizer.cli.OPTIMISTIC_NUMBER_COMMONIZATION_ENABLED_ALIAS
import org.jetbrains.kotlin.commonizer.cli.PLATFORM_INTEGER_COMMONIZATION_ENABLED_ALIAS
public interface CommonizerSettings {
@@ -22,3 +23,9 @@ public object OptimisticNumberCommonizationEnabledKey : CommonizerSettings.Key<B
override val alias: String
get() = OPTIMISTIC_NUMBER_COMMONIZATION_ENABLED_ALIAS
}
public object PlatformIntegerCommonizationEnabledKey : CommonizerSettings.Key<Boolean>() {
override val defaultValue: Boolean = false
override val alias: String
get() = PLATFORM_INTEGER_COMMONIZATION_ENABLED_ALIAS
}
@@ -20,3 +20,4 @@ public const val COPY_ENDORSED_LIBS_ALIAS: String = "copy-endorsed-libs"
// Commonizer settings
public const val OPTIMISTIC_NUMBER_COMMONIZATION_ENABLED_ALIAS: String = "optimistic-numbers"
public const val PLATFORM_INTEGER_COMMONIZATION_ENABLED_ALIAS: String = "platform-integers"
@@ -15,7 +15,3 @@ internal sealed class CommonizerSettingOptionType<T : Any>(
description,
mandatory = false,
)
internal val ADDITIONAL_COMMONIZER_SETTINGS: List<CommonizerSettingOptionType<*>> = listOf(
OptimisticNumberCommonizationOptionType,
)
@@ -6,6 +6,12 @@
package org.jetbrains.kotlin.commonizer.cli
import org.jetbrains.kotlin.commonizer.OptimisticNumberCommonizationEnabledKey
import org.jetbrains.kotlin.commonizer.PlatformIntegerCommonizationEnabledKey
internal val ADDITIONAL_COMMONIZER_SETTINGS: List<CommonizerSettingOptionType<*>> = listOf(
OptimisticNumberCommonizationOptionType,
PlatformIntegerCommonizationOptionType,
)
internal object OptimisticNumberCommonizationOptionType : CommonizerSettingOptionType<Boolean>(
OptimisticNumberCommonizationEnabledKey,
@@ -14,3 +20,12 @@ internal object OptimisticNumberCommonizationOptionType : CommonizerSettingOptio
override fun parse(rawValue: String, onError: (reason: String) -> Nothing): Option<Boolean> =
Option(this, parseBoolean(rawValue, onError))
}
internal object PlatformIntegerCommonizationOptionType : CommonizerSettingOptionType<Boolean>(
PlatformIntegerCommonizationEnabledKey,
"Boolean (default false)\n" +
"Enable support of experimental commonization of integers with different bit width to a platform-dependent type",
) {
override fun parse(rawValue: String, onError: (reason: String) -> Nothing): Option<Boolean> =
Option(this, parseBoolean(rawValue, onError))
}
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.commonizer.core
import org.jetbrains.kotlin.commonizer.CommonizerSettings
import org.jetbrains.kotlin.commonizer.OptimisticNumberCommonizationEnabledKey
import org.jetbrains.kotlin.commonizer.PlatformIntegerCommonizationEnabledKey
import org.jetbrains.kotlin.commonizer.cir.*
import org.jetbrains.kotlin.commonizer.mergedtree.*
import org.jetbrains.kotlin.commonizer.utils.isUnderKotlinNativeSyntheticPackages
@@ -18,14 +19,18 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
internal class ClassOrTypeAliasTypeCommonizer(
private val typeCommonizer: TypeCommonizer,
private val classifiers: CirKnownClassifiers,
private val isOptimisticNumberTypeCommonizationEnabled: Boolean
private val isOptimisticNumberTypeCommonizationEnabled: Boolean,
private val isPlatformIntegerCommonizationEnabled: Boolean,
) : NullableSingleInvocationCommonizer<CirClassOrTypeAliasType> {
constructor(typeCommonizer: TypeCommonizer, classifiers: CirKnownClassifiers, settings: CommonizerSettings) : this(
typeCommonizer, classifiers, settings.getSetting(OptimisticNumberCommonizationEnabledKey)
typeCommonizer, classifiers,
settings.getSetting(OptimisticNumberCommonizationEnabledKey),
settings.getSetting(PlatformIntegerCommonizationEnabledKey),
)
private val isMarkedNullableCommonizer = TypeNullabilityCommonizer(typeCommonizer.context)
private val platformIntegerCommonizer = PlatformIntegerCommonizer(typeCommonizer)
private val typeDistanceMeasurement = TypeDistanceMeasurement(typeCommonizer.context)
override fun invoke(values: List<CirClassOrTypeAliasType>): CirClassOrTypeAliasType? {
@@ -34,7 +39,9 @@ internal class ClassOrTypeAliasTypeCommonizer(
val isMarkedNullable = isMarkedNullableCommonizer.commonize(expansions.map { it.isMarkedNullable }) ?: return null
val substitutedTypes = substituteTypesIfNecessary(values)
?: isOptimisticNumberTypeCommonizationEnabled.ifTrue {
?: isPlatformIntegerCommonizationEnabled.ifTrue {
return platformIntegerCommonizer.commonize(expansions)?.makeNullableIfNecessary(isMarkedNullable)
} ?: isOptimisticNumberTypeCommonizationEnabled.ifTrue {
return OptimisticNumbersTypeCommonizer.commonize(expansions)?.makeNullableIfNecessary(isMarkedNullable)
} ?: return null
@@ -0,0 +1,129 @@
/*
* 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.descriptors.konan.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.utils.SmartList
class PlatformIntegerCommonizer(
private val typeArgumentListCommonizer: TypeArgumentListCommonizer
) : AssociativeCommonizer<CirClassOrTypeAliasType> {
constructor(typeCommonizer: TypeCommonizer) : this(TypeArgumentListCommonizer(typeCommonizer))
override fun commonize(first: CirClassOrTypeAliasType, second: CirClassOrTypeAliasType): CirClassOrTypeAliasType? {
return when {
both(first, second) { it.classifierId in commonizableSignedIntegerIds } -> platformIntType
both(first, second) { it.classifierId in commonizableUnsignedIntegerIds } -> platformUIntType
both(first, second) { it.classifierId in commonizableSignedVarIds } -> commonizeVarOf(first, second, isSigned = true)
both(first, second) { it.classifierId in commonizableUnsignedVarIds } -> commonizeVarOf(first, second, isSigned = false)
both(first, second) { it.classifierId in commonizableSignedArrayIds } -> platformIntArrayType
both(first, second) { it.classifierId in commonizableUnsignedArrayIds } -> platformUIntArrayType
both(first, second) { it.classifierId in commonizableSignedRangeIds } -> platformIntRangeType
both(first, second) { it.classifierId in commonizableUnsignedRangeIds } -> platformUIntRangeType
both(first, second) { it.classifierId in commonizableSignedProgressionIds } -> platformIntProgressionType
both(first, second) { it.classifierId in commonizableUnsignedProgressionIds } -> platformUIntProgressionType
else -> null
}
}
private inline fun <T> both(first: T, second: T, predicate: (T) -> Boolean) =
predicate(first) && predicate(second)
private fun commonizeVarOf(
first: CirClassOrTypeAliasType,
second: CirClassOrTypeAliasType,
isSigned: Boolean
): CirClassOrTypeAliasType? {
if (first !is CirClassType || second !is CirClassType) return null
val argument = typeArgumentListCommonizer.commonize(listOf(first.arguments, second.arguments))?.singleOrNull()
?: return null
return createCommonVarOfType(isSigned = isSigned, argument = argument)
}
}
// commonizable groups
private val commonizableSignedIntegerIds: Set<CirEntityId> = listOf(
KOTLIN_INT_ID, KOTLIN_LONG_ID, PLATFORM_INT_ID
).toCirEntityIds()
private val commonizableUnsignedIntegerIds: Set<CirEntityId> = listOf(
KOTLIN_UINT_ID, KOTLIN_ULONG_ID, PLATFORM_UINT_ID
).toCirEntityIds()
private val commonizableSignedVarIds: Set<CirEntityId> = listOf(
INT_VAR_OF_ID, LONG_VAR_OF_ID, PLATFORM_INT_VAR_OF_ID
).toCirEntityIds()
private val commonizableUnsignedVarIds: Set<CirEntityId> = listOf(
UINT_VAR_OF_ID, ULONG_VAR_OF_ID, PLATFORM_UINT_VAR_OF_ID
).toCirEntityIds()
private val commonizableSignedArrayIds: Set<CirEntityId> = listOf(
INT_ARRAY_ID, LONG_ARRAY_ID, PLATFORM_INT_ARRAY_ID
).toCirEntityIds()
private val commonizableUnsignedArrayIds: Set<CirEntityId> = listOf(
UINT_ARRAY_ID, ULONG_ARRAY_ID, PLATFORM_UINT_ARRAY_ID
).toCirEntityIds()
private val commonizableSignedRangeIds: Set<CirEntityId> = listOf(
INT_RANGE_ID, LONG_RANGE_ID, PLATFORM_INT_RANGE_ID
).toCirEntityIds()
private val commonizableUnsignedRangeIds: Set<CirEntityId> = listOf(
UINT_RANGE_ID, ULONG_RANGE_ID, PLATFORM_UINT_RANGE_ID
).toCirEntityIds()
private val commonizableSignedProgressionIds: Set<CirEntityId> = listOf(
INT_PROGRESSION_ID, LONG_PROGRESSION_ID, PLATFORM_INT_PROGRESSION_ID
).toCirEntityIds()
private val commonizableUnsignedProgressionIds: Set<CirEntityId> = listOf(
UINT_PROGRESSION, ULONG_PROGRESSION, PLATFORM_UINT_PROGRESSION_ID
).toCirEntityIds()
private fun ClassId.toCirEntityId(): CirEntityId =
CirEntityId.create(this)
private fun Collection<ClassId>.toCirEntityIds(): Set<CirEntityId> =
map { it.toCirEntityId()}.toSet()
// plain integers
private val platformIntType: CirClassType = createSimpleCirTypeWithoutArguments(PLATFORM_INT_ID.toCirEntityId())
private val platformUIntType: CirClassType = createSimpleCirTypeWithoutArguments(PLATFORM_UINT_ID.toCirEntityId())
// arrays
private val platformIntArrayType: CirClassType = createSimpleCirTypeWithoutArguments(PLATFORM_INT_ARRAY_ID.toCirEntityId())
private val platformUIntArrayType: CirClassType = createSimpleCirTypeWithoutArguments(PLATFORM_UINT_ARRAY_ID.toCirEntityId())
// ranges
private val platformIntRangeType: CirClassType = createSimpleCirTypeWithoutArguments(PLATFORM_INT_RANGE_ID.toCirEntityId())
private val platformUIntRangeType: CirClassType = createSimpleCirTypeWithoutArguments(PLATFORM_UINT_RANGE_ID.toCirEntityId())
// progressions
private val platformIntProgressionType: CirClassType = createSimpleCirTypeWithoutArguments(PLATFORM_INT_PROGRESSION_ID.toCirEntityId())
private val platformUIntProgressionType: CirClassType = createSimpleCirTypeWithoutArguments(PLATFORM_UINT_PROGRESSION_ID.toCirEntityId())
private fun createSimpleCirTypeWithoutArguments(id: CirEntityId): CirClassType =
CirClassType.createInterned(
classId = id,
outerType = null,
arguments = emptyList(),
isMarkedNullable = false,
)
private fun createCommonVarOfType(isSigned: Boolean, argument: CirTypeProjection): CirClassType {
return CirClassType.createInterned(
classId = if (isSigned) PLATFORM_INT_VAR_OF_ID.toCirEntityId() else PLATFORM_UINT_VAR_OF_ID.toCirEntityId(),
outerType = null,
arguments = SmartList(argument),
isMarkedNullable = false,
)
}
@@ -589,14 +589,14 @@ class HierarchicalOptimisticNumbersTypeCommonizerTest : AbstractInlineSourcesCom
outputTarget("(a, b)")
setting(OptimisticNumberCommonizationEnabledKey, true)
registerFakeStdlibIntegersDependency("(a, b)")
simpleSingleSourceTarget("a", "typealias X = kotlinx.cinterop.UIntVarOf")
simpleSingleSourceTarget("b", "typealias X = kotlinx.cinterop.ULongVarOf")
simpleSingleSourceTarget("a", "typealias X = kotlinx.cinterop.UIntVarOf<UInt>")
simpleSingleSourceTarget("b", "typealias X = kotlinx.cinterop.ULongVarOf<ULong>")
}
result.assertCommonized(
"(a, b)", """
@UnsafeNumber(["a: kotlinx.cinterop.UIntVarOf", "b: kotlinx.cinterop.ULongVarOf"])
typealias X = kotlinx.cinterop.UIntVarOf
typealias X = kotlinx.cinterop.UIntVarOf<UInt>
""".trimIndent()
)
}
@@ -606,14 +606,14 @@ class HierarchicalOptimisticNumbersTypeCommonizerTest : AbstractInlineSourcesCom
outputTarget("(a, b)")
setting(OptimisticNumberCommonizationEnabledKey, true)
registerFakeStdlibIntegersDependency("(a, b)")
simpleSingleSourceTarget("a", "typealias X = kotlinx.cinterop.IntVarOf")
simpleSingleSourceTarget("b", "typealias X = kotlinx.cinterop.LongVarOf")
simpleSingleSourceTarget("a", "typealias X = kotlinx.cinterop.IntVarOf<Int>")
simpleSingleSourceTarget("b", "typealias X = kotlinx.cinterop.LongVarOf<Long>")
}
result.assertCommonized(
"(a, b)", """
@UnsafeNumber(["a: kotlinx.cinterop.IntVarOf", "b: kotlinx.cinterop.LongVarOf"])
typealias X = kotlinx.cinterop.IntVarOf
typealias X = kotlinx.cinterop.IntVarOf<Int>
""".trimIndent()
)
}
@@ -0,0 +1,416 @@
/*
* Copyright 2010-2022 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.hierarchical
import org.jetbrains.kotlin.commonizer.AbstractInlineSourcesCommonizationTest
import org.jetbrains.kotlin.commonizer.PlatformIntegerCommonizationEnabledKey
import org.jetbrains.kotlin.commonizer.assertCommonized
class HierarchicalPlatformIntegerCommonizationTest : AbstractInlineSourcesCommonizationTest() {
fun `test signed ints`() {
val result = commonize {
outputTarget("(a, b)")
setting(PlatformIntegerCommonizationEnabledKey, true)
registerFakeStdlibIntegersDependency("(a, b)")
"a" withSource """
typealias X = Int
typealias Y = Long
""".trimIndent()
"b" withSource """
typealias X = Long
typealias Y = Int
""".trimIndent()
}
result.assertCommonized(
"(a, b)", """
@UnsafeNumber(["a: kotlin.Int", "b: kotlin.Long"])
typealias X = PlatformInt
@UnsafeNumber(["a: kotlin.Long", "b: kotlin.Int"])
typealias Y = PlatformInt
""".trimIndent()
)
}
fun `test unsigned ints`() {
val result = commonize {
outputTarget("(a, b)")
setting(PlatformIntegerCommonizationEnabledKey, true)
registerFakeStdlibIntegersDependency("(a, b)")
"a" withSource """
typealias X = UInt
typealias Y = ULong
""".trimIndent()
"b" withSource """
typealias X = ULong
typealias Y = UInt
""".trimIndent()
}
result.assertCommonized(
"(a, b)", """
@UnsafeNumber(["a: kotlin.UInt", "b: kotlin.ULong"])
typealias X = PlatformUInt
@UnsafeNumber(["a: kotlin.ULong", "b: kotlin.UInt"])
typealias Y = PlatformUInt
""".trimIndent()
)
}
fun `test signed vars`() {
val result = commonize {
outputTarget("(a, b)")
setting(PlatformIntegerCommonizationEnabledKey, true)
registerFakeStdlibIntegersDependency("(a, b)")
"a" withSource """
import kotlinx.cinterop.*
typealias AX = Int
typealias AY = Long
typealias X = IntVarOf<AX>
typealias Y = LongVarOf<AY>
""".trimIndent()
"b" withSource """
import kotlinx.cinterop.*
typealias AX = Long
typealias AY = Int
typealias X = LongVarOf<AX>
typealias Y = IntVarOf<AY>
""".trimIndent()
}
result.assertCommonized(
"(a, b)", """
import kotlinx.cinterop.*
@UnsafeNumber(["a: kotlin.Int", "b: kotlin.Long"])
typealias AX = PlatformInt
@UnsafeNumber(["a: kotlin.Long", "b: kotlin.Int"])
typealias AY = PlatformInt
@UnsafeNumber(["a: kotlinx.cinterop.IntVarOf", "b: kotlinx.cinterop.LongVarOf"])
typealias X = PlatformIntVarOf<AX>
@UnsafeNumber(["a: kotlinx.cinterop.LongVarOf", "b: kotlinx.cinterop.IntVarOf"])
typealias Y = PlatformIntVarOf<AY>
""".trimIndent()
)
}
fun `test unsigned vars`() {
val result = commonize {
outputTarget("(a, b)")
setting(PlatformIntegerCommonizationEnabledKey, true)
registerFakeStdlibIntegersDependency("(a, b)")
"a" withSource """
import kotlinx.cinterop.*
typealias AX = UInt
typealias AY = ULong
typealias X = UIntVarOf<AX>
typealias Y = ULongVarOf<AY>
""".trimIndent()
"b" withSource """
import kotlinx.cinterop.*
typealias AX = ULong
typealias AY = UInt
typealias X = ULongVarOf<AX>
typealias Y = UIntVarOf<AY>
""".trimIndent()
}
result.assertCommonized(
"(a, b)", """
import kotlinx.cinterop.*
@UnsafeNumber(["a: kotlin.UInt", "b: kotlin.ULong"])
typealias AX = PlatformUInt
@UnsafeNumber(["a: kotlin.ULong", "b: kotlin.UInt"])
typealias AY = PlatformUInt
@UnsafeNumber(["a: kotlinx.cinterop.UIntVarOf", "b: kotlinx.cinterop.ULongVarOf"])
typealias X = PlatformUIntVarOf<AX>
@UnsafeNumber(["a: kotlinx.cinterop.ULongVarOf", "b: kotlinx.cinterop.UIntVarOf"])
typealias Y = PlatformUIntVarOf<AY>
""".trimIndent()
)
}
fun `test signed arrays`() {
val result = commonize {
outputTarget("(a, b)")
setting(PlatformIntegerCommonizationEnabledKey, true)
registerFakeStdlibIntegersDependency("(a, b)")
"a" withSource """
typealias X = IntArray
typealias Y = LongArray
""".trimIndent()
"b" withSource """
typealias X = LongArray
typealias Y = IntArray
""".trimIndent()
}
result.assertCommonized(
"(a, b)", """
import kotlinx.cinterop.*
typealias X = PlatformIntArray
typealias Y = PlatformIntArray
""".trimIndent()
)
}
fun `test unsigned arrays`() {
val result = commonize {
outputTarget("(a, b)")
setting(PlatformIntegerCommonizationEnabledKey, true)
registerFakeStdlibIntegersDependency("(a, b)")
"a" withSource """
typealias X = UIntArray
typealias Y = ULongArray
""".trimIndent()
"b" withSource """
typealias X = ULongArray
typealias Y = UIntArray
""".trimIndent()
}
result.assertCommonized(
"(a, b)", """
import kotlinx.cinterop.*
typealias X = PlatformUIntArray
typealias Y = PlatformUIntArray
""".trimIndent()
)
}
fun `test signed ranges`() {
val result = commonize {
outputTarget("(a, b)")
setting(PlatformIntegerCommonizationEnabledKey, true)
registerFakeStdlibIntegersDependency("(a, b)")
"a" withSource """
import kotlin.ranges.*
typealias X = IntRange
typealias Y = LongRange
""".trimIndent()
"b" withSource """
typealias X = LongRange
typealias Y = IntRange
""".trimIndent()
}
result.assertCommonized(
"(a, b)", """
import kotlin.ranges.*
typealias X = PlatformIntRange
typealias Y = PlatformIntRange
""".trimIndent()
)
}
fun `test unsigned ranges`() {
val result = commonize {
outputTarget("(a, b)")
setting(PlatformIntegerCommonizationEnabledKey, true)
registerFakeStdlibIntegersDependency("(a, b)")
"a" withSource """
import kotlin.ranges.*
typealias X = UIntRange
typealias Y = ULongRange
""".trimIndent()
"b" withSource """
typealias X = ULongRange
typealias Y = UIntRange
""".trimIndent()
}
result.assertCommonized(
"(a, b)", """
import kotlin.ranges.*
typealias X = PlatformUIntRange
typealias Y = PlatformUIntRange
""".trimIndent()
)
}
fun `test signed progressions`() {
val result = commonize {
outputTarget("(a, b)")
setting(PlatformIntegerCommonizationEnabledKey, true)
registerFakeStdlibIntegersDependency("(a, b)")
"a" withSource """
import kotlin.ranges.*
typealias X = IntProgression
typealias Y = LongProgression
""".trimIndent()
"b" withSource """
typealias X = LongProgression
typealias Y = IntProgression
""".trimIndent()
}
result.assertCommonized(
"(a, b)", """
import kotlin.ranges.*
typealias X = PlatformIntProgression
typealias Y = PlatformIntProgression
""".trimIndent()
)
}
fun `test unsigned progressions`() {
val result = commonize {
outputTarget("(a, b)")
setting(PlatformIntegerCommonizationEnabledKey, true)
registerFakeStdlibIntegersDependency("(a, b)")
"a" withSource """
import kotlin.ranges.*
typealias X = UIntProgression
typealias Y = ULongProgression
""".trimIndent()
"b" withSource """
typealias X = ULongProgression
typealias Y = UIntProgression
""".trimIndent()
}
result.assertCommonized(
"(a, b)", """
import kotlin.ranges.*
typealias X = PlatformUIntProgression
typealias Y = PlatformUIntProgression
""".trimIndent()
)
}
fun `test platform types in return positions`() {
val result = commonize {
outputTarget("(a, b)")
setting(PlatformIntegerCommonizationEnabledKey, true)
registerFakeStdlibIntegersDependency("(a, b)")
"a" withSource """
import kotlin.ranges.*
import kotlinx.cinterop.*
class C {
val i: Int = null!!
fun v(): IntVarOf<Int> = null!!
fun r(): IntRange = null!!
}
val a: IntArray = null!!
fun p(): IntProgression = null!!
""".trimIndent()
"b" withSource """
import kotlin.ranges.*
import kotlinx.cinterop.*
class C {
val i: Long = null!!
fun v(): LongVarOf<Long> = null!!
fun r(): LongRange = null!!
}
val a: LongArray = null!!
fun p(): LongProgression = null!!
""".trimIndent()
}
result.assertCommonized(
"(a, b)", """
import kotlin.ranges.*
import kotlinx.cinterop.*
expect class C() {
val i: PlatformInt
fun v(): PlatformIntVarOf<PlatformInt>
fun r(): PlatformIntRange
}
expect val a: PlatformIntArray
expect fun p(): PlatformIntProgression
""".trimIndent()
)
}
fun `test platform types in signatures`() {
val result = commonize {
outputTarget("(a, b)")
setting(PlatformIntegerCommonizationEnabledKey, true)
registerFakeStdlibIntegersDependency("(a, b)")
"a" withSource """
import kotlin.ranges.*
import kotlinx.cinterop.*
class C {
fun i(arg: Int) {}
fun v(arg: IntVarOf<Int>) {}
fun r(arg: IntRange) {}
}
fun a(arg: IntArray) {}
fun p(arg: IntProgression) {}
""".trimIndent()
"b" withSource """
import kotlin.ranges.*
import kotlinx.cinterop.*
class C {
fun i(arg: Long) {}
fun v(arg: LongVarOf<Long>) {}
fun r(arg: LongRange) {}
}
fun a(arg: LongArray) {}
fun p(arg: LongProgression) {}
""".trimIndent()
}
result.assertCommonized(
"(a, b)", """
import kotlin.ranges.*
import kotlinx.cinterop.*
expect class C() {
}
""".trimIndent()
)
}
}
@@ -17,6 +17,8 @@ internal fun AbstractInlineSourcesCommonizationTest.ParametersBuilder.registerFa
unsingedVarIntegers()
singedVarIntegers()
unsafeNumberAnnotationSource()
ranges()
platformIntegers()
}
}
@@ -24,10 +26,16 @@ internal fun InlineSourceBuilder.ModuleBuilder.unsignedIntegers() {
source(
"""
package kotlin
class UByte
class UShort
class UInt
class ULong
class UByte : Comparable<UByte> { override fun compareTo(other: UByte): Int = null!! }
class UShort : Comparable<UShort> { override fun compareTo(other: UShort): Int = null!! }
class UInt : Comparable<UInt> { override fun compareTo(other: UInt): Int = null!! }
class ULong : Comparable<ULong> { override fun compareTo(other: ULong): Int = null!! }
class UByteArray
class UShortArray
class UIntArray
class ULongArray
""".trimIndent(), "unsigned.kt"
)
}
@@ -36,10 +44,10 @@ private fun InlineSourceBuilder.ModuleBuilder.unsingedVarIntegers() {
source(
"""
package kotlinx.cinterop
class UByteVarOf
class UShortVarOf
class UIntVarOf
class ULongVarOf
class UByteVarOf<T : UByte>
class UShortVarOf<T : UShort>
class UIntVarOf<T : UInt>
class ULongVarOf<T : ULong>
""".trimIndent(), "UnsignedVarOf.kt"
)
}
@@ -48,10 +56,10 @@ private fun InlineSourceBuilder.ModuleBuilder.singedVarIntegers() {
source(
"""
package kotlinx.cinterop
class ByteVarOf
class ShortVarOf
class IntVarOf
class LongVarOf
class ByteVarOf<T : Byte>
class ShortVarOf<T : Short>
class IntVarOf<T : Int>
class LongVarOf<T : Long>
""".trimIndent(), "SignedVarOf.kt"
)
}
@@ -74,3 +82,61 @@ internal fun InlineSourceBuilder.ModuleBuilder.unsafeNumberAnnotationSource() {
"UnsafeNumberTypeAlias.kt"
)
}
internal fun InlineSourceBuilder.ModuleBuilder.ranges() {
source(
"""
package kotlin.ranges
interface ClosedRange<T : Comparable<T>>
open class IntProgression
open class UIntProgression
open class LongProgression
open class ULongProgression
class IntRange : IntProgression(), ClosedRange<Int>
class UIntRange : UIntProgression(), ClosedRange<UInt>
class LongRange : LongProgression(), ClosedRange<Long>
class ULongRange : ULongProgression(), ClosedRange<ULong>
""".trimIndent(),
"Ranges.kt"
)
}
private fun InlineSourceBuilder.ModuleBuilder.platformIntegers() {
source(
"""
package kotlin
expect class PlatformInt : Number, Comparable<PlatformInt>
expect class PlatformUInt : Comparable<PlatformUInt>
expect class PlatformIntArray
expect class PlatformUIntArray
""".trimIndent(),
"PlatformInts.kt"
)
source(
"""
package kotlinx.cinterop
abstract class CVariable
expect class PlatformIntVarOf<T : PlatformInt> : CVariable
expect class PlatformUIntVarOf<T : PlatformUInt> : CVariable
""".trimIndent(),
"PlatformVars.kt"
)
source(
"""
package kotlin.ranges
expect open class PlatformIntProgression
expect open class PlatformUIntProgression
expect class PlatformIntRange : PlatformIntProgression, ClosedRange<PlatformInt>
expect class PlatformUIntRange : PlatformUIntProgression, ClosedRange<PlatformUInt>
""".trimIndent()
)
}
@@ -0,0 +1,76 @@
/*
* 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.descriptors.konan
import org.jetbrains.kotlin.name.ClassId
val KOTLIN_INT_ID = ClassId.fromString("kotlin/Int")
val KOTLIN_LONG_ID = ClassId.fromString("kotlin/Long")
val KOTLIN_UINT_ID = ClassId.fromString("kotlin/UInt")
val KOTLIN_ULONG_ID = ClassId.fromString("kotlin/ULong")
val INT_VAR_OF_ID = ClassId.fromString("kotlinx/cinterop/IntVarOf")
val LONG_VAR_OF_ID = ClassId.fromString("kotlinx/cinterop/LongVarOf")
val UINT_VAR_OF_ID = ClassId.fromString("kotlinx/cinterop/UIntVarOf")
val ULONG_VAR_OF_ID = ClassId.fromString("kotlinx/cinterop/ULongVarOf")
val INT_ARRAY_ID = ClassId.fromString("kotlin/IntArray")
val LONG_ARRAY_ID = ClassId.fromString("kotlin/LongArray")
val UINT_ARRAY_ID = ClassId.fromString("kotlin/UIntArray")
val ULONG_ARRAY_ID = ClassId.fromString("kotlin/ULongArray")
val INT_RANGE_ID = ClassId.fromString("kotlin/ranges/IntRange")
val LONG_RANGE_ID = ClassId.fromString("kotlin/ranges/LongRange")
val UINT_RANGE_ID = ClassId.fromString("kotlin/ranges/UIntRange")
val ULONG_RANGE_ID = ClassId.fromString("kotlin/ranges/ULongRange")
val INT_PROGRESSION_ID = ClassId.fromString("kotlin/ranges/IntProgression")
val LONG_PROGRESSION_ID = ClassId.fromString("kotlin/ranges/LongProgression")
val UINT_PROGRESSION = ClassId.fromString("kotlin/ranges/UIntProgression")
val ULONG_PROGRESSION = ClassId.fromString("kotlin/ranges/ULongProgression")
val PLATFORM_INT_ID = ClassId.fromString("kotlin/PlatformInt")
val PLATFORM_UINT_ID = ClassId.fromString("kotlin/PlatformUInt")
val PLATFORM_INT_VAR_OF_ID = ClassId.fromString("kotlinx/cinterop/PlatformIntVarOf")
val PLATFORM_UINT_VAR_OF_ID = ClassId.fromString("kotlinx/cinterop/PlatformUIntVarOf")
val PLATFORM_INT_ARRAY_ID = ClassId.fromString("kotlin/PlatformIntArray")
val PLATFORM_UINT_ARRAY_ID = ClassId.fromString("kotlin/PlatformUIntArray")
val PLATFORM_INT_RANGE_ID = ClassId.fromString("kotlin/ranges/PlatformIntRange")
val PLATFORM_UINT_RANGE_ID = ClassId.fromString("kotlin/ranges/PlatformUIntRange")
val PLATFORM_INT_PROGRESSION_ID = ClassId.fromString("kotlin/ranges/PlatformIntProgression")
val PLATFORM_UINT_PROGRESSION_ID = ClassId.fromString("kotlin/ranges/PlatformUIntProgression")
val PLATFORM_INTEGERS: Set<ClassId> = setOf(
PLATFORM_INT_ID, PLATFORM_UINT_ID
)
val PLATFORM_VARIABLES: Set<ClassId> = setOf(
PLATFORM_INT_VAR_OF_ID, PLATFORM_UINT_VAR_OF_ID
)
val PLATFORM_ARRAYS: Set<ClassId> = setOf(
PLATFORM_INT_ARRAY_ID, PLATFORM_UINT_ARRAY_ID
)
val PLATFORM_RANGES: Set<ClassId> = setOf(
PLATFORM_INT_RANGE_ID, PLATFORM_UINT_RANGE_ID
)
val PLATFORM_PROGRESSIONS: Set<ClassId> = setOf(
PLATFORM_INT_PROGRESSION_ID, PLATFORM_UINT_PROGRESSION_ID
)
val PLATFORM_TYPES: Set<ClassId> =
PLATFORM_INTEGERS + PLATFORM_VARIABLES + PLATFORM_ARRAYS + PLATFORM_RANGES + PLATFORM_PROGRESSIONS