-
Notifications
You must be signed in to change notification settings - Fork 55
Use getDartType rather than getFfiDartType in ObjC block codegen #632
Conversation
Marking not ready for review. I can't repro the mac CI failure locally. Need to investigate more. |
The failures were to do with ref counting mismatches. They're all fixed now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm w. comments
Thanks @liamappelbe!
(If you want to release a version, don't forget changelog entry and pubspec version bump.)
@@ -34,6 +70,10 @@ + (NSThread*)callOnNewThread:(VoidBlock)block; | |||
+ (float)callFloatBlock:(FloatBlock)block; | |||
+ (double)callDoubleBlock:(DoubleBlock)block; | |||
+ (Vec4)callVec4Block:(Vec4Block)block; | |||
+ (DummyObject*)callObjectBlock:(ObjectBlock)block NS_RETURNS_RETAINED; | |||
+ (DummyObject* _Nullable)callNullableBlock:(NullableBlock)block; | |||
+ (IntBlock)newBlock:(BlockBlock)block withMult:(int)mult; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+ (IntBlock)newBlock:(BlockBlock)block withMult:(int)mult; | |
+ (nullable DummyObject*)callNullableBlock:(NullableBlock)block; |
Ditto in other places.
Also, does Objective-C default to nonnull
if nullable
is omitted? Or is that Objective-C version specific?
It might be worth adding at least one test with nonnull
to make sure we parse it correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, does Objective-C default to
nonnull
ifnullable
is omitted?
Yep. From the parser's perspective, we don't even see the annotations. We just see the clang_Type_getNullability
flag, which combines both these annotations. I've added a test case to nullable_test anyway.
test/native_objc_test/block_test.m
Outdated
typedef int32_t (^IntBlock)(int32_t); | ||
typedef float (^FloatBlock)(float); | ||
typedef double (^DoubleBlock)(double); | ||
typedef Vec4 (^Vec4Block)(Vec4); | ||
typedef void (^VoidBlock)(); | ||
typedef DummyObject* (^ObjectBlock)(DummyObject*); | ||
typedef DummyObject* _Nullable (^NullableBlock)(DummyObject* _Nullable); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: The block itself isn't nullable, but the argument and return type are. I don't have a good suggestion for a better name though. If we split the test in two blocks, one with nullable argument and one with nullable return it could be NullableReturnBlock
and NullableArgumentBlock
or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about NullableObjectBlock?
@@ -12,11 +12,47 @@ | |||
double w; | |||
} Vec4; | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit for block_config.yaml
description: 'Tests calling Objective-C blocks.'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
}); | ||
|
||
final obj = DummyObject.new1(lib); | ||
final result1 = block(obj); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add test which pass null?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
|
||
test('Block block', () { | ||
final blockBlock = BlockBlock.fromFunction(lib, (IntBlock intBlock) { | ||
return IntBlock.fromFunction(lib, (int x) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice! 😃
/// only. This string should not be printed as generated code. | ||
/// Returns generated Dart code that converts the given value from its | ||
/// DartType to its FfiDartType. | ||
String convertDartTypeToFfiDartType( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please document the params so that if someone not familiar with objC introduces a new implementation of Type
doesn't have to reverse engineer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
|
||
/// Returns generated Dart code that converts the given value from its | ||
/// FfiDartType to its DartType. | ||
String convertFfiDartTypeToDartType( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto, please document the arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
lib/src/code_generator/type.dart
Outdated
String convertDartTypeToFfiDartType( | ||
Writer w, | ||
String value, { | ||
bool objCShouldRetain = false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
objCRetain
(It's not a should, it's guaranteed, we generate a retain: true
.)
Also, let's make it non-optional. I think it would be useful that all call sites explicitly reason about memory management in the generated code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
lib/src/code_generator/type.dart
Outdated
Writer w, | ||
String value, | ||
String library, { | ||
bool objCShouldRetain = true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ditto, objCRetain
and required arg.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
String? objCEnclosingClass, | ||
}) => | ||
ObjCInterface.generateConstructor( | ||
objCEnclosingClass ?? 'NSObject', value, library, objCShouldRetain); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is NSObject
ever happening?
If so, is it a sign we are not generating a class because it's not part of the ffigen.yaml
?
If it can happen:
- Please add a test case that exercises this.
- Leave a comment here to that test case.
- Emit a warning.
If it cannot (or should not) happen:
- Add an assert or exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't ever happen (clang should give an error). Added a null assertion instead.
Improves the codegen for blocks with arguments or return types that are objects, nullables, or blocks. Users can now pass or receive the Dart wrapper object, rather than dealing with pointers.
Ref counting notes:
Fixes dart-lang/native#473