Java 8 is really old and unsupported on macOS ARM64.
This commit bumps remaining Java 8 usages to Java 11. Source/target compatibility is still Java 8.
This commit changes dispatching logic to a much simpler one that does not require usage of intrinsics.
In order to synchronously get an instance of `bindJob`, we start the `unbindJob` coroutine undispatched (`bindJob` is a child of `unbindJob`, so we need an instance of `unbindJob` to create an instance of `bindJob`).
After saving `bindJob`, we properly dispatch in a cancellable way by simply `launch`ing a new coroutine.
`Worker.asRibCoroutineWorker` and `RibCoroutineWorker.asWorker` converters now return the instance unchanged if the class already implements the target interface.
This is important for correctness. For example:
```
class DualWorker : Worker, RibCoroutineWorker {
fun onStart(lifecycle: WorkerScopeProvider) {
doX()
}
suspend fun onStart(scope: CoroutineScope) {
doY()
}
}
```
Binding this `worker.asWorker()` should call `doX()`, not `doY()`, and binding this `worker.asRibCoroutineWorker()` should call `doY()`, not `doX()`.
This fixes Rx subscriptions using `autoDispose(CoroutineScope)` immediately terminating.
In order to properly support `autoDispose(CoroutineScope)` subscriptions, we must keep the `CoroutineScope` received in `onStart` alive as long as the `WorkerScopeProvider` lifecycle.
`autoDispose` does *not* create a children coroutine: instead it installs a completion handler. Hence, outer scope will not have children to wait for completion and will terminate immediately.
We don't need `crossinline` for `testBody`. Usage of cross-inline makes suspend functions non-callable in the test body, which forbids patterns like:
```
test(worker) {
sharedFlow.emit(someValue)
// assert worker processed it
}
```
This helper utility is meant to be used in tests inside `runTest { }` blocks
and should facilitate `RibCoroutineWorker` testing by automatically binding
and unbinding the worker in the scope of the lambda.
```
@Test fun test() = runTest {
test(worker) {
// Worker is bound. Make assertions
}
// Worker is unbound.
}
```
For accessing internal declarations from other modules (e.g. access `rib-base` internals from `rib-test`), we are currently suppressing compiler errors with `@file:Suppress("invisible_reference", "invisible_member")`
A better approach is to:
1. Create an `internal` opt-in annotation.
2. Make the "accessible to friend modules" component `public`
3. Mark the (now public) component with the opt-in annotation.
4. Opt-in to the annotation from `build.gradle`.
Because the new annotation is `internal`, it cannot be normally accessed from external modules. But Gradle can see it if it's part of the source set.
This makes the internal visibility of those friend-modules APIs even stricter, since consumers now cannot just suppress `"invisible_reference"` and `"invisible_member"` to directly access the friend-module API. Plus, we get rid of the hacky suppressions in our codebase.
`RibCoroutineWorker` is already a functional interface; the purpose of this builder is to allow consumers
to create a `RibCoroutineWorker` with `CoroutineScope` in receiver position. E.g.
- Functional interface:
```
RibCoroutineWorker { scope ->
scope.launch { ... }
}
```
- This factory method:
```
RibCoroutineWorker {
launch { ... }
}
```