Skip to content
This repository has been archived by the owner on Apr 29, 2024. It is now read-only.

Commit

Permalink
remove suspend_fun_to_async
Browse files Browse the repository at this point in the history
  • Loading branch information
HosseinYousefi committed Jun 26, 2023
1 parent 61af4e0 commit 6421451
Show file tree
Hide file tree
Showing 9 changed files with 65 additions and 31 deletions.
3 changes: 3 additions & 0 deletions jnigen/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 0.6.0-dev.0
* **Breaking Change** Removed `suspend_fun_to_async` flag from the config. It's now happening by default since we read the Kotlin's metadata and reliably identify the `suspend fun`s.

## 0.5.0
* **Breaking Change** ([#72](https://github.com/dart-lang/jnigen/issues/72)): Removed support for `importMap` in favor of the newly added interop mechanism with importing yaml files.
* **Breaking Change** ([#72](https://github.com/dart-lang/jnigen/issues/72)): `java.util.Set`, `java.util.Map`, `java.util.List`, `java.util.Iterator` and the boxed types like `java.lang.Integer`, `java.lang.Double`, ... will be generated as their corresponding classes in `package:jni`.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@
package com.github.dart_lang.jnigen.apisummarizer.elements;

import kotlinx.metadata.Flag;
import kotlinx.metadata.FlagsKt;
import kotlinx.metadata.KmFunction;
import kotlinx.metadata.jvm.JvmExtensionsKt;
import kotlinx.metadata.jvm.internal.JvmFunctionExtension;

import java.util.List;
import java.util.stream.Collectors;
Expand Down
56 changes: 56 additions & 0 deletions jnigen/lib/src/bindings/kotlin_processor.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import '../elements/elements.dart';
import 'visitor.dart';

class KotlinProcessor extends Visitor<Classes, void> {
@override
void visit(Classes node) {
final classProcessor = _KotlinClassProcessor();
for (final classDecl in node.decls.values) {
classDecl.accept(classProcessor);
}
}
}

class _KotlinClassProcessor extends Visitor<ClassDecl, void> {
@override
void visit(ClassDecl node) {
if (node.kotlinClass == null) {
return;
}
// This [ClassDecl] is actually a Kotlin class.
// Matching methods and functions from the metadata.
final functions = <String, KotlinFunction>{};
for (final function in node.kotlinClass!.functions) {
functions[function.descriptor] = function;
}
for (final method in node.methods) {
if (functions.containsKey(method.descriptor!)) {
method.accept(_KotlinMethodProcessor(functions[method.descriptor!]!));
}
}
}
}

class _KotlinMethodProcessor extends Visitor<Method, void> {
final KotlinFunction function;

_KotlinMethodProcessor(this.function);

@override
void visit(Method node) {
if (function.isSuspend) {
const kotlinContinutationType = 'kotlin.coroutines.Continuation';
assert(node.params.isNotEmpty &&
node.params.last.type.kind == Kind.declared &&
node.params.last.type.name == kotlinContinutationType);
final continuationType = node.params.last.type.type as DeclaredType;
node.asyncReturnType = continuationType.params.isEmpty
? TypeUsage.object
: continuationType.params.first;
}
}
}
13 changes: 0 additions & 13 deletions jnigen/lib/src/bindings/linker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -130,19 +130,6 @@ class _MethodLinker extends Visitor<Method, void> {
final paramLinker = _ParamLinker(typeVisitor);
node.typeParams.accept(typeParamLinker).toList();
node.params.accept(paramLinker).toList();
// Kotlin specific
const kotlinContinutationType = 'kotlin.coroutines.Continuation';
if (config.suspendFunToAsync &&
node.params.isNotEmpty &&
node.params.last.type.kind == Kind.declared &&
node.params.last.type.name == kotlinContinutationType) {
final continuationType = node.params.last.type.type as DeclaredType;
node.asyncReturnType = continuationType.params.isEmpty
? TypeUsage.object
: continuationType.params.first;
} else {
node.asyncReturnType = null;
}
node.asyncReturnType?.accept(typeVisitor);
}
}
Expand Down
10 changes: 0 additions & 10 deletions jnigen/lib/src/config/config_types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,6 @@ class Config {
required this.outputConfig,
required this.classes,
this.exclude,
this.suspendFunToAsync = false,
this.sourcePath,
this.classPath,
this.preamble,
Expand Down Expand Up @@ -317,12 +316,6 @@ class Config {
/// Common text to be pasted on top of generated C and Dart files.
final String? preamble;

/// Whether or not to change Kotlin's suspend functions to Dart async ones.
///
/// This will remove the final Continuation argument.
/// Defaults to [false].
final bool suspendFunToAsync;

/// Configuration to search for Android SDK libraries (Experimental).
final AndroidSdkConfig? androidSdkConfig;

Expand Down Expand Up @@ -522,7 +515,6 @@ class Config {
methods: regexFilter<Method>(_Props.excludeMethods),
fields: regexFilter<Field>(_Props.excludeFields),
),
suspendFunToAsync: prov.getBool(_Props.suspendFunToAsync) ?? false,
outputConfig: OutputConfig(
bindingsType: getBindingsType(
prov.getString(_Props.bindingsType),
Expand Down Expand Up @@ -613,8 +605,6 @@ class _Props {
static const excludeMethods = '$exclude.methods';
static const excludeFields = '$exclude.fields';

static const suspendFunToAsync = 'suspend_fun_to_async';

static const import = 'import';
static const outputConfig = 'output';
static const bindingsType = '$outputConfig.bindings_type';
Expand Down
7 changes: 3 additions & 4 deletions jnigen/lib/src/elements/elements.dart
Original file line number Diff line number Diff line change
Expand Up @@ -478,12 +478,11 @@ class Method extends ClassMember implements Element<Method> {
@JsonKey(includeFromJson: false)
late bool isOverridden;

/// This gets populated in the preprocessing stage.
/// The actual return type when the method is a Kotlin's suspend fun.
///
/// It will contain a type only when the suspendFunToAsync flag is on
/// and the method has a `kotlin.coroutines.Continuation` final argument.
/// Populated by [KotlinProcessor].
@JsonKey(includeFromJson: false)
late TypeUsage? asyncReturnType;
TypeUsage? asyncReturnType;

@JsonKey(includeFromJson: false)
late String javaSig = '$name$descriptor';
Expand Down
2 changes: 2 additions & 0 deletions jnigen/lib/src/generate_bindings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import 'dart:convert';
import 'bindings/c_generator.dart';
import 'bindings/dart_generator.dart';
import 'bindings/excluder.dart';
import 'bindings/kotlin_processor.dart';
import 'bindings/linker.dart';
import 'bindings/unnester.dart';
import 'bindings/renamer.dart';
Expand Down Expand Up @@ -36,6 +37,7 @@ Future<void> generateJniBindings(Config config) async {
}

classes.accept(Excluder(config));
classes.accept(KotlinProcessor());
await classes.accept(Linker(config));
classes.accept(Unnester());
classes.accept(Renamer(config));
Expand Down
2 changes: 1 addition & 1 deletion jnigen/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# BSD-style license that can be found in the LICENSE file.

name: jnigen
version: 0.5.0
version: 0.6.0-dev.0
description: Experimental generator for FFI+JNI bindings.
repository: https://github.com/dart-lang/jnigen/tree/main/jnigen

Expand Down
1 change: 0 additions & 1 deletion jnigen/test/kotlin_test/generate.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ Config getConfig([BindingsType bindingsType = BindingsType.cBased]) {
// way to the generated code.
'com.github.dart_lang.jnigen',
],
suspendFunToAsync: true,
logLevel: Level.ALL,
outputConfig: OutputConfig(
bindingsType: bindingsType,
Expand Down

0 comments on commit 6421451

Please sign in to comment.