Skip to content

Commit

Permalink
Fix some other little bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
liamappelbe committed Oct 29, 2024
1 parent 0bec7ce commit d363475
Show file tree
Hide file tree
Showing 10 changed files with 68 additions and 14 deletions.
2 changes: 1 addition & 1 deletion pkgs/ffigen/lib/src/code_generator/imports.dart
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,6 @@ final wCharType = ImportedType(ffiImport, 'WChar', 'int', 'wchar_t', '0');
final objCObjectType =
ImportedType(objcPkgImport, 'ObjCObject', 'ObjCObject', 'void');
final objCSelType = ImportedType(
objcPkgImport, 'ObjCSelector', 'ObjCSelector', 'objc_selector');
objcPkgImport, 'ObjCSelector', 'ObjCSelector', 'struct objc_selector');
final objCBlockType =
ImportedType(objcPkgImport, 'ObjCBlockImpl', 'ObjCBlockImpl', 'id');
18 changes: 9 additions & 9 deletions pkgs/ffigen/lib/src/code_generator/objc_interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,18 @@ class ObjCInterface extends BindingType with ObjCMethods {
s.write(' {\n');

// Implementation.
final target = isStatic
? _classObject.name
: convertDartTypeToFfiDartType(
w,
'this',
objCRetain: m.consumesSelf,
objCAutorelease: false,
);
final sel = m.selObject.name;
if (m.isOptional) {
s.write('''
if (!${ObjCBuiltInFunctions.respondsToSelector.gen(w)}(ref.pointer, $sel)) {
if (!${ObjCBuiltInFunctions.respondsToSelector.gen(w)}($target, $sel)) {
throw ${ObjCBuiltInFunctions.unimplementedOptionalMethodException.gen(w)}(
'$originalName', '${m.originalName}');
}
Expand All @@ -166,14 +174,6 @@ class ObjCInterface extends BindingType with ObjCMethods {
final convertReturn = m.kind != ObjCMethodKind.propertySetter &&
!returnType.sameDartAndFfiDartType;

final target = isStatic
? _classObject.name
: convertDartTypeToFfiDartType(
w,
'this',
objCRetain: m.consumesSelf,
objCAutorelease: false,
);
final msgSendParams =
m.params.map((p) => p.type.convertDartTypeToFfiDartType(
w,
Expand Down
15 changes: 11 additions & 4 deletions pkgs/ffigen/lib/src/visitor/apply_config_filters.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,22 @@ class ApplyConfigFiltersVisitation extends Visitation {

@override
void visitObjCInterface(ObjCInterface node) {
node.filterMethods((method) =>
config.objcInterfaces.shouldIncludeMember(node, method.originalName));
node.filterMethods(
(m) => config.objcInterfaces.shouldIncludeMember(node, m.originalName));
_visitImpl(node, config.objcInterfaces);
}

@override
void visitObjCProtocol(ObjCProtocol node) {
node.filterMethods((method) =>
config.objcProtocols.shouldIncludeMember(node, method.originalName));
node.filterMethods((m) {
// TODO(https://github.com/dart-lang/native/issues/1149): Support class
// methods on protocols if there's a use case. For now filter them. We
// filter here instead of during parsing so that these methods are still
// copied to any interfaces that implement the protocol.
if (m.isClassMethod) return false;

return config.objcProtocols.shouldIncludeMember(node, m.originalName);
});
_visitImpl(node, config.objcProtocols);
}

Expand Down
1 change: 1 addition & 0 deletions pkgs/ffigen/test/native_objc_test/block_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ typedefs:
- FloatBlock
- DoubleBlock
- Vec4Block
- SelectorBlock
- VoidBlock
- ObjectBlock
- NullableObjectBlock
Expand Down
14 changes: 14 additions & 0 deletions pkgs/ffigen/test/native_objc_test/block_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ typedef ListenerBlock = ObjCBlock_ffiVoid_IntBlock;
typedef FloatBlock = ObjCBlock_ffiFloat_ffiFloat;
typedef DoubleBlock = ObjCBlock_ffiDouble_ffiDouble;
typedef Vec4Block = ObjCBlock_Vec4_Vec4;
typedef SelectorBlock = ObjCBlock_ffiVoid_objcObjCSelector;
typedef ObjectBlock = ObjCBlock_DummyObject_DummyObject;
typedef NullableObjectBlock = ObjCBlock_DummyObject_DummyObject1;
typedef NullableStringBlock = ObjCBlock_NSString_NSString;
Expand Down Expand Up @@ -162,6 +163,19 @@ void main() {
});
});

test('Selector block', () {
late String sel;
final block = SelectorBlock.fromFunction((Pointer<ObjCSelector> x) {
sel = x.toDartString();
});

block('Hello'.toSelector());
expect(sel, 'Hello');

BlockTester.callSelectorBlock_(block);
expect(sel, 'Select');
});

test('Object block', () {
bool isCalled = false;
final block = ObjectBlock.fromFunction((DummyObject x) {
Expand Down
2 changes: 2 additions & 0 deletions pkgs/ffigen/test/native_objc_test/block_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ typedef float (^FloatBlock)(float);
typedef double (^DoubleBlock)(double);
typedef Vec4 (^Vec4Block)(Vec4);
typedef void (^VoidBlock)();
typedef void (^SelectorBlock)(SEL);
typedef DummyObject* (^ObjectBlock)(DummyObject*);
typedef DummyObject* _Nullable (^NullableObjectBlock)(DummyObject* _Nullable);
typedef NSString* _Nullable (^NullableStringBlock)(NSString* _Nullable);
Expand Down Expand Up @@ -64,6 +65,7 @@ typedef void (^NoTrampolineListenerBlock)(int32_t, Vec4, const char*);
+ (float)callFloatBlock:(FloatBlock)block;
+ (double)callDoubleBlock:(DoubleBlock)block;
+ (Vec4)callVec4Block:(Vec4Block)block;
+ (void)callSelectorBlock:(SelectorBlock)block;
+ (DummyObject*)callObjectBlock:(ObjectBlock)block NS_RETURNS_RETAINED;
+ (nullable DummyObject*)callNullableObjectBlock:(NullableObjectBlock)block
NS_RETURNS_RETAINED;
Expand Down
4 changes: 4 additions & 0 deletions pkgs/ffigen/test/native_objc_test/block_test.m
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ + (Vec4)callVec4Block:(Vec4Block)block {
return block(vec4);
}

+ (void)callSelectorBlock:(SelectorBlock)block {
block(sel_registerName("Select"));
}

+ (DummyObject*)callObjectBlock:(ObjectBlock)block NS_RETURNS_RETAINED {
return block([DummyObject new]);
}
Expand Down
7 changes: 7 additions & 0 deletions pkgs/ffigen/test/native_objc_test/protocol_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ void main() {

// Method from a protocol that isn't included by the filters.
expect(protocolImpl.fooMethod(), 2468);

// Class methods.
expect(ObjCProtocolImpl.requiredClassMethod(), 9876);
expect(ObjCProtocolImpl.optionalClassMethod(), 5432);
});

test('Unimplemented method', () {
Expand All @@ -94,6 +98,9 @@ void main() {
expect(() => protocolImpl.optionalMethod_(structPtr.ref),
throwsA(isA<UnimplementedOptionalMethodException>()));
calloc.free(structPtr);

expect(() => ObjCProtocolImpl.unimplementedOtionalClassMethod(),
throwsA(isA<UnimplementedOptionalMethodException>()));
});
});

Expand Down
11 changes: 11 additions & 0 deletions pkgs/ffigen/test/native_objc_test/protocol_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@ typedef struct {
@optional
- (void)voidMethod:(int32_t)x;

// Class methods aren't supported in protocol implementation from Dart, but they
// are still codegenned for any native interfaces that implement this protocol.
@required
+ (int32_t)requiredClassMethod;

@optional
+ (int32_t)optionalClassMethod;

@optional
+ (int32_t)unimplementedOtionalClassMethod;

@end


Expand Down
8 changes: 8 additions & 0 deletions pkgs/ffigen/test/native_objc_test/protocol_test.m
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,14 @@ - (int32_t)fooMethod {
return 2468;
}

+ (int32_t)requiredClassMethod {
return 9876;
}

+ (int32_t)optionalClassMethod {
return 5432;
}

@end


Expand Down

0 comments on commit d363475

Please sign in to comment.