[jnigen] Convert Kotlin's `suspend fun` to Dart's async methods (https://github.com/dart-lang/jnigen/issues/171)

Added a boolean option to jnigen.yaml called `suspend_fun_to_async`. When `true`, Kotlin suspendable functions, specified by `suspend fun`, will be converted into Dart async methods. 

A Kotlin suspendable function gets de-sugared into a continutation-passing style (CPS) method which takes a `kotlin.coroutines.Continuation` as its final argument. 

At the preprocessing stage – if the `suspend_fun_to_async` option is set – the `asyncReturnType` of each method that has `kotlin.coroutines.Continuation` as its final argument will be set so that later in the binding generation step, the return type of the method gets converted to `Future<{asyncReturnType}>`.

The generated bindings instead passes a special `PortContinuation` instance which is defined by `package:jni`. This class implements `Continuation` and gets a native send port address in its constructor. Later, when the `suspend fun` wants to resume, the `resumeWith` method of the `PortContinuation` instance gets called, which in turn calls the `_resumeWith` native method defined in `dartjni.c`. This method send the address of the object to through the send port specified.

All the boilerplate regarding the creation of `NativePort`, `PortContinuation`, awaiting responses, checking for errors and such are automatically generated by `package:jnigen`.

For native ports to work, `package:jni` provides a handy `Jni.initDLApi()` to be called first.

Example:

This:

```kotlin
public suspend fun thinkBeforeAnswering(): String
```

Gets converted to:

```dart
Future<jni.JString> thinkBeforeAnswering() async
```
114 files changed
tree: e067214a467501128b3aa584c688e910360e0669
  1. .github/
  2. pkgs/