Skip to content
This repository has been archived by the owner on Jan 28, 2024. It is now read-only.

Commit

Permalink
Daco's comments
Browse files Browse the repository at this point in the history
  • Loading branch information
liamappelbe committed Oct 26, 2023
1 parent 214b82b commit 8225705
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 103 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- Fix ObjC methods returning instancetype having the wrong type in sublasses.
- When generating typedefs for `Pointer<NativeFunction<Function>>`, also
generate a typedef for the `Function`.
- Use Dart wrapper types in args and returns of ObjCBlocks.
- Bump min SDK version to 3.2.0-114.0.dev.

# 9.0.1
Expand Down
19 changes: 10 additions & 9 deletions lib/src/code_generator/objc_block.dart
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,12 @@ $returnFfiDartType $closureTrampoline($blockCType block, $paramsFfiDartType) =>
// Snippet that converts a Dart typed closure to FfiDart type. This snippet
// is used below. Note that the closure being converted is called `fn`.
final convertedFnArgs = params
.map((p) => p.type.convertFfiDartTypeToDartType(w, p.name, 'lib',
objCShouldRetain: true))
.map((p) => p.type
.convertFfiDartTypeToDartType(w, p.name, 'lib', objCRetain: true))
.join(', ');
final convFnInvocation = returnType.convertDartTypeToFfiDartType(
w, 'fn($convertedFnArgs)',
objCShouldRetain: true);
objCRetain: true);
final convFn = '($paramsFfiDartType) => $convFnInvocation';

// Write the wrapper class.
Expand Down Expand Up @@ -187,14 +187,15 @@ class $name extends _ObjCBlockBase {
// Call method.
s.write(' ${returnType.getDartType(w)} call($paramsDartType) =>');
final callMethodArgs = params
.map((p) => p.type.convertDartTypeToFfiDartType(w, p.name))
.map((p) =>
p.type.convertDartTypeToFfiDartType(w, p.name, objCRetain: false))
.join(', ');
final callMethodInvocation = '''
_id.ref.invoke.cast<$natTrampFnType>().asFunction<$trampFuncFfiDartType>()(
_id, $callMethodArgs)''';
s.write(returnType.convertFfiDartTypeToDartType(
w, callMethodInvocation, '_lib',
objCShouldRetain: false));
objCRetain: false));
s.write(';\n');

s.write('}\n');
Expand Down Expand Up @@ -231,19 +232,19 @@ _id.ref.invoke.cast<$natTrampFnType>().asFunction<$trampFuncFfiDartType>()(
String convertDartTypeToFfiDartType(
Writer w,
String value, {
bool objCShouldRetain = false,
required bool objCRetain,
}) =>
ObjCInterface.generateGetId(value, objCShouldRetain);
ObjCInterface.generateGetId(value, objCRetain);

@override
String convertFfiDartTypeToDartType(
Writer w,
String value,
String library, {
bool objCShouldRetain = true,
required bool objCRetain,
String? objCEnclosingClass,
}) =>
ObjCInterface.generateConstructor(name, value, library, objCShouldRetain);
ObjCInterface.generateConstructor(name, value, library, objCRetain);

@override
String toString() => '($returnType (^)(${argTypes.join(', ')}))';
Expand Down
22 changes: 12 additions & 10 deletions lib/src/code_generator/objc_interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -207,15 +207,17 @@ class $name extends ${superType?.name ?? '_ObjCWrapper'} {
s.write(isStatic ? '_lib.${_classObject.name}' : '_id');
s.write(', _lib.${m.selObject!.name}');
for (final p in m.params) {
s.write(', ${p.type.convertDartTypeToFfiDartType(w, p.name)}');
final convertedParam =
p.type.convertDartTypeToFfiDartType(w, p.name, objCRetain: false);
s.write(', $convertedParam');
}
s.write(');\n');
if (convertReturn) {
final result = returnType.convertFfiDartTypeToDartType(
w,
'_ret',
'_lib',
objCShouldRetain: !m.isOwnedReturn,
objCRetain: !m.isOwnedReturn,
objCEnclosingClass: name,
);
s.write(' return $result;');
Expand Down Expand Up @@ -403,30 +405,30 @@ class $name extends ${superType?.name ?? '_ObjCWrapper'} {
String convertDartTypeToFfiDartType(
Writer w,
String value, {
bool objCShouldRetain = false,
required bool objCRetain,
}) =>
ObjCInterface.generateGetId(value, objCShouldRetain);
ObjCInterface.generateGetId(value, objCRetain);

static String generateGetId(String value, bool objCShouldRetain) =>
objCShouldRetain ? '$value._retainAndReturnId()' : '$value._id';
static String generateGetId(String value, bool objCRetain) =>
objCRetain ? '$value._retainAndReturnId()' : '$value._id';

@override
String convertFfiDartTypeToDartType(
Writer w,
String value,
String library, {
bool objCShouldRetain = true,
required bool objCRetain,
String? objCEnclosingClass,
}) =>
ObjCInterface.generateConstructor(name, value, library, objCShouldRetain);
ObjCInterface.generateConstructor(name, value, library, objCRetain);

static String generateConstructor(
String className,
String value,
String library,
bool objCShouldRetain,
bool objCRetain,
) {
final ownershipFlags = 'retain: $objCShouldRetain, release: true';
final ownershipFlags = 'retain: $objCRetain, release: true';
return '$className._($value, $library, $ownershipFlags)';
}

Expand Down
8 changes: 4 additions & 4 deletions lib/src/code_generator/objc_nullable.dart
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,13 @@ class ObjCNullable extends Type {
String convertDartTypeToFfiDartType(
Writer w,
String value, {
bool objCShouldRetain = false,
required bool objCRetain,
}) {
// This is a bit of a hack, but works for all the types that are allowed to
// be a child type. If we add more allowed child types, we may have to start
// special casing each type. Turns value._id into value?._id ?? nullptr.
final convertedValue = child.convertDartTypeToFfiDartType(w, '$value?',
objCShouldRetain: objCShouldRetain);
objCRetain: objCRetain);
return '$convertedValue ?? ${w.ffiLibraryPrefix}.nullptr';
}

Expand All @@ -63,15 +63,15 @@ class ObjCNullable extends Type {
Writer w,
String value,
String library, {
bool objCShouldRetain = true,
required bool objCRetain,
String? objCEnclosingClass,
}) {
// All currently supported child types have a Pointer as their FfiDartType.
final convertedValue = child.convertFfiDartTypeToDartType(
w,
value,
library,
objCShouldRetain: objCShouldRetain,
objCRetain: objCRetain,
objCEnclosingClass: objCEnclosingClass,
);
return '$value.address == 0 ? null : $convertedValue';
Expand Down
9 changes: 4 additions & 5 deletions lib/src/code_generator/pointer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,18 +91,17 @@ class ObjCObjectPointer extends PointerType {
String convertDartTypeToFfiDartType(
Writer w,
String value, {
bool objCShouldRetain = false,
required bool objCRetain,
}) =>
'$value._id';
ObjCInterface.generateGetId(value, objCRetain);

@override
String convertFfiDartTypeToDartType(
Writer w,
String value,
String library, {
bool objCShouldRetain = true,
required bool objCRetain,
String? objCEnclosingClass,
}) =>
ObjCInterface.generateConstructor(
'NSObject', value, library, objCShouldRetain);
ObjCInterface.generateConstructor('NSObject', value, library, objCRetain);
}
18 changes: 14 additions & 4 deletions lib/src/code_generator/type.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,20 +56,30 @@ abstract class Type {

/// Returns generated Dart code that converts the given value from its
/// DartType to its FfiDartType.
///
/// [value] is the value to be converted. If [objCRetain] is true, the ObjC
/// object will be reained (ref count incremented) during conversion.
String convertDartTypeToFfiDartType(
Writer w,
String value, {
bool objCShouldRetain = false,
required bool objCRetain,
}) =>
value;

/// Returns generated Dart code that converts the given value from its
/// FfiDartType to its DartType.
///
/// [value] is the value to be converted, and [library] is an instance of the
/// native library object. If [objCRetain] is true, the ObjC wrapper object
/// will retain (ref count increment) the wrapped object pointer. If this
/// conversion is occuring in the context of an ObjC class, then
/// [objCEnclosingClass] should be the name of the Dart wrapper class (this is
/// used by instancetype).
String convertFfiDartTypeToDartType(
Writer w,
String value,
String library, {
bool objCShouldRetain = true,
required bool objCRetain,
String? objCEnclosingClass,
}) =>
value;
Expand Down Expand Up @@ -132,7 +142,7 @@ abstract class BindingType extends NoLookUpBinding implements Type {
String convertDartTypeToFfiDartType(
Writer w,
String value, {
bool objCShouldRetain = false,
required bool objCRetain,
}) =>
value;

Expand All @@ -141,7 +151,7 @@ abstract class BindingType extends NoLookUpBinding implements Type {
Writer w,
String value,
String library, {
bool objCShouldRetain = true,
required bool objCRetain,
String? objCEnclosingClass,
}) =>
value;
Expand Down
19 changes: 10 additions & 9 deletions lib/src/code_generator/typealias.dart
Original file line number Diff line number Diff line change
Expand Up @@ -162,24 +162,23 @@ class Typealias extends BindingType {
String convertDartTypeToFfiDartType(
Writer w,
String value, {
bool objCShouldRetain = false,
required bool objCRetain,
}) =>
type.convertDartTypeToFfiDartType(w, value,
objCShouldRetain: objCShouldRetain);
type.convertDartTypeToFfiDartType(w, value, objCRetain: objCRetain);

@override
String convertFfiDartTypeToDartType(
Writer w,
String value,
String library, {
bool objCShouldRetain = true,
required bool objCRetain,
String? objCEnclosingClass,
}) =>
type.convertFfiDartTypeToDartType(
w,
value,
library,
objCShouldRetain: objCShouldRetain,
objCRetain: objCRetain,
objCEnclosingClass: objCEnclosingClass,
);

Expand Down Expand Up @@ -211,18 +210,20 @@ class ObjCInstanceType extends Typealias {
String convertDartTypeToFfiDartType(
Writer w,
String value, {
bool objCShouldRetain = false,
required bool objCRetain,
}) =>
ObjCInterface.generateGetId(value, objCShouldRetain);
ObjCInterface.generateGetId(value, objCRetain);

@override
String convertFfiDartTypeToDartType(
Writer w,
String value,
String library, {
bool objCShouldRetain = true,
required bool objCRetain,
String? objCEnclosingClass,
}) =>
// objCEnclosingClass must be present, because instancetype can only
// occur inside a class.
ObjCInterface.generateConstructor(
objCEnclosingClass ?? 'NSObject', value, library, objCShouldRetain);
objCEnclosingClass!, value, library, objCRetain);
}
2 changes: 1 addition & 1 deletion test/native_objc_test/block_config.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: BlockTestObjCLibrary
description: 'Tests calling Objective-C blocks'
description: 'Tests calling Objective-C blocks.'
language: objc
output: 'block_bindings.dart'
exclude-all-by-default: true
Expand Down
Loading

0 comments on commit 8225705

Please sign in to comment.