diff --git a/pkgs/jni/CHANGELOG.md b/pkgs/jni/CHANGELOG.md index 1290ea14c..ab49de1ea 100644 --- a/pkgs/jni/CHANGELOG.md +++ b/pkgs/jni/CHANGELOG.md @@ -1,6 +1,10 @@ -## 0.12.0-wip +## 0.12.0 +- **Breaking Change**: Renamed `castTo` to `as`. - Renamed library `internal_helpers_for_jnigen` to `_internal`. +- Using 16KB page size to support Android 15. +- Added `JImplementer` which enables building an object that implements multiple + Java interfaces. ## 0.11.0 diff --git a/pkgs/jni/pubspec.yaml b/pkgs/jni/pubspec.yaml index 954db901e..4dea4acfe 100644 --- a/pkgs/jni/pubspec.yaml +++ b/pkgs/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.12.0-wip +version: 0.12.0 repository: https://github.com/dart-lang/native/tree/main/pkgs/jni topics: diff --git a/pkgs/jnigen/CHANGELOG.md b/pkgs/jnigen/CHANGELOG.md index dc71ab96f..e18420eee 100644 --- a/pkgs/jnigen/CHANGELOG.md +++ b/pkgs/jnigen/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.12.0-wip +## 0.12.0 - **Breaking Change**([#1530](https://github.com/dart-lang/native/pull/1530)): Changed the renaming strategy for method overloadings. Instead of adding a @@ -12,7 +12,6 @@ - **Breaking Change**: Removed the `Impl` suffix from the generated implemenation classes. So the implementation class for an interface named `Foo` is now simply called `$Foo` instead of `$FooImpl`. -- **Breaking Change**: Renamed `castTo` to `as`. - **Breaking Change**: Renamed and made the typeclasses internal. - **Breaking Change**: Relaxed the renaming rules to allow for more identifiers to remain unchanged. @@ -26,7 +25,6 @@ - No longer generating constructors for abstract classes. - No longer generating `protected` elements. - Fixed an issue where synthetic methods caused code generation to fail. -- Renamed library `internal_helpers_for_jnigen` to `_internal`. ## 0.11.0 diff --git a/pkgs/jnigen/example/in_app_java/lib/android_utils.dart b/pkgs/jnigen/example/in_app_java/lib/android_utils.dart index e249c9ef2..e42b9e681 100644 --- a/pkgs/jnigen/example/in_app_java/lib/android_utils.dart +++ b/pkgs/jnigen/example/in_app_java/lib/android_utils.dart @@ -51,6 +51,88 @@ class EmojiCompat_CodepointSequenceMatchResult extends _$jni.JObject { /// The type which includes information such as the signature of this class. static const type = $EmojiCompat_CodepointSequenceMatchResult$Type(); + + /// Maps a specific port to the implemented interface. + static final _$core.Map + _$impls = {}; + static _$jni.JObjectPtr _$invoke( + int port, + _$jni.JObjectPtr descriptor, + _$jni.JObjectPtr args, + ) { + return _$invokeMethod( + port, + _$jni.MethodInvocation.fromAddresses( + 0, + descriptor.address, + args.address, + ), + ); + } + + static final _$jni.Pointer< + _$jni.NativeFunction< + _$jni.JObjectPtr Function( + _$jni.Int64, _$jni.JObjectPtr, _$jni.JObjectPtr)>> + _$invokePointer = _$jni.Pointer.fromFunction(_$invoke); + + static _$jni.Pointer<_$jni.Void> _$invokeMethod( + int $p, + _$jni.MethodInvocation $i, + ) { + try { + final $d = $i.methodDescriptor.toDartString(releaseOriginal: true); + final $a = $i.args; + } catch (e) { + return _$jni.ProtectedJniExtensions.newDartException(e); + } + return _$jni.nullptr; + } + + static void implementIn( + _$jni.JImplementer implementer, + $EmojiCompat_CodepointSequenceMatchResult $impl, + ) { + late final _$jni.RawReceivePort $p; + $p = _$jni.RawReceivePort(($m) { + if ($m == null) { + _$impls.remove($p.sendPort.nativePort); + $p.close(); + return; + } + final $i = _$jni.MethodInvocation.fromMessage($m); + final $r = _$invokeMethod($p.sendPort.nativePort, $i); + _$jni.ProtectedJniExtensions.returnResult($i.result, $r); + }); + implementer.add( + r'androidx.emoji2.text.EmojiCompat$CodepointSequenceMatchResult', + $p, + _$invokePointer, + [], + ); + final $a = $p.sendPort.nativePort; + _$impls[$a] = $impl; + } + + factory EmojiCompat_CodepointSequenceMatchResult.implement( + $EmojiCompat_CodepointSequenceMatchResult $impl, + ) { + final $i = _$jni.JImplementer(); + implementIn($i, $impl); + return EmojiCompat_CodepointSequenceMatchResult.fromReference( + $i.implementReference(), + ); + } +} + +abstract mixin class $EmojiCompat_CodepointSequenceMatchResult { + factory $EmojiCompat_CodepointSequenceMatchResult() = + _$EmojiCompat_CodepointSequenceMatchResult; +} + +class _$EmojiCompat_CodepointSequenceMatchResult + implements $EmojiCompat_CodepointSequenceMatchResult { + _$EmojiCompat_CodepointSequenceMatchResult(); } final class $EmojiCompat_CodepointSequenceMatchResult$Type @@ -559,6 +641,115 @@ class EmojiCompat_GlyphChecker extends _$jni.JObject { charSequence.reference.pointer, i, i1, i2) .boolean; } + + /// Maps a specific port to the implemented interface. + static final _$core.Map _$impls = {}; + static _$jni.JObjectPtr _$invoke( + int port, + _$jni.JObjectPtr descriptor, + _$jni.JObjectPtr args, + ) { + return _$invokeMethod( + port, + _$jni.MethodInvocation.fromAddresses( + 0, + descriptor.address, + args.address, + ), + ); + } + + static final _$jni.Pointer< + _$jni.NativeFunction< + _$jni.JObjectPtr Function( + _$jni.Int64, _$jni.JObjectPtr, _$jni.JObjectPtr)>> + _$invokePointer = _$jni.Pointer.fromFunction(_$invoke); + + static _$jni.Pointer<_$jni.Void> _$invokeMethod( + int $p, + _$jni.MethodInvocation $i, + ) { + try { + final $d = $i.methodDescriptor.toDartString(releaseOriginal: true); + final $a = $i.args; + if ($d == r'hasGlyph(Ljava/lang/CharSequence;III)Z') { + final $r = _$impls[$p]!.hasGlyph( + $a[0].as(const _$jni.JObjectType(), releaseOriginal: true), + $a[1] + .as(const _$jni.JIntegerType(), releaseOriginal: true) + .intValue(releaseOriginal: true), + $a[2] + .as(const _$jni.JIntegerType(), releaseOriginal: true) + .intValue(releaseOriginal: true), + $a[3] + .as(const _$jni.JIntegerType(), releaseOriginal: true) + .intValue(releaseOriginal: true), + ); + return _$jni.JBoolean($r).reference.toPointer(); + } + } catch (e) { + return _$jni.ProtectedJniExtensions.newDartException(e); + } + return _$jni.nullptr; + } + + static void implementIn( + _$jni.JImplementer implementer, + $EmojiCompat_GlyphChecker $impl, + ) { + late final _$jni.RawReceivePort $p; + $p = _$jni.RawReceivePort(($m) { + if ($m == null) { + _$impls.remove($p.sendPort.nativePort); + $p.close(); + return; + } + final $i = _$jni.MethodInvocation.fromMessage($m); + final $r = _$invokeMethod($p.sendPort.nativePort, $i); + _$jni.ProtectedJniExtensions.returnResult($i.result, $r); + }); + implementer.add( + r'androidx.emoji2.text.EmojiCompat$GlyphChecker', + $p, + _$invokePointer, + [], + ); + final $a = $p.sendPort.nativePort; + _$impls[$a] = $impl; + } + + factory EmojiCompat_GlyphChecker.implement( + $EmojiCompat_GlyphChecker $impl, + ) { + final $i = _$jni.JImplementer(); + implementIn($i, $impl); + return EmojiCompat_GlyphChecker.fromReference( + $i.implementReference(), + ); + } +} + +abstract mixin class $EmojiCompat_GlyphChecker { + factory $EmojiCompat_GlyphChecker({ + required bool Function(_$jni.JObject charSequence, int i, int i1, int i2) + hasGlyph, + }) = _$EmojiCompat_GlyphChecker; + + bool hasGlyph(_$jni.JObject charSequence, int i, int i1, int i2); +} + +class _$EmojiCompat_GlyphChecker implements $EmojiCompat_GlyphChecker { + _$EmojiCompat_GlyphChecker({ + required bool Function(_$jni.JObject charSequence, int i, int i1, int i2) + hasGlyph, + }) : _hasGlyph = hasGlyph; + + final bool Function(_$jni.JObject charSequence, int i, int i1, int i2) + _hasGlyph; + + bool hasGlyph(_$jni.JObject charSequence, int i, int i1, int i2) { + return _hasGlyph(charSequence, i, i1, i2); + } } final class $EmojiCompat_GlyphChecker$Type @@ -708,6 +899,85 @@ class EmojiCompat_LoadStrategy extends _$jni.JObject { /// The type which includes information such as the signature of this class. static const type = $EmojiCompat_LoadStrategy$Type(); + + /// Maps a specific port to the implemented interface. + static final _$core.Map _$impls = {}; + static _$jni.JObjectPtr _$invoke( + int port, + _$jni.JObjectPtr descriptor, + _$jni.JObjectPtr args, + ) { + return _$invokeMethod( + port, + _$jni.MethodInvocation.fromAddresses( + 0, + descriptor.address, + args.address, + ), + ); + } + + static final _$jni.Pointer< + _$jni.NativeFunction< + _$jni.JObjectPtr Function( + _$jni.Int64, _$jni.JObjectPtr, _$jni.JObjectPtr)>> + _$invokePointer = _$jni.Pointer.fromFunction(_$invoke); + + static _$jni.Pointer<_$jni.Void> _$invokeMethod( + int $p, + _$jni.MethodInvocation $i, + ) { + try { + final $d = $i.methodDescriptor.toDartString(releaseOriginal: true); + final $a = $i.args; + } catch (e) { + return _$jni.ProtectedJniExtensions.newDartException(e); + } + return _$jni.nullptr; + } + + static void implementIn( + _$jni.JImplementer implementer, + $EmojiCompat_LoadStrategy $impl, + ) { + late final _$jni.RawReceivePort $p; + $p = _$jni.RawReceivePort(($m) { + if ($m == null) { + _$impls.remove($p.sendPort.nativePort); + $p.close(); + return; + } + final $i = _$jni.MethodInvocation.fromMessage($m); + final $r = _$invokeMethod($p.sendPort.nativePort, $i); + _$jni.ProtectedJniExtensions.returnResult($i.result, $r); + }); + implementer.add( + r'androidx.emoji2.text.EmojiCompat$LoadStrategy', + $p, + _$invokePointer, + [], + ); + final $a = $p.sendPort.nativePort; + _$impls[$a] = $impl; + } + + factory EmojiCompat_LoadStrategy.implement( + $EmojiCompat_LoadStrategy $impl, + ) { + final $i = _$jni.JImplementer(); + implementIn($i, $impl); + return EmojiCompat_LoadStrategy.fromReference( + $i.implementReference(), + ); + } +} + +abstract mixin class $EmojiCompat_LoadStrategy { + factory $EmojiCompat_LoadStrategy() = _$EmojiCompat_LoadStrategy; +} + +class _$EmojiCompat_LoadStrategy implements $EmojiCompat_LoadStrategy { + _$EmojiCompat_LoadStrategy(); } final class $EmojiCompat_LoadStrategy$Type @@ -783,6 +1053,118 @@ class EmojiCompat_MetadataRepoLoader extends _$jni.JObject { metadataRepoLoaderCallback.reference.pointer) .check(); } + + /// Maps a specific port to the implemented interface. + static final _$core.Map _$impls = {}; + static _$jni.JObjectPtr _$invoke( + int port, + _$jni.JObjectPtr descriptor, + _$jni.JObjectPtr args, + ) { + return _$invokeMethod( + port, + _$jni.MethodInvocation.fromAddresses( + 0, + descriptor.address, + args.address, + ), + ); + } + + static final _$jni.Pointer< + _$jni.NativeFunction< + _$jni.JObjectPtr Function( + _$jni.Int64, _$jni.JObjectPtr, _$jni.JObjectPtr)>> + _$invokePointer = _$jni.Pointer.fromFunction(_$invoke); + + static _$jni.Pointer<_$jni.Void> _$invokeMethod( + int $p, + _$jni.MethodInvocation $i, + ) { + try { + final $d = $i.methodDescriptor.toDartString(releaseOriginal: true); + final $a = $i.args; + if ($d == + r'load(Landroidx/emoji2/text/EmojiCompat$MetadataRepoLoaderCallback;)V') { + _$impls[$p]!.load( + $a[0].as(const $EmojiCompat_MetadataRepoLoaderCallback$Type(), + releaseOriginal: true), + ); + return _$jni.nullptr; + } + } catch (e) { + return _$jni.ProtectedJniExtensions.newDartException(e); + } + return _$jni.nullptr; + } + + static void implementIn( + _$jni.JImplementer implementer, + $EmojiCompat_MetadataRepoLoader $impl, + ) { + late final _$jni.RawReceivePort $p; + $p = _$jni.RawReceivePort(($m) { + if ($m == null) { + _$impls.remove($p.sendPort.nativePort); + $p.close(); + return; + } + final $i = _$jni.MethodInvocation.fromMessage($m); + final $r = _$invokeMethod($p.sendPort.nativePort, $i); + _$jni.ProtectedJniExtensions.returnResult($i.result, $r); + }); + implementer.add( + r'androidx.emoji2.text.EmojiCompat$MetadataRepoLoader', + $p, + _$invokePointer, + [ + if ($impl.load$async) + r'load(Landroidx/emoji2/text/EmojiCompat$MetadataRepoLoaderCallback;)V', + ], + ); + final $a = $p.sendPort.nativePort; + _$impls[$a] = $impl; + } + + factory EmojiCompat_MetadataRepoLoader.implement( + $EmojiCompat_MetadataRepoLoader $impl, + ) { + final $i = _$jni.JImplementer(); + implementIn($i, $impl); + return EmojiCompat_MetadataRepoLoader.fromReference( + $i.implementReference(), + ); + } +} + +abstract mixin class $EmojiCompat_MetadataRepoLoader { + factory $EmojiCompat_MetadataRepoLoader({ + required void Function( + EmojiCompat_MetadataRepoLoaderCallback metadataRepoLoaderCallback) + load, + bool load$async, + }) = _$EmojiCompat_MetadataRepoLoader; + + void load(EmojiCompat_MetadataRepoLoaderCallback metadataRepoLoaderCallback); + bool get load$async => false; +} + +class _$EmojiCompat_MetadataRepoLoader + implements $EmojiCompat_MetadataRepoLoader { + _$EmojiCompat_MetadataRepoLoader({ + required void Function( + EmojiCompat_MetadataRepoLoaderCallback metadataRepoLoaderCallback) + load, + this.load$async = false, + }) : _load = load; + + final void Function( + EmojiCompat_MetadataRepoLoaderCallback metadataRepoLoaderCallback) _load; + final bool load$async; + + void load(EmojiCompat_MetadataRepoLoaderCallback metadataRepoLoaderCallback) { + return _load(metadataRepoLoaderCallback); + } } final class $EmojiCompat_MetadataRepoLoader$Type @@ -938,6 +1320,85 @@ class EmojiCompat_ReplaceStrategy extends _$jni.JObject { /// The type which includes information such as the signature of this class. static const type = $EmojiCompat_ReplaceStrategy$Type(); + + /// Maps a specific port to the implemented interface. + static final _$core.Map _$impls = {}; + static _$jni.JObjectPtr _$invoke( + int port, + _$jni.JObjectPtr descriptor, + _$jni.JObjectPtr args, + ) { + return _$invokeMethod( + port, + _$jni.MethodInvocation.fromAddresses( + 0, + descriptor.address, + args.address, + ), + ); + } + + static final _$jni.Pointer< + _$jni.NativeFunction< + _$jni.JObjectPtr Function( + _$jni.Int64, _$jni.JObjectPtr, _$jni.JObjectPtr)>> + _$invokePointer = _$jni.Pointer.fromFunction(_$invoke); + + static _$jni.Pointer<_$jni.Void> _$invokeMethod( + int $p, + _$jni.MethodInvocation $i, + ) { + try { + final $d = $i.methodDescriptor.toDartString(releaseOriginal: true); + final $a = $i.args; + } catch (e) { + return _$jni.ProtectedJniExtensions.newDartException(e); + } + return _$jni.nullptr; + } + + static void implementIn( + _$jni.JImplementer implementer, + $EmojiCompat_ReplaceStrategy $impl, + ) { + late final _$jni.RawReceivePort $p; + $p = _$jni.RawReceivePort(($m) { + if ($m == null) { + _$impls.remove($p.sendPort.nativePort); + $p.close(); + return; + } + final $i = _$jni.MethodInvocation.fromMessage($m); + final $r = _$invokeMethod($p.sendPort.nativePort, $i); + _$jni.ProtectedJniExtensions.returnResult($i.result, $r); + }); + implementer.add( + r'androidx.emoji2.text.EmojiCompat$ReplaceStrategy', + $p, + _$invokePointer, + [], + ); + final $a = $p.sendPort.nativePort; + _$impls[$a] = $impl; + } + + factory EmojiCompat_ReplaceStrategy.implement( + $EmojiCompat_ReplaceStrategy $impl, + ) { + final $i = _$jni.JImplementer(); + implementIn($i, $impl); + return EmojiCompat_ReplaceStrategy.fromReference( + $i.implementReference(), + ); + } +} + +abstract mixin class $EmojiCompat_ReplaceStrategy { + factory $EmojiCompat_ReplaceStrategy() = _$EmojiCompat_ReplaceStrategy; +} + +class _$EmojiCompat_ReplaceStrategy implements $EmojiCompat_ReplaceStrategy { + _$EmojiCompat_ReplaceStrategy(); } final class $EmojiCompat_ReplaceStrategy$Type @@ -1014,6 +1475,110 @@ class EmojiCompat_SpanFactory extends _$jni.JObject { typefaceEmojiRasterizer.reference.pointer) .object(const _$jni.JObjectType()); } + + /// Maps a specific port to the implemented interface. + static final _$core.Map _$impls = {}; + static _$jni.JObjectPtr _$invoke( + int port, + _$jni.JObjectPtr descriptor, + _$jni.JObjectPtr args, + ) { + return _$invokeMethod( + port, + _$jni.MethodInvocation.fromAddresses( + 0, + descriptor.address, + args.address, + ), + ); + } + + static final _$jni.Pointer< + _$jni.NativeFunction< + _$jni.JObjectPtr Function( + _$jni.Int64, _$jni.JObjectPtr, _$jni.JObjectPtr)>> + _$invokePointer = _$jni.Pointer.fromFunction(_$invoke); + + static _$jni.Pointer<_$jni.Void> _$invokeMethod( + int $p, + _$jni.MethodInvocation $i, + ) { + try { + final $d = $i.methodDescriptor.toDartString(releaseOriginal: true); + final $a = $i.args; + if ($d == + r'createSpan(Landroidx/emoji2/text/TypefaceEmojiRasterizer;)Landroidx/emoji2/text/EmojiSpan;') { + final $r = _$impls[$p]!.createSpan( + $a[0].as(const _$jni.JObjectType(), releaseOriginal: true), + ); + return ($r as _$jni.JObject) + .as(const _$jni.JObjectType()) + .reference + .toPointer(); + } + } catch (e) { + return _$jni.ProtectedJniExtensions.newDartException(e); + } + return _$jni.nullptr; + } + + static void implementIn( + _$jni.JImplementer implementer, + $EmojiCompat_SpanFactory $impl, + ) { + late final _$jni.RawReceivePort $p; + $p = _$jni.RawReceivePort(($m) { + if ($m == null) { + _$impls.remove($p.sendPort.nativePort); + $p.close(); + return; + } + final $i = _$jni.MethodInvocation.fromMessage($m); + final $r = _$invokeMethod($p.sendPort.nativePort, $i); + _$jni.ProtectedJniExtensions.returnResult($i.result, $r); + }); + implementer.add( + r'androidx.emoji2.text.EmojiCompat$SpanFactory', + $p, + _$invokePointer, + [], + ); + final $a = $p.sendPort.nativePort; + _$impls[$a] = $impl; + } + + factory EmojiCompat_SpanFactory.implement( + $EmojiCompat_SpanFactory $impl, + ) { + final $i = _$jni.JImplementer(); + implementIn($i, $impl); + return EmojiCompat_SpanFactory.fromReference( + $i.implementReference(), + ); + } +} + +abstract mixin class $EmojiCompat_SpanFactory { + factory $EmojiCompat_SpanFactory({ + required _$jni.JObject Function(_$jni.JObject typefaceEmojiRasterizer) + createSpan, + }) = _$EmojiCompat_SpanFactory; + + _$jni.JObject createSpan(_$jni.JObject typefaceEmojiRasterizer); +} + +class _$EmojiCompat_SpanFactory implements $EmojiCompat_SpanFactory { + _$EmojiCompat_SpanFactory({ + required _$jni.JObject Function(_$jni.JObject typefaceEmojiRasterizer) + createSpan, + }) : _createSpan = createSpan; + + final _$jni.JObject Function(_$jni.JObject typefaceEmojiRasterizer) + _createSpan; + + _$jni.JObject createSpan(_$jni.JObject typefaceEmojiRasterizer) { + return _createSpan(typefaceEmojiRasterizer); + } } final class $EmojiCompat_SpanFactory$Type diff --git a/pkgs/jnigen/lib/src/bindings/dart_generator.dart b/pkgs/jnigen/lib/src/bindings/dart_generator.dart index 57af2deca..b87f39a36 100644 --- a/pkgs/jnigen/lib/src/bindings/dart_generator.dart +++ b/pkgs/jnigen/lib/src/bindings/dart_generator.dart @@ -7,7 +7,6 @@ import 'dart:io'; import 'package:meta/meta.dart'; import '../config/config.dart'; -import '../config/experiments.dart'; import '../elements/elements.dart'; import '../logging/logging.dart'; import '../util/string_util.dart'; @@ -402,10 +401,7 @@ class $name$typeParamsDef extends $superName { // Fields and Methods generateFieldsAndMethods(node, classRef); - // Experimental: Interface implementation. - if (node.declKind == DeclKind.interfaceKind && - (config.experiments?.contains(Experiment.interfaceImplementation) ?? - false)) { + if (node.declKind == DeclKind.interfaceKind) { s.write(''' /// Maps a specific port to the implemented interface. static final $_core.Map _\$impls = {}; @@ -513,12 +509,9 @@ class $name$typeParamsDef extends $superName { // End of Class definition. s.writeln('}'); - // Experimental: Interface implementation // Abstract and concrete Impl class definition. // Used for interface implementation. - if (node.declKind == DeclKind.interfaceKind && - (config.experiments?.contains(Experiment.interfaceImplementation) ?? - false)) { + if (node.declKind == DeclKind.interfaceKind) { // Abstract Impl class. final typeClassGetters = typeParams .map((typeParam) => diff --git a/pkgs/jnigen/lib/src/config/experiments.dart b/pkgs/jnigen/lib/src/config/experiments.dart index 9e3105760..55afcf32c 100644 --- a/pkgs/jnigen/lib/src/config/experiments.dart +++ b/pkgs/jnigen/lib/src/config/experiments.dart @@ -5,35 +5,38 @@ import '../logging/logging.dart'; class Experiment { - static const available = [ + static const _available = [ + // ignore: deprecated_member_use_from_same_package interfaceImplementation, ]; + @Deprecated('The experiment is enabled by default') static const interfaceImplementation = Experiment( name: 'interface_implementation', description: 'Enables generation of machinery for ' 'implementing Java interfaces in Dart.', - isExpired: false, + expired: 'The experiment is enabled by default', ); final String name; final String description; - final bool isExpired; + final String? expired; const Experiment({ required this.name, required this.description, - required this.isExpired, + required this.expired, }); factory Experiment.fromString(String s) { - final search = available.where((element) => element.name == s); + final search = _available.where((element) => element.name == s); if (search.isEmpty) { log.fatal('The experiment $s is not available in this version.'); } final result = search.single; - if (result.isExpired) { - log.fatal('The experiment $s can no longer be used in this version.'); + if (result.expired != null) { + log.fatal('The experiment $s can no longer be used in this version: ' + '${result.expired}.'); } return result; } diff --git a/pkgs/jnigen/pubspec.yaml b/pkgs/jnigen/pubspec.yaml index a99beac93..3c922d5b5 100644 --- a/pkgs/jnigen/pubspec.yaml +++ b/pkgs/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.12.0-wip +version: 0.12.0 repository: https://github.com/dart-lang/native/tree/main/pkgs/jnigen environment: diff --git a/pkgs/jnigen/test/jackson_core_test/generate.dart b/pkgs/jnigen/test/jackson_core_test/generate.dart index 6ee6b0cab..e7653df22 100644 --- a/pkgs/jnigen/test/jackson_core_test/generate.dart +++ b/pkgs/jnigen/test/jackson_core_test/generate.dart @@ -3,7 +3,6 @@ // BSD-style license that can be found in the LICENSE file. import 'package:jnigen/jnigen.dart'; -import 'package:jnigen/src/config/experiments.dart'; import 'package:logging/logging.dart'; import 'package:path/path.dart' hide equals; @@ -71,7 +70,6 @@ Config getConfig({ 'com.fasterxml.jackson.core.JsonFactoryBuilder', ), ), - experiments: {Experiment.interfaceImplementation}, ); return config; } diff --git a/pkgs/jnigen/test/jackson_core_test/jnigen.yaml b/pkgs/jnigen/test/jackson_core_test/jnigen.yaml index 66bd515ee..f0f7eedd8 100644 --- a/pkgs/jnigen/test/jackson_core_test/jnigen.yaml +++ b/pkgs/jnigen/test/jackson_core_test/jnigen.yaml @@ -39,6 +39,3 @@ preamble: | // limitations under the License. log_level: warning - -enable_experiment: - - interface_implementation diff --git a/pkgs/jnigen/test/kotlin_test/bindings/kotlin.dart b/pkgs/jnigen/test/kotlin_test/bindings/kotlin.dart index 92aae7dfe..7290cad2f 100644 --- a/pkgs/jnigen/test/kotlin_test/bindings/kotlin.dart +++ b/pkgs/jnigen/test/kotlin_test/bindings/kotlin.dart @@ -243,6 +243,117 @@ class MeasureUnit extends _$jni.JObject { reference.pointer, _id_getCoefficient as _$jni.JMethodIDPtr) .float; } + + /// Maps a specific port to the implemented interface. + static final _$core.Map _$impls = {}; + static _$jni.JObjectPtr _$invoke( + int port, + _$jni.JObjectPtr descriptor, + _$jni.JObjectPtr args, + ) { + return _$invokeMethod( + port, + _$jni.MethodInvocation.fromAddresses( + 0, + descriptor.address, + args.address, + ), + ); + } + + static final _$jni.Pointer< + _$jni.NativeFunction< + _$jni.JObjectPtr Function( + _$jni.Int64, _$jni.JObjectPtr, _$jni.JObjectPtr)>> + _$invokePointer = _$jni.Pointer.fromFunction(_$invoke); + + static _$jni.Pointer<_$jni.Void> _$invokeMethod( + int $p, + _$jni.MethodInvocation $i, + ) { + try { + final $d = $i.methodDescriptor.toDartString(releaseOriginal: true); + final $a = $i.args; + if ($d == r'getSign()Ljava/lang/String;') { + final $r = _$impls[$p]!.getSign(); + return ($r as _$jni.JObject) + .as(const _$jni.JObjectType()) + .reference + .toPointer(); + } + if ($d == r'getCoefficient()F') { + final $r = _$impls[$p]!.getCoefficient(); + return _$jni.JFloat($r).reference.toPointer(); + } + } catch (e) { + return _$jni.ProtectedJniExtensions.newDartException(e); + } + return _$jni.nullptr; + } + + static void implementIn( + _$jni.JImplementer implementer, + $MeasureUnit $impl, + ) { + late final _$jni.RawReceivePort $p; + $p = _$jni.RawReceivePort(($m) { + if ($m == null) { + _$impls.remove($p.sendPort.nativePort); + $p.close(); + return; + } + final $i = _$jni.MethodInvocation.fromMessage($m); + final $r = _$invokeMethod($p.sendPort.nativePort, $i); + _$jni.ProtectedJniExtensions.returnResult($i.result, $r); + }); + implementer.add( + r'com.github.dart_lang.jnigen.MeasureUnit', + $p, + _$invokePointer, + [], + ); + final $a = $p.sendPort.nativePort; + _$impls[$a] = $impl; + } + + factory MeasureUnit.implement( + $MeasureUnit $impl, + ) { + final $i = _$jni.JImplementer(); + implementIn($i, $impl); + return MeasureUnit.fromReference( + $i.implementReference(), + ); + } +} + +abstract mixin class $MeasureUnit { + factory $MeasureUnit({ + required _$jni.JString Function() getSign, + required double Function() getCoefficient, + }) = _$MeasureUnit; + + _$jni.JString getSign(); + double getCoefficient(); +} + +class _$MeasureUnit implements $MeasureUnit { + _$MeasureUnit({ + required _$jni.JString Function() getSign, + required double Function() getCoefficient, + }) : _getSign = getSign, + _getCoefficient = getCoefficient; + + final _$jni.JString Function() _getSign; + final double Function() _getCoefficient; + + _$jni.JString getSign() { + return _getSign(); + } + + double getCoefficient() { + return _getCoefficient(); + } } final class $MeasureUnit$Type extends _$jni.JObjType { diff --git a/pkgs/jnigen/test/simple_package_test/generate.dart b/pkgs/jnigen/test/simple_package_test/generate.dart index b91478059..ba55b3483 100644 --- a/pkgs/jnigen/test/simple_package_test/generate.dart +++ b/pkgs/jnigen/test/simple_package_test/generate.dart @@ -5,7 +5,6 @@ import 'dart:io'; import 'package:jnigen/jnigen.dart'; -import 'package:jnigen/src/config/experiments.dart'; import 'package:jnigen/src/logging/logging.dart'; import 'package:logging/logging.dart'; import 'package:path/path.dart'; @@ -92,7 +91,6 @@ Config getConfig() { ), ), preamble: preamble, - experiments: {Experiment.interfaceImplementation}, ); return config; }