[ffigen] Better block names (#606)
* Better Block names
* Test
* Move swift_api.h to third_party
* merge cruft
diff --git a/pkgs/ffigen/example/swift/README.md b/pkgs/ffigen/example/swift/README.md
index d53778e..caa482e 100644
--- a/pkgs/ffigen/example/swift/README.md
+++ b/pkgs/ffigen/example/swift/README.md
@@ -8,9 +8,9 @@
`-emit-objc-header-path filename.h`:
```shell
-swiftc -c swift_api.swift \
- -module-name swift_module \
- -emit-objc-header-path swift_api.h \
+swiftc -c swift_api.swift \
+ -module-name swift_module \
+ -emit-objc-header-path third_party/swift_api.h \
-emit-library -o libswiftapi.dylib
```
@@ -43,7 +43,7 @@
language: objc
headers:
entry-points:
- - 'swift_api.h'
+ - 'third_party/swift_api.h'
```
Swift classes become Objective-C interfaces, so include them like this:
diff --git a/pkgs/ffigen/example/swift/config.yaml b/pkgs/ffigen/example/swift/config.yaml
index 6082e97..7f820ba 100644
--- a/pkgs/ffigen/example/swift/config.yaml
+++ b/pkgs/ffigen/example/swift/config.yaml
@@ -12,10 +12,10 @@
'SwiftClass': 'swift_module'
headers:
entry-points:
- - 'swift_api.h'
+ - 'third_party/swift_api.h'
preamble: |
// ignore_for_file: camel_case_types, non_constant_identifier_names
// ignore_for_file: unused_element, unused_field, return_of_invalid_type
// ignore_for_file: void_checks, annotate_overrides
// ignore_for_file: no_leading_underscores_for_local_identifiers
- // ignore_for_file: library_private_types_in_public_api
\ No newline at end of file
+ // ignore_for_file: library_private_types_in_public_api
diff --git a/pkgs/ffigen/example/swift/swift_api.h b/pkgs/ffigen/example/swift/third_party/swift_api.h
similarity index 100%
rename from pkgs/ffigen/example/swift/swift_api.h
rename to pkgs/ffigen/example/swift/third_party/swift_api.h
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_block.dart b/pkgs/ffigen/lib/src/code_generator/objc_block.dart
index ba028d6..7bbb4c0 100644
--- a/pkgs/ffigen/lib/src/code_generator/objc_block.dart
+++ b/pkgs/ffigen/lib/src/code_generator/objc_block.dart
@@ -14,6 +14,19 @@
ObjCBlock({
required String usr,
+ required Type returnType,
+ required List<Type> argTypes,
+ required ObjCBuiltInFunctions builtInFunctions,
+ }) : this._(
+ usr: usr,
+ name: _getBlockName(returnType, argTypes),
+ returnType: returnType,
+ argTypes: argTypes,
+ builtInFunctions: builtInFunctions,
+ );
+
+ ObjCBlock._({
+ required String usr,
required String name,
required this.returnType,
required this.argTypes,
@@ -24,6 +37,16 @@
name: name,
);
+ // Generates a human readable name for the block based on the args and return
+ // type. These names will be pretty verbose and unweildy, but they're at least
+ // sensible and stable. Users can always add their own typedef with a simpler
+ // name if necessary.
+ static String _getBlockName(Type returnType, List<Type> argTypes) =>
+ 'ObjCBlock_${[returnType, ...argTypes].map(_typeName).join('_')}';
+ static String _typeName(Type type) =>
+ type.toString().replaceAll(_illegalNameChar, '');
+ static final _illegalNameChar = RegExp(r'[^0-9a-zA-Z]');
+
@override
BindingString toBindingString(Writer w) {
final s = StringBuffer();
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objc_block_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objc_block_parser.dart
index f7ac662..313de4e 100644
--- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objc_block_parser.dart
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objc_block_parser.dart
@@ -32,7 +32,6 @@
return ObjCBlock(
usr: usr.toString(),
- name: 'ObjCBlock',
returnType: returnType,
argTypes: argTypes,
builtInFunctions: objCBuiltInFunctions,
diff --git a/pkgs/ffigen/test/example_tests/swift_example_test.dart b/pkgs/ffigen/test/example_tests/swift_example_test.dart
index 02ed00a..a4ac61e 100644
--- a/pkgs/ffigen/test/example_tests/swift_example_test.dart
+++ b/pkgs/ffigen/test/example_tests/swift_example_test.dart
@@ -31,7 +31,7 @@
'-module-name',
'swift_module',
'-emit-objc-header-path',
- 'swift_api.h',
+ 'third_party/swift_api.h',
'-emit-library',
'-o',
'libswiftapi.dylib',
diff --git a/pkgs/ffigen/test/native_objc_test/block_test.dart b/pkgs/ffigen/test/native_objc_test/block_test.dart
index 908e8fc..0253eaf 100644
--- a/pkgs/ffigen/test/native_objc_test/block_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/block_test.dart
@@ -15,6 +15,13 @@
import 'block_bindings.dart';
import 'util.dart';
+// The generated block names are stable but verbose, so typedef them.
+typedef IntBlock = ObjCBlock_Int32_Int32;
+typedef FloatBlock = ObjCBlock_ffiFloat_ffiFloat;
+typedef DoubleBlock = ObjCBlock_ffiDouble_ffiDouble;
+typedef Vec4Block = ObjCBlock_Vec4_Vec4;
+typedef VoidBlock = ObjCBlock_ffiVoid;
+
void main() {
late BlockTestObjCLibrary lib;
late void Function(Pointer<Char>, Pointer<Void>) executeInternalCommand;
@@ -52,8 +59,8 @@
});
test('Block from function pointer', () {
- final block = ObjCBlock1.fromFunctionPointer(
- lib, Pointer.fromFunction(_add100, 999));
+ final block =
+ IntBlock.fromFunctionPointer(lib, Pointer.fromFunction(_add100, 999));
final blockTester = BlockTester.makeFromBlock_(lib, block);
blockTester.pokeBlock();
expect(blockTester.call_(123), 223);
@@ -65,7 +72,7 @@
}
test('Block from function', () {
- final block = ObjCBlock1.fromFunction(lib, makeAdder(4000));
+ final block = IntBlock.fromFunction(lib, makeAdder(4000));
final blockTester = BlockTester.makeFromBlock_(lib, block);
blockTester.pokeBlock();
expect(blockTester.call_(123), 4123);
@@ -75,7 +82,7 @@
test('Listener block same thread', () async {
final hasRun = Completer();
int value = 0;
- final block = ObjCBlock.listener(lib, () {
+ final block = VoidBlock.listener(lib, () {
value = 123;
hasRun.complete();
});
@@ -89,7 +96,7 @@
test('Listener block new thread', () async {
final hasRun = Completer();
int value = 0;
- final block = ObjCBlock.listener(lib, () {
+ final block = VoidBlock.listener(lib, () {
value = 123;
hasRun.complete();
});
@@ -102,7 +109,7 @@
});
test('Float block', () {
- final block = ObjCBlock2.fromFunction(lib, (double x) {
+ final block = FloatBlock.fromFunction(lib, (double x) {
return x + 4.56;
});
expect(block(1.23), closeTo(5.79, 1e-6));
@@ -110,7 +117,7 @@
});
test('Double block', () {
- final block = ObjCBlock3.fromFunction(lib, (double x) {
+ final block = DoubleBlock.fromFunction(lib, (double x) {
return x + 4.56;
});
expect(block(1.23), closeTo(5.79, 1e-6));
@@ -127,7 +134,7 @@
final tempPtr = calloc<Vec4>();
final temp = tempPtr.ref;
- final block = ObjCBlock4.fromFunction(lib, (Vec4 v) {
+ final block = Vec4Block.fromFunction(lib, (Vec4 v) {
// Twiddle the Vec4 components.
temp.x = v.y;
temp.y = v.z;
@@ -156,8 +163,8 @@
});
Pointer<Void> funcPointerBlockRefCountTest() {
- final block = ObjCBlock1.fromFunctionPointer(
- lib, Pointer.fromFunction(_add100, 999));
+ final block =
+ IntBlock.fromFunctionPointer(lib, Pointer.fromFunction(_add100, 999));
expect(BlockTester.getBlockRetainCount_(lib, block.pointer.cast()), 1);
return block.pointer.cast();
}
@@ -169,7 +176,7 @@
});
Pointer<Void> funcBlockRefCountTest() {
- final block = ObjCBlock1.fromFunction(lib, makeAdder(4000));
+ final block = IntBlock.fromFunction(lib, makeAdder(4000));
expect(BlockTester.getBlockRetainCount_(lib, block.pointer.cast()), 1);
return block.pointer.cast();
}
@@ -181,7 +188,7 @@
});
test('Block fields have sensible values', () {
- final block = ObjCBlock1.fromFunction(lib, makeAdder(4000));
+ final block = IntBlock.fromFunction(lib, makeAdder(4000));
final blockPtr = block.pointer;
expect(blockPtr.ref.isa, isNot(0));
expect(blockPtr.ref.flags, isNot(0)); // Set by Block_copy.