Skip to content

Commit

Permalink
[ffigen] Make sure all protocols are used (#1673)
Browse files Browse the repository at this point in the history
  • Loading branch information
liamappelbe authored Oct 23, 2024
1 parent c6e2580 commit fb39b6f
Show file tree
Hide file tree
Showing 13 changed files with 68 additions and 26 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/objective_c.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ on:
branches: [main, stable]
paths:
- '.github/workflows/objective_c.yaml'
- 'pkgs/ffigen/**'
- 'pkgs/objective_c/**'
pull_request:
branches: [main, stable]
paths:
- '.github/workflows/objective_c.yaml'
- 'pkgs/ffigen/**'
- 'pkgs/objective_c/**'
schedule:
- cron: "0 0 * * 0"
Expand Down
4 changes: 4 additions & 0 deletions pkgs/ffigen/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 15.1.0-wip

- Ensure all protocols referenced in bindings are available at runtime.

## 15.0.0

- Bump minimum Dart version to 3.4.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ import 'writer.dart';

/// Built in functions used by the Objective C bindings.
class ObjCBuiltInFunctions {
ObjCBuiltInFunctions(this._wrapperName, this.generateForPackageObjectiveC);
ObjCBuiltInFunctions(this.wrapperName, this.generateForPackageObjectiveC);

final String _wrapperName;
final String wrapperName;
final bool generateForPackageObjectiveC;

static const registerName = ObjCImport('registerName');
Expand Down Expand Up @@ -179,7 +179,7 @@ class ObjCBuiltInFunctions {
final idHash = fnvHash32(id).toRadixString(36);

return _blockTrampolines[id] ??= ObjCListenerBlockTrampoline(Func(
name: '_${_wrapperName}_wrapListenerBlock_$idHash',
name: '_${wrapperName}_wrapListenerBlock_$idHash',
returnType: PointerType(objCBlockType),
parameters: [
Parameter(
Expand Down
14 changes: 14 additions & 0 deletions pkgs/ffigen/lib/src/code_generator/objc_protocol.dart
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,20 @@ ${makeDartDoc(dartDoc ?? originalName)}abstract final class $name {
type: BindingStringType.objcProtocol, string: mainString);
}

@override
BindingString? toObjCBindingString(Writer w) {
if (!generateBindings) return null;

final wrapperName = builtInFunctions.wrapperName;
final mainString = '''
Protocol* _${wrapperName}_$originalName() { return @protocol($originalName); }
''';

return BindingString(
type: BindingStringType.objcProtocol, string: mainString);
}

@override
String toString() => originalName;

Expand Down
2 changes: 1 addition & 1 deletion pkgs/ffigen/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# BSD-style license that can be found in the LICENSE file.

name: ffigen
version: 15.0.0
version: 15.1.0-wip
description: >
Generator for FFI bindings, using LibClang to parse C, Objective-C, and Swift
files.
Expand Down
1 change: 1 addition & 0 deletions pkgs/ffigen/test/native_objc_test/protocol_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ objc-protocols:
- EmptyProtocol
- MyProtocol
- SecondaryProtocol
- UnusedProtocol
headers:
entry-points:
- 'protocol_test.h'
Expand Down
6 changes: 6 additions & 0 deletions pkgs/ffigen/test/native_objc_test/protocol_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -394,5 +394,11 @@ void main() {
expect(bindings, isNot(contains('SuperProtocol')));
expect(bindings, isNot(contains('FilteredProtocol')));
});

test('Unused protocol', () {
// Regression test for https://github.com/dart-lang/native/issues/1672.
final proto = UnusedProtocol.implement(someMethod: () => 123);
expect(proto, isNotNull);
});
});
}
5 changes: 5 additions & 0 deletions pkgs/ffigen/test/native_objc_test/protocol_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,8 @@ typedef struct {

@interface ObjCProtocolImplMissingMethod : NSObject<MyProtocol>
@end

@protocol UnusedProtocol<NSObject>
@required
- (int32_t)someMethod;
@end
4 changes: 4 additions & 0 deletions pkgs/objective_c/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 3.1.0-wip

- Use ffigen 15.1.0

## 3.0.0

- Add the following stream-related types to the core package:
Expand Down
35 changes: 19 additions & 16 deletions pkgs/objective_c/lib/src/objective_c_bindings_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,24 @@ set NSLocalizedDescriptionKey(NSString value) {
@ffi.Native<
ffi.Pointer<objc.ObjCBlockImpl> Function(
ffi.Pointer<objc.ObjCBlockImpl>)>(isLeaf: true)
external ffi.Pointer<objc.ObjCBlockImpl> _wrapListenerBlock_hepzs(
external ffi.Pointer<objc.ObjCBlockImpl>
_ObjectiveCBindings_wrapListenerBlock_hepzs(
ffi.Pointer<objc.ObjCBlockImpl> block,
);

@ffi.Native<
ffi.Pointer<objc.ObjCBlockImpl> Function(
ffi.Pointer<objc.ObjCBlockImpl>)>(isLeaf: true)
external ffi.Pointer<objc.ObjCBlockImpl> _wrapListenerBlock_m1viep(
external ffi.Pointer<objc.ObjCBlockImpl>
_ObjectiveCBindings_wrapListenerBlock_m1viep(
ffi.Pointer<objc.ObjCBlockImpl> block,
);

@ffi.Native<
ffi.Pointer<objc.ObjCBlockImpl> Function(
ffi.Pointer<objc.ObjCBlockImpl>)>(isLeaf: true)
external ffi.Pointer<objc.ObjCBlockImpl> _wrapListenerBlock_sjfpmz(
external ffi.Pointer<objc.ObjCBlockImpl>
_ObjectiveCBindings_wrapListenerBlock_sjfpmz(
ffi.Pointer<objc.ObjCBlockImpl> block,
);

Expand Down Expand Up @@ -12008,7 +12011,7 @@ abstract final class ObjCBlock_ffiVoid_ffiVoid {
final raw = objc.newClosureBlock(
_ObjCBlock_ffiVoid_ffiVoid_listenerCallable.nativeFunction.cast(),
(ffi.Pointer<ffi.Void> arg0) => fn(arg0));
final wrapper = _wrapListenerBlock_hepzs(raw);
final wrapper = _ObjectiveCBindings_wrapListenerBlock_hepzs(raw);
objc.objectRelease(raw.cast());
return objc.ObjCBlock<ffi.Void Function(ffi.Pointer<ffi.Void>)>(wrapper,
retain: false, release: true);
Expand Down Expand Up @@ -12137,7 +12140,7 @@ abstract final class ObjCBlock_ffiVoid_ffiVoid_NSCoder {
.cast(),
(ffi.Pointer<ffi.Void> arg0, ffi.Pointer<objc.ObjCObject> arg1) => fn(
arg0, NSCoder.castFromPointer(arg1, retain: false, release: true)));
final wrapper = _wrapListenerBlock_sjfpmz(raw);
final wrapper = _ObjectiveCBindings_wrapListenerBlock_sjfpmz(raw);
objc.objectRelease(raw.cast());
return objc.ObjCBlock<ffi.Void Function(ffi.Pointer<ffi.Void>, NSCoder)>(
wrapper,
Expand Down Expand Up @@ -12300,7 +12303,7 @@ abstract final class ObjCBlock_ffiVoid_ffiVoid_NSStream_NSStreamEvent {
arg0,
NSStream.castFromPointer(arg1, retain: false, release: true),
NSStreamEvent.fromValue(arg2)));
final wrapper = _wrapListenerBlock_m1viep(raw);
final wrapper = _ObjectiveCBindings_wrapListenerBlock_m1viep(raw);
objc.objectRelease(raw.cast());
return objc.ObjCBlock<
ffi.Void Function(ffi.Pointer<ffi.Void>, NSStream,
Expand Down Expand Up @@ -13420,10 +13423,10 @@ final _objc_msgSend_171owuh = objc.msgSendPointer
final _objc_msgSend_176f8tz = objc.msgSendPointer
.cast<
ffi.NativeFunction<
ffi.Pointer<objc.ObjCObject> Function(ffi.Pointer<objc.ObjCObject>,
instancetype Function(ffi.Pointer<objc.ObjCObject>,
ffi.Pointer<objc.ObjCSelector>, NSRange)>>()
.asFunction<
ffi.Pointer<objc.ObjCObject> Function(ffi.Pointer<objc.ObjCObject>,
instancetype Function(ffi.Pointer<objc.ObjCObject>,
ffi.Pointer<objc.ObjCSelector>, NSRange)>();
final _objc_msgSend_17fkh4i = objc.msgSendPointer
.cast<
Expand Down Expand Up @@ -13948,10 +13951,10 @@ final _objc_msgSend_1o478a1 = objc.msgSendPointer
final _objc_msgSend_1og3t2d = objc.msgSendPointer
.cast<
ffi.NativeFunction<
ffi.Pointer<objc.ObjCObject> Function(ffi.Pointer<objc.ObjCObject>,
instancetype Function(ffi.Pointer<objc.ObjCObject>,
ffi.Pointer<objc.ObjCSelector>, ffi.Pointer<ffi.Char>)>>()
.asFunction<
ffi.Pointer<objc.ObjCObject> Function(ffi.Pointer<objc.ObjCObject>,
instancetype Function(ffi.Pointer<objc.ObjCObject>,
ffi.Pointer<objc.ObjCSelector>, ffi.Pointer<ffi.Char>)>();
final _objc_msgSend_1ov25i7 = objc.msgSendPointer
.cast<
Expand Down Expand Up @@ -14177,10 +14180,10 @@ final _objc_msgSend_1u9el4t = objc.msgSendPointer
final _objc_msgSend_1unuoxw = objc.msgSendPointer
.cast<
ffi.NativeFunction<
instancetype Function(ffi.Pointer<objc.ObjCObject>,
ffi.Pointer<objc.ObjCObject> Function(ffi.Pointer<objc.ObjCObject>,
ffi.Pointer<objc.ObjCSelector>)>>()
.asFunction<
instancetype Function(
ffi.Pointer<objc.ObjCObject> Function(
ffi.Pointer<objc.ObjCObject>, ffi.Pointer<objc.ObjCSelector>)>();
final _objc_msgSend_1upz917 = objc.msgSendPointer
.cast<
Expand Down Expand Up @@ -14681,10 +14684,10 @@ final _objc_msgSend_e94jsr = objc.msgSendPointer
final _objc_msgSend_ehxl2g = objc.msgSendPointer
.cast<
ffi.NativeFunction<
ffi.Pointer<objc.ObjCObject> Function(ffi.Pointer<objc.ObjCObject>,
instancetype Function(ffi.Pointer<objc.ObjCObject>,
ffi.Pointer<objc.ObjCSelector>, ffi.UnsignedLong)>>()
.asFunction<
ffi.Pointer<objc.ObjCObject> Function(ffi.Pointer<objc.ObjCObject>,
instancetype Function(ffi.Pointer<objc.ObjCObject>,
ffi.Pointer<objc.ObjCSelector>, int)>();
final _objc_msgSend_eldhrq = objc.msgSendPointer
.cast<
Expand Down Expand Up @@ -14848,13 +14851,13 @@ final _objc_msgSend_imc4v7 = objc.msgSendPointer
final _objc_msgSend_iq11qg = objc.msgSendPointer
.cast<
ffi.NativeFunction<
instancetype Function(
ffi.Pointer<objc.ObjCObject> Function(
ffi.Pointer<objc.ObjCObject>,
ffi.Pointer<objc.ObjCSelector>,
ffi.Pointer<objc.ObjCObject>,
ffi.Pointer<objc.ObjCObject>)>>()
.asFunction<
instancetype Function(
ffi.Pointer<objc.ObjCObject> Function(
ffi.Pointer<objc.ObjCObject>,
ffi.Pointer<objc.ObjCSelector>,
ffi.Pointer<objc.ObjCObject>,
Expand Down
4 changes: 2 additions & 2 deletions pkgs/objective_c/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

name: objective_c
description: 'A library to access Objective C from Flutter that acts as a support library for package:ffigen.'
version: 3.0.0
version: 3.1.0-wip
repository: https://github.com/dart-lang/native/tree/main/pkgs/objective_c

topics:
Expand All @@ -28,7 +28,7 @@ dev_dependencies:
args: ^2.0.0
coverage: ^1.10.0
dart_flutter_team_lints: ^2.0.0
ffigen: ^14.0.0
ffigen: ^15.1.0
flutter_lints: ^3.0.0
flutter_test:
sdk: flutter
Expand Down
8 changes: 5 additions & 3 deletions pkgs/objective_c/src/objective_c_bindings_generated.m
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,26 @@
id objc_retain(id);
id objc_retainBlock(id);

Protocol* _ObjectiveCBindings_NSStreamDelegate() { return @protocol(NSStreamDelegate); }

typedef void (^_ListenerTrampoline)(void * arg0);
_ListenerTrampoline _wrapListenerBlock_hepzs(_ListenerTrampoline block) NS_RETURNS_RETAINED {
_ListenerTrampoline _ObjectiveCBindings_wrapListenerBlock_hepzs(_ListenerTrampoline block) NS_RETURNS_RETAINED {
return ^void(void * arg0) {
objc_retainBlock(block);
block(arg0);
};
}

typedef void (^_ListenerTrampoline1)(void * arg0, id arg1);
_ListenerTrampoline1 _wrapListenerBlock_sjfpmz(_ListenerTrampoline1 block) NS_RETURNS_RETAINED {
_ListenerTrampoline1 _ObjectiveCBindings_wrapListenerBlock_sjfpmz(_ListenerTrampoline1 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 _wrapListenerBlock_m1viep(_ListenerTrampoline2 block) NS_RETURNS_RETAINED {
_ListenerTrampoline2 _ObjectiveCBindings_wrapListenerBlock_m1viep(_ListenerTrampoline2 block) NS_RETURNS_RETAINED {
return ^void(void * arg0, id arg1, NSStreamEvent arg2) {
objc_retainBlock(block);
block(arg0, objc_retain(arg1), arg2);
Expand Down
3 changes: 2 additions & 1 deletion pkgs/objective_c/test/setup.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,6 @@ void main(List<String> arguments) {
lib.lookup('runOnMainThread'); // objective_c.m
lib.lookup('Dart_InitializeApiDL'); // dart_api_dl.c
lib.lookup('OBJC_CLASS_\$_DartProxy'); // proxy.m
lib.lookup('_wrapListenerBlock_hepzs'); // objective_c_bindings_generated.m
// objective_c_bindings_generated.m
lib.lookup('_ObjectiveCBindings_wrapListenerBlock_hepzs');
}

0 comments on commit fb39b6f

Please sign in to comment.