From 6af8ebdfd640db6f51a79786e0311e8c076cbc16 Mon Sep 17 00:00:00 2001 From: Hossein Yousefi Date: Wed, 20 Sep 2023 13:18:25 +0200 Subject: [PATCH] Use Dart 3 class modifiers in `package:jni` (#398) --- jni/CHANGELOG.md | 4 +++ jni/lib/jni.dart | 1 - jni/lib/src/jarray.dart | 6 ++-- jni/lib/src/jni.dart | 2 +- jni/lib/src/jprimitives.dart | 36 +++++++++---------- jni/lib/src/jvalues.dart | 12 +++---- jni/lib/src/nio/jbyte_buffer.dart | 1 - jni/lib/src/types.dart | 4 ++- jni/test/jarray_test.dart | 7 ++-- jnigen/CHANGELOG.md | 5 +++ jnigen/lib/src/bindings/dart_generator.dart | 2 +- jnigen/pubspec.yaml | 2 +- .../c_based/dart_bindings/simple_package.dart | 4 +-- .../dart_bindings/simple_package.dart | 4 +-- 14 files changed, 47 insertions(+), 43 deletions(-) diff --git a/jni/CHANGELOG.md b/jni/CHANGELOG.md index 15e7e9ec..982f626e 100644 --- a/jni/CHANGELOG.md +++ b/jni/CHANGELOG.md @@ -14,6 +14,10 @@ - **Breaking Change**: The default return `callType` of type parameter `int` for methods such as `JObject.callMethodByName` is now Java's `long` instead of `int` to be consistent with the way arguments work. +- **Breaking Change**: `JType` is now `sealed`. +- **Breaking Change**: Primitive types and their type classes are now `final`. +- **Breaking Change**: `JArray.filled` now uses the generated type class of the + `fill` object and not its Java runtime type. ## 0.7.0 diff --git a/jni/lib/jni.dart b/jni/lib/jni.dart index ce372fff..5f0f34cd 100644 --- a/jni/lib/jni.dart +++ b/jni/lib/jni.dart @@ -66,7 +66,6 @@ export 'src/jvalues.dart' hide JValueArgs, toJValues; export 'src/types.dart'; export 'src/jarray.dart'; export 'src/jobject.dart'; -export 'src/jprimitives.dart'; export 'src/jreference.dart' show JReferenceUseExtension; export 'src/lang/lang.dart'; diff --git a/jni/lib/src/jarray.dart b/jni/lib/src/jarray.dart index fac1d85c..23643127 100644 --- a/jni/lib/src/jarray.dart +++ b/jni/lib/src/jarray.dart @@ -13,7 +13,6 @@ import 'package:jni/src/third_party/generated_bindings.dart'; import 'jni.dart'; import 'jobject.dart'; -import 'jprimitives.dart'; import 'types.dart'; final class JArrayType extends JObjType> { @@ -92,10 +91,9 @@ class JArray extends JObject { /// Creates a [JArray] of the given length with [fill] at each position. /// /// The [length] must be a non-negative integer. - /// The [fill] must be a non-null [JObject]. static JArray filled(int length, E fill) { - assert(!fill.isNull, "fill must not be null."); - final clazz = fill.getClass(); + RangeError.checkNotNegative(length); + final clazz = fill.$type.getClass(); final array = JArray.fromRef( fill.$type as JObjType, Jni.accessors diff --git a/jni/lib/src/jni.dart b/jni/lib/src/jni.dart index 0bc154b9..2554041d 100644 --- a/jni/lib/src/jni.dart +++ b/jni/lib/src/jni.dart @@ -43,7 +43,7 @@ DynamicLibrary _loadDartJniLibrary({String? dir, String baseName = "dartjni"}) { } /// Utilities to spawn and manage JNI. -abstract class Jni { +abstract final class Jni { static final DynamicLibrary _dylib = _loadDartJniLibrary(dir: _dylibDir); static final JniBindings _bindings = JniBindings(_dylib); static final _getJniEnvFn = _dylib.lookup('GetJniEnv'); diff --git a/jni/lib/src/jprimitives.dart b/jni/lib/src/jprimitives.dart index 67225572..04448da2 100644 --- a/jni/lib/src/jprimitives.dart +++ b/jni/lib/src/jprimitives.dart @@ -6,92 +6,92 @@ // lowercase. // ignore_for_file: camel_case_types -import 'types.dart'; +part of 'types.dart'; -abstract class JPrimitive {} +abstract final class JPrimitive {} -abstract class jbyte extends JPrimitive { +abstract final class jbyte extends JPrimitive { static const type = jbyteType(); } -class jbyteType extends JType { +final class jbyteType extends JType { const jbyteType(); @override final signature = 'B'; } -abstract class jboolean extends JPrimitive { +abstract final class jboolean extends JPrimitive { static const type = jbooleanType(); } -class jbooleanType extends JType { +final class jbooleanType extends JType { const jbooleanType(); @override final signature = 'Z'; } -abstract class jchar extends JPrimitive { +abstract final class jchar extends JPrimitive { static const type = jcharType(); } -class jcharType extends JType { +final class jcharType extends JType { const jcharType(); @override final signature = 'C'; } -abstract class jshort extends JPrimitive { +abstract final class jshort extends JPrimitive { static const type = jshortType(); } -class jshortType extends JType { +final class jshortType extends JType { const jshortType(); @override final signature = 'S'; } -abstract class jint extends JPrimitive { +abstract final class jint extends JPrimitive { static const type = jintType(); } -class jintType extends JType { +final class jintType extends JType { const jintType(); @override final signature = 'I'; } -abstract class jlong extends JPrimitive { +abstract final class jlong extends JPrimitive { static const type = jlongType(); } -class jlongType extends JType { +final class jlongType extends JType { const jlongType(); @override final signature = 'J'; } -abstract class jfloat extends JPrimitive { +abstract final class jfloat extends JPrimitive { static const type = jfloatType(); } -class jfloatType extends JType { +final class jfloatType extends JType { const jfloatType(); @override final signature = 'F'; } -abstract class jdouble extends JPrimitive { +abstract final class jdouble extends JPrimitive { static const type = jdoubleType(); } -class jdoubleType extends JType { +final class jdoubleType extends JType { const jdoubleType(); @override diff --git a/jni/lib/src/jvalues.dart b/jni/lib/src/jvalues.dart index 84439bf4..dc177361 100644 --- a/jni/lib/src/jvalues.dart +++ b/jni/lib/src/jvalues.dart @@ -67,35 +67,35 @@ Pointer toJValues(List args, {Allocator allocator = calloc}) { /// Use this class as wrapper to convert an integer /// to Java `int` in jvalues method. -class JValueInt { +final class JValueInt { int value; JValueInt(this.value); } /// Use this class as wrapper to convert an integer /// to Java `short` in jvalues method. -class JValueShort { +final class JValueShort { int value; JValueShort(this.value); } /// Use this class as wrapper to convert an integer /// to Java `byte` in jvalues method. -class JValueByte { +final class JValueByte { int value; JValueByte(this.value); } /// Use this class as wrapper to convert an double /// to Java `float` in jvalues method. -class JValueFloat { +final class JValueFloat { double value; JValueFloat(this.value); } /// Use this class as wrapper to convert an integer /// to Java `char` in jvalues method. -class JValueChar { +final class JValueChar { int value; JValueChar(this.value); JValueChar.fromString(String s) : value = 0 { @@ -115,7 +115,7 @@ class JValueChar { /// /// Returned value is allocated using provided allocator. /// But default allocator may be used for string conversions. -class JValueArgs { +final class JValueArgs { late Pointer values; final List createdRefs = []; diff --git a/jni/lib/src/nio/jbyte_buffer.dart b/jni/lib/src/nio/jbyte_buffer.dart index 1b0acb2b..d5f54885 100644 --- a/jni/lib/src/nio/jbyte_buffer.dart +++ b/jni/lib/src/nio/jbyte_buffer.dart @@ -8,7 +8,6 @@ import 'dart:typed_data'; import '../accessors.dart'; import '../jarray.dart'; import '../jni.dart'; -import '../jprimitives.dart'; import '../jreference.dart'; import '../jvalues.dart'; import '../third_party/generated_bindings.dart'; diff --git a/jni/lib/src/types.dart b/jni/lib/src/types.dart index c6f44b65..d560b2da 100644 --- a/jni/lib/src/types.dart +++ b/jni/lib/src/types.dart @@ -7,7 +7,9 @@ import 'dart:ffi'; import 'jni.dart'; import 'jobject.dart'; -abstract class JType { +part 'jprimitives.dart'; + +sealed class JType { const JType(); String get signature; diff --git a/jni/test/jarray_test.dart b/jni/test/jarray_test.dart index 9a9f59cc..064bc84e 100644 --- a/jni/test/jarray_test.dart +++ b/jni/test/jarray_test.dart @@ -289,11 +289,8 @@ void run({required TestRunnerCallback testRunner}) { final string = "abc".toJString()..releasedBy(arena); final array = JArray.filled(3, string)..releasedBy(arena); expect( - () { - final _ = JArray.filled(3, JString.fromRef(nullptr)) - ..releasedBy(arena); - }, - throwsA(isA()), + () => JArray.filled(-3, JString.fromRef(nullptr)), + throwsA(isA()), ); expect(array.length, 3); expect(array[0].toDartString(releaseOriginal: true), "abc"); diff --git a/jnigen/CHANGELOG.md b/jnigen/CHANGELOG.md index 00b2fc18..0056f41d 100644 --- a/jnigen/CHANGELOG.md +++ b/jnigen/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.8.0-wip + +- **Breaking Change**: The generated impl class for interfaces is now an + `interface`. + ## 0.7.0 - **Breaking Change** ([#387](https://github.com/dart-lang/jnigen/issues/387)): diff --git a/jnigen/lib/src/bindings/dart_generator.dart b/jnigen/lib/src/bindings/dart_generator.dart index ed523736..9c206929 100644 --- a/jnigen/lib/src/bindings/dart_generator.dart +++ b/jnigen/lib/src/bindings/dart_generator.dart @@ -520,7 +520,7 @@ class $name$typeParamsDef extends $superName { '}', ); s.write(''' -abstract class $implClassName$typeParamsDef { +abstract interface class $implClassName$typeParamsDef { factory $implClassName( $abstractFactoryArgs ) = _$implClassName; diff --git a/jnigen/pubspec.yaml b/jnigen/pubspec.yaml index 3fbd456b..35e01bc2 100644 --- a/jnigen/pubspec.yaml +++ b/jnigen/pubspec.yaml @@ -4,7 +4,7 @@ name: jnigen description: A Dart bindings generator for Java and Kotlin that uses JNI under the hood to interop with Java virtual machine. -version: 0.7.0 +version: 0.8.0-wip repository: https://github.com/dart-lang/jnigen/tree/main/jnigen environment: diff --git a/jnigen/test/simple_package_test/c_based/dart_bindings/simple_package.dart b/jnigen/test/simple_package_test/c_based/dart_bindings/simple_package.dart index 1142fd67..7327fcfb 100644 --- a/jnigen/test/simple_package_test/c_based/dart_bindings/simple_package.dart +++ b/jnigen/test/simple_package_test/c_based/dart_bindings/simple_package.dart @@ -3446,7 +3446,7 @@ class MyInterface<$T extends jni.JObject> extends jni.JObject { static Map get $impls => _$impls; } -abstract class $MyInterfaceImpl<$T extends jni.JObject> { +abstract interface class $MyInterfaceImpl<$T extends jni.JObject> { factory $MyInterfaceImpl({ required jni.JObjType<$T> T, required void Function(jni.JString s) voidCallback, @@ -3743,7 +3743,7 @@ class MyRunnable extends jni.JObject { } } -abstract class $MyRunnableImpl { +abstract interface class $MyRunnableImpl { factory $MyRunnableImpl({ required void Function() run, }) = _$MyRunnableImpl; diff --git a/jnigen/test/simple_package_test/dart_only/dart_bindings/simple_package.dart b/jnigen/test/simple_package_test/dart_only/dart_bindings/simple_package.dart index 7ac848d0..ba022690 100644 --- a/jnigen/test/simple_package_test/dart_only/dart_bindings/simple_package.dart +++ b/jnigen/test/simple_package_test/dart_only/dart_bindings/simple_package.dart @@ -3255,7 +3255,7 @@ class MyInterface<$T extends jni.JObject> extends jni.JObject { static Map get $impls => _$impls; } -abstract class $MyInterfaceImpl<$T extends jni.JObject> { +abstract interface class $MyInterfaceImpl<$T extends jni.JObject> { factory $MyInterfaceImpl({ required jni.JObjType<$T> T, required void Function(jni.JString s) voidCallback, @@ -3550,7 +3550,7 @@ class MyRunnable extends jni.JObject { } } -abstract class $MyRunnableImpl { +abstract interface class $MyRunnableImpl { factory $MyRunnableImpl({ required void Function() run, }) = _$MyRunnableImpl;