Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kotlin 2.1.20 #457

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ jobs:
strategy:
fail-fast: false
matrix:
poko_sample_kotlin_version: [ 2.1.0, ~, 2.1.20-Beta2 ]
poko_sample_kotlin_version: [ 2.1.0, 2.1.10, ~ ]
env:
poko_sample_kotlin_version: ${{ matrix.poko_sample_kotlin_version }}
steps:
Expand Down
2 changes: 1 addition & 1 deletion .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

androidx-compose-runtime = "1.7.7"

kotlin = "2.1.10"
kotlin = "2.1.20-Beta2"
kotlinCompileTesting = "1.6.0"
# https://central.sonatype.com/artifact/dev.zacsweers.kctfork/core/versions:
kotlinCompileTestingFork = "0.7.0"
# https://github.com/google/ksp/releases:
ksp = "2.1.10-1.0.29"
ksp = "2.1.20-Beta2-1.0.29"

[libraries]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,19 @@ import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope
import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.isNullable
import org.jetbrains.kotlin.ir.util.superTypes
import org.jetbrains.kotlin.ir.types.isNullable as isNullableDeprecated
import org.jetbrains.kotlin.ir.types.superTypes as superTypesDeprecated

/**
* Alias for [irCall] from 2.1.0 – 2.1.20.
*
* Remove when support for 2.1.0 & 2.1.1x is dropped.
*/
@OptIn(UnsafeDuringIrConstructionAPI::class)
internal fun IrBuilderWithScope.irCallCompat(
Expand All @@ -20,17 +27,15 @@ internal fun IrBuilderWithScope.irCallCompat(
origin: IrStatementOrigin? = null,
): IrCall {
return try {
// 2.1.0:
// 2.1.20+:
irCall(
callee = callee,
type = type,
valueArgumentsCount = valueArgumentsCount,
typeArgumentsCount = typeArgumentsCount,
origin = origin,
)
} catch (noSuchMethodError: NoSuchMethodError) {
// TODO: Flip order when 2.1.20 is the compile version
// https://github.com/JetBrains/kotlin/blob/v2.1.20-Beta1/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt#L240
// https://github.com/JetBrains/kotlin/blob/v2.1.0/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/builders/ExpressionHelpers.kt#L240
javaClass.classLoader.loadClass("org.jetbrains.kotlin.ir.builders.ExpressionHelpersKt")
.methods
.single { function ->
Expand All @@ -39,6 +44,7 @@ internal fun IrBuilderWithScope.irCallCompat(
IrBuilderWithScope::class.java, // extension receiver
IrSimpleFunctionSymbol::class.java, // callee
IrType::class.java, // type
Int::class.java, // valueArgumentsCount
Int::class.java, // typeArgumentsCount
IrStatementOrigin::class.java, // origin
)
Expand All @@ -48,8 +54,37 @@ internal fun IrBuilderWithScope.irCallCompat(
this, // extension receiver
callee, // param: callee
type, // param: type
typeArgumentsCount, // param: type
valueArgumentsCount, // param: valueArgumentsCount
typeArgumentsCount, // param: typeArgumentsCount
origin, // param: origin
) as IrCall
}
}

/**
* Alias for [isNullable] from 2.1.0 – 2.1.20.
*
* Remove when support for 2.1.0 & 2.1.1x is dropped.
*/
internal fun IrType.isNullableCompat(): Boolean {
return try {
isNullable()
} catch (noSuchMethodError: NoSuchMethodError) {
@Suppress("DEPRECATION")
isNullableDeprecated()
}
}

/**
* Alias for [superTypes] from 2.1.0 – 2.1.20.
*
* Remove when support for 2.1.0 & 2.1.1x is dropped.
*/
internal fun IrClassifierSymbol.superTypesCompat(): List<IrType> {
return try {
superTypes()
} catch (noSuchMethodError: NoSuchMethodError) {
@Suppress("DEPRECATION")
superTypesDeprecated()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.isNullable
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.isArrayOrPrimitiveArray
import org.jetbrains.kotlin.ir.util.render
Expand Down Expand Up @@ -228,7 +227,7 @@ private fun findContentDeepEqualsFunctionSymbol(
// Find the single function with the relevant array type and disambiguate against the
// older non-nullable receiver overload:
functionSymbol.owner.extensionReceiverParameter?.type?.let {
it.classifierOrNull == classifier && it.isNullable()
it.classifierOrNull == classifier && it.isNullableCompat()
} ?: false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.createType
import org.jetbrains.kotlin.ir.types.impl.IrStarProjectionImpl
import org.jetbrains.kotlin.ir.types.superTypes
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.util.isAnnotationClass
import org.jetbrains.kotlin.ir.util.isInterface
Expand Down Expand Up @@ -79,7 +78,7 @@ internal fun IrClassifierSymbol?.mayBeRuntimeArray(
private fun IrTypeParameterSymbol.hasArrayOrPrimitiveArrayUpperBound(
context: IrGeneratorContextInterface,
): Boolean {
superTypes().forEach { superType ->
superTypesCompat().forEach { superType ->
val superTypeClassifier = superType.classifierOrNull
// Note: A generic type cannot have an array as an upper bound, else that would also
// be checked here.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.isInt
import org.jetbrains.kotlin.ir.types.isNullable
import org.jetbrains.kotlin.ir.types.isUInt
import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.ir.util.isArrayOrPrimitiveArray
Expand Down Expand Up @@ -133,7 +132,7 @@ private fun IrBlockBodyBuilder.getHashCodeOfProperty(
val field = property.backingField!!
val irGetField = { irGetField(receiver(function), field) }
return when {
property.type.isNullable() -> irIfNull(
property.type.isNullableCompat() -> irIfNull(
type = context.irBuiltIns.intType,
subject = irGetField(),
thenPart = irInt(0),
Expand Down Expand Up @@ -293,7 +292,7 @@ private fun findArrayContentDeepHashCodeFunction(
).single { functionSymbol ->
// Disambiguate against the older non-nullable receiver overload:
functionSymbol.owner.extensionReceiverParameter?.type?.let {
it.classifierOrNull == propertyClassifier && it.isNullable()
it.classifierOrNull == propertyClassifier && it.isNullableCompat()
} ?: false
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.isNullable
import org.jetbrains.kotlin.ir.util.isArrayOrPrimitiveArray
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.name.CallableId
Expand Down Expand Up @@ -201,7 +200,7 @@ private fun findContentDeepToStringFunctionSymbol(
// Find the single function with the relevant array type and disambiguate against the
// older non-nullable receiver overload:
functionSymbol.owner.extensionReceiverParameter?.type?.let {
it.classifierOrNull == propertyClassifier && it.isNullable()
it.classifierOrNull == propertyClassifier && it.isNullableCompat()
} ?: false
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import org.junit.runner.RunWith
@OptIn(ExperimentalCompilerApi::class)
@RunWith(TestParameterInjector::class)
class PokoCompilerPluginTest(
@TestParameter private val compilationMode: CompilationMode,
@param:TestParameter private val compilationMode: CompilationMode,
) {

@JvmField
Expand Down Expand Up @@ -313,6 +313,7 @@ class PokoCompilerPluginTest(
value.toString()
)

@Suppress("DEPRECATION") // Safe as long as we don't write new files at runtime
private fun SourceFile.Companion.fromPath(path: String): SourceFile = fromPath(File(path))

@Suppress("unused") // Test parameter values
Expand Down
21 changes: 15 additions & 6 deletions poko-tests/performance/src/test/kotlin/JsPerformanceTest.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
import assertk.all

import assertk.assertAll
import assertk.assertThat
import assertk.assertions.contains
import assertk.assertions.doesNotContain
import assertk.assertions.hasSize
import assertk.assertions.isEmpty
import org.junit.Test

class JsPerformanceTest {
@Test fun `equals does not perform redundant instanceof check`() {
val javascript = jsOutput().readText()
assertThat(javascript).all {
contains("other instanceof IntAndLong")
doesNotContain("THROW_CCE")

// Hack to filter out data classes, which do have the `THROW_CCE` code:
val intAndLongLines = javascript.split("\n").filter { it.contains("IntAndLong") }
assertAll {
assertThat(
actual = intAndLongLines.filter { it.contains("other instanceof IntAndLong") },
).hasSize(1)

assertThat(
actual = intAndLongLines.filter { it.contains("THROW_CCE") },
).isEmpty()
Comment on lines +12 to +21
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Less hacky workaround ideas welcome!

}
}
}