ronantakizawa/codereview-bench huggingface dataset:
Repository: ktorio/ktor
File: ktor-network/ktor-network-tls/jvm/src/io/ktor/network/tls/CipherSuitesJvm.kt (Kotlin)

Code before:
/*
 * Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.network.tls

import io.ktor.network.tls.platform.*

internal actual fun CipherSuite.isSupported(): Boolean = when (platformVersion.major) {
    "1.8.0" -> platformVersion.minor >= 161 || keyStrength <= 128
    "1.7.0" -> platformVersion.minor >= 171 || keyStrength <= 128
    "1.6.0" -> platformVersion.minor >= 181 || keyStrength <= 128
    else -> true
}

public actual typealias TLSException = javax.net.ssl.SSLException
public actual typealias TLSPeerUnverifiedException = javax.net.ssl.SSLPeerUnverifiedException


Review comment (suggestion):
This is a source-compatible, but binary-incompatible change for JVM. `TLSException` has been made public in 3.0.0-beta2, so it shouldn't be extensively used yet, but I can make this change binary compatible by introducing a new class `TlsException` and deprecating the old one:

```kotlin
public actual typealias = TlsException = javax.net.ssl.SSLException

@Deprecated("Use TlsException instead")
class TLSException(message: String, cause: Throwable?) : TlsException(message, cause)
```

As a bonus, this solution lets us fix capitalization in the exception name.

Code after:
/*
 * Copyright 2014-2025 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.network.tls

import io.ktor.network.tls.platform.*

internal actual fun CipherSuite.isSupported(): Boolean = when (platformVersion.major) {
    "1.8.0" -> platformVersion.minor >= 161 || keyStrength <= 128
    "1.7.0" -> platformVersion.minor >= 171 || keyStrength <= 128
    "1.6.0" -> platformVersion.minor >= 181 || keyStrength <= 128
    else -> true
}

public actual typealias TlsException = javax.net.ssl.SSLException
public actual typealias TlsPeerUnverifiedException = javax.net.ssl.SSLPeerUnverifiedException
Repository: ktorio/ktor
File: ktor-io/jvm/src/io/ktor/utils/io/JvmSerializable.jvm.kt (Kotlin)

Code before:
/*
 * Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.utils.io

import java.io.*

public actual typealias JvmSerializable = Serializable

@Suppress("UNCHECKED_CAST")
public actual fun <T : Any> JvmSerializerReplacement(serializer: JvmSerializer<T>, value: T): Any =
    DefaultJvmSerializerReplacement(serializer, value)

@PublishedApi // IMPORTANT: changing the class name would result in serialization incompatibility
internal class DefaultJvmSerializerReplacement<T : Any>(
    private var serializer: JvmSerializer<T>?,
    private var value: T?
) : Externalizable {
    constructor() : this(null, null)

    override fun writeExternal(out: ObjectOutput) {
        out.writeObject(serializer)
        out.writeObject(serializer!!.jvmSerialize(value!!))
    }

    @Suppress("UNCHECKED_CAST")
    override fun readExternal(`in`: ObjectInput) {
        serializer = `in`.readObject() as JvmSerializer<T>
        value = serializer!!.jvmDeserialize(`in`.readObject() as ByteArray)
    }

    private fun readResolve(): Any =
        value!!

    companion object {
        private const val serialVersionUID: Long = 0L
    }
}


Review comment (suggestion):
Should such an API better be integrated as part of the Kotlin stdlib itself or at least in a separate library for reuse in other projects? It could also be useful in kotlinx-datetime: https://github.com/Kotlin/kotlinx-datetime/pull/373
And I'll also add the same code to my open-source lib, too (https://github.com/ensody/ReactiveState-Kotlin).
That's unnecessary duplication in multiple places.

Code after:
/*
 * Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.utils.io

import java.io.*

@InternalAPI
public actual typealias JvmSerializable = Serializable

@Suppress("UNCHECKED_CAST")
@InternalAPI
public actual fun <T : Any> JvmSerializerReplacement(serializer: JvmSerializer<T>, value: T): Any =
    DefaultJvmSerializerReplacement(serializer, value)

@OptIn(InternalAPI::class)
@PublishedApi // IMPORTANT: changing the class name would result in serialization incompatibility
internal class DefaultJvmSerializerReplacement<T : Any>(
    private var serializer: JvmSerializer<T>?,
    private var value: T?
) : Externalizable {
    constructor() : this(null, null)

    override fun writeExternal(out: ObjectOutput) {
        out.writeObject(serializer)
        out.writeObject(serializer!!.jvmSerialize(value!!))
    }

    @Suppress("UNCHECKED_CAST")
    override fun readExternal(`in`: ObjectInput) {
        serializer = `in`.readObject() as JvmSerializer<T>
        value = serializer!!.jvmDeserialize(`in`.readObject() as ByteArray)
    }

    private fun readResolve(): Any =
        value!!

    companion object {
        private const val serialVersionUID: Long = 0L
    }
}
Repository: ktorio/ktor
File: ktor-http/common/src/io/ktor/http/Url.kt (Kotlin)

Code before:
            append(host)
        } else {
            append(hostWithPort)
        }
    }

internal val Url.encodedUserAndPassword: String
    get() = buildString {
        appendUserAndPassword(encodedUser, encodedPassword)
    }

public class UrlSerializer : KSerializer<Url> {
    override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Url", PrimitiveKind.STRING)

    override fun deserialize(decoder: Decoder): Url =
        Url(decoder.decodeString())

    override fun serialize(encoder: Encoder, value: Url) {
        encoder.encodeString(value.toString())
    }
}

internal object UrlJvmSerializer : JvmSerializer<Url> {
    override fun jvmSerialize(value: Url): ByteArray =
        value.toString().encodeToByteArray()

    override fun jvmDeserialize(value: ByteArray): Url =
        Url(value.decodeToString())
}


Review comment (refactor):
Just an idea: To make this slightly easier to implement one could also add a reusable serializer which utilizes kotlinx-serialization (e.g. using JSON or BSON or CBOR internally).

Code after:

        if (specifiedPort == DEFAULT_PORT || specifiedPort == protocol.defaultPort) {
            append(host)
        } else {
            append(hostWithPort)
        }
    }

internal val Url.encodedUserAndPassword: String
    get() = buildString {
        appendUserAndPassword(encodedUser, encodedPassword)
    }

public object UrlSerializer : KSerializer<Url> {
    override val descriptor: SerialDescriptor =
        PrimitiveSerialDescriptor("io.ktor.http.Url", PrimitiveKind.STRING)

    override fun deserialize(decoder: Decoder): Url =
        Url(decoder.decodeString())

    override fun serialize(encoder: Encoder, value: Url) {
        encoder.encodeString(value.toString())
    }
}

internal object UrlJvmSerializer : JvmSerializer<Url> {
    override fun jvmSerialize(value: Url): ByteArray =
        value.toString().encodeToByteArray()

    override fun jvmDeserialize(value: ByteArray): Url =
        Url(value.decodeToString())
}
Repository: ktorio/ktor
File: ktor-http/common/src/io/ktor/http/Url.kt (Kotlin)

Code before:
        append(hostWithPortIfSpecified)
    }

/**
 * A [Url] protocol and authority.
 */
public val Url.protocolWithAuthority: String
    get() = buildString {
        append(protocol.name)
        append("://")
        append(encodedUserAndPassword)

        if (specifiedPort == DEFAULT_PORT || specifiedPort == protocol.defaultPort) {
            append(host)
        } else {
            append(hostWithPort)
        }
    }

internal val Url.encodedUserAndPassword: String
    get() = buildString {
        appendUserAndPassword(encodedUser, encodedPassword)
    }

public class UrlSerializer : KSerializer<Url> {
    override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Url", PrimitiveKind.STRING)

    override fun deserialize(decoder: Decoder): Url =
        Url(decoder.decodeString())

    override fun serialize(encoder: Encoder, value: Url) {
        encoder.encodeString(value.toString())
    }
}

internal object UrlJvmSerializer : JvmSerializer<Url> {
    override fun jvmSerialize(value: Url): ByteArray =
        value.toString().encodeToByteArray()

    override fun jvmDeserialize(value: ByteArray): Url =
        Url(value.decodeToString())
}


Review comment (suggestion):
Let's use a qualified name
```suggestion
    override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("io.ktor.http.Url", PrimitiveKind.STRING)
```

Code after:
    get() = buildString {
        append(encodedUserAndPassword)
        append(hostWithPortIfSpecified)
    }

/**
 * A [Url] protocol and authority.
 */
public val Url.protocolWithAuthority: String
    get() = buildString {
        append(protocol.name)
        append("://")
        append(encodedUserAndPassword)

        if (specifiedPort == DEFAULT_PORT || specifiedPort == protocol.defaultPort) {
            append(host)
        } else {
            append(hostWithPort)
        }
    }

internal val Url.encodedUserAndPassword: String
    get() = buildString {
        appendUserAndPassword(encodedUser, encodedPassword)
    }

public object UrlSerializer : KSerializer<Url> {
    override val descriptor: SerialDescriptor =
        PrimitiveSerialDescriptor("io.ktor.http.Url", PrimitiveKind.STRING)

    override fun deserialize(decoder: Decoder): Url =
        Url(decoder.decodeString())

    override fun serialize(encoder: Encoder, value: Url) {
        encoder.encodeString(value.toString())
    }
}

internal object UrlJvmSerializer : JvmSerializer<Url> {
    override fun jvmSerialize(value: Url): ByteArray =
        value.toString().encodeToByteArray()

    override fun jvmDeserialize(value: ByteArray): Url =
        Url(value.decodeToString())
}
Repository: ktorio/ktor
File: ktor-shared/ktor-junit/jvm/src/io/ktor/junit/Assertions.kt (Kotlin)

Code before:
        collection.map { item ->
            {
                org.junit.jupiter.api.Assertions.assertTrue(predicate(item), message)
            }
        }
    )
}

/**
 * Convenience function for asserting on all elements of a collection.
 */
fun <T> assertAll(collection: Iterable<T>, assertion: (T) -> Unit) {
    org.junit.jupiter.api.assertAll(
        collection.map { item ->
            {
                assertion(item)
            }
        }
    )
}

inline fun <reified T : Any> assertSerializable(obj: T): T {
    val encoded = ByteArrayOutputStream().also {
        ObjectOutputStream(it).writeObject(obj)
    }.toByteArray()
    return ObjectInputStream(encoded.inputStream()).readObject() as T
}


Review comment (suggestion):
Should the `assertEquals` call be right here?
```suggestion
    val decoded = ObjectInputStream(encoded.inputStream()).readObject() as T
    assertEquals(obj, decoded)
    return decoded
```


Code after:
    org.junit.jupiter.api.assertAll(
        collection.map { item ->
            {
                org.junit.jupiter.api.Assertions.assertTrue(predicate(item), message)
            }
        }
    )
}

/**
 * Convenience function for asserting on all elements of a collection.
 */
fun <T> assertAll(collection: Iterable<T>, assertion: (T) -> Unit) {
    org.junit.jupiter.api.assertAll(
        collection.map { item ->
            {
                assertion(item)
            }
        }
    )
}

inline fun <reified T : Any> assertSerializable(obj: T, checkEquality: Boolean = true): T {
    val encoded = ByteArrayOutputStream().also {
        ObjectOutputStream(it).writeObject(obj)
    }.toByteArray()
    val decoded = ObjectInputStream(encoded.inputStream()).readObject() as T
    if (checkEquality) {
        assertEquals(obj, decoded, "deserialized object must be equal to original object")
    }
    return decoded
}
Repository: ktorio/ktor
File: ktor-http/common/src/io/ktor/http/Url.kt (Kotlin)

Code before:
        append(encodedUserAndPassword)
        append(hostWithPortIfSpecified)
    }

/**
 * A [Url] protocol and authority.
 */
public val Url.protocolWithAuthority: String
    get() = buildString {
        append(protocol.name)
        append("://")
        append(encodedUserAndPassword)

        if (specifiedPort == DEFAULT_PORT || specifiedPort == protocol.defaultPort) {
            append(host)
        } else {
            append(hostWithPort)
        }
    }

internal val Url.encodedUserAndPassword: String
    get() = buildString {
        appendUserAndPassword(encodedUser, encodedPassword)
    }

public class UrlSerializer : KSerializer<Url> {
    override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Url", PrimitiveKind.STRING)

    override fun deserialize(decoder: Decoder): Url =
        Url(decoder.decodeString())

    override fun serialize(encoder: Encoder, value: Url) {
        encoder.encodeString(value.toString())
    }
}

internal object UrlJvmSerializer : JvmSerializer<Url> {
    override fun jvmSerialize(value: Url): ByteArray =
        value.toString().encodeToByteArray()

    override fun jvmDeserialize(value: ByteArray): Url =
        Url(value.decodeToString())
}


Review comment (suggestion):
It could be an object. And probably make it inner object `Url.Serializer`
```suggestion
public object UrlSerializer : KSerializer<Url> {
```

Code after:
public val Url.authority: String
    get() = buildString {
        append(encodedUserAndPassword)
        append(hostWithPortIfSpecified)
    }

/**
 * A [Url] protocol and authority.
 */
public val Url.protocolWithAuthority: String
    get() = buildString {
        append(protocol.name)
        append("://")
        append(encodedUserAndPassword)

        if (specifiedPort == DEFAULT_PORT || specifiedPort == protocol.defaultPort) {
            append(host)
        } else {
            append(hostWithPort)
        }
    }

internal val Url.encodedUserAndPassword: String
    get() = buildString {
        appendUserAndPassword(encodedUser, encodedPassword)
    }

public object UrlSerializer : KSerializer<Url> {
    override val descriptor: SerialDescriptor =
        PrimitiveSerialDescriptor("io.ktor.http.Url", PrimitiveKind.STRING)

    override fun deserialize(decoder: Decoder): Url =
        Url(decoder.decodeString())

    override fun serialize(encoder: Encoder, value: Url) {
        encoder.encodeString(value.toString())
    }
}

internal object UrlJvmSerializer : JvmSerializer<Url> {
    override fun jvmSerialize(value: Url): ByteArray =
        value.toString().encodeToByteArray()

    override fun jvmDeserialize(value: ByteArray): Url =
        Url(value.decodeToString())
}
Repository: ktorio/ktor
File: ktor-client/ktor-client-core/common/src/io/ktor/client/utils/CoroutineUtils.kt (Kotlin)

Code before:
/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

package io.ktor.client.utils

import io.ktor.utils.io.*
import kotlinx.coroutines.*

/**
 * Creates [CoroutineDispatcher] for the client with fixed [threadCount] and specified [dispatcherName].
 */
@InternalAPI
public expect fun Dispatchers.clientDispatcher(
    threadCount: Int,
    dispatcherName: String = "ktor-client-dispatcher"
): CoroutineDispatcher


Review comment (suggestion):
Here we can also use `@param` to describe `threadCount` and `dispatcherName` in the same way it is done in the other KDocs.

Code after:
/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

package io.ktor.client.utils

import io.ktor.utils.io.*
import kotlinx.coroutines.*

/**
 * Creates [CoroutineDispatcher] for the client with fixed [threadCount] and specified [dispatcherName].
 *
 * @param threadCount the number of threads for the new [CoroutineDispatcher].
 * @param dispatcherName the name of the new [CoroutineDispatcher].
 */
@InternalAPI
public expect fun Dispatchers.clientDispatcher(
    threadCount: Int,
    dispatcherName: String = "ktor-client-dispatcher"
): CoroutineDispatcher
Repository: ktorio/ktor
File: ktor-utils/jvm/src/io/ktor/util/reflect/ServiceLoader.kt (Kotlin)

Code before:
/*
 * Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.util.reflect

import io.ktor.utils.io.*
import java.util.*

/**
 * Loads implementations of service [T] using [ServiceLoader.load].
 *
 * NOTE: ServiceLoader should use specific call convention to be optimized by R8 on Android:
 * `ServiceLoader.load(X.class, X.class.getClassLoader()).iterator()`
 * See: https://r8.googlesource.com/r8/+/refs/heads/main/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
 */
@InternalAPI
public inline fun <reified T> loadService(): Iterable<T> = Iterable {
    ServiceLoader.load(
        T::class.java,
        T::class.java.classLoader,
    ).iterator()
}


Review comment (performance):
note: it's better to recheck, that R8 will optimize this pattern with `inline` and `reified` usage. While from the code perspective it should be the same, I'm not confident, that the byte code will be the same.

Code after:
/*
 * Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.util.reflect

import io.ktor.utils.io.*
import java.util.*

// NOTE: ServiceLoader should use specific call convention to be optimized by R8 on Android:
// `ServiceLoader.load(X.class, X.class.getClassLoader()).iterator()`
// See: https://r8.googlesource.com/r8/+/refs/heads/main/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java

/**
 * Loads all implementations of the service [T] using [ServiceLoader.load].
 * @see loadServiceOrNull
 */
@InternalAPI
public inline fun <reified T : Any> loadServices(): List<T> = ServiceLoader.load(
    T::class.java,
    T::class.java.classLoader,
).iterator().asSequence().toList()

/**
 * Loads single implementation of the service [T] using [ServiceLoader.load]
 * returns `null` if there are no any implementations.
 * @see loadServices
 */
@InternalAPI
public inline fun <reified T : Any> loadServiceOrNull(): T? = ServiceLoader.load(
    T::class.java,
    T::class.java.classLoader,
).iterator().asSequence().firstOrNull()
Repository: ktorio/ktor
File: ktor-utils/jvm/src/io/ktor/util/reflect/ServiceLoader.kt (Kotlin)

Code before:
/*
 * Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.util.reflect

import io.ktor.utils.io.*
import java.util.*

/**
 * Loads implementations of service [T] using [ServiceLoader.load].
 *
 * NOTE: ServiceLoader should use specific call convention to be optimized by R8 on Android:
 * `ServiceLoader.load(X.class, X.class.getClassLoader()).iterator()`
 * See: https://r8.googlesource.com/r8/+/refs/heads/main/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java
 */
@InternalAPI
public inline fun <reified T> loadService(): Iterable<T> = Iterable {
    ServiceLoader.load(
        T::class.java,
        T::class.java.classLoader,
    ).iterator()
}


Review comment (suggestion):
I've tried to replace it with the following code, to retrieve iterator only once:
```kotlin
public inline fun <reified T> loadService(): Iterable<T>
    val iterator = ServiceLoader.load(
        T::class.java,
        T::class.java.classLoader,
    ).iterator()
    
    return Iterable { iterator }
}
```

But for some reason this change [breaks serialization tests](https://ktor.teamcity.com/buildConfiguration/Ktor_KtorMatrixCoreLinuxJava21/291227?expandBuildDeploymentsSection=false&hideTestsFromDependencies=false&expandBuildTestsSection=true&hideProblemsFromDependencies=false&expandPull+Request+Details=true&expandBuildChangesSection=true) 🤔 

Code after:
/*
 * Copyright 2014-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
 */

package io.ktor.util.reflect

import io.ktor.utils.io.*
import java.util.*

// NOTE: ServiceLoader should use specific call convention to be optimized by R8 on Android:
// `ServiceLoader.load(X.class, X.class.getClassLoader()).iterator()`
// See: https://r8.googlesource.com/r8/+/refs/heads/main/src/main/java/com/android/tools/r8/ir/optimize/ServiceLoaderRewriter.java

/**
 * Loads all implementations of the service [T] using [ServiceLoader.load].
 * @see loadServiceOrNull
 */
@InternalAPI
public inline fun <reified T : Any> loadServices(): List<T> = ServiceLoader.load(
    T::class.java,
    T::class.java.classLoader,
).iterator().asSequence().toList()

/**
 * Loads single implementation of the service [T] using [ServiceLoader.load]
 * returns `null` if there are no any implementations.
 * @see loadServices
 */
@InternalAPI
public inline fun <reified T : Any> loadServiceOrNull(): T? = ServiceLoader.load(
    T::class.java,
    T::class.java.classLoader,
).iterator().asSequence().firstOrNull()
Repository: ktorio/ktor
File: ktor-client/ktor-client-core/common/src/io/ktor/client/HttpClientConfig.kt (Kotlin)

Code before:
/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

package io.ktor.client

import io.ktor.client.engine.*
import io.ktor.client.plugins.*
import io.ktor.util.*
import io.ktor.utils.io.*

/**
 * A mutable [HttpClient] configuration used to adjust settings, install plugins and interceptors.
 *
 * This class is available as block in [HttpClient] constructor or [HttpClient.config] builder:
 * ```kotlin
 * val client = HttpClient { // HttpClientConfig<Engine>()
 *     // Configure engine settings
 *     engine { // HttpClientEngineConfig
 *         threadsCount = 4
 *         pipelining = true
 *     }
 *
 *     // Install and configure plugins
 *     install(ContentNegotiation) {
 *         json()
 *     }
 *
 *     // Configure default request parameters
 *     defaultRequest {
 *         url("https://api.example.com")
 *         header("X-Custom-Header", "value")
 *     }
 *
 *     // Configure client-wide settings
 *     expectSuccess = true
 *     followRedirects = true
 * }
 * ```
 * ## Configuring [HttpClientEngine]

Review comment (suggestion):
```suggestion
 * This configuration can be provided as a lambda in the [HttpClient] constructor or the [HttpClient.config] builder:
```

Code after:
/*
* Copyright 2014-2021 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/

package io.ktor.client

import io.ktor.client.engine.*
import io.ktor.client.plugins.*
import io.ktor.util.*
import io.ktor.utils.io.*

/**
 * A mutable [HttpClient] configuration used to adjust settings, install plugins and interceptors.
 *
 * This configuration can be provided as a lambda in the [HttpClient] constructor or the [HttpClient.config] builder:
 * ```kotlin
 * val client = HttpClient { // HttpClientConfig<Engine>()
 *     // Configure engine settings
 *     engine { // HttpClientEngineConfig
 *         threadsCount = 4
 *         pipelining = true
 *     }
 *
 *     // Install and configure plugins
 *     install(ContentNegotiation) {
 *         json()
 *     }
 *
 *     // Configure default request parameters
 *     defaultRequest {
 *         url("https://api.example.com")
 *         header("X-Custom-Header", "value")
 *     }
 *
 *     // Configure client-wide settings
 *     expectSuccess = true
 *     followRedirects = true
 * }
 * ```
 * ## Configuring [HttpClientEngine]