diff --git a/jni/CHANGELOG.md b/jni/CHANGELOG.md index f9975313..64ddb4d7 100644 --- a/jni/CHANGELOG.md +++ b/jni/CHANGELOG.md @@ -1,33 +1,57 @@ +## 0.7.0 + +- **Breaking Change** ([#387](https://github.com/dart-lang/jnigen/issues/387)): + Added `JBuffer` and `JByteBuffer` classes as default classes for + `java.nio.Buffer` and `java.nio.ByteBuffer` respectively. +- **Breaking Change**: Made the type classes `final`. +- Fixed a bug where `addAll`, `removeAll` and `retainAll` in `JSet` would run + their respective operation twice. +- Fixed a bug where `JList.insertAll` would not throw the potentially thrown + Java exception. + ## 0.6.1 -* Depend on the stable version of Dart 3.1. + +- Depend on the stable version of Dart 3.1. ## 0.6.0 -* **Breaking Change** ([#131](https://github.com/dart-lang/jnigen/issues/131)): Renamed `delete*` to `release*`. -* Added `PortProxy` and related methods used for interface implementation. -* Added the missing binding for `java.lang.Character`. + +- **Breaking Change** ([#131](https://github.com/dart-lang/jnigen/issues/131)): + Renamed `delete*` to `release*`. +- Added `PortProxy` and related methods used for interface implementation. +- Added the missing binding for `java.lang.Character`. ## 0.5.0 -* **Breaking Change** ([#137](https://github.com/dart-lang/jnigen/issues/137)): Java primitive types are now all lowercase like `jint`, `jshort`, ... -* The bindings for `java.util.Set`, `java.util.Map`, `java.util.List` and the numeric types like `java.lang.Integer`, `java.lang.Boolean`, ... are now included in `package:jni`. + +- **Breaking Change** ([#137](https://github.com/dart-lang/jnigen/issues/137)): + Java primitive types are now all lowercase like `jint`, `jshort`, ... +- The bindings for `java.util.Set`, `java.util.Map`, `java.util.List` and the + numeric types like `java.lang.Integer`, `java.lang.Boolean`, ... are now + included in `package:jni`. ## 0.4.0 -* Type classes now have `superCount` and `superType` getters used for type inference. + +- Type classes now have `superCount` and `superType` getters used for type + inference. ## 0.3.0 -* Added `PortContinuation` used for `suspend fun` in Kotlin. -* `dartjni` now depends on `dart_api_dl.h`. + +- Added `PortContinuation` used for `suspend fun` in Kotlin. +- `dartjni` now depends on `dart_api_dl.h`. ## 0.2.1 -* Added `.clang-format` to pub. + +- Added `.clang-format` to pub. ## 0.2.0 -* Added array support -* Added generic support -* `JniX` turned into `JX` for a more terse code. + +- Added array support +- Added generic support +- `JniX` turned into `JX` for a more terse code. ## 0.1.1 -* Windows support for running tests and examples on development machines. + +- Windows support for running tests and examples on development machines. ## 0.1.0 -* Initial version: Android and Linux support, JObject API +- Initial version: Android and Linux support, JObject API diff --git a/jni/lib/jni.dart b/jni/lib/jni.dart index d63fc73a..85f99fa3 100644 --- a/jni/lib/jni.dart +++ b/jni/lib/jni.dart @@ -71,6 +71,7 @@ export 'src/jobject.dart'; export 'src/jprimitives.dart'; export 'src/jreference.dart' show JReferenceUseExtension; export 'src/lang/lang.dart'; +export 'src/nio/nio.dart'; export 'src/util/util.dart'; export 'package:ffi/ffi.dart' show using, Arena; diff --git a/jni/lib/jni_symbols.yaml b/jni/lib/jni_symbols.yaml index 5159dc9c..ac4a74c0 100644 --- a/jni/lib/jni_symbols.yaml +++ b/jni/lib/jni_symbols.yaml @@ -75,3 +75,11 @@ files: 'java.lang.Object': DECLARED V: 'java.lang.Object': DECLARED + 'java.nio.Buffer': + name: JBuffer + type_class: JBufferType + super_count: 1 + 'java.nio.ByteBuffer': + name: JByteBuffer + type_class: JByteBufferType + super_count: 2 diff --git a/jni/lib/src/jarray.dart b/jni/lib/src/jarray.dart index 1b970392..fac1d85c 100644 --- a/jni/lib/src/jarray.dart +++ b/jni/lib/src/jarray.dart @@ -16,7 +16,7 @@ import 'jobject.dart'; import 'jprimitives.dart'; import 'types.dart'; -class JArrayType extends JObjType> { +final class JArrayType extends JObjType> { final JType elementType; const JArrayType(this.elementType); diff --git a/jni/lib/src/jobject.dart b/jni/lib/src/jobject.dart index 6a2cad20..a7e659ce 100644 --- a/jni/lib/src/jobject.dart +++ b/jni/lib/src/jobject.dart @@ -19,7 +19,7 @@ import 'types.dart'; // type switch like a regular type. typedef _VoidType = void; -class JObjectType extends JObjType { +final class JObjectType extends JObjType { const JObjectType(); @override diff --git a/jni/lib/src/lang/jboolean.dart b/jni/lib/src/lang/jboolean.dart index 3dd22b11..9ea92b43 100644 --- a/jni/lib/src/lang/jboolean.dart +++ b/jni/lib/src/lang/jboolean.dart @@ -9,7 +9,7 @@ import '../jni.dart'; import '../third_party/generated_bindings.dart'; import '../types.dart'; -class JBooleanType extends JObjType { +final class JBooleanType extends JObjType { const JBooleanType(); @override diff --git a/jni/lib/src/lang/jbyte.dart b/jni/lib/src/lang/jbyte.dart index 3cb9e96d..6b5aa980 100644 --- a/jni/lib/src/lang/jbyte.dart +++ b/jni/lib/src/lang/jbyte.dart @@ -9,7 +9,7 @@ import '../third_party/generated_bindings.dart'; import '../types.dart'; import 'jnumber.dart'; -class JByteType extends JObjType { +final class JByteType extends JObjType { const JByteType(); @override diff --git a/jni/lib/src/lang/jcharacter.dart b/jni/lib/src/lang/jcharacter.dart index c43d2e0e..b50f67f4 100644 --- a/jni/lib/src/lang/jcharacter.dart +++ b/jni/lib/src/lang/jcharacter.dart @@ -6,7 +6,7 @@ import '../jvalues.dart'; import '../third_party/generated_bindings.dart'; import '../types.dart'; -class JCharacterType extends JObjType { +final class JCharacterType extends JObjType { const JCharacterType(); @override diff --git a/jni/lib/src/lang/jdouble.dart b/jni/lib/src/lang/jdouble.dart index c6852a1e..6db163e4 100644 --- a/jni/lib/src/lang/jdouble.dart +++ b/jni/lib/src/lang/jdouble.dart @@ -8,7 +8,7 @@ import '../third_party/generated_bindings.dart'; import '../types.dart'; import 'jnumber.dart'; -class JDoubleType extends JObjType { +final class JDoubleType extends JObjType { const JDoubleType(); @override diff --git a/jni/lib/src/lang/jfloat.dart b/jni/lib/src/lang/jfloat.dart index f23c2373..a352659e 100644 --- a/jni/lib/src/lang/jfloat.dart +++ b/jni/lib/src/lang/jfloat.dart @@ -9,7 +9,7 @@ import '../third_party/generated_bindings.dart'; import '../types.dart'; import 'jnumber.dart'; -class JFloatType extends JObjType { +final class JFloatType extends JObjType { const JFloatType(); @override diff --git a/jni/lib/src/lang/jinteger.dart b/jni/lib/src/lang/jinteger.dart index 907d7ba9..8ece4667 100644 --- a/jni/lib/src/lang/jinteger.dart +++ b/jni/lib/src/lang/jinteger.dart @@ -9,7 +9,7 @@ import '../third_party/generated_bindings.dart'; import '../types.dart'; import 'jnumber.dart'; -class JIntegerType extends JObjType { +final class JIntegerType extends JObjType { const JIntegerType(); @override diff --git a/jni/lib/src/lang/jlong.dart b/jni/lib/src/lang/jlong.dart index fb2ee801..66d054b9 100644 --- a/jni/lib/src/lang/jlong.dart +++ b/jni/lib/src/lang/jlong.dart @@ -8,7 +8,7 @@ import '../third_party/generated_bindings.dart'; import '../types.dart'; import 'jnumber.dart'; -class JLongType extends JObjType { +final class JLongType extends JObjType { const JLongType(); @override diff --git a/jni/lib/src/lang/jnumber.dart b/jni/lib/src/lang/jnumber.dart index 43e10856..45d86dc0 100644 --- a/jni/lib/src/lang/jnumber.dart +++ b/jni/lib/src/lang/jnumber.dart @@ -17,7 +17,7 @@ import 'jinteger.dart'; import 'jlong.dart'; import 'jshort.dart'; -class JNumberType extends JObjType { +final class JNumberType extends JObjType { const JNumberType(); @override diff --git a/jni/lib/src/lang/jshort.dart b/jni/lib/src/lang/jshort.dart index a07ea4e4..39d3c1d5 100644 --- a/jni/lib/src/lang/jshort.dart +++ b/jni/lib/src/lang/jshort.dart @@ -9,7 +9,7 @@ import '../third_party/generated_bindings.dart'; import '../types.dart'; import 'jnumber.dart'; -class JShortType extends JObjType { +final class JShortType extends JObjType { const JShortType(); @override diff --git a/jni/lib/src/lang/jstring.dart b/jni/lib/src/lang/jstring.dart index 43bda602..9e542ff9 100644 --- a/jni/lib/src/lang/jstring.dart +++ b/jni/lib/src/lang/jstring.dart @@ -12,7 +12,7 @@ import '../jobject.dart'; import '../third_party/generated_bindings.dart'; import '../types.dart'; -class JStringType extends JObjType { +final class JStringType extends JObjType { const JStringType(); @override diff --git a/jni/lib/src/nio/jbuffer.dart b/jni/lib/src/nio/jbuffer.dart new file mode 100644 index 00000000..cae6bc97 --- /dev/null +++ b/jni/lib/src/nio/jbuffer.dart @@ -0,0 +1,255 @@ +// 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 '../accessors.dart'; +import '../jni.dart'; +import '../jobject.dart'; +import '../jvalues.dart'; +import '../third_party/generated_bindings.dart'; +import '../types.dart'; + +final class JBufferType extends JObjType { + const JBufferType(); + + @override + String get signature => r"Ljava/nio/Buffer;"; + + @override + JBuffer fromRef(JObjectPtr ref) => JBuffer.fromRef(ref); + + @override + JObjType get superType => const JObjectType(); + + @override + final superCount = 1; + + @override + int get hashCode => (JBufferType).hashCode; + + @override + bool operator ==(Object other) { + return other.runtimeType == (JBufferType) && other is JBufferType; + } +} + +/// A container for data of a specific primitive type. +/// +/// The bindings for `java.nio.Buffer`. +/// +/// A buffer is a linear, finite sequence of elements of a specific primitive +/// type. Aside from its content, the essential properties of a buffer are its +/// [capacity], [limit], and [position]. +/// +/// There is one subclass of this class for each non-boolean primitive type. +/// We currently only have the bindings for `java.nio.ByteBuffer` in this +/// package as [JByteBuffer]. +class JBuffer extends JObject { + @override + // ignore: overridden_fields + late final JObjType $type = type; + + JBuffer.fromRef( + JObjectPtr ref, + ) : super.fromRef(ref); + + static final _class = Jni.findJClass(r"java/nio/Buffer"); + + /// The type which includes information such as the signature of this class. + static const type = JBufferType(); + + static final _capacityId = + Jni.accessors.getMethodIDOf(_class.reference, r"capacity", r"()I"); + + /// The number of elements this buffer contains. + /// + /// It is never negative and never changes. + int get capacity { + return Jni.accessors.callMethodWithArgs( + reference, _capacityId, JniCallType.intType, []).integer; + } + + static final _positionId = + Jni.accessors.getMethodIDOf(_class.reference, r"position", r"()I"); + + /// The index of the next element to be read or written. + /// + /// It is never negative and is never greater than its [limit]. + int get position { + return Jni.accessors.callMethodWithArgs( + reference, _positionId, JniCallType.intType, []).integer; + } + + static final _setPositionId = Jni.accessors + .getMethodIDOf(_class.reference, r"position", r"(I)Ljava/nio/Buffer;"); + + /// Throws: + /// * [IllegalArgumentException] - If the preconditions on [newPosition] do + /// not hold. + set position(int position) { + Jni.env.DeleteGlobalRef(Jni.accessors.callMethodWithArgs(reference, + _setPositionId, JniCallType.objectType, [JValueInt(position)]).object); + } + + static final _limitId = + Jni.accessors.getMethodIDOf(_class.reference, r"limit", r"()I"); + + /// The index of the first element that should not be read or written. + /// + /// It is never negative and is never greater than its [capacity]. + int get limit { + return Jni.accessors.callMethodWithArgs( + reference, _limitId, JniCallType.intType, []).integer; + } + + static final _setLimitId = Jni.accessors + .getMethodIDOf(_class.reference, r"limit", r"(I)Ljava/nio/Buffer;"); + + /// Throws: + /// * [IllegalArgumentException] - If the preconditions on [newLimit] do not + /// hold. + set limit(int newLimit) { + Jni.env.DeleteGlobalRef(Jni.accessors.callMethodWithArgs(reference, + _setLimitId, JniCallType.objectType, [JValueInt(newLimit)]).object); + } + + static final _markId = Jni.accessors + .getMethodIDOf(_class.reference, r"mark", r"()Ljava/nio/Buffer;"); + + /// Sets this buffer's mark at its [position]. + /// + /// Mark is the index to which its [position] will be reset when the [reset] + /// method is invoked. + void mark() { + Jni.env.DeleteGlobalRef(Jni.accessors.callMethodWithArgs( + reference, _markId, JniCallType.objectType, []).object); + } + + static final _resetId = Jni.accessors + .getMethodIDOf(_class.reference, r"reset", r"()Ljava/nio/Buffer;"); + + /// Resets this buffer's [position] to the previously-marked position. + /// + /// Throws: + /// * [InvalidMarkException] - If the mark has not been set + void reset() { + Jni.env.DeleteGlobalRef(Jni.accessors.callMethodWithArgs( + reference, _resetId, JniCallType.objectType, []).object); + } + + static final _clearId = Jni.accessors + .getMethodIDOf(_class.reference, r"clear", r"()Ljava/nio/Buffer;"); + + /// Clears this buffer. + /// + /// The [position] is set to zero, the [limit] is set to + /// the [capacity], and the mark is discarded. + void clear() { + Jni.env.DeleteGlobalRef(Jni.accessors.callMethodWithArgs( + reference, _clearId, JniCallType.objectType, []).object); + } + + static final _flipId = Jni.accessors + .getMethodIDOf(_class.reference, r"flip", r"()Ljava/nio/Buffer;"); + + /// Flips this buffer. + /// + /// The limit is set to the current [position] and then the [position] is set + /// to zero. If the mark is defined then it is discarded. + void flip() { + Jni.env.DeleteGlobalRef(Jni.accessors.callMethodWithArgs( + reference, _flipId, JniCallType.objectType, []).object); + } + + static final _rewindId = Jni.accessors + .getMethodIDOf(_class.reference, r"rewind", r"()Ljava/nio/Buffer;"); + + /// Rewinds this buffer. + /// + /// The [position] is set to zero and the mark is discarded. + void rewind() { + Jni.env.DeleteGlobalRef(Jni.accessors.callMethodWithArgs( + reference, _rewindId, JniCallType.objectType, []).object); + } + + static final _remainingId = + Jni.accessors.getMethodIDOf(_class.reference, r"remaining", r"()I"); + + /// The number of elements between the current [position] and the + /// [limit]. + int get remaining { + return Jni.accessors.callMethodWithArgs( + reference, _remainingId, JniCallType.intType, []).integer; + } + + static final _hasRemainingId = + Jni.accessors.getMethodIDOf(_class.reference, r"hasRemaining", r"()Z"); + + /// Whether there are any elements between the current [position] and + /// the [limit]. + bool get hasRemaining { + return Jni.accessors.callMethodWithArgs( + reference, _hasRemainingId, JniCallType.booleanType, []).boolean; + } + + static final _isReadOnlyId = + Jni.accessors.getMethodIDOf(_class.reference, r"isReadOnly", r"()Z"); + + /// Whether or not this buffer is read-only. + bool get isReadOnly { + return Jni.accessors.callMethodWithArgs( + reference, _isReadOnlyId, JniCallType.booleanType, []).boolean; + } + + static final _hasArrayId = + Jni.accessors.getMethodIDOf(_class.reference, r"hasArray", r"()Z"); + + /// Whether or not this buffer is backed by an accessible array. + bool get hasArray { + return Jni.accessors.callMethodWithArgs( + reference, _hasArrayId, JniCallType.booleanType, []).boolean; + } + + static final _arrayId = Jni.accessors + .getMethodIDOf(_class.reference, r"array", r"()Ljava/lang/Object;"); + + /// The array that backs this buffer. + /// + /// Concrete subclasses like [JByteBuffer] provide more strongly-typed return + /// values for this method. + /// + /// Throws: + /// * [ReadOnlyBufferException] - If this buffer is backed by an array but is + /// read-only + /// * [UnsupportedOperationException] - If this buffer is not backed by an + /// accessible array + JObject get array { + return const JObjectType().fromRef(Jni.accessors.callMethodWithArgs( + reference, _arrayId, JniCallType.objectType, []).object); + } + + static final _arrayOffsetId = + Jni.accessors.getMethodIDOf(_class.reference, r"arrayOffset", r"()I"); + + /// The offset within this buffer's backing array of the first element + /// of the buffer. + /// + /// Throws: + /// * [ReadOnlyBufferException] - If this buffer is backed by an array but is + /// read-only + /// * [UnsupportedOperationException] - If this buffer is not backed by an + /// accessible array + int get arrayOffset { + return Jni.accessors.callMethodWithArgs( + reference, _arrayOffsetId, JniCallType.intType, []).integer; + } + + static final _isDirectId = + Jni.accessors.getMethodIDOf(_class.reference, r"isDirect", r"()Z"); + + /// Whether or not this buffer is direct. + bool get isDirect { + return Jni.accessors.callMethodWithArgs( + reference, _isDirectId, JniCallType.booleanType, []).boolean; + } +} diff --git a/jni/lib/src/nio/jbyte_buffer.dart b/jni/lib/src/nio/jbyte_buffer.dart new file mode 100644 index 00000000..1b0acb2b --- /dev/null +++ b/jni/lib/src/nio/jbyte_buffer.dart @@ -0,0 +1,316 @@ +// 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 'dart:ffi'; +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'; +import '../types.dart'; +import 'jbuffer.dart'; + +final class JByteBufferType extends JObjType { + const JByteBufferType(); + + @override + String get signature => r"Ljava/nio/ByteBuffer;"; + + @override + JByteBuffer fromRef(JObjectPtr ref) => JByteBuffer.fromRef(ref); + + @override + JObjType get superType => const JBufferType(); + + @override + final superCount = 2; + + @override + int get hashCode => (JByteBufferType).hashCode; + + @override + bool operator ==(Object other) { + return other.runtimeType == (JByteBufferType) && other is JByteBufferType; + } +} + +/// A byte [JBuffer]. +/// +/// The bindings for `java.nio.ByteBuffer`. +/// +/// This enables fast memory copying between Java and Dart when directly +/// allocated (See [JByteBuffer.allocateDirect]). +/// +/// To create a [JByteBuffer] from the content of a [Uint8List], +/// use [JByteBuffer.fromList]. This uses direct allocation to enable fast +/// copying. +/// +/// [asUint8List] provides a direct access to the underlying [Uint8List] that +/// this buffer uses. This means any changes to it will change the content of +/// the buffer and vice versa. This can be used to access to [Uint8List] methods +/// such as [Uint8List.setRange]. +/// +/// Example: +/// ```dart +/// final directBuffer = JByteBuffer.allocateDirect(3); +/// directBuffer.asUint8List().setAll(0, [1, 2, 3]); +/// // The buffer is now 1, 2, 3. +/// ``` +/// +/// Both the original buffer and the [Uint8List] keep the underlying Java buffer +/// alive. Once all the instances of the original buffer and the lists produced +/// from [asUint8List] are inaccessible both in Java and Dart, Java will +/// correctly garbage collects the buffer and frees its underlying memory. +/// +/// Example: +/// ```dart +/// final directBuffer = JByteBuffer.allocateDirect(3); +/// final data = directBuffer.asUint8List(); +/// directBuffer.release(); // Releasing the original buffer. +/// data.setAll(0, [1, 2, 3]); // Works! [data] is still accessible. +/// ``` +/// +/// The original buffer can be [release]d when calling [asUint8List] +/// by setting the `releaseOriginal` parameter to `true`. +/// +/// Example: +/// ```dart +/// final directBuffer = JByteBuffer.allocateDirect(3); +/// // [releaseOriginal] is `false` by default. +/// final data1 = directBuffer.asUint8List(); +/// directBuffer.nextByte = 42; // No problem! +/// print(data1[0]); // prints 42! +/// final data2 = directBuffer.asUint8List(releaseOriginal: true); +/// // directBuffer.nextByte = 42; // throws [UseAfterReleaseException]! +/// ``` +class JByteBuffer extends JBuffer { + @override + // ignore: overridden_fields + late final JObjType $type = type; + + JByteBuffer.fromRef( + JObjectPtr ref, + ) : super.fromRef(ref); + + static final _class = Jni.findJClass(r"java/nio/ByteBuffer"); + + /// The type which includes information such as the signature of this class. + static const type = JByteBufferType(); + + static final _allocateDirectId = Jni.accessors.getStaticMethodIDOf( + _class.reference, r"allocateDirect", r"(I)Ljava/nio/ByteBuffer;"); + + /// Allocates a new direct byte buffer. + /// + /// Throws: + /// * [IllegalArgumentException] - If the capacity is a negative integer + factory JByteBuffer.allocateDirect(int capacity) { + return JByteBuffer.fromRef( + Jni.accessors.callStaticMethodWithArgs( + _class.reference, + _allocateDirectId, + JniCallType.objectType, + [JValueInt(capacity)]).object, + ); + } + + static final _allocateId = Jni.accessors.getStaticMethodIDOf( + _class.reference, r"allocate", r"(I)Ljava/nio/ByteBuffer;"); + + /// Allocates a new byte buffer. + /// + /// Throws: + /// * [IllegalArgumentException] - If the capacity is a negative integer + factory JByteBuffer.allocate(int capacity) { + return const JByteBufferType().fromRef(Jni.accessors + .callStaticMethodWithArgs(_class.reference, _allocateId, + JniCallType.objectType, [JValueInt(capacity)]).object); + } + + static final _wrapWholeId = Jni.accessors.getStaticMethodIDOf( + _class.reference, r"wrap", r"([B)Ljava/nio/ByteBuffer;"); + static final _wrapId = Jni.accessors.getStaticMethodIDOf( + _class.reference, r"wrap", r"([BII)Ljava/nio/ByteBuffer;"); + + /// Wraps a byte array into a buffer. + /// + /// The new buffer will be backed by the given byte array; that is, + /// modifications to the buffer will cause the array to be modified + /// and vice versa. + static JByteBuffer wrap( + JArray array, [ + int? offset, + int? length, + ]) { + if (offset == null && length == null) { + return const JByteBufferType().fromRef( + Jni.accessors.callStaticMethodWithArgs( + _class.reference, + _wrapWholeId, + JniCallType.objectType, + [array.reference], + ).object, + ); + } + offset ??= 0; + length ??= array.length - offset; + return const JByteBufferType().fromRef( + Jni.accessors.callStaticMethodWithArgs( + _class.reference, + _wrapId, + JniCallType.objectType, + [array.reference, JValueInt(offset), JValueInt(length)], + ).object, + ); + } + + /// Creates a [JByteBuffer] from the content of [list]. + /// + /// The [JByteBuffer] will be allocated using [JByteBuffer.allocateDirect]. + factory JByteBuffer.fromList(Uint8List list) { + final buffer = JByteBuffer.allocateDirect(list.length); + buffer._asUint8ListUnsafe().setAll(0, list); + return buffer; + } + + static final _sliceId = Jni.accessors + .getMethodIDOf(_class.reference, r"slice", r"()Ljava/nio/ByteBuffer;"); + + /// Creates a new byte buffer whose content is a shared subsequence of this + /// buffer's content. + JByteBuffer slice() { + return const JByteBufferType().fromRef(Jni.accessors.callMethodWithArgs( + reference, _sliceId, JniCallType.objectType, []).object); + } + + static final _duplicateId = Jni.accessors.getMethodIDOf( + _class.reference, r"duplicate", r"()Ljava/nio/ByteBuffer;"); + + /// Creates a new byte buffer that shares this buffer's content. + JByteBuffer duplicate() { + return const JByteBufferType().fromRef(Jni.accessors.callMethodWithArgs( + reference, _duplicateId, JniCallType.objectType, []).object); + } + + static final _asReadOnlyBufferId = Jni.accessors.getMethodIDOf( + _class.reference, r"asReadOnlyBuffer", r"()Ljava/nio/ByteBuffer;"); + + /// Creates a new, read-only byte buffer that shares this buffer's content. + JByteBuffer asReadOnlyBuffer() { + return const JByteBufferType().fromRef(Jni.accessors.callMethodWithArgs( + reference, _asReadOnlyBufferId, JniCallType.objectType, []).object); + } + + static final _getId = + Jni.accessors.getMethodIDOf(_class.reference, r"get", r"()B"); + + /// Reads the byte at this buffer's current [position], and then increments the + /// [position]. + /// + /// Throws: + /// * [BufferOverflowException] - If the buffer's current [position] is not + /// smaller than its [limit] + int get nextByte { + return Jni.accessors + .callMethodWithArgs(reference, _getId, JniCallType.byteType, []).byte; + } + + static final _putId = Jni.accessors + .getMethodIDOf(_class.reference, r"put", r"(B)Ljava/nio/ByteBuffer;"); + + /// Writes the given byte into this buffer at the current [position], and then + /// increments the [position]. + /// + /// Throws: + /// * [BufferOverflowException] - If this buffer's current [position] is not + /// smaller than its [limit] + /// * [ReadOnlyBufferException] - If this buffer is read-only + set nextByte(int b) { + Jni.env.DeleteGlobalRef(Jni.accessors.callMethodWithArgs( + reference, _putId, JniCallType.objectType, [JValueByte(b)]).object); + } + + static final _arrayId = + Jni.accessors.getMethodIDOf(_class.reference, r"array", r"()[B"); + + @override + JArray get array { + return const JArrayType(jbyteType()).fromRef(Jni.accessors + .callMethodWithArgs( + reference, _arrayId, JniCallType.objectType, []).object); + } + + void _ensureIsDirect() { + if (!isDirect) { + throw StateError( + 'The buffer must be created with `JByteBuffer.allocateDirect`.', + ); + } + } + + Pointer _directBufferAddress() { + final address = Jni.env.GetDirectBufferAddress(reference); + if (address == nullptr) { + throw StateError( + 'The memory region is undefined or ' + 'direct buffer access is not supported by this JVM.', + ); + } + return address; + } + + int _directBufferCapacity() { + final capacity = Jni.env.GetDirectBufferCapacity(reference); + if (capacity == -1) { + throw StateError( + 'The object is an unaligned view buffer and the processor ' + 'architecture does not support unaligned access.', + ); + } + return capacity; + } + + Uint8List _asUint8ListUnsafe() { + _ensureIsDirect(); + final address = _directBufferAddress(); + final capacity = _directBufferCapacity(); + return address.cast().asTypedList(capacity); + } + + /// Returns this byte buffer as a [Uint8List]. + /// + /// If [releaseOriginal] is `true`, this byte buffer will be released. + /// + /// Throws [StateError] if the buffer is not direct + /// (see [JByteBuffer.allocateDirect]) or the JVM does not support the direct + /// buffer operations or the object is an unaligned view buffer and + /// the processor does not support unaligned access. + Uint8List asUint8List({bool releaseOriginal = false}) { + _ensureIsDirect(); + final address = _directBufferAddress(); + final capacity = _directBufferCapacity(); + final token = releaseOriginal ? reference : Jni.env.NewGlobalRef(reference); + if (releaseOriginal) { + setAsReleased(); + } + return address.cast().asTypedList( + capacity, + token: token, + finalizer: Jni.env.ptr.ref.DeleteGlobalRef.cast(), + ); + } +} + +extension Uint8ListToJava on Uint8List { + /// Creates a [JByteBuffer] from the content of this list. + /// + /// The [JByteBuffer] will be allocated using [JByteBuffer.allocateDirect]. + JByteBuffer toJByteBuffer() { + return JByteBuffer.fromList(this); + } +} diff --git a/jni/lib/src/nio/nio.dart b/jni/lib/src/nio/nio.dart new file mode 100644 index 00000000..3092870f --- /dev/null +++ b/jni/lib/src/nio/nio.dart @@ -0,0 +1,6 @@ +// 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. + +export 'jbuffer.dart'; +export 'jbyte_buffer.dart'; diff --git a/jni/lib/src/util/jiterator.dart b/jni/lib/src/util/jiterator.dart index eab305d0..0d0122ff 100644 --- a/jni/lib/src/util/jiterator.dart +++ b/jni/lib/src/util/jiterator.dart @@ -8,7 +8,7 @@ import '../jobject.dart'; import '../third_party/generated_bindings.dart'; import '../types.dart'; -class JIteratorType<$E extends JObject> extends JObjType> { +final class JIteratorType<$E extends JObject> extends JObjType> { final JObjType<$E> E; const JIteratorType( diff --git a/jni/lib/src/util/jlist.dart b/jni/lib/src/util/jlist.dart index 19cb1ed0..9779032a 100644 --- a/jni/lib/src/util/jlist.dart +++ b/jni/lib/src/util/jlist.dart @@ -15,7 +15,7 @@ import '../third_party/generated_bindings.dart'; import '../types.dart'; import 'jiterator.dart'; -class JListType<$E extends JObject> extends JObjType> { +final class JListType<$E extends JObject> extends JObjType> { final JObjType<$E> E; const JListType( @@ -193,10 +193,11 @@ class JList<$E extends JObject> extends JObject with ListMixin<$E> { Jni.env.IsInstanceOf( (iterable as JObject).reference, _collectionClass.reference)) { Jni.accessors.callMethodWithArgs( - reference, - _insertAllId, - JniCallType.booleanType, - [JValueInt(index), (iterable as JObject).reference]); + reference, + _insertAllId, + JniCallType.booleanType, + [JValueInt(index), (iterable as JObject).reference], + ).boolean; return; } super.insertAll(index, iterable); diff --git a/jni/lib/src/util/jmap.dart b/jni/lib/src/util/jmap.dart index 015fea85..73a6d623 100644 --- a/jni/lib/src/util/jmap.dart +++ b/jni/lib/src/util/jmap.dart @@ -11,7 +11,7 @@ import '../third_party/jni_bindings_generated.dart'; import '../types.dart'; import 'jset.dart'; -class JMapType<$K extends JObject, $V extends JObject> +final class JMapType<$K extends JObject, $V extends JObject> extends JObjType> { final JObjType<$K> K; final JObjType<$V> V; @@ -107,11 +107,9 @@ class JMap<$K extends JObject, $V extends JObject> extends JObject if (other is JMap<$K, $V>) { Jni.accessors.callMethodWithArgs(reference, _addAllId, JniCallType.voidType, [other.reference]).check(); - } else { - for (final entry in other.entries) { - this[entry.key] = entry.value; - } + return; } + super.addAll(other); } static final _clearId = diff --git a/jni/lib/src/util/jset.dart b/jni/lib/src/util/jset.dart index 367c1213..df510036 100644 --- a/jni/lib/src/util/jset.dart +++ b/jni/lib/src/util/jset.dart @@ -12,7 +12,7 @@ import '../jobject.dart'; import '../types.dart'; import 'jiterator.dart'; -class JSetType<$E extends JObject> extends JObjType> { +final class JSetType<$E extends JObject> extends JObjType> { final JObjType<$E> E; const JSetType( @@ -93,6 +93,7 @@ class JSet<$E extends JObject> extends JObject with SetMixin<$E> { JniCallType.booleanType, [(elements as JObject).reference], ).boolean; + return; } return super.addAll(elements); } @@ -173,6 +174,7 @@ class JSet<$E extends JObject> extends JObject with SetMixin<$E> { (elements as JObject).reference, _collectionClass.reference)) { Jni.accessors.callMethodWithArgs(reference, _removeAllId, JniCallType.booleanType, [(elements as JObject).reference]).boolean; + return; } return super.removeAll(elements); } @@ -186,6 +188,7 @@ class JSet<$E extends JObject> extends JObject with SetMixin<$E> { (elements as JObject).reference, _collectionClass.reference)) { Jni.accessors.callMethodWithArgs(reference, _retainAllId, JniCallType.booleanType, [(elements as JObject).reference]).boolean; + return; } return super.retainAll(elements); } diff --git a/jni/pubspec.yaml b/jni/pubspec.yaml index 62ba94d4..46bedce2 100644 --- a/jni/pubspec.yaml +++ b/jni/pubspec.yaml @@ -4,7 +4,7 @@ name: jni description: A library to access JNI from Dart and Flutter that acts as a support library for package:jnigen. -version: 0.6.1 +version: 0.7.0 repository: https://github.com/dart-lang/jnigen/tree/main/jni topics: diff --git a/jni/test/jarray_test.dart b/jni/test/jarray_test.dart index 3cc7c988..9a9f59cc 100644 --- a/jni/test/jarray_test.dart +++ b/jni/test/jarray_test.dart @@ -319,6 +319,12 @@ void run({required TestRunnerCallback testRunner}) { expect((arr[0]..releasedBy(arena)).isNull, true); }); }); + testRunner('JArray of JCharacter', () { + using((arena) { + final arr = JArray(JCharacter.type, 1)..releasedBy(arena); + expect((arr[0]..releasedBy(arena)).isNull, true); + }); + }); testRunner('JArray of JLong', () { using((arena) { final arr = JArray(JLong.type, 1)..releasedBy(arena); diff --git a/jni/test/jbyte_buffer_test.dart b/jni/test/jbyte_buffer_test.dart new file mode 100644 index 00000000..f68c47b0 --- /dev/null +++ b/jni/test/jbyte_buffer_test.dart @@ -0,0 +1,229 @@ +// 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 'dart:io'; +import 'dart:typed_data'; + +import 'package:jni/jni.dart'; +import 'package:test/test.dart'; + +import 'test_util/test_util.dart'; + +void main() { + // Don't forget to initialize JNI. + if (!Platform.isAndroid) { + checkDylibIsUpToDate(); + Jni.spawnIfNotExists(dylibDir: "build/jni_libs", jvmOptions: ["-Xmx128m"]); + } + run(testRunner: test); +} + +void run({required TestRunnerCallback testRunner}) { + final throwsAJniException = throwsA(isA()); + JByteBuffer testDataBuffer(Arena arena) { + final buffer = JByteBuffer.allocate(3)..releasedBy(arena); + buffer.nextByte = 1; + buffer.nextByte = 2; + buffer.nextByte = 3; + buffer.position = 0; + return buffer; + } + + testRunner('wrap whole array', () { + using((arena) { + final array = JArray(jbyte.type, 3)..releasedBy(arena); + array[0] = 1; + array[1] = 2; + array[2] = 3; + final buffer = JByteBuffer.wrap(array)..releasedBy(arena); + expect(buffer, testDataBuffer(arena)); + }); + }); + + testRunner('wrap partial array', () { + using((arena) { + final array = JArray(jbyte.type, 3)..releasedBy(arena); + array[0] = 1; + array[1] = 2; + array[2] = 3; + final buffer = JByteBuffer.wrap(array, 1, 1)..releasedBy(arena); + expect(buffer.nextByte, 2); + expect(() => buffer.nextByte, throwsAJniException); + }); + }); + + testRunner('capacity', () { + using((arena) { + final buffer = testDataBuffer(arena); + expect(buffer.capacity, 3); + }); + }); + + testRunner('position', () { + using((arena) { + final buffer = testDataBuffer(arena); + expect(buffer.position, 0); + buffer.position = 2; + expect(buffer.position, 2); + }); + }); + + testRunner('limit', () { + using((arena) { + final buffer = testDataBuffer(arena); + expect(buffer.limit, 3); + buffer.limit = 2; + expect(buffer.limit, 2); + }); + }); + + testRunner('mark and reset', () { + using((arena) { + final buffer = testDataBuffer(arena); + buffer.position = 1; + buffer.mark(); + buffer.position = 2; + buffer.reset(); + expect(buffer.position, 1); + }); + }); + + testRunner('clear', () { + using((arena) { + final buffer = testDataBuffer(arena); + buffer.position = 2; + buffer.limit = 2; + buffer.clear(); + expect(buffer.limit, 3); + expect(buffer.position, 0); + }); + }); + + testRunner('flip', () { + using((arena) { + final buffer = testDataBuffer(arena); + buffer.position = 2; + buffer.flip(); + expect(buffer.limit, 2); + expect(buffer.position, 0); + }); + }); + + testRunner('rewind', () { + using((arena) { + final buffer = testDataBuffer(arena); + buffer.mark(); + buffer.position = 2; + buffer.rewind(); + expect(buffer.position, 0); + expect(buffer.reset, throwsAJniException); + }); + }); + + testRunner('remaining and hasRemaining', () { + using((arena) { + final buffer = testDataBuffer(arena); + buffer.position = 2; + expect(buffer.remaining, 1); + expect(buffer.hasRemaining, true); + buffer.position = 3; + expect(buffer.remaining, 0); + expect(buffer.hasRemaining, false); + }); + }); + + testRunner('isReadOnly and asReadOnlyBuffer', () { + using((arena) { + final buffer = testDataBuffer(arena); + expect(buffer.isReadOnly, false); + final readOnly = buffer.asReadOnlyBuffer()..releasedBy(arena); + expect(readOnly.isReadOnly, true); + }); + }); + + testRunner('hasArray, array and arrayOffset', () { + using((arena) { + final buffer = testDataBuffer(arena); + expect(buffer.hasArray, true); + expect(buffer.arrayOffset, 0); + expect(buffer.array.length, 3); + final directBuffer = JByteBuffer.allocateDirect(3)..releasedBy(arena); + expect(directBuffer.hasArray, false); + }); + }); + + testRunner('isDirect', () { + using((arena) { + final buffer = testDataBuffer(arena); + expect(buffer.isDirect, false); + final directBuffer = JByteBuffer.allocateDirect(3)..releasedBy(arena); + expect(directBuffer.isDirect, true); + }); + }); + + testRunner('slice', () { + using((arena) { + final buffer = testDataBuffer(arena); + buffer.position = 1; + buffer.limit = 2; + final sliced = buffer.slice()..releasedBy(arena); + expect(sliced.capacity, 1); + expect(sliced.nextByte, 2); + }); + }); + + testRunner('duplicate', () { + using((arena) { + final buffer = testDataBuffer(arena); + buffer.position = 1; + buffer.limit = 2; + final duplicate = buffer.duplicate()..releasedBy(arena); + expect(duplicate.capacity, 3); + expect(duplicate.position, 1); + expect(duplicate.limit, 2); + }); + }); + + testRunner('asUint8List', () { + using((arena) { + final buffer = testDataBuffer(arena); + expect(buffer.asUint8List, throwsA(isA())); + final list = Uint8List.fromList([1, 2, 3]); + final directBuffer = list.toJByteBuffer()..releasedBy(arena); + expect(directBuffer.asUint8List(), list); + }); + }); + + testRunner('type hashCode, ==', () { + using((arena) { + final a = testDataBuffer(arena); + final b = testDataBuffer(arena); + expect(a.$type, b.$type); + expect(a.$type.hashCode, b.$type.hashCode); + final c = JBuffer.fromRef(nullptr); + final d = JBuffer.fromRef(nullptr); + expect(c.$type, d.$type); + expect(c.$type.hashCode, d.$type.hashCode); + + expect(a.$type, isNot(c.$type)); + expect(a.$type.hashCode, isNot(c.$type.hashCode)); + }); + }); + + testRunner('asUint8List releasing original', () { + using((arena) { + // Used as an example in [JByteBuffer]. + final directBuffer = JByteBuffer.allocateDirect(3); + final data1 = directBuffer.asUint8List(); + directBuffer.nextByte = 42; // No problem! + expect(data1[0], 42); + final data2 = directBuffer.asUint8List(releaseOriginal: true); + expect( + () => directBuffer.nextByte = 42, + throwsA(isA()), + ); + expect(data2[0], 42); + }); + }); +} diff --git a/jni/test/type_test.dart b/jni/test/type_test.dart index f0f3caaa..0ad8490a 100644 --- a/jni/test/type_test.dart +++ b/jni/test/type_test.dart @@ -25,7 +25,7 @@ class A extends JObject { JObjType get $type => $AType(); } -class $AType extends JObjType { +final class $AType extends JObjType { @override A fromRef(Pointer ref) { return A.fromRef(ref); @@ -55,7 +55,7 @@ class B extends JObject { JObjType get $type => $BType(); } -class $BType extends JObjType { +final class $BType extends JObjType { @override B fromRef(Pointer ref) { return B.fromRef(ref); @@ -86,7 +86,7 @@ class C extends A { JObjType get $type => $CType(); } -class $CType extends JObjType { +final class $CType extends JObjType { @override C fromRef(Pointer ref) { return C.fromRef(ref); @@ -117,7 +117,7 @@ class D extends A { JObjType get $type => $DType(); } -class $DType extends JObjType { +final class $DType extends JObjType { @override D fromRef(Pointer ref) { return D.fromRef(ref); @@ -148,7 +148,7 @@ class E extends B { JObjType get $type => $EType(); } -class $EType extends JObjType { +final class $EType extends JObjType { @override E fromRef(Pointer ref) { return E.fromRef(ref); @@ -179,7 +179,7 @@ class F extends C { JObjType get $type => $FType(); } -class $FType extends JObjType { +final class $FType extends JObjType { @override F fromRef(Pointer ref) { return F.fromRef(ref); @@ -292,6 +292,13 @@ void run({required TestRunnerCallback testRunner}) { ]), JObject.type, ); + expect( + lowestCommonSuperType([ + JByteBuffer.type, + JBuffer.type, + ]), + JBuffer.type, + ); }); }); diff --git a/jnigen/CHANGELOG.md b/jnigen/CHANGELOG.md index 7e18e402..00b2fc18 100644 --- a/jnigen/CHANGELOG.md +++ b/jnigen/CHANGELOG.md @@ -1,41 +1,74 @@ -## 0.6.1-wip -* Add `ignore_for_file: lines_longer_than_80_chars` to the generated file preamble. -* Added an explicit cast in generated `.implement` code to allow `dart analyze` to pass when `strict-casts` is set. +## 0.7.0 + +- **Breaking Change** ([#387](https://github.com/dart-lang/jnigen/issues/387)): + Added `JBuffer` and `JByteBuffer` classes as default classes for + `java.nio.Buffer` and `java.nio.ByteBuffer` respectively. +- **Breaking Change**: Made the type classes `final`. +- Added `ignore_for_file: lines_longer_than_80_chars` to the generated file + preamble. +- Added an explicit cast in generated `.implement` code to allow + `dart analyze` to pass when `strict-casts` is set. ## 0.6.0 -* **Breaking Change** ([#131](https://github.com/dart-lang/jnigen/issues/131)): Renamed `delete*` to `release*`. -* **Breaking Change** ([#354](https://github.com/dart-lang/jnigen/issues/354)): Renamed constructors from `ctor1`, `ctor2`, ... to `new1`, `new2`, ... -* **Breaking Change**: Specifying a class always pulls in nested classes by default. If a nested class is specified in config, it will be an error. -* **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. -* Fixed a bug where the nested classes would be generated incorrectly depending on the backend used for generation. -* Fixed a bug where ASM backend would produce the incorrect parent for multi-level nested classes. -* Fixed a bug where the backends would produce different descriptors for the same method. -* Added `enable_experiment` option to config. -* Created an experiment called `interface_implementation` which creates a `.implement` method for interfaces, so you can implement them using Dart. -* Save all `jnigen` logs to a file in `.dart_tool/jnigen/logs/`. This is useful for debugging. + +- **Breaking Change** ([#131](https://github.com/dart-lang/jnigen/issues/131)): + Renamed `delete*` to `release*`. +- **Breaking Change** ([#354](https://github.com/dart-lang/jnigen/issues/354)): + Renamed constructors from `ctor1`, `ctor2`, ... to `new1`, `new2`, ... +- **Breaking Change**: Specifying a class always pulls in nested classes by + default. If a nested class is specified in config, it will be an error. +- **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. +- Fixed a bug where the nested classes would be generated incorrectly depending + on the backend used for generation. +- Fixed a bug where ASM backend would produce the incorrect parent for + multi-level nested classes. +- Fixed a bug where the backends would produce different descriptors for the + same method. +- Added `enable_experiment` option to config. +- Created an experiment called `interface_implementation` which creates a + `.implement` method for interfaces, so you can implement them using Dart. +- Save all `jnigen` logs to a file in `.dart_tool/jnigen/logs/`. This is useful + for debugging. ## 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`. -* Strings now use UTF16. + +- **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`. +- Strings now use UTF16. ## 0.4.0 -* **Breaking Change** ([#145](https://github.com/dart-lang/jnigen/issues/145)): Type arguments are now named instead of positional. -* Type parameters can now be inferred when possible. -* Fixed a bug where passing a `long` argument truncated it to `int` in pure dart bindings. -* Removed array extensions from the generated code. -* Added the ability to use source dependencies from Gradle. -* Fixed an issue with the field setter. -* Fixed an issue where exceptions were not properly thrown in pure Dart bindings. + +- **Breaking Change** ([#145](https://github.com/dart-lang/jnigen/issues/145)): + Type arguments are now named instead of positional. +- Type parameters can now be inferred when possible. +- Fixed a bug where passing a `long` argument truncated it to `int` in pure dart + bindings. +- Removed array extensions from the generated code. +- Added the ability to use source dependencies from Gradle. +- Fixed an issue with the field setter. +- Fixed an issue where exceptions were not properly thrown in pure Dart + bindings. ## 0.3.0 -* Added the option to convert Kotlin `suspend fun` to Dart async methods. Add `suspend_fun_to_async: true` to `jnigen.yaml`. + +- Added the option to convert Kotlin `suspend fun` to Dart async methods. Add + `suspend_fun_to_async: true` to `jnigen.yaml`. ## 0.2.0 -* Support generating bindings for generics. + +- Support generating bindings for generics. ## 0.1.1 -* Windows support for running tests and examples on development machines. + +- Windows support for running tests and examples on development machines. ## 0.1.0 -* Initial version: Basic bindings generation, maven and android utilities + +- Initial version: Basic bindings generation, maven and android utilities diff --git a/jnigen/example/in_app_java/lib/android_utils.dart b/jnigen/example/in_app_java/lib/android_utils.dart index ec722865..8a0e58a8 100644 --- a/jnigen/example/in_app_java/lib/android_utils.dart +++ b/jnigen/example/in_app_java/lib/android_utils.dart @@ -55,7 +55,7 @@ class AndroidUtils extends jni.JObject { } } -class $AndroidUtilsType extends jni.JObjType { +final class $AndroidUtilsType extends jni.JObjType { const $AndroidUtilsType(); @override @@ -1027,7 +1027,7 @@ class EmojiCompat extends jni.JObject { } } -class $EmojiCompatType extends jni.JObjType { +final class $EmojiCompatType extends jni.JObjType { const $EmojiCompatType(); @override @@ -1361,7 +1361,7 @@ class EmojiCompat_Config extends jni.JObject { } } -class $EmojiCompat_ConfigType extends jni.JObjType { +final class $EmojiCompat_ConfigType extends jni.JObjType { const $EmojiCompat_ConfigType(); @override @@ -1450,7 +1450,7 @@ class EmojiCompat_MetadataRepoLoaderCallback extends jni.JObject { } } -class $EmojiCompat_MetadataRepoLoaderCallbackType +final class $EmojiCompat_MetadataRepoLoaderCallbackType extends jni.JObjType { const $EmojiCompat_MetadataRepoLoaderCallbackType(); @@ -1551,7 +1551,7 @@ class EmojiCompat_GlyphChecker extends jni.JObject { } } -class $EmojiCompat_GlyphCheckerType +final class $EmojiCompat_GlyphCheckerType extends jni.JObjType { const $EmojiCompat_GlyphCheckerType(); @@ -1613,7 +1613,7 @@ class EmojiCompat_MetadataRepoLoader extends jni.JObject { } } -class $EmojiCompat_MetadataRepoLoaderType +final class $EmojiCompat_MetadataRepoLoaderType extends jni.JObjType { const $EmojiCompat_MetadataRepoLoaderType(); @@ -1697,7 +1697,7 @@ class EmojiCompat_InitCallback extends jni.JObject { } } -class $EmojiCompat_InitCallbackType +final class $EmojiCompat_InitCallbackType extends jni.JObjType { const $EmojiCompat_InitCallbackType(); @@ -1771,7 +1771,7 @@ class EmojiCompat_DefaultSpanFactory extends jni.JObject { } } -class $EmojiCompat_DefaultSpanFactoryType +final class $EmojiCompat_DefaultSpanFactoryType extends jni.JObjType { const $EmojiCompat_DefaultSpanFactoryType(); @@ -1841,7 +1841,7 @@ class EmojiCompat_SpanFactory extends jni.JObject { } } -class $EmojiCompat_SpanFactoryType +final class $EmojiCompat_SpanFactoryType extends jni.JObjType { const $EmojiCompat_SpanFactoryType(); @@ -1939,7 +1939,7 @@ class DefaultEmojiCompatConfig extends jni.JObject { } } -class $DefaultEmojiCompatConfigType +final class $DefaultEmojiCompatConfigType extends jni.JObjType { const $DefaultEmojiCompatConfigType(); @@ -2017,7 +2017,7 @@ class DefaultEmojiCompatConfig_DefaultEmojiCompatConfigHelper_API28 } } -class $DefaultEmojiCompatConfig_DefaultEmojiCompatConfigHelper_API28Type +final class $DefaultEmojiCompatConfig_DefaultEmojiCompatConfigHelper_API28Type extends jni .JObjType { const $DefaultEmojiCompatConfig_DefaultEmojiCompatConfigHelper_API28Type(); @@ -2126,7 +2126,7 @@ class DefaultEmojiCompatConfig_DefaultEmojiCompatConfigHelper_API19 } } -class $DefaultEmojiCompatConfig_DefaultEmojiCompatConfigHelper_API19Type +final class $DefaultEmojiCompatConfig_DefaultEmojiCompatConfigHelper_API19Type extends jni .JObjType { const $DefaultEmojiCompatConfig_DefaultEmojiCompatConfigHelper_API19Type(); @@ -2264,7 +2264,8 @@ class DefaultEmojiCompatConfig_DefaultEmojiCompatConfigHelper } } -class $DefaultEmojiCompatConfig_DefaultEmojiCompatConfigHelperType extends jni +final class $DefaultEmojiCompatConfig_DefaultEmojiCompatConfigHelperType + extends jni .JObjType { const $DefaultEmojiCompatConfig_DefaultEmojiCompatConfigHelperType(); @@ -2353,7 +2354,8 @@ class DefaultEmojiCompatConfig_DefaultEmojiCompatConfigFactory } } -class $DefaultEmojiCompatConfig_DefaultEmojiCompatConfigFactoryType extends jni +final class $DefaultEmojiCompatConfig_DefaultEmojiCompatConfigFactoryType + extends jni .JObjType { const $DefaultEmojiCompatConfig_DefaultEmojiCompatConfigFactoryType(); @@ -2461,7 +2463,7 @@ class Build_Partition extends jni.JObject { } } -class $Build_PartitionType extends jni.JObjType { +final class $Build_PartitionType extends jni.JObjType { const $Build_PartitionType(); @override @@ -2613,7 +2615,7 @@ class Build_VERSION extends jni.JObject { } } -class $Build_VERSIONType extends jni.JObjType { +final class $Build_VERSIONType extends jni.JObjType { const $Build_VERSIONType(); @override @@ -2763,7 +2765,7 @@ class Build_VERSION_CODES extends jni.JObject { } } -class $Build_VERSION_CODESType extends jni.JObjType { +final class $Build_VERSION_CODESType extends jni.JObjType { const $Build_VERSION_CODESType(); @override @@ -3112,7 +3114,7 @@ class Build extends jni.JObject { } } -class $BuildType extends jni.JObjType { +final class $BuildType extends jni.JObjType { const $BuildType(); @override @@ -3624,7 +3626,7 @@ class HashMap<$K extends jni.JObject, $V extends jni.JObject> } } -class $HashMapType<$K extends jni.JObject, $V extends jni.JObject> +final class $HashMapType<$K extends jni.JObject, $V extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$K> K; final jni.JObjType<$V> V; diff --git a/jnigen/example/kotlin_plugin/lib/kotlin_bindings.dart b/jnigen/example/kotlin_plugin/lib/kotlin_bindings.dart index ed2d034c..efd0351f 100644 --- a/jnigen/example/kotlin_plugin/lib/kotlin_bindings.dart +++ b/jnigen/example/kotlin_plugin/lib/kotlin_bindings.dart @@ -71,7 +71,7 @@ class Example extends jni.JObject { } } -class $ExampleType extends jni.JObjType { +final class $ExampleType extends jni.JObjType { const $ExampleType(); @override diff --git a/jnigen/example/notification_plugin/lib/notifications.dart b/jnigen/example/notification_plugin/lib/notifications.dart index ebb2f59e..9855d16a 100644 --- a/jnigen/example/notification_plugin/lib/notifications.dart +++ b/jnigen/example/notification_plugin/lib/notifications.dart @@ -75,7 +75,7 @@ class Notifications extends jni.JObject { } } -class $NotificationsType extends jni.JObjType { +final class $NotificationsType extends jni.JObjType { const $NotificationsType(); @override diff --git a/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocument.dart b/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocument.dart index 03a9da2a..b2c40a28 100644 --- a/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocument.dart +++ b/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocument.dart @@ -1510,7 +1510,7 @@ class PDDocument extends jni.JObject { } } -class $PDDocumentType extends jni.JObjType { +final class $PDDocumentType extends jni.JObjType { const $PDDocumentType(); @override diff --git a/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocumentInformation.dart b/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocumentInformation.dart index d928d213..3c959e76 100644 --- a/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocumentInformation.dart +++ b/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/pdmodel/PDDocumentInformation.dart @@ -496,7 +496,8 @@ class PDDocumentInformation extends jni.JObject { } } -class $PDDocumentInformationType extends jni.JObjType { +final class $PDDocumentInformationType + extends jni.JObjType { const $PDDocumentInformationType(); @override diff --git a/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/text/PDFTextStripper.dart b/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/text/PDFTextStripper.dart index b42cd9a6..930240b7 100644 --- a/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/text/PDFTextStripper.dart +++ b/jnigen/example/pdfbox_plugin/lib/src/third_party/org/apache/pdfbox/text/PDFTextStripper.dart @@ -1398,7 +1398,7 @@ class PDFTextStripper extends jni.JObject { } } -class $PDFTextStripperType extends jni.JObjType { +final class $PDFTextStripperType extends jni.JObjType { const $PDFTextStripperType(); @override diff --git a/jnigen/lib/src/bindings/dart_generator.dart b/jnigen/lib/src/bindings/dart_generator.dart index d8fb60d0..ed523736 100644 --- a/jnigen/lib/src/bindings/dart_generator.dart +++ b/jnigen/lib/src/bindings/dart_generator.dart @@ -589,7 +589,7 @@ class _$implClassName$typeParamsDef implements $implClassName$typeParamsCall { ? '($typeClassName).hashCode' : 'Object.hash($typeClassName, $hashCodeTypeClasses)'; s.write(''' -class $typeClassName$typeParamsDef extends $_jType<$name$typeParamsCall> { +final class $typeClassName$typeParamsDef extends $_jType<$name$typeParamsCall> { $typeClassesDef const $typeClassName( diff --git a/jnigen/pubspec.yaml b/jnigen/pubspec.yaml index d8d08f72..3fbd456b 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.6.1-wip +version: 0.7.0 repository: https://github.com/dart-lang/jnigen/tree/main/jnigen environment: diff --git a/jnigen/test/jackson_core_test/third_party/c_based/dart_bindings/com/fasterxml/jackson/core/JsonFactory.dart b/jnigen/test/jackson_core_test/third_party/c_based/dart_bindings/com/fasterxml/jackson/core/JsonFactory.dart index e1f19fe5..95ddfd57 100644 --- a/jnigen/test/jackson_core_test/third_party/c_based/dart_bindings/com/fasterxml/jackson/core/JsonFactory.dart +++ b/jnigen/test/jackson_core_test/third_party/c_based/dart_bindings/com/fasterxml/jackson/core/JsonFactory.dart @@ -1854,7 +1854,7 @@ class JsonFactory extends jni.JObject { } } -class $JsonFactoryType extends jni.JObjType { +final class $JsonFactoryType extends jni.JObjType { const $JsonFactoryType(); @override @@ -1969,7 +1969,7 @@ class JsonFactory_Feature extends jni.JObject { } } -class $JsonFactory_FeatureType extends jni.JObjType { +final class $JsonFactory_FeatureType extends jni.JObjType { const $JsonFactory_FeatureType(); @override diff --git a/jnigen/test/jackson_core_test/third_party/c_based/dart_bindings/com/fasterxml/jackson/core/JsonParser.dart b/jnigen/test/jackson_core_test/third_party/c_based/dart_bindings/com/fasterxml/jackson/core/JsonParser.dart index 1dac51cc..5775da71 100644 --- a/jnigen/test/jackson_core_test/third_party/c_based/dart_bindings/com/fasterxml/jackson/core/JsonParser.dart +++ b/jnigen/test/jackson_core_test/third_party/c_based/dart_bindings/com/fasterxml/jackson/core/JsonParser.dart @@ -2636,7 +2636,7 @@ class JsonParser extends jni.JObject { } } -class $JsonParserType extends jni.JObjType { +final class $JsonParserType extends jni.JObjType { const $JsonParserType(); @override @@ -2750,7 +2750,7 @@ class JsonParser_Feature extends jni.JObject { } } -class $JsonParser_FeatureType extends jni.JObjType { +final class $JsonParser_FeatureType extends jni.JObjType { const $JsonParser_FeatureType(); @override @@ -2818,7 +2818,8 @@ class JsonParser_NumberType extends jni.JObject { } } -class $JsonParser_NumberTypeType extends jni.JObjType { +final class $JsonParser_NumberTypeType + extends jni.JObjType { const $JsonParser_NumberTypeType(); @override diff --git a/jnigen/test/jackson_core_test/third_party/c_based/dart_bindings/com/fasterxml/jackson/core/JsonToken.dart b/jnigen/test/jackson_core_test/third_party/c_based/dart_bindings/com/fasterxml/jackson/core/JsonToken.dart index fdbd542a..bab355e9 100644 --- a/jnigen/test/jackson_core_test/third_party/c_based/dart_bindings/com/fasterxml/jackson/core/JsonToken.dart +++ b/jnigen/test/jackson_core_test/third_party/c_based/dart_bindings/com/fasterxml/jackson/core/JsonToken.dart @@ -213,7 +213,7 @@ class JsonToken extends jni.JObject { } } -class $JsonTokenType extends jni.JObjType { +final class $JsonTokenType extends jni.JObjType { const $JsonTokenType(); @override diff --git a/jnigen/test/jackson_core_test/third_party/dart_only/dart_bindings/com/fasterxml/jackson/core/JsonFactory.dart b/jnigen/test/jackson_core_test/third_party/dart_only/dart_bindings/com/fasterxml/jackson/core/JsonFactory.dart index f9f36316..3cdf2ff8 100644 --- a/jnigen/test/jackson_core_test/third_party/dart_only/dart_bindings/com/fasterxml/jackson/core/JsonFactory.dart +++ b/jnigen/test/jackson_core_test/third_party/dart_only/dart_bindings/com/fasterxml/jackson/core/JsonFactory.dart @@ -1756,7 +1756,7 @@ class JsonFactory extends jni.JObject { } } -class $JsonFactoryType extends jni.JObjType { +final class $JsonFactoryType extends jni.JObjType { const $JsonFactoryType(); @override @@ -1868,7 +1868,7 @@ class JsonFactory_Feature extends jni.JObject { } } -class $JsonFactory_FeatureType extends jni.JObjType { +final class $JsonFactory_FeatureType extends jni.JObjType { const $JsonFactory_FeatureType(); @override diff --git a/jnigen/test/jackson_core_test/third_party/dart_only/dart_bindings/com/fasterxml/jackson/core/JsonParser.dart b/jnigen/test/jackson_core_test/third_party/dart_only/dart_bindings/com/fasterxml/jackson/core/JsonParser.dart index ae607a98..d94c2205 100644 --- a/jnigen/test/jackson_core_test/third_party/dart_only/dart_bindings/com/fasterxml/jackson/core/JsonParser.dart +++ b/jnigen/test/jackson_core_test/third_party/dart_only/dart_bindings/com/fasterxml/jackson/core/JsonParser.dart @@ -2489,7 +2489,7 @@ class JsonParser extends jni.JObject { } } -class $JsonParserType extends jni.JObjType { +final class $JsonParserType extends jni.JObjType { const $JsonParserType(); @override @@ -2600,7 +2600,7 @@ class JsonParser_Feature extends jni.JObject { } } -class $JsonParser_FeatureType extends jni.JObjType { +final class $JsonParser_FeatureType extends jni.JObjType { const $JsonParser_FeatureType(); @override @@ -2672,7 +2672,8 @@ class JsonParser_NumberType extends jni.JObject { } } -class $JsonParser_NumberTypeType extends jni.JObjType { +final class $JsonParser_NumberTypeType + extends jni.JObjType { const $JsonParser_NumberTypeType(); @override diff --git a/jnigen/test/jackson_core_test/third_party/dart_only/dart_bindings/com/fasterxml/jackson/core/JsonToken.dart b/jnigen/test/jackson_core_test/third_party/dart_only/dart_bindings/com/fasterxml/jackson/core/JsonToken.dart index da0a49e5..573a815a 100644 --- a/jnigen/test/jackson_core_test/third_party/dart_only/dart_bindings/com/fasterxml/jackson/core/JsonToken.dart +++ b/jnigen/test/jackson_core_test/third_party/dart_only/dart_bindings/com/fasterxml/jackson/core/JsonToken.dart @@ -199,7 +199,7 @@ class JsonToken extends jni.JObject { } } -class $JsonTokenType extends jni.JObjType { +final class $JsonTokenType extends jni.JObjType { const $JsonTokenType(); @override diff --git a/jnigen/test/kotlin_test/c_based/dart_bindings/kotlin.dart b/jnigen/test/kotlin_test/c_based/dart_bindings/kotlin.dart index 5b80bb88..3e264274 100644 --- a/jnigen/test/kotlin_test/c_based/dart_bindings/kotlin.dart +++ b/jnigen/test/kotlin_test/c_based/dart_bindings/kotlin.dart @@ -102,7 +102,7 @@ class SuspendFun extends jni.JObject { } } -class $SuspendFunType extends jni.JObjType { +final class $SuspendFunType extends jni.JObjType { const $SuspendFunType(); @override diff --git a/jnigen/test/kotlin_test/dart_only/dart_bindings/kotlin.dart b/jnigen/test/kotlin_test/dart_only/dart_bindings/kotlin.dart index c352dfb0..bd4441f3 100644 --- a/jnigen/test/kotlin_test/dart_only/dart_bindings/kotlin.dart +++ b/jnigen/test/kotlin_test/dart_only/dart_bindings/kotlin.dart @@ -92,7 +92,7 @@ class SuspendFun extends jni.JObject { } } -class $SuspendFunType extends jni.JObjType { +final class $SuspendFunType extends jni.JObjType { const $SuspendFunType(); @override 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 2879e351..1142fd67 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 @@ -66,7 +66,7 @@ class Color extends jni.JObject { } } -class $ColorType extends jni.JObjType { +final class $ColorType extends jni.JObjType { const $ColorType(); @override @@ -779,7 +779,7 @@ class Example extends jni.JObject { } } -class $ExampleType extends jni.JObjType { +final class $ExampleType extends jni.JObjType { const $ExampleType(); @override @@ -864,7 +864,7 @@ class Example_Nested extends jni.JObject { } } -class $Example_NestedType extends jni.JObjType { +final class $Example_NestedType extends jni.JObjType { const $Example_NestedType(); @override @@ -928,7 +928,7 @@ class Example_Nested_NestedTwice extends jni.JObject { } } -class $Example_Nested_NestedTwiceType +final class $Example_Nested_NestedTwiceType extends jni.JObjType { const $Example_Nested_NestedTwiceType(); @@ -1004,7 +1004,7 @@ class Example_NonStaticNested extends jni.JObject { } } -class $Example_NonStaticNestedType +final class $Example_NonStaticNestedType extends jni.JObjType { const $Example_NonStaticNestedType(); @@ -1249,7 +1249,7 @@ class Exceptions extends jni.JObject { } } -class $ExceptionsType extends jni.JObjType { +final class $ExceptionsType extends jni.JObjType { const $ExceptionsType(); @override @@ -1504,7 +1504,7 @@ class Fields extends jni.JObject { } } -class $FieldsType extends jni.JObjType { +final class $FieldsType extends jni.JObjType { const $FieldsType(); @override @@ -1594,7 +1594,7 @@ class Fields_Nested extends jni.JObject { } } -class $Fields_NestedType extends jni.JObjType { +final class $Fields_NestedType extends jni.JObjType { const $Fields_NestedType(); @override @@ -1658,7 +1658,7 @@ class C2 extends jni.JObject { } } -class $C2Type extends jni.JObjType { +final class $C2Type extends jni.JObjType { const $C2Type(); @override @@ -1715,7 +1715,7 @@ class Example1 extends jni.JObject { } } -class $Example1Type extends jni.JObjType { +final class $Example1Type extends jni.JObjType { const $Example1Type(); @override @@ -1780,8 +1780,8 @@ class GenericTypeParams<$S extends jni.JObject, $K extends jni.JObject> } } -class $GenericTypeParamsType<$S extends jni.JObject, $K extends jni.JObject> - extends jni.JObjType> { +final class $GenericTypeParamsType<$S extends jni.JObject, + $K extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$S> S; final jni.JObjType<$K> K; @@ -1959,7 +1959,7 @@ class GrandParent<$T extends jni.JObject> extends jni.JObject { } } -class $GrandParentType<$T extends jni.JObject> +final class $GrandParentType<$T extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$T> T; @@ -2096,8 +2096,8 @@ class GrandParent_Parent<$T extends jni.JObject, $S extends jni.JObject> } } -class $GrandParent_ParentType<$T extends jni.JObject, $S extends jni.JObject> - extends jni.JObjType> { +final class $GrandParent_ParentType<$T extends jni.JObject, + $S extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$T> T; final jni.JObjType<$S> S; @@ -2275,7 +2275,7 @@ class GrandParent_Parent_Child<$T extends jni.JObject, $S extends jni.JObject, } } -class $GrandParent_Parent_ChildType<$T extends jni.JObject, +final class $GrandParent_Parent_ChildType<$T extends jni.JObject, $S extends jni.JObject, $U extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$T> T; @@ -2381,7 +2381,7 @@ class GrandParent_StaticParent<$S extends jni.JObject> extends jni.JObject { } } -class $GrandParent_StaticParentType<$S extends jni.JObject> +final class $GrandParent_StaticParentType<$S extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$S> S; @@ -2528,7 +2528,7 @@ class GrandParent_StaticParent_Child<$S extends jni.JObject, } } -class $GrandParent_StaticParent_ChildType<$S extends jni.JObject, +final class $GrandParent_StaticParent_ChildType<$S extends jni.JObject, $U extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$S> S; @@ -2653,7 +2653,7 @@ class MyMap<$K extends jni.JObject, $V extends jni.JObject> } } -class $MyMapType<$K extends jni.JObject, $V extends jni.JObject> +final class $MyMapType<$K extends jni.JObject, $V extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$K> K; final jni.JObjType<$V> V; @@ -2796,7 +2796,7 @@ class MyMap_MyEntry<$K extends jni.JObject, $V extends jni.JObject> } } -class $MyMap_MyEntryType<$K extends jni.JObject, $V extends jni.JObject> +final class $MyMap_MyEntryType<$K extends jni.JObject, $V extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$K> K; final jni.JObjType<$V> V; @@ -2996,7 +2996,8 @@ class MyStack<$T extends jni.JObject> extends jni.JObject { } } -class $MyStackType<$T extends jni.JObject> extends jni.JObjType> { +final class $MyStackType<$T extends jni.JObject> + extends jni.JObjType> { final jni.JObjType<$T> T; const $MyStackType( @@ -3060,7 +3061,7 @@ class StringKeyedMap<$V extends jni.JObject> extends MyMap { } } -class $StringKeyedMapType<$V extends jni.JObject> +final class $StringKeyedMapType<$V extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$V> V; @@ -3115,7 +3116,7 @@ class StringMap extends StringKeyedMap { } } -class $StringMapType extends jni.JObjType { +final class $StringMapType extends jni.JObjType { const $StringMapType(); @override @@ -3161,7 +3162,7 @@ class StringStack extends MyStack { } } -class $StringStackType extends jni.JObjType { +final class $StringStackType extends jni.JObjType { const $StringStackType(); @override @@ -3219,7 +3220,7 @@ class StringValuedMap<$K extends jni.JObject> extends MyMap<$K, jni.JString> { } } -class $StringValuedMapType<$K extends jni.JObject> +final class $StringValuedMapType<$K extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$K> K; @@ -3500,7 +3501,7 @@ class _$MyInterfaceImpl<$T extends jni.JObject> } } -class $MyInterfaceType<$T extends jni.JObject> +final class $MyInterfaceType<$T extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$T> T; @@ -3624,7 +3625,7 @@ class MyInterfaceConsumer extends jni.JObject { } } -class $MyInterfaceConsumerType extends jni.JObjType { +final class $MyInterfaceConsumerType extends jni.JObjType { const $MyInterfaceConsumerType(); @override @@ -3762,7 +3763,7 @@ class _$MyRunnableImpl implements $MyRunnableImpl { } } -class $MyRunnableType extends jni.JObjType { +final class $MyRunnableType extends jni.JObjType { const $MyRunnableType(); @override @@ -3862,7 +3863,7 @@ class MyRunnableRunner extends jni.JObject { } } -class $MyRunnableRunnerType extends jni.JObjType { +final class $MyRunnableRunnerType extends jni.JObjType { const $MyRunnableRunnerType(); @override @@ -3927,7 +3928,8 @@ class JsonSerializable_Case extends jni.JObject { } } -class $JsonSerializable_CaseType extends jni.JObjType { +final class $JsonSerializable_CaseType + extends jni.JObjType { const $JsonSerializable_CaseType(); @override @@ -3976,7 +3978,7 @@ class MyDataClass extends jni.JObject { } } -class $MyDataClassType extends jni.JObjType { +final class $MyDataClassType extends jni.JObjType { const $MyDataClassType(); @override 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 b549cc89..7ac848d0 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 @@ -68,7 +68,7 @@ class Color extends jni.JObject { } } -class $ColorType extends jni.JObjType { +final class $ColorType extends jni.JObjType { const $ColorType(); @override @@ -718,7 +718,7 @@ class Example extends jni.JObject { } } -class $ExampleType extends jni.JObjType { +final class $ExampleType extends jni.JObjType { const $ExampleType(); @override @@ -799,7 +799,7 @@ class Example_Nested extends jni.JObject { } } -class $Example_NestedType extends jni.JObjType { +final class $Example_NestedType extends jni.JObjType { const $Example_NestedType(); @override @@ -865,7 +865,7 @@ class Example_Nested_NestedTwice extends jni.JObject { } } -class $Example_Nested_NestedTwiceType +final class $Example_Nested_NestedTwiceType extends jni.JObjType { const $Example_Nested_NestedTwiceType(); @@ -935,7 +935,7 @@ class Example_NonStaticNested extends jni.JObject { } } -class $Example_NonStaticNestedType +final class $Example_NonStaticNestedType extends jni.JObjType { const $Example_NonStaticNestedType(); @@ -1172,7 +1172,7 @@ class Exceptions extends jni.JObject { } } -class $ExceptionsType extends jni.JObjType { +final class $ExceptionsType extends jni.JObjType { const $ExceptionsType(); @override @@ -1383,7 +1383,7 @@ class Fields extends jni.JObject { } } -class $FieldsType extends jni.JObjType { +final class $FieldsType extends jni.JObjType { const $FieldsType(); @override @@ -1467,7 +1467,7 @@ class Fields_Nested extends jni.JObject { } } -class $Fields_NestedType extends jni.JObjType { +final class $Fields_NestedType extends jni.JObjType { const $Fields_NestedType(); @override @@ -1533,7 +1533,7 @@ class C2 extends jni.JObject { } } -class $C2Type extends jni.JObjType { +final class $C2Type extends jni.JObjType { const $C2Type(); @override @@ -1591,7 +1591,7 @@ class Example1 extends jni.JObject { } } -class $Example1Type extends jni.JObjType { +final class $Example1Type extends jni.JObjType { const $Example1Type(); @override @@ -1662,8 +1662,8 @@ class GenericTypeParams<$S extends jni.JObject, $K extends jni.JObject> } } -class $GenericTypeParamsType<$S extends jni.JObject, $K extends jni.JObject> - extends jni.JObjType> { +final class $GenericTypeParamsType<$S extends jni.JObject, + $K extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$S> S; final jni.JObjType<$K> K; @@ -1835,7 +1835,7 @@ class GrandParent<$T extends jni.JObject> extends jni.JObject { } } -class $GrandParentType<$T extends jni.JObject> +final class $GrandParentType<$T extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$T> T; @@ -1957,8 +1957,8 @@ class GrandParent_Parent<$T extends jni.JObject, $S extends jni.JObject> } } -class $GrandParent_ParentType<$T extends jni.JObject, $S extends jni.JObject> - extends jni.JObjType> { +final class $GrandParent_ParentType<$T extends jni.JObject, + $S extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$T> T; final jni.JObjType<$S> S; @@ -2111,7 +2111,7 @@ class GrandParent_Parent_Child<$T extends jni.JObject, $S extends jni.JObject, } } -class $GrandParent_Parent_ChildType<$T extends jni.JObject, +final class $GrandParent_Parent_ChildType<$T extends jni.JObject, $S extends jni.JObject, $U extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$T> T; @@ -2211,7 +2211,7 @@ class GrandParent_StaticParent<$S extends jni.JObject> extends jni.JObject { } } -class $GrandParent_StaticParentType<$S extends jni.JObject> +final class $GrandParent_StaticParentType<$S extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$S> S; @@ -2341,7 +2341,7 @@ class GrandParent_StaticParent_Child<$S extends jni.JObject, } } -class $GrandParent_StaticParent_ChildType<$S extends jni.JObject, +final class $GrandParent_StaticParent_ChildType<$S extends jni.JObject, $U extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$S> S; @@ -2464,7 +2464,7 @@ class MyMap<$K extends jni.JObject, $V extends jni.JObject> } } -class $MyMapType<$K extends jni.JObject, $V extends jni.JObject> +final class $MyMapType<$K extends jni.JObject, $V extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$K> K; final jni.JObjType<$V> V; @@ -2592,7 +2592,7 @@ class MyMap_MyEntry<$K extends jni.JObject, $V extends jni.JObject> } } -class $MyMap_MyEntryType<$K extends jni.JObject, $V extends jni.JObject> +final class $MyMap_MyEntryType<$K extends jni.JObject, $V extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$K> K; final jni.JObjType<$V> V; @@ -2797,7 +2797,8 @@ class MyStack<$T extends jni.JObject> extends jni.JObject { } } -class $MyStackType<$T extends jni.JObject> extends jni.JObjType> { +final class $MyStackType<$T extends jni.JObject> + extends jni.JObjType> { final jni.JObjType<$T> T; const $MyStackType( @@ -2866,7 +2867,7 @@ class StringKeyedMap<$V extends jni.JObject> extends MyMap { } } -class $StringKeyedMapType<$V extends jni.JObject> +final class $StringKeyedMapType<$V extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$V> V; @@ -2924,7 +2925,7 @@ class StringMap extends StringKeyedMap { } } -class $StringMapType extends jni.JObjType { +final class $StringMapType extends jni.JObjType { const $StringMapType(); @override @@ -2973,7 +2974,7 @@ class StringStack extends MyStack { } } -class $StringStackType extends jni.JObjType { +final class $StringStackType extends jni.JObjType { const $StringStackType(); @override @@ -3036,7 +3037,7 @@ class StringValuedMap<$K extends jni.JObject> extends MyMap<$K, jni.JString> { } } -class $StringValuedMapType<$K extends jni.JObject> +final class $StringValuedMapType<$K extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$K> K; @@ -3309,7 +3310,7 @@ class _$MyInterfaceImpl<$T extends jni.JObject> } } -class $MyInterfaceType<$T extends jni.JObject> +final class $MyInterfaceType<$T extends jni.JObject> extends jni.JObjType> { final jni.JObjType<$T> T; @@ -3430,7 +3431,7 @@ class MyInterfaceConsumer extends jni.JObject { } } -class $MyInterfaceConsumerType extends jni.JObjType { +final class $MyInterfaceConsumerType extends jni.JObjType { const $MyInterfaceConsumerType(); @override @@ -3569,7 +3570,7 @@ class _$MyRunnableImpl implements $MyRunnableImpl { } } -class $MyRunnableType extends jni.JObjType { +final class $MyRunnableType extends jni.JObjType { const $MyRunnableType(); @override @@ -3656,7 +3657,7 @@ class MyRunnableRunner extends jni.JObject { } } -class $MyRunnableRunnerType extends jni.JObjType { +final class $MyRunnableRunnerType extends jni.JObjType { const $MyRunnableRunnerType(); @override @@ -3725,7 +3726,8 @@ class JsonSerializable_Case extends jni.JObject { } } -class $JsonSerializable_CaseType extends jni.JObjType { +final class $JsonSerializable_CaseType + extends jni.JObjType { const $JsonSerializable_CaseType(); @override @@ -3777,7 +3779,7 @@ class MyDataClass extends jni.JObject { } } -class $MyDataClassType extends jni.JObjType { +final class $MyDataClassType extends jni.JObjType { const $MyDataClassType(); @override