diff --git a/pkgs/ffigen/CHANGELOG.md b/pkgs/ffigen/CHANGELOG.md index 77aa32042..912717e4e 100644 --- a/pkgs/ffigen/CHANGELOG.md +++ b/pkgs/ffigen/CHANGELOG.md @@ -8,6 +8,8 @@ - https://github.com/dart-lang/native/issues/1582 - https://github.com/dart-lang/native/issues/1594 - https://github.com/dart-lang/native/issues/1595 +- Fix [a bug](https://github.com/dart-lang/native/issues/1701) where nullable + typealiases were treated as non-null. - Allow static and instance methods to have the same name: https://github.com/dart-lang/native/issues/1136 - __Breaking change__: Change the way ObjC categories are generated. Instead of diff --git a/pkgs/ffigen/lib/src/code_generator/objc_nullable.dart b/pkgs/ffigen/lib/src/code_generator/objc_nullable.dart index 4d508fa56..ca9104fa6 100644 --- a/pkgs/ffigen/lib/src/code_generator/objc_nullable.dart +++ b/pkgs/ffigen/lib/src/code_generator/objc_nullable.dart @@ -13,10 +13,11 @@ class ObjCNullable extends Type { Type child; ObjCNullable(this.child) - : assert(isSupported(child.typealiasType), + : assert(isSupported(child), 'Nullable ${child.typealiasType.runtimeType} is not supported'); - static bool isSupported(Type type) => + static bool isSupported(Type type) => _isSupported(type.typealiasType); + static bool _isSupported(Type type) => type is ObjCInterface || type is ObjCBlock || type is ObjCObjectPointer || diff --git a/pkgs/ffigen/test/native_objc_test/nullable_test.dart b/pkgs/ffigen/test/native_objc_test/nullable_test.dart index 0d6da50bc..46ed32626 100644 --- a/pkgs/ffigen/test/native_objc_test/nullable_test.dart +++ b/pkgs/ffigen/test/native_objc_test/nullable_test.dart @@ -71,5 +71,11 @@ void main() { false); }); }); + + test('Nullable typealias', () { + // Regression test for https://github.com/dart-lang/native/issues/1701 + expect(NullableInterface.returnNullableAlias_(true), isNull); + expect(NullableInterface.returnNullableAlias_(false)?.toString(), "Hi"); + }); }); } diff --git a/pkgs/ffigen/test/native_objc_test/nullable_test.m b/pkgs/ffigen/test/native_objc_test/nullable_test.m index 06d257d59..82f573b85 100644 --- a/pkgs/ffigen/test/native_objc_test/nullable_test.m +++ b/pkgs/ffigen/test/native_objc_test/nullable_test.m @@ -1,5 +1,7 @@ #import +typedef NSString* MyString; + @interface NullableInterface : NSObject { } @@ -7,6 +9,7 @@ +(BOOL) isNullWithNullableNSObjectArg:(nullable NSObject *)x; +(BOOL) isNullWithNotNullableNSObjectPtrArg:(NSObject *)x; +(BOOL) isNullWithExplicitNonNullableNSObjectPtrArg:(nonnull NSObject *)x; +(nullable NSObject *) returnNil:(BOOL)r; ++(nullable MyString) returnNullableAlias:(BOOL)r; @property (nullable, retain) NSObject *nullableObjectProperty; @@ -34,4 +37,12 @@ +(nullable NSObject *) returnNil:(BOOL)r { } } ++(nullable MyString) returnNullableAlias:(BOOL)r { + if (r) { + return nil; + } else { + return @"Hi"; + } +} + @end diff --git a/pkgs/objective_c/lib/src/objective_c_bindings_generated.dart b/pkgs/objective_c/lib/src/objective_c_bindings_generated.dart index a8117be61..a8b89be9f 100644 --- a/pkgs/objective_c/lib/src/objective_c_bindings_generated.dart +++ b/pkgs/objective_c/lib/src/objective_c_bindings_generated.dart @@ -44,6 +44,14 @@ external ffi.Pointer ffi.Pointer block, ); +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer)>(isLeaf: true) +external ffi.Pointer + _ObjectiveCBindings_wrapListenerBlock_1j2nt86( + ffi.Pointer block, +); + @ffi.Native< ffi.Pointer Function( ffi.Pointer)>(isLeaf: true) @@ -60,6 +68,14 @@ external ffi.Pointer ffi.Pointer block, ); +@ffi.Native< + ffi.Pointer Function( + ffi.Pointer)>(isLeaf: true) +external ffi.Pointer + _ObjectiveCBindings_wrapListenerBlock_wjvic9( + ffi.Pointer block, +); + /// Helper class to adapt a Dart stream into a `NSInputStream`. class DartInputStreamAdapter extends NSInputStream { DartInputStreamAdapter._(ffi.Pointer pointer, @@ -1571,10 +1587,12 @@ class NSDictionary extends NSObject { } /// objectForKey: - objc.ObjCObjectBase objectForKey_(objc.ObjCObjectBase aKey) { + objc.ObjCObjectBase? objectForKey_(objc.ObjCObjectBase aKey) { final _ret = _objc_msgSend_62nh5j( this.ref.pointer, _sel_objectForKey_, aKey.ref.pointer); - return objc.ObjCObjectBase(_ret, retain: true, release: true); + return _ret.address == 0 + ? null + : objc.ObjCObjectBase(_ret, retain: true, release: true); } } @@ -1650,9 +1668,11 @@ class NSEnumerator extends NSObject { } /// nextObject - objc.ObjCObjectBase nextObject() { + objc.ObjCObjectBase? nextObject() { final _ret = _objc_msgSend_1x359cv(this.ref.pointer, _sel_nextObject); - return objc.ObjCObjectBase(_ret, retain: true, release: true); + return _ret.address == 0 + ? null + : objc.ObjCObjectBase(_ret, retain: true, release: true); } } @@ -2291,6 +2311,20 @@ class NSItemProvider extends NSObject { return NSItemProvider.castFromPointer(_ret, retain: false, release: true); } + /// loadItemForTypeIdentifier:options:completionHandler: + void loadItemForTypeIdentifier_options_completionHandler_( + NSString typeIdentifier, + NSDictionary? options, + objc.ObjCBlock?, NSError)>? + completionHandler) { + _objc_msgSend_91c9gi( + this.ref.pointer, + _sel_loadItemForTypeIdentifier_options_completionHandler_, + typeIdentifier.ref.pointer, + options?.ref.pointer ?? ffi.nullptr, + completionHandler?.ref.pointer ?? ffi.nullptr); + } + /// registerObject:visibility: void registerObject_visibility_(objc.ObjCObjectBase object, NSItemProviderRepresentationVisibility visibility) { @@ -5939,10 +5973,12 @@ class NSSet extends NSObject { } /// member: - objc.ObjCObjectBase member_(objc.ObjCObjectBase object) { + objc.ObjCObjectBase? member_(objc.ObjCObjectBase object) { final _ret = _objc_msgSend_62nh5j( this.ref.pointer, _sel_member_, object.ref.pointer); - return objc.ObjCObjectBase(_ret, retain: true, release: true); + return _ret.address == 0 + ? null + : objc.ObjCObjectBase(_ret, retain: true, release: true); } /// objectEnumerator @@ -9139,6 +9175,212 @@ extension ObjCBlock_bool_ffiVoid_objcObjCSelector_CallExtension ffi.Pointer)>()(ref.pointer, arg0, arg1); } +void + _ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary_fnPtrTrampoline( + ffi.Pointer block, + ffi.Pointer arg0, + ffi.Pointer arg1, + ffi.Pointer arg2) => + block.ref.target + .cast< + ffi.NativeFunction< + ffi.Void Function( + ffi.Pointer arg0, + ffi.Pointer arg1, + ffi.Pointer arg2)>>() + .asFunction< + void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>()(arg0, arg1, arg2); +ffi.Pointer + _ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary_fnPtrCallable = + ffi.Pointer.fromFunction< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>( + _ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary_fnPtrTrampoline) + .cast(); +void + _ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary_closureTrampoline( + ffi.Pointer block, + ffi.Pointer arg0, + ffi.Pointer arg1, + ffi.Pointer arg2) => + (objc.getBlockClosure(block) as void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer))(arg0, arg1, arg2); +ffi.Pointer + _ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary_closureCallable = + ffi.Pointer.fromFunction< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>( + _ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary_closureTrampoline) + .cast(); +void + _ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary_listenerTrampoline( + ffi.Pointer block, + ffi.Pointer arg0, + ffi.Pointer arg1, + ffi.Pointer arg2) { + (objc.getBlockClosure(block) as void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer))(arg0, arg1, arg2); + objc.objectRelease(block.cast()); +} + +ffi.NativeCallable< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)> + _ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary_listenerCallable = + ffi.NativeCallable< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>.listener( + _ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary_listenerTrampoline) + ..keepIsolateAlive = false; + +/// Construction methods for `objc.ObjCBlock?, NSError)>, ffi.Pointer, NSDictionary)>`. +abstract final class ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary { + /// Returns a block that wraps the given raw block pointer. + static objc.ObjCBlock< + ffi.Void Function( + objc.ObjCBlock< + ffi.Void Function(ffi.Pointer?, NSError)>, + ffi.Pointer, + NSDictionary)> + castFromPointer(ffi.Pointer pointer, {bool retain = false, bool release = false}) => + objc.ObjCBlock< + ffi.Void Function( + objc.ObjCBlock?, NSError)>, + ffi.Pointer, + NSDictionary)>(pointer, retain: retain, release: release); + + /// Creates a block from a C function pointer. + /// + /// This block must be invoked by native code running on the same thread as + /// the isolate that registered it. Invoking the block on the wrong thread + /// will result in a crash. + static objc.ObjCBlock< + ffi.Void Function( + objc.ObjCBlock< + ffi.Void Function(ffi.Pointer?, NSError)>, + ffi.Pointer, + NSDictionary)> + fromFunctionPointer(ffi.Pointer arg0, ffi.Pointer arg1, ffi.Pointer arg2)>> ptr) => + objc.ObjCBlock< + ffi.Void Function( + objc.ObjCBlock?, NSError)>, + ffi.Pointer, + NSDictionary)>(objc.newPointerBlock(_ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary_fnPtrCallable, ptr.cast()), retain: false, release: true); + + /// Creates a block from a Dart function. + /// + /// This block must be invoked by native code running on the same thread as + /// the isolate that registered it. Invoking the block on the wrong thread + /// will result in a crash. + static objc.ObjCBlock?, NSError)>, ffi.Pointer, NSDictionary)> + fromFunction(void Function(objc.ObjCBlock?, NSError)>, objc.ObjCObjectBase, NSDictionary) fn) => + objc.ObjCBlock?, NSError)>, ffi.Pointer, NSDictionary)>( + objc.newClosureBlock( + _ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary_closureCallable, + (ffi.Pointer arg0, + ffi.Pointer arg1, + ffi.Pointer arg2) => + fn( + ObjCBlock_ffiVoid_objcObjCObject_NSError.castFromPointer(arg0, retain: true, release: true), + objc.ObjCObjectBase(arg1, retain: true, release: true), + NSDictionary.castFromPointer(arg2, retain: true, release: true))), + retain: false, + release: true); + + /// Creates a listener block from a Dart function. + /// + /// This is based on FFI's NativeCallable.listener, and has the same + /// capabilities and limitations. This block can be invoked from any thread, + /// but only supports void functions, and is not run synchronously. See + /// NativeCallable.listener for more details. + /// + /// Note that unlike the default behavior of NativeCallable.listener, listener + /// blocks do not keep the isolate alive. + static objc.ObjCBlock< + ffi.Void Function( + objc.ObjCBlock< + ffi.Void Function(ffi.Pointer?, NSError)>, + ffi.Pointer, + NSDictionary)> listener( + void Function( + objc.ObjCBlock< + ffi.Void Function(ffi.Pointer?, NSError)>, + objc.ObjCObjectBase, + NSDictionary) + fn) { + final raw = objc.newClosureBlock( + _ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary_listenerCallable + .nativeFunction + .cast(), + (ffi.Pointer arg0, + ffi.Pointer arg1, + ffi.Pointer arg2) => + fn( + ObjCBlock_ffiVoid_objcObjCObject_NSError.castFromPointer(arg0, + retain: false, release: true), + objc.ObjCObjectBase(arg1, retain: false, release: true), + NSDictionary.castFromPointer(arg2, + retain: false, release: true))); + final wrapper = _ObjectiveCBindings_wrapListenerBlock_1j2nt86(raw); + objc.objectRelease(raw.cast()); + return objc.ObjCBlock< + ffi.Void Function( + objc.ObjCBlock< + ffi.Void Function(ffi.Pointer?, NSError)>, + ffi.Pointer, + NSDictionary)>(wrapper, retain: false, release: true); + } +} + +/// Call operator for `objc.ObjCBlock?, NSError)>, ffi.Pointer, NSDictionary)>`. +extension ObjCBlock_ffiVoid_NSItemProviderCompletionHandler_objcObjCObject_NSDictionary_CallExtension + on objc.ObjCBlock< + ffi.Void Function( + objc.ObjCBlock< + ffi.Void Function(ffi.Pointer?, NSError)>, + ffi.Pointer, + NSDictionary)> { + void call( + objc.ObjCBlock?, NSError)> + arg0, + objc.ObjCObjectBase arg1, + NSDictionary arg2) => + ref.pointer.ref.invoke + .cast< + ffi.NativeFunction< + ffi.Void Function( + ffi.Pointer block, + ffi.Pointer arg0, + ffi.Pointer arg1, + ffi.Pointer arg2)>>() + .asFunction< + void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>()( + ref.pointer, arg0.ref.pointer, arg1.ref.pointer, arg2.ref.pointer); +} + void _ObjCBlock_ffiVoid_ffiVoid_fnPtrTrampoline( ffi.Pointer block, ffi.Pointer arg0) => block.ref.target @@ -9548,6 +9790,158 @@ extension ObjCBlock_ffiVoid_ffiVoid_NSStream_NSStreamEvent_CallExtension int)>()(ref.pointer, arg0, arg1.ref.pointer, arg2.value); } +void _ObjCBlock_ffiVoid_objcObjCObject_NSError_fnPtrTrampoline( + ffi.Pointer block, + ffi.Pointer arg0, + ffi.Pointer arg1) => + block.ref.target + .cast< + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer arg0, + ffi.Pointer arg1)>>() + .asFunction< + void Function(ffi.Pointer, + ffi.Pointer)>()(arg0, arg1); +ffi.Pointer _ObjCBlock_ffiVoid_objcObjCObject_NSError_fnPtrCallable = + ffi.Pointer.fromFunction< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>( + _ObjCBlock_ffiVoid_objcObjCObject_NSError_fnPtrTrampoline) + .cast(); +void _ObjCBlock_ffiVoid_objcObjCObject_NSError_closureTrampoline( + ffi.Pointer block, + ffi.Pointer arg0, + ffi.Pointer arg1) => + (objc.getBlockClosure(block) as void Function(ffi.Pointer, + ffi.Pointer))(arg0, arg1); +ffi.Pointer + _ObjCBlock_ffiVoid_objcObjCObject_NSError_closureCallable = + ffi.Pointer.fromFunction< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>( + _ObjCBlock_ffiVoid_objcObjCObject_NSError_closureTrampoline) + .cast(); +void _ObjCBlock_ffiVoid_objcObjCObject_NSError_listenerTrampoline( + ffi.Pointer block, + ffi.Pointer arg0, + ffi.Pointer arg1) { + (objc.getBlockClosure(block) as void Function( + ffi.Pointer, ffi.Pointer))(arg0, arg1); + objc.objectRelease(block.cast()); +} + +ffi.NativeCallable< + ffi.Void Function(ffi.Pointer, + ffi.Pointer, ffi.Pointer)> + _ObjCBlock_ffiVoid_objcObjCObject_NSError_listenerCallable = ffi + .NativeCallable< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>.listener( + _ObjCBlock_ffiVoid_objcObjCObject_NSError_listenerTrampoline) + ..keepIsolateAlive = false; + +/// Construction methods for `objc.ObjCBlock?, NSError)>`. +abstract final class ObjCBlock_ffiVoid_objcObjCObject_NSError { + /// Returns a block that wraps the given raw block pointer. + static objc + .ObjCBlock?, NSError)> + castFromPointer(ffi.Pointer pointer, + {bool retain = false, bool release = false}) => + objc.ObjCBlock< + ffi.Void Function(ffi.Pointer?, + NSError)>(pointer, retain: retain, release: release); + + /// Creates a block from a C function pointer. + /// + /// This block must be invoked by native code running on the same thread as + /// the isolate that registered it. Invoking the block on the wrong thread + /// will result in a crash. + static objc.ObjCBlock?, NSError)> fromFunctionPointer( + ffi.Pointer< + ffi.NativeFunction< + ffi.Void Function(ffi.Pointer arg0, + ffi.Pointer arg1)>> + ptr) => + objc.ObjCBlock?, NSError)>( + objc.newPointerBlock(_ObjCBlock_ffiVoid_objcObjCObject_NSError_fnPtrCallable, ptr.cast()), + retain: false, + release: true); + + /// Creates a block from a Dart function. + /// + /// This block must be invoked by native code running on the same thread as + /// the isolate that registered it. Invoking the block on the wrong thread + /// will result in a crash. + static objc.ObjCBlock?, NSError)> fromFunction( + void Function(objc.ObjCObjectBase?, NSError) fn) => + objc.ObjCBlock?, NSError)>( + objc.newClosureBlock( + _ObjCBlock_ffiVoid_objcObjCObject_NSError_closureCallable, + (ffi.Pointer arg0, + ffi.Pointer arg1) => + fn( + arg0.address == 0 + ? null + : objc.ObjCObjectBase(arg0, retain: true, release: true), + NSError.castFromPointer(arg1, retain: true, release: true))), + retain: false, + release: true); + + /// Creates a listener block from a Dart function. + /// + /// This is based on FFI's NativeCallable.listener, and has the same + /// capabilities and limitations. This block can be invoked from any thread, + /// but only supports void functions, and is not run synchronously. See + /// NativeCallable.listener for more details. + /// + /// Note that unlike the default behavior of NativeCallable.listener, listener + /// blocks do not keep the isolate alive. + static objc + .ObjCBlock?, NSError)> + listener(void Function(objc.ObjCObjectBase?, NSError) fn) { + final raw = objc.newClosureBlock( + _ObjCBlock_ffiVoid_objcObjCObject_NSError_listenerCallable + .nativeFunction + .cast(), + (ffi.Pointer arg0, + ffi.Pointer arg1) => + fn( + arg0.address == 0 + ? null + : objc.ObjCObjectBase(arg0, retain: false, release: true), + NSError.castFromPointer(arg1, retain: false, release: true))); + final wrapper = _ObjectiveCBindings_wrapListenerBlock_wjvic9(raw); + objc.objectRelease(raw.cast()); + return objc.ObjCBlock< + ffi.Void Function(ffi.Pointer?, NSError)>(wrapper, + retain: false, release: true); + } +} + +/// Call operator for `objc.ObjCBlock?, NSError)>`. +extension ObjCBlock_ffiVoid_objcObjCObject_NSError_CallExtension on objc + .ObjCBlock?, NSError)> { + void call(objc.ObjCObjectBase? arg0, NSError arg1) => ref.pointer.ref.invoke + .cast< + ffi.NativeFunction< + ffi.Void Function( + ffi.Pointer block, + ffi.Pointer arg0, + ffi.Pointer arg1)>>() + .asFunction< + void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>()( + ref.pointer, arg0?.ref.pointer ?? ffi.nullptr, arg1.ref.pointer); +} + instancetype _ObjCBlock_instancetype_ffiVoid_NSCoder_fnPtrTrampoline( ffi.Pointer block, ffi.Pointer arg0, @@ -11350,6 +11744,22 @@ final _objc_msgSend_8o14b = objc.msgSendPointer .asFunction< ffi.Pointer Function(ffi.Pointer, ffi.Pointer, int)>(); +final _objc_msgSend_91c9gi = objc.msgSendPointer + .cast< + ffi.NativeFunction< + ffi.Void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>>() + .asFunction< + void Function( + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer, + ffi.Pointer)>(); final _objc_msgSend_91o635 = objc.msgSendPointer .cast< ffi.NativeFunction< @@ -12524,6 +12934,8 @@ late final _sel_lengthOfBytesUsingEncoding_ = late final _sel_letterCharacterSet = objc.registerName("letterCharacterSet"); late final _sel_lineRangeForRange_ = objc.registerName("lineRangeForRange:"); late final _sel_load = objc.registerName("load"); +late final _sel_loadItemForTypeIdentifier_options_completionHandler_ = + objc.registerName("loadItemForTypeIdentifier:options:completionHandler:"); late final _sel_localizedCapitalizedString = objc.registerName("localizedCapitalizedString"); late final _sel_localizedCaseInsensitiveCompare_ = diff --git a/pkgs/objective_c/src/objective_c_bindings_generated.m b/pkgs/objective_c/src/objective_c_bindings_generated.m index adf51c181..478c8ffd6 100644 --- a/pkgs/objective_c/src/objective_c_bindings_generated.m +++ b/pkgs/objective_c/src/objective_c_bindings_generated.m @@ -12,26 +12,42 @@ Protocol* _ObjectiveCBindings_NSStreamDelegate() { return @protocol(NSStreamDelegate); } -typedef void (^_ListenerTrampoline)(void * arg0); -_ListenerTrampoline _ObjectiveCBindings_wrapListenerBlock_ovsamd(_ListenerTrampoline block) NS_RETURNS_RETAINED { +typedef void (^_ListenerTrampoline)(id arg0, id arg1, id arg2); +_ListenerTrampoline _ObjectiveCBindings_wrapListenerBlock_1j2nt86(_ListenerTrampoline block) NS_RETURNS_RETAINED { + return ^void(id arg0, id arg1, id arg2) { + objc_retainBlock(block); + block(objc_retainBlock(arg0), objc_retain(arg1), objc_retain(arg2)); + }; +} + +typedef void (^_ListenerTrampoline1)(void * arg0); +_ListenerTrampoline1 _ObjectiveCBindings_wrapListenerBlock_ovsamd(_ListenerTrampoline1 block) NS_RETURNS_RETAINED { return ^void(void * arg0) { objc_retainBlock(block); block(arg0); }; } -typedef void (^_ListenerTrampoline1)(void * arg0, id arg1); -_ListenerTrampoline1 _ObjectiveCBindings_wrapListenerBlock_wjovn7(_ListenerTrampoline1 block) NS_RETURNS_RETAINED { +typedef void (^_ListenerTrampoline2)(void * arg0, id arg1); +_ListenerTrampoline2 _ObjectiveCBindings_wrapListenerBlock_wjovn7(_ListenerTrampoline2 block) NS_RETURNS_RETAINED { return ^void(void * arg0, id arg1) { objc_retainBlock(block); block(arg0, objc_retain(arg1)); }; } -typedef void (^_ListenerTrampoline2)(void * arg0, id arg1, NSStreamEvent arg2); -_ListenerTrampoline2 _ObjectiveCBindings_wrapListenerBlock_18d6mda(_ListenerTrampoline2 block) NS_RETURNS_RETAINED { +typedef void (^_ListenerTrampoline3)(void * arg0, id arg1, NSStreamEvent arg2); +_ListenerTrampoline3 _ObjectiveCBindings_wrapListenerBlock_18d6mda(_ListenerTrampoline3 block) NS_RETURNS_RETAINED { return ^void(void * arg0, id arg1, NSStreamEvent arg2) { objc_retainBlock(block); block(arg0, objc_retain(arg1), arg2); }; } + +typedef void (^_ListenerTrampoline4)(id arg0, id arg1); +_ListenerTrampoline4 _ObjectiveCBindings_wrapListenerBlock_wjvic9(_ListenerTrampoline4 block) NS_RETURNS_RETAINED { + return ^void(id arg0, id arg1) { + objc_retainBlock(block); + block(objc_retain(arg0), objc_retain(arg1)); + }; +}