diff --git a/arrow-libs/core/arrow-autoclose/build.gradle.kts b/arrow-libs/core/arrow-autoclose/build.gradle.kts index b42aecd9769..d99a1f878bb 100644 --- a/arrow-libs/core/arrow-autoclose/build.gradle.kts +++ b/arrow-libs/core/arrow-autoclose/build.gradle.kts @@ -51,8 +51,3 @@ kotlin { (project.rootProject.properties["kotlin_api_version"] as? String)?.also { apiVersion = KotlinVersion.fromVersion(it) } } } - -// enables context receivers for Jvm Tests -tasks.named("compileTestKotlinJvm") { - compilerOptions.freeCompilerArgs.add("-Xcontext-receivers") -} diff --git a/arrow-libs/core/arrow-autoclose/src/commonMain/kotlin/arrow/AutoCloseScope.kt b/arrow-libs/core/arrow-autoclose/src/commonMain/kotlin/arrow/AutoCloseScope.kt index 834f1b9f2d8..a7e1383571c 100644 --- a/arrow-libs/core/arrow-autoclose/src/commonMain/kotlin/arrow/AutoCloseScope.kt +++ b/arrow-libs/core/arrow-autoclose/src/commonMain/kotlin/arrow/AutoCloseScope.kt @@ -52,11 +52,10 @@ import kotlin.coroutines.cancellation.CancellationException * So both [AutoCloseScope], and `ResourceScope` behave correctly when encountering cancellation, by closing the source, * but `ResourceScope` allows inspecting _complete_, _failure_, **and** _cancellation_ in the finalizer. * - * This DSL works very well with Kotlin's experimental feature context receivers, soon called context parameters. - * We can write the same code from above as a function: + * We can write the same code from above as a function by adding the scope as receiver: + * * ```kotlin - * context(AutoCloseScope) - * fun copyFiles(input: String, output: String) { + * fun AutoCloseScope.copyFiles(input: String, output: String) { * val scanner = install(Scanner(input)) * val printer = install(Printer(output)) * for(line in scanner) { diff --git a/arrow-libs/core/arrow-autoclose/src/jvmTest/kotlin/examples/example-autocloseable-02.kt b/arrow-libs/core/arrow-autoclose/src/jvmTest/kotlin/examples/example-autocloseable-02.kt index fc4d78ef126..8115e8c393f 100644 --- a/arrow-libs/core/arrow-autoclose/src/jvmTest/kotlin/examples/example-autocloseable-02.kt +++ b/arrow-libs/core/arrow-autoclose/src/jvmTest/kotlin/examples/example-autocloseable-02.kt @@ -15,8 +15,7 @@ public class Printer(private val path: String) : AutoCloseable { override fun close(): Unit = Unit } -context(AutoCloseScope) -fun copyFiles(input: String, output: String) { +fun AutoCloseScope.copyFiles(input: String, output: String) { val scanner = install(Scanner(input)) val printer = install(Printer(output)) for(line in scanner) { diff --git a/arrow-libs/core/arrow-cache4k/build.gradle.kts b/arrow-libs/core/arrow-cache4k/build.gradle.kts index fdd073733a0..e83cdc90aa5 100644 --- a/arrow-libs/core/arrow-cache4k/build.gradle.kts +++ b/arrow-libs/core/arrow-cache4k/build.gradle.kts @@ -83,8 +83,3 @@ tasks.named("jvmJar").configure { attributes["Automatic-Module-Name"] = "arrow.cache4k" } } - -// enables context receivers for Jvm Tests -tasks.named("compileTestKotlinJvm") { - compilerOptions.freeCompilerArgs.add("-Xcontext-receivers") -} diff --git a/arrow-libs/core/arrow-core/build.gradle.kts b/arrow-libs/core/arrow-core/build.gradle.kts index c6a5d81ee8f..308d0932623 100644 --- a/arrow-libs/core/arrow-core/build.gradle.kts +++ b/arrow-libs/core/arrow-core/build.gradle.kts @@ -79,11 +79,6 @@ kotlin { } } -// enables context receivers for Jvm Tests -tasks.named("compileTestKotlinJvm") { - compilerOptions.freeCompilerArgs.add("-Xcontext-receivers") -} - tasks.withType().configureEach { useJUnitPlatform() } diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Effect.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Effect.kt index 232f8318627..08cc134a659 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Effect.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Effect.kt @@ -164,17 +164,17 @@ import kotlin.jvm.JvmName * ``` * * - * Adding your own syntax to `Raise` is not advised, yet, but will be easy once "Multiple Receivers" become available. + * Adding your own syntax to `Raise` is not advised, yet, but will be easy once context parameters become available. * * ``` - * context(Raise) + * context(_: Raise) * suspend fun Either.bind(): A = * when (this) { * is Either.Left -> raise(value) * is Either.Right -> value * } * - * context(Raise) + * context(_: Raise) * fun Option.bind(): A = * fold({ raise(it) }, ::identity) * ``` diff --git a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Raise.kt b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Raise.kt index e4285549df9..b97098f26e8 100644 --- a/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Raise.kt +++ b/arrow-libs/core/arrow-core/src/commonMain/kotlin/arrow/core/raise/Raise.kt @@ -169,8 +169,7 @@ public interface Raise { * * data class Config(val mode: Int, val role: String, val serviceType: ServiceType) * - * context(Raise) - * fun readConfig(): Config { + * fun Raise.readConfig(): Config { * val mode = ensureNotNull(readln().toIntOrNull()) { * "Mode should be a valid integer" * } @@ -531,8 +530,7 @@ public inline fun catch(block: () -> A, catch: (t: T) * object ContainsInvalidChars : CountryCodeError * } * - * context(Raise) - * fun countryCode(rawCode: String): CountryCode { + * fun Raise.countryCode(rawCode: String): CountryCode { * ensure(rawCode.length == 2) { CountryCodeError.InvalidLength(rawCode.length) } * ensure(rawCode.any { !it.isLetter() }) { CountryCodeError.ContainsInvalidChars } * return CountryCode(rawCode) @@ -601,8 +599,7 @@ public inline fun Raise.ensure(condition: Boolean, raise: () -> E * object NullValue : NameError * } * - * context(Raise) - * fun fullName(name: String?): FullName { + * fun Raise.fullName(name: String?): FullName { * val nonNullName = ensureNotNull(name) { NameError.NullValue } * return FullName(nonNullName) * } diff --git a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/arrow/core/raise/EffectUsage.kt b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/arrow/core/raise/EffectUsage.kt index d68a1cad54a..82152cbafe8 100644 --- a/arrow-libs/core/arrow-core/src/jvmTest/kotlin/arrow/core/raise/EffectUsage.kt +++ b/arrow-libs/core/arrow-core/src/jvmTest/kotlin/arrow/core/raise/EffectUsage.kt @@ -9,16 +9,13 @@ sealed interface OtherError : MyError { object Actual : OtherError } -context(Raise) - suspend fun subprogram(): Unit = +suspend fun Raise.subprogram(): Unit = println("Hello SubProgram!") -context(Raise) - suspend fun otherprogram(): Unit = +suspend fun Raise.otherprogram(): Unit = println("Hello OtherProgram!") -context(Raise) - suspend fun fail(): MyResponse = +suspend fun Raise.fail(): MyResponse = raise(OtherError.Actual) fun main() = @@ -38,12 +35,10 @@ object EmptyResponse : MyResponse data class ErrorResponse(val error: Throwable) : MyResponse data class BodyResponse(val body: String) : MyResponse -context(Raise) - suspend fun respondWithBody(): BodyResponse = +suspend fun Raise.respondWithBody(): BodyResponse = BodyResponse("Hello Program!") -context(Raise) - suspend fun attemptOrError(): MyResponse = +suspend fun Raise.attemptOrError(): MyResponse = ErrorResponse(RuntimeException("Oh no!")) fun respond(): Effect = diff --git a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessor.kt b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessor.kt index 61fe1b91ce1..cf72783982d 100644 --- a/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessor.kt +++ b/arrow-libs/optics/arrow-optics-ksp-plugin/src/main/kotlin/arrow/optics/plugin/OpticsProcessor.kt @@ -15,6 +15,7 @@ import com.google.devtools.ksp.processing.Resolver import com.google.devtools.ksp.processing.SymbolProcessor import com.google.devtools.ksp.symbol.KSAnnotated import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.google.devtools.ksp.validate class OpticsProcessor( private val codegen: CodeGenerator, @@ -23,15 +24,16 @@ class OpticsProcessor( ) : SymbolProcessor { override fun process(resolver: Resolver): List { - resolver + val (resolved, deferred) = resolver .getSymbolsWithAnnotation("arrow.optics.optics") .filterIsInstance() - .forEach(::processClass) + .partition { it.validate() } + resolved.forEach(::processClass) - // the docs say that [process] should return - // "deferred symbols that the processor can't process" - // and in theory we have none - return emptyList() + // If types used by the annotated class are by other processors, + // such class will fail the validation. In that case, we need to + // defer the code generation for the class to the next round + return deferred } private fun processClass(klass: KSClassDeclaration) { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 06ad2b968e1..bb0c58ffafa 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,16 +1,16 @@ [versions] -animalSniffer = "1.7.1" +animalSniffer = "1.7.2" arrowGradleConfig = "0.12.0-rc.24" coroutines = "1.9.0" classgraph = "4.8.179" dokka = "1.9.20" kotest = "6.0.0.M1" kover = "0.8.3" -kotlin = "2.1.0-RC" +kotlin = "2.1.0-RC2" kotlinBinaryCompatibilityValidator = "0.16.3" kotlinCompileTesting = "0.6.0" knit = "0.5.0" -kspVersion = "2.1.0-RC-1.0.27" +kspVersion = "2.1.0-RC2-1.0.28" kotlinxSerialization = "1.7.3" mockWebServer = "4.12.0" retrofit = "2.11.0" diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 94113f200e6..e2847c82004 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.11-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME