Skip to content

Commit a56d539

Browse files
cpovirkpablobaxter
authored andcommitted
Update code to prepare for nullness annotations in Guava (Kotlin#3026)
Leverage the fact that `FutureCallback<T>.onSuccess` can only accept `null` when `T` is `null`, to remove the unchecked casts.
1 parent 704841b commit a56d539

File tree

3 files changed

+11
-8
lines changed

3 files changed

+11
-8
lines changed

integration/kotlinx-coroutines-guava/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,6 @@ Integration with Guava [ListenableFuture](https://github.com/google/guava/wiki/L
6262

6363
<!--- INDEX com.google.common.util.concurrent -->
6464

65-
[com.google.common.util.concurrent.ListenableFuture]: https://kotlin.github.io/kotlinx.coroutines/https://google.github.io/guava/releases/28.0-jre/api/docs/com/google/common/util/concurrent/ListenableFuture.html
65+
[com.google.common.util.concurrent.ListenableFuture]: https://kotlin.github.io/kotlinx.coroutines/https://google.github.io/guava/releases/31.0.1-jre/api/docs/com/google/common/util/concurrent/ListenableFuture.html
6666

6767
<!--- END -->

integration/kotlinx-coroutines-guava/build.gradle.kts

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@
22
* Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
33
*/
44

5-
val guavaVersion = "28.0-jre"
5+
val guavaVersion = "31.0.1-jre"
66

77
dependencies {
88
compile("com.google.guava:guava:$guavaVersion")
99
}
1010

11+
java {
12+
targetCompatibility = JavaVersion.VERSION_1_8
13+
sourceCompatibility = JavaVersion.VERSION_1_8
14+
}
15+
1116
externalDocumentationLink(
1217
url = "https://google.github.io/guava/releases/$guavaVersion/api/docs/"
1318
)

integration/kotlinx-coroutines-guava/src/ListenableFuture.kt

+4-6
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,8 @@ public fun <T> ListenableFuture<T>.asDeferred(): Deferred<T> {
135135
// Finally, if this isn't done yet, attach a Listener that will complete the Deferred.
136136
val deferred = CompletableDeferred<T>()
137137
Futures.addCallback(this, object : FutureCallback<T> {
138-
override fun onSuccess(result: T?) {
139-
// Here we work with flexible types, so we unchecked cast to trick the type system
140-
@Suppress("UNCHECKED_CAST")
141-
runCatching { deferred.complete(result as T) }
138+
override fun onSuccess(result: T) {
139+
runCatching { deferred.complete(result) }
142140
.onFailure { handleCoroutineException(EmptyCoroutineContext, it) }
143141
}
144142

@@ -351,7 +349,7 @@ private class JobListenableFuture<T>(private val jobToCancel: Job): ListenableFu
351349
*
352350
* To preserve Coroutine's [CancellationException], this future points to either `T` or [Cancelled].
353351
*/
354-
private val auxFuture = SettableFuture.create<Any>()
352+
private val auxFuture = SettableFuture.create<Any?>()
355353

356354
/**
357355
* `true` if [auxFuture.get][ListenableFuture.get] throws [ExecutionException].
@@ -436,7 +434,7 @@ private class JobListenableFuture<T>(private val jobToCancel: Job): ListenableFu
436434
}
437435

438436
/** See [get()]. */
439-
private fun getInternal(result: Any): T = if (result is Cancelled) {
437+
private fun getInternal(result: Any?): T = if (result is Cancelled) {
440438
throw CancellationException().initCause(result.exception)
441439
} else {
442440
// We know that `auxFuture` can contain either `T` or `Cancelled`.

0 commit comments

Comments
 (0)