[ffigen] Migrate test/setup.dart to a build hook (#3334)
diff --git a/.github/workflows/ffigen.yml b/.github/workflows/ffigen.yml
index c06836a..7bb4748 100644
--- a/.github/workflows/ffigen.yml
+++ b/.github/workflows/ffigen.yml
@@ -41,8 +41,6 @@
- name: Check formatting
run: dart format --output=none --set-exit-if-changed .
if: always() && steps.install.outcome == 'success'
- - name: Build test dylib and bindings
- run: dart --enable-asserts test/setup.dart
- name: Analyze code
run: dart analyze --fatal-infos
@@ -61,8 +59,6 @@
run: dart pub get && flutter pub get --directory="../jni"
- name: Install libclang-14-dev
run: sudo apt-get install libclang-14-dev
- - name: Build test dylib and bindings
- run: dart --enable-asserts test/setup.dart
- name: Run VM tests
run: dart test
- name: Generate package:jni bindings
@@ -87,8 +83,6 @@
uses: ConorMacBride/install-package@3e7ad059e07782ee54fa35f827df52aae0626f30
with:
brew: clang-format
- - name: Build test dylib and bindings
- run: dart --enable-asserts test/setup.dart
- name: Install coverage
run: dart pub global activate coverage
- name: Run VM tests and collect coverage
@@ -127,8 +121,6 @@
uses: ConorMacBride/install-package@3e7ad059e07782ee54fa35f827df52aae0626f30
with:
brew: clang-format
- - name: Build test dylib and bindings
- run: dart --enable-asserts test/setup.dart
- name: Run VM tests
run: dart test
@@ -145,8 +137,6 @@
channel: stable
- name: Install dependencies
run: dart pub get && dart pub get --directory="../objective_c"
- - name: Build test dylib and bindings
- run: dart --enable-asserts test/setup.dart
- name: Run Flutter tests
run: dart test
@@ -163,8 +153,6 @@
channel: stable
- name: Install dependencies
run: dart pub get && flutter pub get --directory="../jni"
- - name: Build test dylib and bindings
- run: dart --enable-asserts test/setup.dart
- name: Run VM tests
run: dart test
- name: Generate package:jni bindings
@@ -194,7 +182,5 @@
channel: stable
- name: Install dependencies
run: flutter pub get
- - name: Build test dylib and bindings
- run: dart --enable-asserts test/setup.dart
- name: Run VM tests
run: dart test test_flutter/
diff --git a/.github/workflows/ffigen_weekly.yml b/.github/workflows/ffigen_weekly.yml
index 8ebdb0c..74671fd 100644
--- a/.github/workflows/ffigen_weekly.yml
+++ b/.github/workflows/ffigen_weekly.yml
@@ -37,8 +37,6 @@
uses: ConorMacBride/install-package@3e7ad059e07782ee54fa35f827df52aae0626f30
with:
brew: clang-format
- - name: Build test dylib and bindings
- run: dart --enable-asserts test/setup.dart
- name: Run VM tests
run: dart test
- name: Generate package:jni bindings
diff --git a/pkgs/ffigen/hook/build.dart b/pkgs/ffigen/hook/build.dart
new file mode 100644
index 0000000..e115124
--- /dev/null
+++ b/pkgs/ffigen/hook/build.dart
@@ -0,0 +1,188 @@
+// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:code_assets/code_assets.dart';
+import 'package:hooks/hooks.dart';
+import 'package:logging/logging.dart';
+import 'package:native_toolchain_c/native_toolchain_c.dart';
+import 'package:native_toolchain_c/src/cbuilder/compiler_resolver.dart';
+import 'package:path/path.dart' as p;
+
+// All ObjC source files are compiled with ARC enabled except these.
+const arcDisabledFiles = <String>{'ref_count_test.m'};
+
+final logger = Logger('')
+ ..level = Level.INFO
+ ..onRecord.listen((record) {
+ print('${record.level.name}: ${record.time}: ${record.message}');
+ });
+
+void main(List<String> args) async {
+ await build(args, (input, output) async {
+ if (input.userDefines['include_test_utils'] != true) {
+ return;
+ }
+
+ if (!input.config.buildCodeAssets) {
+ return;
+ }
+
+ final packageName = input.packageName;
+
+ // Build native_test.c. This is an ordinary build, so we can use CBuilder.
+ await CBuilder.library(
+ name: 'native_test',
+ assetName: 'native_test',
+ sources: [
+ 'test/native_test/native_test.c',
+ if (input.config.code.targetOS == OS.windows)
+ 'test/native_test/native_test.def',
+ ],
+ ).run(input: input, output: output, logger: logger);
+
+ if (input.config.code.targetOS == OS.macOS) {
+ final builder = await CustomBuilder.create(
+ input,
+ input.packageRoot.toFilePath(),
+ );
+
+ // Build swift_class_test.swift. There's no swift compilation package, so
+ // we have to use a CustomBuilder.
+ final objcTestDir = input.packageRoot.resolve('test/native_objc_test/');
+ const swiftModule = 'swift_class_test';
+ final swiftFile = objcTestDir.resolve('swift_class_test.swift');
+ final swiftHeader = objcTestDir.resolve('swift_class_test-Swift.h');
+ final swiftLib = input.outputDirectory.resolve('$swiftModule.dylib');
+
+ await builder.buildSwift(swiftFile, swiftModule, swiftHeader, swiftLib);
+ output.assets.code.add(
+ CodeAsset(
+ package: packageName,
+ name: swiftModule,
+ file: swiftLib,
+ linkMode: DynamicLoadingBundled(),
+ ),
+ );
+
+ // Build all the ObjC files. Some of the files have different compile
+ // flags, so we need to use the CustomBuilder again.
+ final mFiles = _findFiles(objcTestDir, '.m');
+ final hFiles = _findFiles(objcTestDir, '.h');
+
+ final objFiles = <String>[];
+ for (final mFile in mFiles) {
+ final useArc = !arcDisabledFiles.contains(mFile.pathSegments.last);
+ objFiles.add(
+ await builder.buildObject(mFile, [
+ '-x',
+ 'objective-c',
+ if (useArc) '-fobjc-arc',
+ '-Wno-nullability-completeness',
+ '-DDISABLE_METHOD',
+ ]),
+ );
+ }
+
+ // Add dart_api_dl.c from objective_c package.
+ final dartApiDl = input.packageRoot.resolve(
+ '../objective_c/src/include/dart_api_dl.c',
+ );
+ objFiles.add(await builder.buildObject(dartApiDl, []));
+
+ const objcAsset = 'objc_test';
+ final objcLib = input.outputDirectory.resolve('$objcAsset.dylib');
+ await builder.linkLib(objFiles, objcLib, ['-framework', 'Foundation']);
+
+ output.dependencies.addAll([...mFiles, ...hFiles, swiftFile, dartApiDl]);
+
+ output.assets.code.add(
+ CodeAsset(
+ package: packageName,
+ name: objcAsset,
+ file: objcLib,
+ linkMode: DynamicLoadingBundled(),
+ ),
+ );
+ }
+ });
+}
+
+List<Uri> _findFiles(Uri dir, String suffix) => Directory.fromUri(dir)
+ .listSync()
+ .whereType<File>()
+ .map((f) => f.uri)
+ .where((uri) => uri.pathSegments.last.endsWith(suffix))
+ .toList();
+
+class CustomBuilder {
+ final String _comp;
+ final String _rootDir;
+ final Uri _tempOutDir;
+ CustomBuilder._(this._comp, this._rootDir, this._tempOutDir);
+
+ static Future<CustomBuilder> create(BuildInput input, String rootDir) async {
+ final resolver = CompilerResolver(
+ codeConfig: input.config.code,
+ logger: logger,
+ );
+ return CustomBuilder._(
+ (await resolver.resolveCompiler()).uri.toFilePath(),
+ rootDir,
+ input.outputDirectory.resolve('obj/'),
+ );
+ }
+
+ Future<String> buildObject(Uri input, List<String> flags) async {
+ assert(input.toFilePath().startsWith(_rootDir));
+ final relativeInput = p.relative(input.toFilePath(), from: _rootDir);
+ final output = '${_tempOutDir.resolve(relativeInput).toFilePath()}.o';
+ File(output).parent.createSync(recursive: true);
+ await _runClang([
+ ...flags,
+ '-c',
+ input.toFilePath(),
+ '-fpic',
+ '-gline-tables-only',
+ ], output);
+ return output;
+ }
+
+ Future<void> linkLib(List<String> objects, Uri output, List<String> flags) =>
+ _runClang(['-shared', ...flags, ...objects], output.toFilePath());
+
+ Future<void> _runClang(List<String> flags, String output) =>
+ _run(_comp, [...flags, '-o', output]);
+
+ Future<void> buildSwift(
+ Uri input,
+ String moduleName,
+ Uri outputHeader,
+ Uri outputLib,
+ ) async {
+ final args = [
+ '-c',
+ input.toFilePath(),
+ '-module-name',
+ moduleName,
+ '-emit-library',
+ '-emit-objc-header-path',
+ outputHeader.toFilePath(),
+ '-o',
+ outputLib.toFilePath(),
+ ];
+ await _run('swiftc', args);
+ }
+
+ Future<void> _run(String cmd, List<String> args) async {
+ final proc = await Process.run(cmd, args);
+ if (proc.exitCode != 0) {
+ throw Exception(
+ 'Command failed: $cmd ${args.join(" ")}\n'
+ '${proc.stdout}\n${proc.stderr}',
+ );
+ }
+ }
+}
diff --git a/pkgs/ffigen/pubspec.yaml b/pkgs/ffigen/pubspec.yaml
index 5d383a8..ac08248 100644
--- a/pkgs/ffigen/pubspec.yaml
+++ b/pkgs/ffigen/pubspec.yaml
@@ -21,13 +21,16 @@
dependencies:
args: ^2.6.0
cli_util: ^0.4.2
+ code_assets: ^1.0.0
collection: ^1.18.0
dart_style: ^3.0.0
ffi: ^2.0.1
file: ^7.0.0
glob: ^2.0.0
+ hooks: ^1.0.0
logging: ^1.0.0
meta: ^1.11.0
+ native_toolchain_c: ^0.17.4
package_config: ^2.1.0
path: ^1.8.0
pub_semver: ^2.1.4
@@ -55,5 +58,7 @@
hooks:
user_defines:
+ ffigen:
+ include_test_utils: true
objective_c:
include_test_utils: true
diff --git a/pkgs/ffigen/test/native_objc_test/arc_config.yaml b/pkgs/ffigen/test/native_objc_test/arc_config.yaml
index 3bfcb20..81d5cc3 100644
--- a/pkgs/ffigen/test/native_objc_test/arc_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/arc_config.yaml
@@ -11,6 +11,8 @@
include:
- ArcTestObject
- ArcDtorTestObject
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'arc_test.h'
diff --git a/pkgs/ffigen/test/native_objc_test/arc_test.dart b/pkgs/ffigen/test/native_objc_test/arc_test.dart
index d333462..f6cd3be 100644
--- a/pkgs/ffigen/test/native_objc_test/arc_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/arc_test.dart
@@ -16,20 +16,9 @@
import 'util.dart';
void main() {
- late ArcTestObjCLibrary lib;
-
group('ARC', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- lib = ArcTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+ loadLibrary();
});
test('objectRetainCount edge cases', () {
@@ -131,7 +120,7 @@
Pointer<ObjCObjectImpl>,
)
copyMethodsInner(Pointer<Int32> counter) {
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
final obj1 = ArcTestObject.newWithCounter(counter);
expect(counter.value, 1);
final obj2 = obj1.copyMe();
@@ -171,7 +160,7 @@
expect(objectRetainCount(obj8raw), greaterThan(0));
expect(objectRetainCount(obj9raw), greaterThan(0));
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
expect(objectRetainCount(obj1raw), greaterThan(0));
expect(objectRetainCount(obj2raw), greaterThan(0));
expect(objectRetainCount(obj3raw), greaterThan(0));
@@ -238,17 +227,17 @@
final counter = calloc<Int32>();
counter.value = 0;
- final pool1 = lib.objc_autoreleasePoolPush();
+ final pool1 = objc_autoreleasePoolPush();
final obj1raw = autoreleaseMethodsInner(counter);
doGC();
// The autorelease pool is still holding a reference to the object.
expect(counter.value, 1);
expect(objectRetainCount(obj1raw), greaterThan(0));
- lib.objc_autoreleasePoolPop(pool1);
+ objc_autoreleasePoolPop(pool1);
expect(counter.value, 0);
expect(objectRetainCount(obj1raw), 0);
- final pool2 = lib.objc_autoreleasePoolPush();
+ final pool2 = objc_autoreleasePoolPush();
final obj2 = ArcTestObject.makeAndAutorelease(counter);
final obj2raw = obj2.ref.pointer;
expect(counter.value, 1);
@@ -256,7 +245,7 @@
doGC();
expect(counter.value, 1);
expect(objectRetainCount(obj2raw), greaterThan(0));
- lib.objc_autoreleasePoolPop(pool2);
+ objc_autoreleasePoolPop(pool2);
// The obj2 variable still holds a reference to the object.
expect(counter.value, 1);
expect(objectRetainCount(obj2raw), greaterThan(0));
@@ -351,13 +340,13 @@
counter.value = 0;
// The getters of retain properties retain+autorelease the value. So we
// need an autorelease pool.
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
final (outerObjRaw, retainObjRaw) = retainPropertiesInner(counter);
doGC();
expect(objectRetainCount(retainObjRaw), greaterThan(0));
expect(objectRetainCount(outerObjRaw), 0);
expect(counter.value, 1);
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
expect(objectRetainCount(retainObjRaw), 0);
expect(objectRetainCount(outerObjRaw), 0);
expect(counter.value, 0);
@@ -397,7 +386,7 @@
counter.value = 0;
// The getters of copy properties retain+autorelease the value. So we need
// an autorelease pool.
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
final (outerObjRaw, copyObjRaw, anotherCopyRaw) = copyPropertiesInner(
counter,
);
@@ -406,7 +395,7 @@
expect(objectRetainCount(outerObjRaw), 0);
expect(objectRetainCount(copyObjRaw), 0);
expect(objectRetainCount(anotherCopyRaw), greaterThan(0));
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
expect(counter.value, 0);
expect(objectRetainCount(outerObjRaw), 0);
expect(objectRetainCount(copyObjRaw), 0);
diff --git a/pkgs/ffigen/test/native_objc_test/arc_test_bindings.dart b/pkgs/ffigen/test/native_objc_test/arc_test_bindings.dart
index bd0f84b..ff8280e 100644
--- a/pkgs/ffigen/test/native_objc_test/arc_test_bindings.dart
+++ b/pkgs/ffigen/test/native_objc_test/arc_test_bindings.dart
@@ -2,47 +2,18 @@
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint, unused_import
+@ffi.DefaultAsset('package:ffigen/objc_test')
+library;
+
import 'dart:ffi' as ffi;
import 'package:objective_c/objective_c.dart' as objc;
import 'package:ffi/ffi.dart' as pkg_ffi;
-/// Tests ARC
-class ArcTestObjCLibrary {
- /// Holds the symbol lookup function.
- final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
- _lookup;
+@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>)>()
+external void objc_autoreleasePoolPop(ffi.Pointer<ffi.Void> pool);
- /// The symbols are looked up in [dynamicLibrary].
- ArcTestObjCLibrary(ffi.DynamicLibrary dynamicLibrary)
- : _lookup = dynamicLibrary.lookup;
-
- /// The symbols are looked up with [lookup].
- ArcTestObjCLibrary.fromLookup(
- ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName) lookup,
- ) : _lookup = lookup;
-
- void objc_autoreleasePoolPop(ffi.Pointer<ffi.Void> pool) {
- return _objc_autoreleasePoolPop(pool);
- }
-
- late final _objc_autoreleasePoolPopPtr =
- _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
- 'objc_autoreleasePoolPop',
- );
- late final _objc_autoreleasePoolPop = _objc_autoreleasePoolPopPtr
- .asFunction<void Function(ffi.Pointer<ffi.Void>)>();
-
- ffi.Pointer<ffi.Void> objc_autoreleasePoolPush() {
- return _objc_autoreleasePoolPush();
- }
-
- late final _objc_autoreleasePoolPushPtr =
- _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
- 'objc_autoreleasePoolPush',
- );
- late final _objc_autoreleasePoolPush = _objc_autoreleasePoolPushPtr
- .asFunction<ffi.Pointer<ffi.Void> Function()>();
-}
+@ffi.Native<ffi.Pointer<ffi.Void> Function()>()
+external ffi.Pointer<ffi.Void> objc_autoreleasePoolPush();
/// ArcDtorTestObject
extension type ArcDtorTestObject._(objc.ObjCObject object$)
diff --git a/pkgs/ffigen/test/native_objc_test/bad_method_config.yaml b/pkgs/ffigen/test/native_objc_test/bad_method_config.yaml
index 7adfb15..4a0634b 100644
--- a/pkgs/ffigen/test/native_objc_test/bad_method_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/bad_method_config.yaml
@@ -14,6 +14,8 @@
objc-interfaces:
include:
- 'BadMethodTestObject'
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'bad_method_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/bad_method_test.dart b/pkgs/ffigen/test/native_objc_test/bad_method_test.dart
index 8227081..619a7cb 100644
--- a/pkgs/ffigen/test/native_objc_test/bad_method_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/bad_method_test.dart
@@ -16,16 +16,7 @@
void main() {
group('bad_method_test', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test("Test incomplete struct methods that weren't skipped", () {
diff --git a/pkgs/ffigen/test/native_objc_test/bad_override_config.yaml b/pkgs/ffigen/test/native_objc_test/bad_override_config.yaml
index 0aa4718..ee92488 100644
--- a/pkgs/ffigen/test/native_objc_test/bad_override_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/bad_override_config.yaml
@@ -16,6 +16,8 @@
- BadOverrideChild
- BadOverrideSibbling
- BadOverrideGrandchild
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'bad_override_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/bad_override_test.dart b/pkgs/ffigen/test/native_objc_test/bad_override_test.dart
index 82cd044..5257a7a 100644
--- a/pkgs/ffigen/test/native_objc_test/bad_override_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/bad_override_test.dart
@@ -18,16 +18,7 @@
void main() {
group('bad overrides', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test('Method vs getter', () {
diff --git a/pkgs/ffigen/test/native_objc_test/block_annotation_config.yaml b/pkgs/ffigen/test/native_objc_test/block_annotation_config.yaml
index 76e0aab..b27f904 100644
--- a/pkgs/ffigen/test/native_objc_test/block_annotation_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/block_annotation_config.yaml
@@ -20,6 +20,8 @@
typedefs:
include:
- EmptyBlock
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'block_annotation_test.h'
diff --git a/pkgs/ffigen/test/native_objc_test/block_annotation_test.dart b/pkgs/ffigen/test/native_objc_test/block_annotation_test.dart
index ffe5dd0..fc3c691 100644
--- a/pkgs/ffigen/test/native_objc_test/block_annotation_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/block_annotation_test.dart
@@ -21,8 +21,6 @@
import 'util.dart';
void main() {
- late final BlockAnnotationTestLibrary lib;
-
group('Block annotations', () {
// Due to https://github.com/dart-lang/native/issues/1490 we can't directly
// codegen blocks that return retain or consume args. Instead we create them
@@ -35,25 +33,14 @@
// correct block type.
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- lib = BlockAnnotationTestLibrary(
- DynamicLibrary.open(dylib.absolute.path),
- );
+ loadLibrary();
});
void objectProducerTest(EmptyObject producer()) {
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
EmptyObject? obj = producer();
final ptr = obj.ref.pointer;
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
doGC();
expect(objectRetainCount(ptr), 1);
expect(obj, isNotNull);
@@ -200,12 +187,12 @@
Future<void> objectListenerTest(
void Function(Completer<EmptyObject>) producer,
) async {
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
Completer<EmptyObject>? completer = Completer<EmptyObject>();
producer(completer);
EmptyObject? obj = await completer.future;
final ptr = obj.ref.pointer;
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
doGC();
expect(objectRetainCount(ptr), 1);
expect(obj, isNotNull);
@@ -292,10 +279,10 @@
}, skip: !canDoGC);
void blockProducerTest(DartEmptyBlock producer()) {
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
DartEmptyBlock? obj = producer();
final ptr = obj.ref.pointer;
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
doGC();
expect(blockRetainCount(ptr), 1);
expect(obj, isNotNull);
diff --git a/pkgs/ffigen/test/native_objc_test/block_annotation_test_bindings.dart b/pkgs/ffigen/test/native_objc_test/block_annotation_test_bindings.dart
index 80e46f5..fb43680 100644
--- a/pkgs/ffigen/test/native_objc_test/block_annotation_test_bindings.dart
+++ b/pkgs/ffigen/test/native_objc_test/block_annotation_test_bindings.dart
@@ -2,48 +2,13 @@
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint, unused_import
+@ffi.DefaultAsset('package:ffigen/objc_test')
+library;
+
import 'dart:ffi' as ffi;
import 'package:objective_c/objective_c.dart' as objc;
import 'package:ffi/ffi.dart' as pkg_ffi;
-/// Tests block annotations
-class BlockAnnotationTestLibrary {
- /// Holds the symbol lookup function.
- final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
- _lookup;
-
- /// The symbols are looked up in [dynamicLibrary].
- BlockAnnotationTestLibrary(ffi.DynamicLibrary dynamicLibrary)
- : _lookup = dynamicLibrary.lookup;
-
- /// The symbols are looked up with [lookup].
- BlockAnnotationTestLibrary.fromLookup(
- ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName) lookup,
- ) : _lookup = lookup;
-
- void objc_autoreleasePoolPop(ffi.Pointer<ffi.Void> pool) {
- return _objc_autoreleasePoolPop(pool);
- }
-
- late final _objc_autoreleasePoolPopPtr =
- _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
- 'objc_autoreleasePoolPop',
- );
- late final _objc_autoreleasePoolPop = _objc_autoreleasePoolPopPtr
- .asFunction<void Function(ffi.Pointer<ffi.Void>)>();
-
- ffi.Pointer<ffi.Void> objc_autoreleasePoolPush() {
- return _objc_autoreleasePoolPush();
- }
-
- late final _objc_autoreleasePoolPushPtr =
- _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
- 'objc_autoreleasePoolPush',
- );
- late final _objc_autoreleasePoolPush = _objc_autoreleasePoolPushPtr
- .asFunction<ffi.Pointer<ffi.Void> Function()>();
-}
-
@ffi.Native<
ffi.Void Function(
ffi.Pointer<objc.ObjCObjectImpl>,
@@ -175,6 +140,12 @@
ffi.Pointer<objc.ObjCBlockImpl> block,
);
+@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>)>()
+external void objc_autoreleasePoolPop(ffi.Pointer<ffi.Void> pool);
+
+@ffi.Native<ffi.Pointer<ffi.Void> Function()>()
+external ffi.Pointer<ffi.Void> objc_autoreleasePoolPush();
+
/// BlockAnnotationTest
extension type BlockAnnotationTest._(objc.ObjCObject object$)
implements objc.ObjCObject, objc.NSObject {
diff --git a/pkgs/ffigen/test/native_objc_test/block_config.yaml b/pkgs/ffigen/test/native_objc_test/block_config.yaml
index 49bc89d..8a3feaa 100644
--- a/pkgs/ffigen/test/native_objc_test/block_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/block_config.yaml
@@ -31,6 +31,8 @@
include:
- objc_autoreleasePoolPop
- objc_autoreleasePoolPush
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'block_test.h'
diff --git a/pkgs/ffigen/test/native_objc_test/block_inherit_config.yaml b/pkgs/ffigen/test/native_objc_test/block_inherit_config.yaml
index 912fd9a..a6630f4 100644
--- a/pkgs/ffigen/test/native_objc_test/block_inherit_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/block_inherit_config.yaml
@@ -15,6 +15,8 @@
- ReturnPlatypus
- AcceptMammal
- AcceptPlatypus
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'block_inherit_test.h'
diff --git a/pkgs/ffigen/test/native_objc_test/block_inherit_test.dart b/pkgs/ffigen/test/native_objc_test/block_inherit_test.dart
index 93b0782..6981d3f 100644
--- a/pkgs/ffigen/test/native_objc_test/block_inherit_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/block_inherit_test.dart
@@ -18,16 +18,7 @@
void main() {
group('Block inheritance', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test('BlockInheritTestBase', () {
diff --git a/pkgs/ffigen/test/native_objc_test/block_test.dart b/pkgs/ffigen/test/native_objc_test/block_test.dart
index 9221f2b..257b2cb 100644
--- a/pkgs/ffigen/test/native_objc_test/block_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/block_test.dart
@@ -48,21 +48,9 @@
)();
void main() {
- late final BlockTestObjCLibrary lib;
-
group('Blocks', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- lib = BlockTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
-
+ loadLibrary();
BlockTester.setup(NativeApi.initializeApiDLData);
});
@@ -501,7 +489,7 @@
(Pointer<ObjCBlockImpl>, Pointer<ObjCBlockImpl>, Pointer<ObjCBlockImpl>)
blockBlockDartCallRefCountTest() {
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
final inputBlock = IntBlock.fromFunction((int x) {
return 5 * x;
});
@@ -514,7 +502,7 @@
});
final outputBlock = blockBlock(inputBlock);
expect(outputBlock(1), 15);
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
doGC();
// One reference held by inputBlock object, another bound to the
@@ -575,7 +563,7 @@
(Pointer<ObjCBlockImpl>, Pointer<ObjCBlockImpl>, Pointer<ObjCBlockImpl>)
blockBlockObjCCallRefCountTest() {
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
late Pointer<ObjCBlockImpl> inputBlock;
final blockBlock = BlockBlock.fromFunction((
ObjCBlock<Int32 Function(Int32)> intBlock,
@@ -587,7 +575,7 @@
});
final outputBlock = BlockTester.newBlock(blockBlock, withMult: 2);
expect(outputBlock(1), 6);
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
doGC();
expect(blockRetainCount(inputBlock), 1);
@@ -639,14 +627,14 @@
(Pointer<ObjCBlockImpl>, Pointer<ObjCBlockImpl>, Pointer<ObjCBlockImpl>)
nativeBlockBlockDartCallRefCountTest() {
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
final inputBlock = IntBlock.fromFunction((int x) {
return 5 * x;
});
final blockBlock = BlockTester.newBlockBlock(7);
final outputBlock = blockBlock(inputBlock);
expect(outputBlock(1), 35);
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
doGC();
// One reference held by inputBlock object, another held internally by the
@@ -700,7 +688,7 @@
);
(Pointer<Int32>, Pointer<Int32>) objectBlockRefCountTest(Allocator alloc) {
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
final inputCounter = alloc<Int32>();
final outputCounter = alloc<Int32>();
inputCounter.value = 0;
@@ -715,7 +703,7 @@
expect(inputCounter.value, 1);
expect(outputCounter.value, 1);
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
return (inputCounter, outputCounter);
}
@@ -735,7 +723,7 @@
(Pointer<Int32>, Pointer<Int32>) objectNativeBlockRefCountTest(
Allocator alloc,
) {
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
final inputCounter = alloc<Int32>();
final outputCounter = alloc<Int32>();
inputCounter.value = 0;
@@ -750,7 +738,7 @@
expect(inputCounter.value, 1);
expect(outputCounter.value, 1);
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
return (inputCounter, outputCounter);
}
diff --git a/pkgs/ffigen/test/native_objc_test/block_test_bindings.dart b/pkgs/ffigen/test/native_objc_test/block_test_bindings.dart
index dd59565..7a98f94 100644
--- a/pkgs/ffigen/test/native_objc_test/block_test_bindings.dart
+++ b/pkgs/ffigen/test/native_objc_test/block_test_bindings.dart
@@ -2,48 +2,13 @@
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint, unused_import
+@ffi.DefaultAsset('package:ffigen/objc_test')
+library;
+
import 'dart:ffi' as ffi;
import 'package:objective_c/objective_c.dart' as objc;
import 'package:ffi/ffi.dart' as pkg_ffi;
-/// Tests calling Objective-C blocks.
-class BlockTestObjCLibrary {
- /// Holds the symbol lookup function.
- final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
- _lookup;
-
- /// The symbols are looked up in [dynamicLibrary].
- BlockTestObjCLibrary(ffi.DynamicLibrary dynamicLibrary)
- : _lookup = dynamicLibrary.lookup;
-
- /// The symbols are looked up with [lookup].
- BlockTestObjCLibrary.fromLookup(
- ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName) lookup,
- ) : _lookup = lookup;
-
- void objc_autoreleasePoolPop(ffi.Pointer<ffi.Void> pool) {
- return _objc_autoreleasePoolPop(pool);
- }
-
- late final _objc_autoreleasePoolPopPtr =
- _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
- 'objc_autoreleasePoolPop',
- );
- late final _objc_autoreleasePoolPop = _objc_autoreleasePoolPopPtr
- .asFunction<void Function(ffi.Pointer<ffi.Void>)>();
-
- ffi.Pointer<ffi.Void> objc_autoreleasePoolPush() {
- return _objc_autoreleasePoolPush();
- }
-
- late final _objc_autoreleasePoolPushPtr =
- _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
- 'objc_autoreleasePoolPush',
- );
- late final _objc_autoreleasePoolPush = _objc_autoreleasePoolPushPtr
- .asFunction<ffi.Pointer<ffi.Void> Function()>();
-}
-
@ffi.Native<
ffi.Pointer<objc.ObjCBlockImpl> Function(
ffi.Pointer<objc.ObjCBlockImpl>,
@@ -204,6 +169,12 @@
ffi.Pointer<objc.ObjCBlockImpl> block,
);
+@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>)>()
+external void objc_autoreleasePoolPop(ffi.Pointer<ffi.Void> pool);
+
+@ffi.Native<ffi.Pointer<ffi.Void> Function()>()
+external ffi.Pointer<ffi.Void> objc_autoreleasePoolPush();
+
typedef BlockBlock = ffi.Pointer<objc.ObjCBlockImpl>;
typedef DartBlockBlock =
objc.ObjCBlock<
diff --git a/pkgs/ffigen/test/native_objc_test/cast_config.yaml b/pkgs/ffigen/test/native_objc_test/cast_config.yaml
index 3750f08..6409523 100644
--- a/pkgs/ffigen/test/native_objc_test/cast_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/cast_config.yaml
@@ -6,6 +6,8 @@
objc-interfaces:
include:
- Castaway
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'cast_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/cast_test.dart b/pkgs/ffigen/test/native_objc_test/cast_test.dart
index ccd6080..ca4acde 100644
--- a/pkgs/ffigen/test/native_objc_test/cast_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/cast_test.dart
@@ -20,16 +20,7 @@
group('cast', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
testInstance = Castaway();
});
diff --git a/pkgs/ffigen/test/native_objc_test/category_config.yaml b/pkgs/ffigen/test/native_objc_test/category_config.yaml
index 87cb8d0..ee80696 100644
--- a/pkgs/ffigen/test/native_objc_test/category_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/category_config.yaml
@@ -20,6 +20,8 @@
- InterfaceOnBuiltInType
- StaticAndInstanceMethodsWithSameNameCategory
- NSString
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'category_test.h'
diff --git a/pkgs/ffigen/test/native_objc_test/category_test.dart b/pkgs/ffigen/test/native_objc_test/category_test.dart
index 85601d6..8cb7321 100644
--- a/pkgs/ffigen/test/native_objc_test/category_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/category_test.dart
@@ -18,16 +18,7 @@
void main() {
group('categories', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test('Category methods', () {
diff --git a/pkgs/ffigen/test/native_objc_test/category_test_bindings.dart b/pkgs/ffigen/test/native_objc_test/category_test_bindings.dart
index 1cc525d..b992b19 100644
--- a/pkgs/ffigen/test/native_objc_test/category_test_bindings.dart
+++ b/pkgs/ffigen/test/native_objc_test/category_test_bindings.dart
@@ -2,6 +2,9 @@
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint, unused_import
+@ffi.DefaultAsset('package:ffigen/objc_test')
+library;
+
import 'dart:ffi' as ffi;
import 'package:objective_c/objective_c.dart' as objc;
import 'package:ffi/ffi.dart' as pkg_ffi;
diff --git a/pkgs/ffigen/test/native_objc_test/enum_config.yaml b/pkgs/ffigen/test/native_objc_test/enum_config.yaml
index 9659a58..0ec968f 100644
--- a/pkgs/ffigen/test/native_objc_test/enum_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/enum_config.yaml
@@ -16,6 +16,8 @@
objc-interfaces:
include:
- EnumTestInterface
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
# Multiple includes to repro https://github.com/dart-lang/native/issues/2782
diff --git a/pkgs/ffigen/test/native_objc_test/enum_test.dart b/pkgs/ffigen/test/native_objc_test/enum_test.dart
index d1b183c..cfe1d99 100644
--- a/pkgs/ffigen/test/native_objc_test/enum_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/enum_test.dart
@@ -18,16 +18,7 @@
void main() {
group('enum', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test('NS_ENUM generates a Dart enum', () {
diff --git a/pkgs/ffigen/test/native_objc_test/error_method_config.yaml b/pkgs/ffigen/test/native_objc_test/error_method_config.yaml
index d21c86b..273ee61 100644
--- a/pkgs/ffigen/test/native_objc_test/error_method_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/error_method_config.yaml
@@ -14,6 +14,8 @@
objc-interfaces:
include:
- 'ErrorMethodTestObject'
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'error_method_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/error_method_test.dart b/pkgs/ffigen/test/native_objc_test/error_method_test.dart
index 3e509b9..a6aa2fd 100644
--- a/pkgs/ffigen/test/native_objc_test/error_method_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/error_method_test.dart
@@ -18,16 +18,7 @@
void main() {
group('error_method_test', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test("Error method that returns bool", () {
diff --git a/pkgs/ffigen/test/native_objc_test/failed_to_load_config.yaml b/pkgs/ffigen/test/native_objc_test/failed_to_load_config.yaml
index cfdca56..619bbae 100644
--- a/pkgs/ffigen/test/native_objc_test/failed_to_load_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/failed_to_load_config.yaml
@@ -6,6 +6,8 @@
objc-interfaces:
include:
- ClassThatWillFailToLoad
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'failed_to_load_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/forward_decl_config.yaml b/pkgs/ffigen/test/native_objc_test/forward_decl_config.yaml
index b6fb3a9..710486e 100644
--- a/pkgs/ffigen/test/native_objc_test/forward_decl_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/forward_decl_config.yaml
@@ -6,6 +6,8 @@
objc-interfaces:
include:
- ForwardDeclaredClass
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'forward_decl_test.h'
diff --git a/pkgs/ffigen/test/native_objc_test/forward_decl_test.dart b/pkgs/ffigen/test/native_objc_test/forward_decl_test.dart
index 94c40ed..8e8d9ba 100644
--- a/pkgs/ffigen/test/native_objc_test/forward_decl_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/forward_decl_test.dart
@@ -16,16 +16,7 @@
void main() {
group('forward decl', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test('Forward declared class', () {
diff --git a/pkgs/ffigen/test/native_objc_test/global_native_config.yaml b/pkgs/ffigen/test/native_objc_test/global_native_config.yaml
index 88c2a3b..04a9074 100644
--- a/pkgs/ffigen/test/native_objc_test/global_native_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/global_native_config.yaml
@@ -4,6 +4,7 @@
output: 'global_native_test_bindings.dart'
exclude-all-by-default: true
ffi-native:
+ asset-id: 'package:ffigen/objc_test'
globals:
include:
- globalString
diff --git a/pkgs/ffigen/test/native_objc_test/global_native_test.dart b/pkgs/ffigen/test/native_objc_test/global_native_test.dart
index ba62a6b..6060314 100644
--- a/pkgs/ffigen/test/native_objc_test/global_native_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/global_native_test.dart
@@ -18,16 +18,7 @@
void main() {
group('global using @Native', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test('Global string', () {
diff --git a/pkgs/ffigen/test/native_objc_test/global_native_test_bindings.dart b/pkgs/ffigen/test/native_objc_test/global_native_test_bindings.dart
index 338fbe2..3b8c71b 100644
--- a/pkgs/ffigen/test/native_objc_test/global_native_test_bindings.dart
+++ b/pkgs/ffigen/test/native_objc_test/global_native_test_bindings.dart
@@ -2,6 +2,9 @@
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint, unused_import
+@ffi.DefaultAsset('package:ffigen/objc_test')
+library;
+
import 'dart:ffi' as ffi;
import 'package:objective_c/objective_c.dart' as objc;
import 'package:ffi/ffi.dart' as pkg_ffi;
diff --git a/pkgs/ffigen/test/native_objc_test/global_test.dart b/pkgs/ffigen/test/native_objc_test/global_test.dart
index d6c6c8b..3dc5dad 100644
--- a/pkgs/ffigen/test/native_objc_test/global_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/global_test.dart
@@ -16,20 +16,10 @@
import 'util.dart';
void main() {
+ late GlobalTestObjCLibrary lib;
group('global', () {
- late GlobalTestObjCLibrary lib;
-
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- lib = GlobalTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+ lib = GlobalTestObjCLibrary(DynamicLibrary.open(findDylib("objc_test")));
});
test('Global string', () {
diff --git a/pkgs/ffigen/test/native_objc_test/inherited_instancetype_config.yaml b/pkgs/ffigen/test/native_objc_test/inherited_instancetype_config.yaml
index 9abafce..23d1499 100644
--- a/pkgs/ffigen/test/native_objc_test/inherited_instancetype_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/inherited_instancetype_config.yaml
@@ -6,6 +6,8 @@
objc-interfaces:
include:
- ChildClass
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'inherited_instancetype_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/inherited_instancetype_test.dart b/pkgs/ffigen/test/native_objc_test/inherited_instancetype_test.dart
index fa576ce..e0317d7 100644
--- a/pkgs/ffigen/test/native_objc_test/inherited_instancetype_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/inherited_instancetype_test.dart
@@ -17,16 +17,7 @@
void main() {
group('inheritedInstancetype', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test('Ordinary init method', () {
diff --git a/pkgs/ffigen/test/native_objc_test/is_instance_config.yaml b/pkgs/ffigen/test/native_objc_test/is_instance_config.yaml
index 463512b..01c9640 100644
--- a/pkgs/ffigen/test/native_objc_test/is_instance_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/is_instance_config.yaml
@@ -7,6 +7,8 @@
include:
- IsInstanceChildClass
- IsInstanceUnrelatedClass
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'is_instance_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/is_instance_test.dart b/pkgs/ffigen/test/native_objc_test/is_instance_test.dart
index dbd0554..d1a5b83 100644
--- a/pkgs/ffigen/test/native_objc_test/is_instance_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/is_instance_test.dart
@@ -18,16 +18,7 @@
void main() {
group('isInstance', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test('Unrelated classes', () {
diff --git a/pkgs/ffigen/test/native_objc_test/isolate_config.yaml b/pkgs/ffigen/test/native_objc_test/isolate_config.yaml
index 5618162..2b75137 100644
--- a/pkgs/ffigen/test/native_objc_test/isolate_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/isolate_config.yaml
@@ -8,6 +8,8 @@
objc-interfaces:
include:
- Sendable
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'isolate_test.h'
diff --git a/pkgs/ffigen/test/native_objc_test/isolate_test.dart b/pkgs/ffigen/test/native_objc_test/isolate_test.dart
index cb2c456..aa56fa8 100644
--- a/pkgs/ffigen/test/native_objc_test/isolate_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/isolate_test.dart
@@ -20,20 +20,12 @@
void main() {
group('isolate', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
// Runs on other isolate (can't use expect function).
void sendingObjectTest(SendPort sendPort) async {
+ loadLibrary();
final port = ReceivePort();
final queue = StreamQueue(port);
sendPort.send(port.sendPort);
@@ -81,6 +73,7 @@
sendable.value = 123;
final oldValue = await Isolate.run(() {
+ loadLibrary();
final oldValue = sendable!.value;
sendable!.value = 456;
return oldValue;
@@ -99,6 +92,7 @@
// Runs on other isolate (can't use expect function).
void sendingBlockTest(SendPort sendPort) async {
+ loadLibrary();
final port = ReceivePort();
final queue = StreamQueue(port);
sendPort.send(port.sendPort);
@@ -154,6 +148,7 @@
ObjCBlock<Void Function(Int32)>? block = makeBlock(completer);
await Isolate.run(() {
+ loadLibrary();
block!(123);
});
final value = await completer.future;
@@ -175,6 +170,7 @@
expect(sendable.ref.isReleased, isFalse);
final (oldIsReleased, newIsReleased) = await Isolate.run(() {
+ loadLibrary();
final oldIsReleased = sendable.ref.isReleased;
sendable!.ref.release();
return (oldIsReleased, sendable.ref.isReleased);
@@ -195,6 +191,7 @@
expect(sendable.ref.isReleased, isFalse);
await Isolate.run(() {
+ loadLibrary();
sendable!.ref.release();
});
diff --git a/pkgs/ffigen/test/native_objc_test/isolate_test_bindings.dart b/pkgs/ffigen/test/native_objc_test/isolate_test_bindings.dart
index caca893..6c698c4 100644
--- a/pkgs/ffigen/test/native_objc_test/isolate_test_bindings.dart
+++ b/pkgs/ffigen/test/native_objc_test/isolate_test_bindings.dart
@@ -2,6 +2,9 @@
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint, unused_import
+@ffi.DefaultAsset('package:ffigen/objc_test')
+library;
+
import 'dart:ffi' as ffi;
import 'package:objective_c/objective_c.dart' as objc;
import 'package:ffi/ffi.dart' as pkg_ffi;
diff --git a/pkgs/ffigen/test/native_objc_test/log_config.yaml b/pkgs/ffigen/test/native_objc_test/log_config.yaml
index 4f368e2..350e8b2 100644
--- a/pkgs/ffigen/test/native_objc_test/log_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/log_config.yaml
@@ -7,6 +7,8 @@
include:
- LogSpamBaseClass
- LogSpamChildClass
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'log_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/log_test.dart b/pkgs/ffigen/test/native_objc_test/log_test.dart
index 6241783..313de14 100644
--- a/pkgs/ffigen/test/native_objc_test/log_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/log_test.dart
@@ -18,16 +18,7 @@
void main() {
group('log_test', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test('Duplicate method log spam', () {
@@ -36,7 +27,7 @@
capturedMessages: logs,
level: Level.SEVERE,
);
- verifyBindings('log', logger);
+ verifyBindings('log', logger: logger);
expect(logs, isNot(contains(contains('matchingMethod'))));
expect(logs, isNot(contains(contains('instancetypeMethod'))));
});
diff --git a/pkgs/ffigen/test/native_objc_test/method_config.yaml b/pkgs/ffigen/test/native_objc_test/method_config.yaml
index ac16866..3be584f 100644
--- a/pkgs/ffigen/test/native_objc_test/method_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/method_config.yaml
@@ -6,6 +6,8 @@
objc-interfaces:
include:
- MethodInterface
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'method_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/method_filtering_config.yaml b/pkgs/ffigen/test/native_objc_test/method_filtering_config.yaml
index b071e09..61dad14 100644
--- a/pkgs/ffigen/test/native_objc_test/method_filtering_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/method_filtering_config.yaml
@@ -28,6 +28,8 @@
include:
- includedProtocolMethod
# If include is non-empty, everything else is excluded.
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'method_filtering_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/method_filtering_test.dart b/pkgs/ffigen/test/native_objc_test/method_filtering_test.dart
index 1f6d645..ccfabdc 100644
--- a/pkgs/ffigen/test/native_objc_test/method_filtering_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/method_filtering_test.dart
@@ -11,6 +11,7 @@
import 'package:ffigen/ffigen.dart';
import 'package:ffigen/src/config_provider/config.dart';
import 'package:ffigen/src/config_provider/config_types.dart';
+import 'package:ffigen/src/header_parser.dart' show parse;
import 'package:logging/logging.dart';
import 'package:path/path.dart' as path;
import 'package:pub_semver/pub_semver.dart';
@@ -20,18 +21,18 @@
void main() {
group('method filtering', () {
- late final String bindings;
group('no version info', () {
late final String bindings;
setUpAll(() {
- bindings = File(
+ final config = testConfigFromPath(
path.join(
packagePathForTests,
'test',
'native_objc_test',
- 'method_filtering_test_bindings.dart',
+ 'method_filtering_config.yaml',
),
- ).readAsStringSync();
+ );
+ bindings = parse(testContext(config)).generate();
});
test('interfaces', () {
diff --git a/pkgs/ffigen/test/native_objc_test/method_filtering_test_bindings.dart b/pkgs/ffigen/test/native_objc_test/method_filtering_test_bindings.dart
index bf6a623..0db2dca 100644
--- a/pkgs/ffigen/test/native_objc_test/method_filtering_test_bindings.dart
+++ b/pkgs/ffigen/test/native_objc_test/method_filtering_test_bindings.dart
@@ -2,6 +2,9 @@
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint, unused_import
+@ffi.DefaultAsset('package:ffigen/objc_test')
+library;
+
import 'dart:ffi' as ffi;
import 'package:objective_c/objective_c.dart' as objc;
import 'package:ffi/ffi.dart' as pkg_ffi;
diff --git a/pkgs/ffigen/test/native_objc_test/method_test.dart b/pkgs/ffigen/test/native_objc_test/method_test.dart
index e0414e4..7b7e333 100644
--- a/pkgs/ffigen/test/native_objc_test/method_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/method_test.dart
@@ -15,38 +15,28 @@
import 'util.dart';
void main() {
- late MethodInterface testInstance;
-
group('method calls', () {
+ late MethodInterface testInterface;
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
- testInstance = MethodInterface();
+ loadLibrary();
+ testInterface = MethodInterface.alloc().init();
});
group('Instance methods', () {
test('No arguments', () {
- expect(testInstance.add(), 5);
+ expect(testInterface.add(), 5);
});
test('One argument', () {
- expect(testInstance.add$1(23), 23);
+ expect(testInterface.add$1(23), 23);
});
test('Two arguments', () {
- expect(testInstance.add$2(23, Y: 17), 40);
+ expect(testInterface.add$2(23, Y: 17), 40);
});
test('Three arguments', () {
- expect(testInstance.add$3(23, Y: 17, Z: 60), 100);
+ expect(testInterface.add$3(23, Y: 17, Z: 60), 100);
});
});
@@ -77,7 +67,7 @@
input.z = 5.6;
input.w = 7.8;
- final result = testInstance.twiddleVec4Components(input);
+ final result = testInterface.twiddleVec4Components(input);
expect(result.x, 3.4);
expect(result.y, 5.6);
expect(result.z, 7.8);
@@ -87,16 +77,16 @@
});
test('Floats', () {
- expect(testInstance.addFloats(1.23, Y: 4.56), closeTo(5.79, 1e-6));
+ expect(testInterface.addFloats(1.23, Y: 4.56), closeTo(5.79, 1e-6));
});
test('Doubles', () {
- expect(testInstance.addDoubles(1.23, Y: 4.56), closeTo(5.79, 1e-6));
+ expect(testInterface.addDoubles(1.23, Y: 4.56), closeTo(5.79, 1e-6));
});
test('Method with same name as a type', () {
// Test for https://github.com/dart-lang/native/issues/1007
- final result = testInstance.Vec4$1();
+ final result = testInterface.Vec4$1();
expect(result.x, 1);
expect(result.y, 2);
expect(result.z, 3);
@@ -106,7 +96,7 @@
test('Instance and static methods with same name', () {
// Test for https://github.com/dart-lang/native/issues/1136
- expect(testInstance.instStaticSameName(), 123);
+ expect(testInterface.instStaticSameName(), 123);
expect(MethodInterface.instStaticSameName$1(), 456);
});
});
diff --git a/pkgs/ffigen/test/native_objc_test/native_objc_config.yaml b/pkgs/ffigen/test/native_objc_test/native_objc_config.yaml
index d8ffdec..81d18ec 100644
--- a/pkgs/ffigen/test/native_objc_test/native_objc_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/native_objc_config.yaml
@@ -14,6 +14,8 @@
objc-interfaces:
include:
- Foo
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'native_objc_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/native_objc_test.dart b/pkgs/ffigen/test/native_objc_test/native_objc_test.dart
index fd03658..5b6851c 100644
--- a/pkgs/ffigen/test/native_objc_test/native_objc_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/native_objc_test.dart
@@ -17,16 +17,7 @@
void main() {
group('native_objc_test', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test('Basic types', () {
diff --git a/pkgs/ffigen/test/native_objc_test/native_objc_test.m b/pkgs/ffigen/test/native_objc_test/native_objc_test.m
index e510df8..1c02df3 100644
--- a/pkgs/ffigen/test/native_objc_test/native_objc_test.m
+++ b/pkgs/ffigen/test/native_objc_test/native_objc_test.m
@@ -5,6 +5,8 @@
#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>
+void ffigen_load_objc_test() {}
+
@interface Foo : NSObject {
double doubleVal;
}
diff --git a/pkgs/ffigen/test/native_objc_test/ns_range_test.dart b/pkgs/ffigen/test/native_objc_test/ns_range_test.dart
index 79c32f2..48fb2de 100644
--- a/pkgs/ffigen/test/native_objc_test/ns_range_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/ns_range_test.dart
@@ -10,6 +10,7 @@
import 'package:ffigen/ffigen.dart';
import 'package:logging/logging.dart';
+import 'package:ffigen/src/header_parser.dart' show parse;
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import '../test_utils.dart';
diff --git a/pkgs/ffigen/test/native_objc_test/nullable_config.yaml b/pkgs/ffigen/test/native_objc_test/nullable_config.yaml
index 1c87afc..9697721 100644
--- a/pkgs/ffigen/test/native_objc_test/nullable_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/nullable_config.yaml
@@ -6,6 +6,8 @@
objc-interfaces:
include:
- NullableInterface
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'nullable_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/nullable_inheritance_config.yaml b/pkgs/ffigen/test/native_objc_test/nullable_inheritance_config.yaml
index dc43aab..b2e2485 100644
--- a/pkgs/ffigen/test/native_objc_test/nullable_inheritance_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/nullable_inheritance_config.yaml
@@ -7,6 +7,8 @@
include:
- NullableBase
- NullableChild
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'nullable_inheritance_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/nullable_inheritance_test.dart b/pkgs/ffigen/test/native_objc_test/nullable_inheritance_test.dart
index 26b861b..39b9ded 100644
--- a/pkgs/ffigen/test/native_objc_test/nullable_inheritance_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/nullable_inheritance_test.dart
@@ -7,7 +7,7 @@
import 'dart:ffi';
import 'dart:io';
-import 'package:objective_c/objective_c.dart';
+import 'package:objective_c/objective_c.dart' as objc;
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
@@ -16,24 +16,15 @@
import 'util.dart';
void main() {
- late NullableBase nullableBase;
- late NullableChild nullableChild;
- late NSObject obj;
group('Nullable inheritance', () {
+ late NullableChild nullableChild;
+ late NullableBase nullableBase;
+ late objc.NSObject obj;
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
- nullableBase = NullableBase();
- nullableChild = NullableChild();
- obj = NSObject();
+ loadLibrary();
+ nullableChild = NullableChild.alloc().init();
+ nullableBase = NullableBase.alloc().init();
+ obj = objc.NSObject.alloc().init();
});
group('Base', () {
@@ -41,18 +32,15 @@
expect(nullableBase.nullableArg(obj), false);
expect(nullableBase.nullableArg(null), true);
});
-
test('Non-null arguments', () {
expect(nullableBase.nonNullArg(obj), false);
});
-
test('Nullable return', () {
- expect(nullableBase.nullableReturn(false), isA<NSObject>());
+ expect(nullableBase.nullableReturn(false), isA<objc.NSObject>());
expect(nullableBase.nullableReturn(true), null);
});
-
test('Non-null return', () {
- expect(nullableBase.nonNullReturn(), isA<NSObject>());
+ expect(nullableBase.nonNullReturn(), isA<objc.NSObject>());
});
});
@@ -67,7 +55,7 @@
});
test('Nullable return, changed to non-null', () {
- expect(nullableChild.nullableReturn(false), isA<NSObject>());
+ expect(nullableChild.nullableReturn(false), isA<objc.NSObject>());
});
test('Non-null return, changed to nullable', () {
diff --git a/pkgs/ffigen/test/native_objc_test/nullable_test.dart b/pkgs/ffigen/test/native_objc_test/nullable_test.dart
index ca75988..2f8bb43 100644
--- a/pkgs/ffigen/test/native_objc_test/nullable_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/nullable_test.dart
@@ -16,32 +16,23 @@
import 'util.dart';
void main() {
- late NullableInterface nullableInterface;
late NSObject obj;
+ late NullableInterface testInterface;
group('Nullability', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
- nullableInterface = NullableInterface();
- obj = NSObject();
+ loadLibrary();
+ obj = NSObject.alloc().init();
+ testInterface = NullableInterface.alloc().init();
});
group('Nullable property', () {
test('Not null', () {
- nullableInterface.nullableObjectProperty = obj;
- expect(nullableInterface.nullableObjectProperty, obj);
+ testInterface.nullableObjectProperty = obj;
+ expect(testInterface.nullableObjectProperty, obj);
});
test('Null', () {
- nullableInterface.nullableObjectProperty = null;
- expect(nullableInterface.nullableObjectProperty, null);
+ testInterface.nullableObjectProperty = null;
+ expect(testInterface.nullableObjectProperty, null);
});
});
diff --git a/pkgs/ffigen/test/native_objc_test/property_config.yaml b/pkgs/ffigen/test/native_objc_test/property_config.yaml
index 4afcc3d..e737491 100644
--- a/pkgs/ffigen/test/native_objc_test/property_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/property_config.yaml
@@ -6,6 +6,8 @@
objc-interfaces:
include:
- PropertyInterface
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'property_test.h'
diff --git a/pkgs/ffigen/test/native_objc_test/property_test.dart b/pkgs/ffigen/test/native_objc_test/property_test.dart
index a897dde..6fa711d 100644
--- a/pkgs/ffigen/test/native_objc_test/property_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/property_test.dart
@@ -16,31 +16,21 @@
import 'util.dart';
void main() {
- late PropertyInterface testInstance;
-
group('properties', () {
+ late PropertyInterface testInterface;
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
- testInstance = PropertyInterface();
+ loadLibrary();
+ testInterface = PropertyInterface.alloc().init();
});
group('instance properties', () {
test('read-only property', () {
- expect(testInstance.readOnlyProperty, 7);
+ expect(testInterface.readOnlyProperty, 7);
});
test('read-write property', () {
- testInstance.readWriteProperty = 23;
- expect(testInstance.readWriteProperty, 23);
+ testInterface.readWriteProperty = 23;
+ expect(testInterface.readWriteProperty, 23);
});
});
@@ -65,8 +55,8 @@
input.z = 5.6;
input.w = 7.8;
- testInstance.structProperty = input;
- final result = testInstance.structProperty;
+ testInterface.structProperty = input;
+ final result = testInterface.structProperty;
expect(result.x, 1.2);
expect(result.y, 3.4);
expect(result.z, 5.6);
@@ -76,19 +66,19 @@
});
test('Floats', () {
- testInstance.floatProperty = 1.23;
- expect(testInstance.floatProperty, closeTo(1.23, 1e-6));
+ testInterface.floatProperty = 1.23;
+ expect(testInterface.floatProperty, closeTo(1.23, 1e-6));
});
test('Doubles', () {
- testInstance.doubleProperty = 1.23;
- expect(testInstance.doubleProperty, 1.23);
+ testInterface.doubleProperty = 1.23;
+ expect(testInterface.doubleProperty, 1.23);
});
});
test('Instance and static properties with same name', () {
// Test for https://github.com/dart-lang/native/issues/1136
- expect(testInstance.instStaticSameName, 123);
+ expect(testInterface.instStaticSameName, 123);
expect(PropertyInterface.getInstStaticSameName$1(), 456);
});
diff --git a/pkgs/ffigen/test/native_objc_test/protocol_config.yaml b/pkgs/ffigen/test/native_objc_test/protocol_config.yaml
index 418f2f2..ebbd294 100644
--- a/pkgs/ffigen/test/native_objc_test/protocol_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/protocol_config.yaml
@@ -22,6 +22,8 @@
- MyProtocol
- SecondaryProtocol
- UnusedProtocol
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'protocol_test.h'
diff --git a/pkgs/ffigen/test/native_objc_test/protocol_test.dart b/pkgs/ffigen/test/native_objc_test/protocol_test.dart
index fd5b9e9..5bb68b7 100644
--- a/pkgs/ffigen/test/native_objc_test/protocol_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/protocol_test.dart
@@ -10,7 +10,7 @@
import 'dart:isolate';
import 'package:ffi/ffi.dart';
-import 'package:objective_c/objective_c.dart' hide ObjCProtocolImpl;
+import 'package:objective_c/objective_c.dart' hide ObjCProtocolImpl, getClass;
import 'package:objective_c/src/internal.dart' show getProtocol;
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
@@ -25,20 +25,9 @@
typedef OtherMethodBlock = ObjCBlock_Int32_ffiVoid_Int32_Int32_Int32_Int32;
void main() {
- late ProtocolTestObjCLibrary lib;
-
group('protocol', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- lib = ProtocolTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+ loadLibrary();
});
group('ObjC implementation', () {
@@ -484,7 +473,7 @@
});
(NSObject, Pointer<ObjCBlockImpl>) blockRefCountTestInner() {
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
final protocolBuilder = ObjCProtocolBuilder();
final block = InstanceMethodBlock.fromFunction(
@@ -495,7 +484,7 @@
block,
);
final protocol = protocolBuilder.build();
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
final blockPtr = block.ref.pointer;
@@ -552,6 +541,7 @@
final isolate = Isolate.spawn(
(sendPort) {
+ loadLibrary();
final protoKeepAlive = ObjCProtocolBuilder().build(
keepIsolateAlive: true,
);
@@ -598,19 +588,19 @@
}, skip: !canDoGC);
test('class disposal, builder first', () {
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
ObjCProtocolBuilder? protocolBuilder = ObjCProtocolBuilder(
debugName: 'Foo',
);
NSObject? protocol = protocolBuilder.build();
- final clazz = lib.getClass(protocol);
+ final clazz = getClass(protocol);
expect(
- lib.getClassName(clazz).cast<Utf8>().toDartString(),
+ getClassName(clazz).cast<Utf8>().toDartString(),
startsWith('Foo'),
);
expect(isValidClass(clazz), isTrue);
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
protocolBuilder = null;
doGC();
@@ -622,19 +612,19 @@
}, skip: !canDoGC);
test('class disposal, instance first', () {
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
ObjCProtocolBuilder? protocolBuilder = ObjCProtocolBuilder(
debugName: 'Foo',
);
NSObject? protocol = protocolBuilder.build();
- final clazz = lib.getClass(protocol);
+ final clazz = getClass(protocol);
expect(
- lib.getClassName(clazz).cast<Utf8>().toDartString(),
+ getClassName(clazz).cast<Utf8>().toDartString(),
startsWith('Foo'),
);
expect(isValidClass(clazz), isTrue);
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
protocolBuilder = null;
doGC();
diff --git a/pkgs/ffigen/test/native_objc_test/protocol_test.m b/pkgs/ffigen/test/native_objc_test/protocol_test.m
index 7a313bf..05a3b83 100644
--- a/pkgs/ffigen/test/native_objc_test/protocol_test.m
+++ b/pkgs/ffigen/test/native_objc_test/protocol_test.m
@@ -4,8 +4,6 @@
#import <dispatch/dispatch.h>
-#define DISABLE_METHOD 1
-
#include "protocol_test.h"
const char* class_getName(Class cls);
diff --git a/pkgs/ffigen/test/native_objc_test/protocol_test_bindings.dart b/pkgs/ffigen/test/native_objc_test/protocol_test_bindings.dart
index eb2e33e..fbcf77d 100644
--- a/pkgs/ffigen/test/native_objc_test/protocol_test_bindings.dart
+++ b/pkgs/ffigen/test/native_objc_test/protocol_test_bindings.dart
@@ -2,76 +2,13 @@
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint, unused_import
+@ffi.DefaultAsset('package:ffigen/objc_test')
+library;
+
import 'dart:ffi' as ffi;
import 'package:objective_c/objective_c.dart' as objc;
import 'package:ffi/ffi.dart' as pkg_ffi;
-/// Tests implementing protocols
-class ProtocolTestObjCLibrary {
- /// Holds the symbol lookup function.
- final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
- _lookup;
-
- /// The symbols are looked up in [dynamicLibrary].
- ProtocolTestObjCLibrary(ffi.DynamicLibrary dynamicLibrary)
- : _lookup = dynamicLibrary.lookup;
-
- /// The symbols are looked up with [lookup].
- ProtocolTestObjCLibrary.fromLookup(
- ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName) lookup,
- ) : _lookup = lookup;
-
- ffi.Pointer<ffi.Void> getClass(objc.ObjCObject object) {
- return _getClass(object.ref.pointer);
- }
-
- late final _getClassPtr =
- _lookup<
- ffi.NativeFunction<
- ffi.Pointer<ffi.Void> Function(ffi.Pointer<objc.ObjCObjectImpl>)
- >
- >('getClass');
- late final _getClass = _getClassPtr
- .asFunction<
- ffi.Pointer<ffi.Void> Function(ffi.Pointer<objc.ObjCObjectImpl>)
- >();
-
- ffi.Pointer<ffi.Char> getClassName(ffi.Pointer<ffi.Void> cls) {
- return _getClassName(cls);
- }
-
- late final _getClassNamePtr =
- _lookup<
- ffi.NativeFunction<
- ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Void>)
- >
- >('getClassName');
- late final _getClassName = _getClassNamePtr
- .asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Void>)>();
-
- void objc_autoreleasePoolPop(ffi.Pointer<ffi.Void> pool) {
- return _objc_autoreleasePoolPop(pool);
- }
-
- late final _objc_autoreleasePoolPopPtr =
- _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
- 'objc_autoreleasePoolPop',
- );
- late final _objc_autoreleasePoolPop = _objc_autoreleasePoolPopPtr
- .asFunction<void Function(ffi.Pointer<ffi.Void>)>();
-
- ffi.Pointer<ffi.Void> objc_autoreleasePoolPush() {
- return _objc_autoreleasePoolPush();
- }
-
- late final _objc_autoreleasePoolPushPtr =
- _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
- 'objc_autoreleasePoolPush',
- );
- late final _objc_autoreleasePoolPush = _objc_autoreleasePoolPushPtr
- .asFunction<ffi.Pointer<ffi.Void> Function()>();
-}
-
@ffi.Native<
ffi.Int32 Function(ffi.Pointer<objc.ObjCObjectImpl>, ffi.Pointer<ffi.Void>)
>()
@@ -201,6 +138,25 @@
ffi.Pointer<objc.ObjCBlockImpl> block,
);
+@ffi.Native<ffi.Pointer<ffi.Void> Function(ffi.Pointer<objc.ObjCObjectImpl>)>(
+ symbol: 'getClass',
+)
+external ffi.Pointer<ffi.Void> _getClass(
+ ffi.Pointer<objc.ObjCObjectImpl> object,
+);
+
+ffi.Pointer<ffi.Void> getClass(objc.ObjCObject object) =>
+ _getClass(object.ref.pointer);
+
+@ffi.Native<ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Void>)>()
+external ffi.Pointer<ffi.Char> getClassName(ffi.Pointer<ffi.Void> cls);
+
+@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>)>()
+external void objc_autoreleasePoolPop(ffi.Pointer<ffi.Void> pool);
+
+@ffi.Native<ffi.Pointer<ffi.Void> Function()>()
+external ffi.Pointer<ffi.Void> objc_autoreleasePoolPush();
+
/// EmptyProtocol
extension type EmptyProtocol._(objc.ObjCProtocol object$)
implements objc.ObjCProtocol {
diff --git a/pkgs/ffigen/test/native_objc_test/ref_count_config.yaml b/pkgs/ffigen/test/native_objc_test/ref_count_config.yaml
index 9e198ae..1fe0602 100644
--- a/pkgs/ffigen/test/native_objc_test/ref_count_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/ref_count_config.yaml
@@ -11,6 +11,8 @@
include:
- RefCountTestObject
- RefCounted
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'ref_count_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/ref_count_test.dart b/pkgs/ffigen/test/native_objc_test/ref_count_test.dart
index 3016fbb..7d74df6 100644
--- a/pkgs/ffigen/test/native_objc_test/ref_count_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/ref_count_test.dart
@@ -16,20 +16,9 @@
import 'util.dart';
void main() {
- late RefCountTestObjCLibrary lib;
-
group('Reference counting', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- lib = RefCountTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
+ loadLibrary();
});
test('objectRetainCount edge cases', () {
@@ -131,7 +120,7 @@
Pointer<ObjCObjectImpl>,
)
copyMethodsInner(Pointer<Int32> counter) {
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
final obj1 = RefCountTestObject.newWithCounter(counter);
expect(counter.value, 1);
final obj2 = obj1.copyMe();
@@ -171,7 +160,7 @@
expect(objectRetainCount(obj8raw), greaterThan(0));
expect(objectRetainCount(obj9raw), greaterThan(0));
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
expect(objectRetainCount(obj1raw), greaterThan(0));
expect(objectRetainCount(obj2raw), greaterThan(0));
expect(objectRetainCount(obj3raw), greaterThan(0));
@@ -238,17 +227,17 @@
final counter = calloc<Int32>();
counter.value = 0;
- final pool1 = lib.objc_autoreleasePoolPush();
+ final pool1 = objc_autoreleasePoolPush();
final obj1raw = autoreleaseMethodsInner(counter);
doGC();
// The autorelease pool is still holding a reference to the object.
expect(counter.value, 1);
expect(objectRetainCount(obj1raw), greaterThan(0));
- lib.objc_autoreleasePoolPop(pool1);
+ objc_autoreleasePoolPop(pool1);
expect(counter.value, 0);
expect(objectRetainCount(obj1raw), 0);
- final pool2 = lib.objc_autoreleasePoolPush();
+ final pool2 = objc_autoreleasePoolPush();
final obj2 = RefCountTestObject.makeAndAutorelease(counter);
final obj2raw = obj2.ref.pointer;
expect(counter.value, 1);
@@ -256,7 +245,7 @@
doGC();
expect(counter.value, 1);
expect(objectRetainCount(obj2raw), greaterThan(0));
- lib.objc_autoreleasePoolPop(pool2);
+ objc_autoreleasePoolPop(pool2);
// The obj2 variable still holds a reference to the object.
expect(counter.value, 1);
expect(objectRetainCount(obj2raw), greaterThan(0));
@@ -351,13 +340,13 @@
counter.value = 0;
// The getters of retain properties retain+autorelease the value. So we
// need an autorelease pool.
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
final (outerObjRaw, retainObjRaw) = retainPropertiesInner(counter);
doGC();
expect(objectRetainCount(retainObjRaw), greaterThan(0));
expect(objectRetainCount(outerObjRaw), 0);
expect(counter.value, 1);
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
expect(objectRetainCount(retainObjRaw), 0);
expect(objectRetainCount(outerObjRaw), 0);
expect(counter.value, 0);
@@ -397,7 +386,7 @@
counter.value = 0;
// The getters of copy properties retain+autorelease the value. So we need
// an autorelease pool.
- final pool = lib.objc_autoreleasePoolPush();
+ final pool = objc_autoreleasePoolPush();
final (outerObjRaw, copyObjRaw, anotherCopyRaw) = copyPropertiesInner(
counter,
);
@@ -406,7 +395,7 @@
expect(objectRetainCount(outerObjRaw), 0);
expect(objectRetainCount(copyObjRaw), 0);
expect(objectRetainCount(anotherCopyRaw), greaterThan(0));
- lib.objc_autoreleasePoolPop(pool);
+ objc_autoreleasePoolPop(pool);
expect(counter.value, 0);
expect(objectRetainCount(outerObjRaw), 0);
expect(objectRetainCount(copyObjRaw), 0);
diff --git a/pkgs/ffigen/test/native_objc_test/ref_count_test_bindings.dart b/pkgs/ffigen/test/native_objc_test/ref_count_test_bindings.dart
index 39210fe..55cd5ef 100644
--- a/pkgs/ffigen/test/native_objc_test/ref_count_test_bindings.dart
+++ b/pkgs/ffigen/test/native_objc_test/ref_count_test_bindings.dart
@@ -2,47 +2,18 @@
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint, unused_import
+@ffi.DefaultAsset('package:ffigen/objc_test')
+library;
+
import 'dart:ffi' as ffi;
import 'package:objective_c/objective_c.dart' as objc;
import 'package:ffi/ffi.dart' as pkg_ffi;
-/// Tests reference counting of Objective-C objects
-class RefCountTestObjCLibrary {
- /// Holds the symbol lookup function.
- final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
- _lookup;
+@ffi.Native<ffi.Void Function(ffi.Pointer<ffi.Void>)>()
+external void objc_autoreleasePoolPop(ffi.Pointer<ffi.Void> pool);
- /// The symbols are looked up in [dynamicLibrary].
- RefCountTestObjCLibrary(ffi.DynamicLibrary dynamicLibrary)
- : _lookup = dynamicLibrary.lookup;
-
- /// The symbols are looked up with [lookup].
- RefCountTestObjCLibrary.fromLookup(
- ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName) lookup,
- ) : _lookup = lookup;
-
- void objc_autoreleasePoolPop(ffi.Pointer<ffi.Void> pool) {
- return _objc_autoreleasePoolPop(pool);
- }
-
- late final _objc_autoreleasePoolPopPtr =
- _lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
- 'objc_autoreleasePoolPop',
- );
- late final _objc_autoreleasePoolPop = _objc_autoreleasePoolPopPtr
- .asFunction<void Function(ffi.Pointer<ffi.Void>)>();
-
- ffi.Pointer<ffi.Void> objc_autoreleasePoolPush() {
- return _objc_autoreleasePoolPush();
- }
-
- late final _objc_autoreleasePoolPushPtr =
- _lookup<ffi.NativeFunction<ffi.Pointer<ffi.Void> Function()>>(
- 'objc_autoreleasePoolPush',
- );
- late final _objc_autoreleasePoolPush = _objc_autoreleasePoolPushPtr
- .asFunction<ffi.Pointer<ffi.Void> Function()>();
-}
+@ffi.Native<ffi.Pointer<ffi.Void> Function()>()
+external ffi.Pointer<ffi.Void> objc_autoreleasePoolPush();
/// RefCountTestObject
extension type RefCountTestObject._(objc.ObjCObject object$)
diff --git a/pkgs/ffigen/test/native_objc_test/rename_config.yaml b/pkgs/ffigen/test/native_objc_test/rename_config.yaml
index 2113620..7af6f09 100644
--- a/pkgs/ffigen/test/native_objc_test/rename_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/rename_config.yaml
@@ -23,6 +23,8 @@
structs:
include:
- CollidingStructName
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'rename_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/rename_test.dart b/pkgs/ffigen/test/native_objc_test/rename_test.dart
index bed447c..ebbedb1 100644
--- a/pkgs/ffigen/test/native_objc_test/rename_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/rename_test.dart
@@ -17,16 +17,7 @@
void main() {
group('rename_test', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test('Renamed class', () {
diff --git a/pkgs/ffigen/test/native_objc_test/runtime_version_config.yaml b/pkgs/ffigen/test/native_objc_test/runtime_version_config.yaml
index df6920b..96918f6 100644
--- a/pkgs/ffigen/test/native_objc_test/runtime_version_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/runtime_version_config.yaml
@@ -10,6 +10,8 @@
objc-categories:
include:
- FutureAPICategoryMethods
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'runtime_version_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/runtime_version_test.dart b/pkgs/ffigen/test/native_objc_test/runtime_version_test.dart
index 296e7e4..2112916 100644
--- a/pkgs/ffigen/test/native_objc_test/runtime_version_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/runtime_version_test.dart
@@ -18,16 +18,7 @@
void main() {
group('runtime version check', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test('Interface', () {
diff --git a/pkgs/ffigen/test/native_objc_test/sdk_variable_config.yaml b/pkgs/ffigen/test/native_objc_test/sdk_variable_config.yaml
index 94b2c88..d08cdc0 100644
--- a/pkgs/ffigen/test/native_objc_test/sdk_variable_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/sdk_variable_config.yaml
@@ -13,6 +13,8 @@
exclude:
# This method is missing on some machines.
- includesTextListMarkers
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- '$XCODE/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/AppKit.framework/Headers/NSColorPicker.h'
diff --git a/pkgs/ffigen/test/native_objc_test/sdk_variable_test.dart b/pkgs/ffigen/test/native_objc_test/sdk_variable_test.dart
index d072b42..678f173 100644
--- a/pkgs/ffigen/test/native_objc_test/sdk_variable_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/sdk_variable_test.dart
@@ -7,6 +7,8 @@
import 'dart:ffi';
import 'dart:io';
+import 'package:ffigen/ffigen.dart';
+import 'package:ffigen/src/header_parser.dart' show parse;
import 'package:path/path.dart' as path;
import 'package:test/test.dart';
import '../test_utils.dart';
@@ -14,27 +16,17 @@
void main() {
group('SDK variable', () {
- late String bindings;
-
+ late final String bindings;
setUpAll(() {
- final dylib = File(
+ final config = testConfigFromPath(
path.join(
packagePathForTests,
'test',
'native_objc_test',
- 'objc_test.dylib',
+ 'sdk_variable_config.yaml',
),
);
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
- bindings = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'sdk_variable_test_bindings.dart',
- ),
- ).readAsStringSync();
+ bindings = parse(testContext(config)).generate();
});
test('XCODE', () {
diff --git a/pkgs/ffigen/test/native_objc_test/setup.dart b/pkgs/ffigen/test/native_objc_test/setup.dart
deleted file mode 100644
index b06a82d..0000000
--- a/pkgs/ffigen/test/native_objc_test/setup.dart
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:io';
-
-import 'package:args/args.dart';
-
-// All ObjC source files are compiled with ARC enabled except these.
-const arcDisabledFiles = <String>{'ref_count_test.m'};
-
-Future<void> _runClang(List<String> flags, String output) async {
- final args = [...flags, '-o', output];
- final process = await Process.start('clang', args);
- unawaited(stdout.addStream(process.stdout));
- unawaited(stderr.addStream(process.stderr));
- final result = await process.exitCode;
- if (result != 0) {
- throw ProcessException('clang', args, 'Build failed', result);
- }
- print('Generated file: $output');
-}
-
-Future<String> _buildObject(String input, {bool objc = false}) async {
- final output = '$input.o';
- await _runClang([
- if (objc) ...['-x', 'objective-c'],
- if (objc && !arcDisabledFiles.contains(input)) '-fobjc-arc',
- '-Wno-nullability-completeness',
- '-c',
- input,
- '-fpic',
- ], output);
- return output;
-}
-
-Future<void> _linkLib(List<String> inputs, String output) =>
- _runClang(['-shared', '-framework', 'Foundation', ...inputs], output);
-
-Future<void> _buildLib(List<String> inputs, String output) async {
- final objFiles = <String>[];
- for (final input in inputs) {
- objFiles.add(await _buildObject(input, objc: true));
- }
- objFiles.add(
- await _buildObject('../../../objective_c/src/include/dart_api_dl.c'),
- );
- await _linkLib(objFiles, output);
-}
-
-Future<void> _buildSwift(
- String input,
- String outputHeader,
- String outputLib,
-) async {
- final args = [
- '-c',
- input,
- '-emit-objc-header-path',
- outputHeader,
- '-emit-library',
- '-o',
- outputLib,
- ];
- final process = await Process.start('swiftc', args);
- unawaited(stdout.addStream(process.stdout));
- unawaited(stderr.addStream(process.stderr));
- final result = await process.exitCode;
- if (result != 0) {
- throw ProcessException('swiftc', args, 'Build failed', result);
- }
- print('Generated files: $outputHeader and $outputLib');
-}
-
-List<String> _getTestNames() {
- const configSuffix = '_config.yaml';
- final names = <String>[];
- for (final entity in Directory.current.listSync()) {
- final filename = entity.uri.pathSegments.last;
- if (filename.endsWith(configSuffix)) {
- names.add(filename.substring(0, filename.length - configSuffix.length));
- }
- }
- return names;
-}
-
-Future<void> build(List<String> testNames) async {
- // Swift build comes first because the generated header is consumed by FFIgen.
- print('Building Dynamic Library and Header for Swift Tests...');
- for (final name in testNames) {
- final swiftFile = '${name}_test.swift';
- if (File(swiftFile).existsSync()) {
- await _buildSwift(
- swiftFile,
- '${name}_test-Swift.h',
- '${name}_test.dylib',
- );
- }
- }
-
- // Finally we build the dylib containing all the ObjC test code.
- print('Building Dynamic Library for Objective C Native Tests...');
- final mFiles = <String>[];
- for (final name in _getTestNames()) {
- final mFile = '${name}_test.m';
- if (File(mFile).existsSync()) mFiles.add(mFile);
- final bindingMFile = '${name}_test_bindings.m';
- if (File(bindingMFile).existsSync()) mFiles.add(bindingMFile);
- }
- if (mFiles.isNotEmpty) {
- await _buildLib(mFiles, 'objc_test.dylib');
- }
-}
-
-Future<void> clean(List<String> testNames) async {
- print('Deleting built files...');
- final filenames = [
- for (final name in testNames) ...[
- '${name}_test_bindings.o',
- '${name}_test.o',
- ],
- 'objc_test.dylib',
- ];
- for (final filename in filenames) {
- final file = File(filename);
- if (file.existsSync()) file.deleteSync();
- }
-}
-
-Future<void> main(List<String> arguments) async {
- final parser = ArgParser();
- parser.addFlag('clean');
- final args = parser.parse(arguments);
-
- // Allow running this script directly from any path (or an IDE).
- Directory.current = Platform.script.resolve('.').toFilePath();
- if (!Platform.isMacOS) {
- throw const OSError('Objective C tests are only supported on MacOS');
- }
-
- if (args.flag('clean')) {
- return await clean(_getTestNames());
- }
-
- return await build(args.rest.isNotEmpty ? args.rest : _getTestNames());
-}
diff --git a/pkgs/ffigen/test/native_objc_test/static_func_native_config.yaml b/pkgs/ffigen/test/native_objc_test/static_func_native_config.yaml
index 0c90c24..1ca3e60 100644
--- a/pkgs/ffigen/test/native_objc_test/static_func_native_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/static_func_native_config.yaml
@@ -4,6 +4,7 @@
output: 'static_func_native_test_bindings.dart'
exclude-all-by-default: true
ffi-native:
+ asset-id: 'package:ffigen/objc_test'
functions:
include:
- foo
diff --git a/pkgs/ffigen/test/native_objc_test/static_func_native_test.dart b/pkgs/ffigen/test/native_objc_test/static_func_native_test.dart
index ac6dd8d..76afa9f 100644
--- a/pkgs/ffigen/test/native_objc_test/static_func_native_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/static_func_native_test.dart
@@ -23,16 +23,7 @@
void main() {
group('static functions', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
Pointer<Int32> staticFuncOfObjectRefCountTest(Allocator alloc) {
diff --git a/pkgs/ffigen/test/native_objc_test/static_func_native_test_bindings.dart b/pkgs/ffigen/test/native_objc_test/static_func_native_test_bindings.dart
index 9e36181..f544b6c 100644
--- a/pkgs/ffigen/test/native_objc_test/static_func_native_test_bindings.dart
+++ b/pkgs/ffigen/test/native_objc_test/static_func_native_test_bindings.dart
@@ -2,6 +2,9 @@
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint, unused_import
+@ffi.DefaultAsset('package:ffigen/objc_test')
+library;
+
import 'dart:ffi' as ffi;
import 'package:objective_c/objective_c.dart' as objc;
import 'package:ffi/ffi.dart' as pkg_ffi;
diff --git a/pkgs/ffigen/test/native_objc_test/static_func_test.dart b/pkgs/ffigen/test/native_objc_test/static_func_test.dart
index afd82d7..a8027f6 100644
--- a/pkgs/ffigen/test/native_objc_test/static_func_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/static_func_test.dart
@@ -22,19 +22,11 @@
void main() {
late StaticFuncTestObjCLibrary lib;
-
group('static functions', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
+ lib = StaticFuncTestObjCLibrary(
+ DynamicLibrary.open(findDylib("objc_test")),
);
- verifySetupFile(dylib);
- lib = StaticFuncTestObjCLibrary(DynamicLibrary.open(dylib.absolute.path));
});
Pointer<Int32> staticFuncOfObjectRefCountTest(Allocator alloc) {
diff --git a/pkgs/ffigen/test/native_objc_test/string_config.yaml b/pkgs/ffigen/test/native_objc_test/string_config.yaml
index 395542a..fe7b6e7 100644
--- a/pkgs/ffigen/test/native_objc_test/string_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/string_config.yaml
@@ -6,6 +6,8 @@
objc-interfaces:
include:
- StringUtil
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'string_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/string_test.dart b/pkgs/ffigen/test/native_objc_test/string_test.dart
index d631410..9952b94 100644
--- a/pkgs/ffigen/test/native_objc_test/string_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/string_test.dart
@@ -18,16 +18,7 @@
void main() {
group('string', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
for (final s in ['Hello', '🇵🇬', 'Embedded\u0000Null']) {
diff --git a/pkgs/ffigen/test/native_objc_test/swift_class_config.yaml b/pkgs/ffigen/test/native_objc_test/swift_class_config.yaml
index c9e3c64..59f5f67 100644
--- a/pkgs/ffigen/test/native_objc_test/swift_class_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/swift_class_config.yaml
@@ -3,6 +3,8 @@
language: objc
output: 'swift_class_test_bindings.dart'
exclude-all-by-default: true
+ffi-native:
+ asset-id: 'package:ffigen/swift_class_test'
objc-interfaces:
include:
- MySwiftClass
diff --git a/pkgs/ffigen/test/native_objc_test/swift_class_test.dart b/pkgs/ffigen/test/native_objc_test/swift_class_test.dart
index 0b321fb..2a598dc 100644
--- a/pkgs/ffigen/test/native_objc_test/swift_class_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/swift_class_test.dart
@@ -16,16 +16,8 @@
void main() {
group('swift_class_test', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'swift_class_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
+ loadSwiftLibrary();
});
test('Renamed class', () {
diff --git a/pkgs/ffigen/test/native_objc_test/swift_class_test.swift b/pkgs/ffigen/test/native_objc_test/swift_class_test.swift
index 26ae016..6e920a1 100644
--- a/pkgs/ffigen/test/native_objc_test/swift_class_test.swift
+++ b/pkgs/ffigen/test/native_objc_test/swift_class_test.swift
@@ -1,5 +1,8 @@
import Foundation
+@_cdecl("ffigen_load_swift_test")
+public func ffigen_load_swift_test() {}
+
@objc public class MySwiftClass: NSObject {
var val = 123;
@objc public func getValue() -> Int {
diff --git a/pkgs/ffigen/test/native_objc_test/transitive_test.h b/pkgs/ffigen/test/native_objc_test/transitive_test.h
index 9d23455..b5bd49e 100644
--- a/pkgs/ffigen/test/native_objc_test/transitive_test.h
+++ b/pkgs/ffigen/test/native_objc_test/transitive_test.h
@@ -161,7 +161,7 @@
-(int)bug2935TransitiveBlockInterfaceMethod;
@end
-@protocol Bug2935TransitiveProtocol<NSObject> {}
+@protocol Bug2935TransitiveProtocol<NSObject>
-(void)bug2935TransitiveProtocolMethod:
(void (^)(Bug2935TransitiveBlockInterface* itf)) block;
@end
diff --git a/pkgs/ffigen/test/native_objc_test/typedef_config.yaml b/pkgs/ffigen/test/native_objc_test/typedef_config.yaml
index 976ddea..2fcde43 100644
--- a/pkgs/ffigen/test/native_objc_test/typedef_config.yaml
+++ b/pkgs/ffigen/test/native_objc_test/typedef_config.yaml
@@ -10,6 +10,8 @@
typedefs:
include:
- SomeClassPtr
+ffi-native:
+ asset-id: 'package:ffigen/objc_test'
headers:
entry-points:
- 'typedef_test.m'
diff --git a/pkgs/ffigen/test/native_objc_test/typedef_test.dart b/pkgs/ffigen/test/native_objc_test/typedef_test.dart
index 011364e..6857976 100644
--- a/pkgs/ffigen/test/native_objc_test/typedef_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/typedef_test.dart
@@ -16,16 +16,7 @@
void main() {
group('typedef', () {
setUpAll(() {
- final dylib = File(
- path.join(
- packagePathForTests,
- 'test',
- 'native_objc_test',
- 'objc_test.dylib',
- ),
- );
- verifySetupFile(dylib);
- DynamicLibrary.open(dylib.absolute.path);
+ loadLibrary();
});
test('Regression test for #386', () {
diff --git a/pkgs/ffigen/test/native_objc_test/util.dart b/pkgs/ffigen/test/native_objc_test/util.dart
index 3a02145..43a57bc 100644
--- a/pkgs/ffigen/test/native_objc_test/util.dart
+++ b/pkgs/ffigen/test/native_objc_test/util.dart
@@ -21,7 +21,12 @@
import '../test_utils.dart';
-void verifyBindings(String testName, [Logger? logger]) {
+void verifyBindings(
+ String testName, {
+ Logger? logger,
+ bool Function(String expected, String actual)? dartVerify,
+ bool Function(String expected, String actual)? objCVerify,
+}) {
final thisDir = p.join(packagePathForTests, 'test', 'native_objc_test');
final configFile = p.join(thisDir, '${testName}_config.yaml');
@@ -34,14 +39,14 @@
'test',
'native_objc_test',
bindingsName,
- ]);
+ ], verify: dartVerify);
final mFileName = context.config.output.objCFile.pathSegments.last;
matchObjCFileWithExpected(context, library, mFileName, [
'test',
'native_objc_test',
mFileName,
- ]);
+ ], verify: objCVerify);
}
final _executeInternalCommand = () {
@@ -119,3 +124,19 @@
bool isValidClass(Pointer<Void> clazz) =>
internal_for_testing.isValidClass(clazz.cast(), forceReloadClasses: true);
+
+String findDylib(String name) =>
+ p.join(packagePathForTests, '.dart_tool', 'lib', '$name.dylib');
+
+// TODO(https://github.com/dart-lang/native/issues/3338): Remove these.
+@Native<Void Function()>(
+ symbol: 'ffigen_load_objc_test',
+ assetId: 'package:ffigen/objc_test',
+)
+external void loadLibrary();
+
+@Native<Void Function()>(
+ symbol: 'ffigen_load_swift_test',
+ assetId: 'package:ffigen/swift_class_test',
+)
+external void loadSwiftLibrary();
diff --git a/pkgs/ffigen/test/native_objc_test/verify_bindings_test.dart b/pkgs/ffigen/test/native_objc_test/verify_bindings_test.dart
index 583471a..f5b5938 100644
--- a/pkgs/ffigen/test/native_objc_test/verify_bindings_test.dart
+++ b/pkgs/ffigen/test/native_objc_test/verify_bindings_test.dart
@@ -28,6 +28,13 @@
'verify_bindings_test.dart',
};
+ const customVerifiers = {
+ 'protocol_test.dart': (
+ _verifyProtocolTestDartBindings,
+ _verifyProtocolTestObjCBindings,
+ ),
+ };
+
final testFiles =
testDir
.listSync()
@@ -42,8 +49,61 @@
final configName = testFile.replaceFirst('_test.dart', '');
test('verifyBindings for $testFile', () {
- verifyBindings(configName);
+ final verifiers = customVerifiers[testFile];
+ verifyBindings(
+ configName,
+ dartVerify: verifiers?.$1,
+ objCVerify: verifiers?.$2,
+ );
});
}
});
}
+
+bool _verifyProtocolTestDartBindings(String expected, String actual) {
+ expect(
+ actual,
+ contains('extension type ProtocolConsumer._(objc.ObjCObject '),
+ );
+ expect(
+ actual,
+ contains('extension type ObjCProtocolImpl._(objc.ObjCObject '),
+ );
+ expect(actual, contains('extension type MyProtocol._(objc.ObjCProtocol '));
+ expect(
+ actual,
+ contains('extension type SecondaryProtocol._(objc.ObjCProtocol '),
+ );
+ expect(actual, contains(r'interface class MyProtocol$Builder {'));
+ expect(actual, contains(r'interface class SecondaryProtocol$Builder {'));
+ expect(
+ actual,
+ contains(
+ 'objc.NSString instanceMethod('
+ 'objc.NSString s, {required double withDouble})',
+ ),
+ );
+ expect(actual, contains('int optionalMethod(SomeStruct s)'));
+ expect(
+ actual,
+ contains(
+ 'int otherMethod('
+ 'int a, {required int b, required int c, required int d})',
+ ),
+ );
+ expect(actual, contains('int fooMethod()'));
+ expect(actual, contains('extension type EmptyProtocol._(objc.ObjCProtocol '));
+ expect(actual, isNot(contains('EmptyProtocol is a stub')));
+ expect(actual, contains('SuperProtocol is a stub'));
+ expect(actual, contains('FilteredProtocol is a stub'));
+ return true;
+}
+
+bool _verifyProtocolTestObjCBindings(String expected, String actual) {
+ expect(actual, contains('@protocol(EmptyProtocol)'));
+ expect(actual, contains('@protocol(MyProtocol)'));
+ expect(actual, contains('@protocol(SecondaryProtocol)'));
+ expect(actual, contains('@protocol(UnusedProtocol)'));
+ expect(actual, contains('BLOCKING_BLOCK_IMPL'));
+ return true;
+}
diff --git a/pkgs/ffigen/test/native_test/_expected_native_test_bindings.dart b/pkgs/ffigen/test/native_test/_expected_native_test_bindings.dart
index 090b9f5..0d0e9ae 100644
--- a/pkgs/ffigen/test/native_test/_expected_native_test_bindings.dart
+++ b/pkgs/ffigen/test/native_test/_expected_native_test_bindings.dart
@@ -2,233 +2,74 @@
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint, unused_import
+@ffi.DefaultAsset('package:ffigen/native_test')
+library;
+
import 'dart:ffi' as ffi;
-/// Native tests.
-class NativeLibrary {
- /// Holds the symbol lookup function.
- final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
- _lookup;
+@ffi.Native<ffi.Bool Function(ffi.Bool)>()
+external bool Function1Bool(bool x);
- /// The symbols are looked up in [dynamicLibrary].
- NativeLibrary(ffi.DynamicLibrary dynamicLibrary)
- : _lookup = dynamicLibrary.lookup;
+@ffi.Native<ffi.Double Function(ffi.Double)>()
+external double Function1Double(double x);
- /// The symbols are looked up with [lookup].
- NativeLibrary.fromLookup(
- ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName) lookup,
- ) : _lookup = lookup;
+@ffi.Native<ffi.Float Function(ffi.Float)>()
+external double Function1Float(double x);
- bool Function1Bool(bool x) {
- return _Function1Bool(x);
- }
+@ffi.Native<ffi.Int16 Function(ffi.Int16)>()
+external int Function1Int16(int x);
- late final _Function1BoolPtr =
- _lookup<ffi.NativeFunction<ffi.Bool Function(ffi.Bool)>>('Function1Bool');
- late final _Function1Bool =
- _Function1BoolPtr.asFunction<bool Function(bool)>();
+@ffi.Native<ffi.Int32 Function(ffi.Int32)>()
+external int Function1Int32(int x);
- double Function1Double(double x) {
- return _Function1Double(x);
- }
+@ffi.Native<ffi.Int64 Function(ffi.Int64)>()
+external int Function1Int64(int x);
- late final _Function1DoublePtr =
- _lookup<ffi.NativeFunction<ffi.Double Function(ffi.Double)>>(
- 'Function1Double',
- );
- late final _Function1Double =
- _Function1DoublePtr.asFunction<double Function(double)>();
+@ffi.Native<ffi.Int8 Function(ffi.Int8)>()
+external int Function1Int8(int x);
- double Function1Float(double x) {
- return _Function1Float(x);
- }
+@ffi.Native<ffi.IntPtr Function(ffi.IntPtr)>()
+external int Function1IntPtr(int x);
- late final _Function1FloatPtr =
- _lookup<ffi.NativeFunction<ffi.Float Function(ffi.Float)>>(
- 'Function1Float',
- );
- late final _Function1Float =
- _Function1FloatPtr.asFunction<double Function(double)>();
+@ffi.Native<ffi.Int Function(Struct3)>()
+external int Function1StructPassByValue(Struct3 sum_a_b_c);
- int Function1Int16(int x) {
- return _Function1Int16(x);
- }
+@ffi.Native<Struct3 Function(ffi.Int, ffi.Int, ffi.Int)>()
+external Struct3 Function1StructReturnByValue(int a, int b, int c);
- late final _Function1Int16Ptr =
- _lookup<ffi.NativeFunction<ffi.Int16 Function(ffi.Int16)>>(
- 'Function1Int16',
- );
- late final _Function1Int16 =
- _Function1Int16Ptr.asFunction<int Function(int)>();
+@ffi.Native<ffi.Uint16 Function(ffi.Uint16)>()
+external int Function1Uint16(int x);
- int Function1Int32(int x) {
- return _Function1Int32(x);
- }
+@ffi.Native<ffi.Uint32 Function(ffi.Uint32)>()
+external int Function1Uint32(int x);
- late final _Function1Int32Ptr =
- _lookup<ffi.NativeFunction<ffi.Int32 Function(ffi.Int32)>>(
- 'Function1Int32',
- );
- late final _Function1Int32 =
- _Function1Int32Ptr.asFunction<int Function(int)>();
+@ffi.Native<ffi.Uint64 Function(ffi.Uint64)>()
+external int Function1Uint64(int x);
- int Function1Int64(int x) {
- return _Function1Int64(x);
- }
+@ffi.Native<ffi.Uint8 Function(ffi.Uint8)>()
+external int Function1Uint8(int x);
- late final _Function1Int64Ptr =
- _lookup<ffi.NativeFunction<ffi.Int64 Function(ffi.Int64)>>(
- 'Function1Int64',
- );
- late final _Function1Int64 =
- _Function1Int64Ptr.asFunction<int Function(int)>();
+@ffi.Native<ffi.UintPtr Function(ffi.UintPtr)>()
+external int Function1UintPtr(int x);
- int Function1Int8(int x) {
- return _Function1Int8(x);
- }
+@ffi.Native<ffi.UnsignedInt Function(ffi.UnsignedInt)>(symbol: 'funcWithEnum1')
+external int _funcWithEnum1(int value);
- late final _Function1Int8Ptr =
- _lookup<ffi.NativeFunction<ffi.Int8 Function(ffi.Int8)>>('Function1Int8');
- late final _Function1Int8 = _Function1Int8Ptr.asFunction<int Function(int)>();
+Enum1 funcWithEnum1(Enum1 value) =>
+ Enum1.fromValue(_funcWithEnum1(value.value));
- int Function1IntPtr(int x) {
- return _Function1IntPtr(x);
- }
+@ffi.Native<ffi.UnsignedInt Function(ffi.UnsignedInt)>()
+external int funcWithEnum2(int value);
- late final _Function1IntPtrPtr =
- _lookup<ffi.NativeFunction<ffi.IntPtr Function(ffi.IntPtr)>>(
- 'Function1IntPtr',
- );
- late final _Function1IntPtr =
- _Function1IntPtrPtr.asFunction<int Function(int)>();
+@ffi.Native<ffi.Pointer<Struct1> Function()>()
+external ffi.Pointer<Struct1> getStruct1();
- int Function1StructPassByValue(Struct3 sum_a_b_c) {
- return _Function1StructPassByValue(sum_a_b_c);
- }
+@ffi.Native<StructWithEnums Function()>()
+external StructWithEnums getStructWithEnums();
- late final _Function1StructPassByValuePtr =
- _lookup<ffi.NativeFunction<ffi.Int Function(Struct3)>>(
- 'Function1StructPassByValue',
- );
- late final _Function1StructPassByValue =
- _Function1StructPassByValuePtr.asFunction<int Function(Struct3)>();
-
- Struct3 Function1StructReturnByValue(int a, int b, int c) {
- return _Function1StructReturnByValue(a, b, c);
- }
-
- late final _Function1StructReturnByValuePtr =
- _lookup<ffi.NativeFunction<Struct3 Function(ffi.Int, ffi.Int, ffi.Int)>>(
- 'Function1StructReturnByValue',
- );
- late final _Function1StructReturnByValue =
- _Function1StructReturnByValuePtr.asFunction<
- Struct3 Function(int, int, int)
- >();
-
- int Function1Uint16(int x) {
- return _Function1Uint16(x);
- }
-
- late final _Function1Uint16Ptr =
- _lookup<ffi.NativeFunction<ffi.Uint16 Function(ffi.Uint16)>>(
- 'Function1Uint16',
- );
- late final _Function1Uint16 =
- _Function1Uint16Ptr.asFunction<int Function(int)>();
-
- int Function1Uint32(int x) {
- return _Function1Uint32(x);
- }
-
- late final _Function1Uint32Ptr =
- _lookup<ffi.NativeFunction<ffi.Uint32 Function(ffi.Uint32)>>(
- 'Function1Uint32',
- );
- late final _Function1Uint32 =
- _Function1Uint32Ptr.asFunction<int Function(int)>();
-
- int Function1Uint64(int x) {
- return _Function1Uint64(x);
- }
-
- late final _Function1Uint64Ptr =
- _lookup<ffi.NativeFunction<ffi.Uint64 Function(ffi.Uint64)>>(
- 'Function1Uint64',
- );
- late final _Function1Uint64 =
- _Function1Uint64Ptr.asFunction<int Function(int)>();
-
- int Function1Uint8(int x) {
- return _Function1Uint8(x);
- }
-
- late final _Function1Uint8Ptr =
- _lookup<ffi.NativeFunction<ffi.Uint8 Function(ffi.Uint8)>>(
- 'Function1Uint8',
- );
- late final _Function1Uint8 =
- _Function1Uint8Ptr.asFunction<int Function(int)>();
-
- int Function1UintPtr(int x) {
- return _Function1UintPtr(x);
- }
-
- late final _Function1UintPtrPtr =
- _lookup<ffi.NativeFunction<ffi.UintPtr Function(ffi.UintPtr)>>(
- 'Function1UintPtr',
- );
- late final _Function1UintPtr =
- _Function1UintPtrPtr.asFunction<int Function(int)>();
-
- Enum1 funcWithEnum1(Enum1 value) {
- return Enum1.fromValue(_funcWithEnum1(value.value));
- }
-
- late final _funcWithEnum1Ptr =
- _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(ffi.UnsignedInt)>>(
- 'funcWithEnum1',
- );
- late final _funcWithEnum1 = _funcWithEnum1Ptr.asFunction<int Function(int)>();
-
- int funcWithEnum2(int value) {
- return _funcWithEnum2(value);
- }
-
- late final _funcWithEnum2Ptr =
- _lookup<ffi.NativeFunction<ffi.UnsignedInt Function(ffi.UnsignedInt)>>(
- 'funcWithEnum2',
- );
- late final _funcWithEnum2 = _funcWithEnum2Ptr.asFunction<int Function(int)>();
-
- ffi.Pointer<Struct1> getStruct1() {
- return _getStruct1();
- }
-
- late final _getStruct1Ptr =
- _lookup<ffi.NativeFunction<ffi.Pointer<Struct1> Function()>>(
- 'getStruct1',
- );
- late final _getStruct1 = _getStruct1Ptr
- .asFunction<ffi.Pointer<Struct1> Function()>();
-
- StructWithEnums getStructWithEnums() {
- return _getStructWithEnums();
- }
-
- late final _getStructWithEnumsPtr =
- _lookup<ffi.NativeFunction<StructWithEnums Function()>>(
- 'getStructWithEnums',
- );
- late final _getStructWithEnums = _getStructWithEnumsPtr
- .asFunction<StructWithEnums Function()>();
-
- late final ffi.Pointer<ffi.Int> _globalArray = _lookup<ffi.Int>(
- 'globalArray',
- );
-
- ffi.Pointer<ffi.Int> get globalArray => _globalArray;
-}
+@ffi.Array.multi([3])
+@ffi.Native<ffi.Array<ffi.Int>>()
+external ffi.Array<ffi.Int> globalArray;
enum Enum1 {
enum1Value1(0),
diff --git a/pkgs/ffigen/test/native_test/build_test_dylib.dart b/pkgs/ffigen/test/native_test/build_test_dylib.dart
deleted file mode 100644
index bc3eeb8..0000000
--- a/pkgs/ffigen/test/native_test/build_test_dylib.dart
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// =======================================================================
-/// ==== Script to generate dynamic library for native_function_tests =====
-/// =======================================================================
-/// This Script effectively calls the following (but user can provide
-/// command line args which will replace the defaults shown below)-
-///
-/// Linux:
-/// ```
-/// clang -shared -fpic native_test.c -o native_test.so
-/// ```
-/// MacOS:
-/// ```
-/// clang -shared -fpic native_test.c -o native_test.dylib
-/// ```
-/// Windows:
-/// ```
-/// call clang -shared native_test.c -o native_test.dll -Wl,"/DEF:native_test.def"
-/// del native_test.exp
-/// del native_test.lib
-/// ```
-/// =======================================================================
-/// =======================================================================
-/// =======================================================================
-library;
-
-import 'dart:io';
-
-const macOS = 'macos';
-const windows = 'windows';
-const linux = 'linux';
-
-Map<String, Options> platformOptions = {
- linux: Options(
- outputfilename: 'native_test.so',
- sharedFlag: '-shared',
- inputHeader: 'native_test.c',
- fPIC: '-fpic',
- ),
- windows: Options(
- outputfilename: 'native_test.dll',
- sharedFlag: '-shared',
- inputHeader: 'native_test.c',
- moduleDefPath: '-Wl,/DEF:native_test.def',
- ),
- macOS: Options(
- outputfilename: 'native_test.dylib',
- sharedFlag: '-shared',
- inputHeader: 'native_test.c',
- fPIC: '-fpic',
- ),
-};
-
-void main(List<String> arguments) {
- print('Building Dynamic Library for Native Tests... ');
- final options = getPlatformOptions()!;
-
- // Run clang compiler to generate the dynamic library.
- final processResult = runClangProcess(options);
- printSuccess(processResult, options);
-}
-
-/// Calls the clang compiler.
-ProcessResult runClangProcess(Options options) {
- final result = Process.runSync('clang', [
- options.sharedFlag,
- options.fPIC,
- options.inputHeader,
- '-o',
- options.outputfilename,
- options.moduleDefPath,
- '-Wno-nullability-completeness',
- ]);
- return result;
-}
-
-/// Prints success message (or process error if any).
-void printSuccess(ProcessResult result, Options options) {
- print(result.stdout);
- if ((result.stderr as String).isEmpty) {
- print('Generated file: ${options.outputfilename}');
- } else {
- print(result.stderr);
- }
-}
-
-/// Get options based on current platform.
-Options? getPlatformOptions() {
- if (Platform.isMacOS) {
- return platformOptions[macOS];
- } else if (Platform.isWindows) {
- return platformOptions[windows];
- } else if (Platform.isLinux) {
- return platformOptions[linux];
- } else {
- throw Exception('Unknown Platform.');
- }
-}
-
-/// Hold options which would be passed to clang.
-class Options {
- /// Name of dynamic library to generate.
- final String outputfilename;
-
- /// Tells compiler to generate a shared library.
- final String sharedFlag;
-
- /// Flag for generating Position Independant Code (Not used on windows).
- final String fPIC;
-
- /// Input file.
- final String inputHeader;
-
- /// Path to `.def` file containing symbols to export, windows use only.
- final String moduleDefPath;
-
- Options({
- required this.outputfilename,
- required this.sharedFlag,
- required this.inputHeader,
- this.fPIC = '',
- this.moduleDefPath = '',
- });
-}
diff --git a/pkgs/ffigen/test/native_test/config.yaml b/pkgs/ffigen/test/native_test/config.yaml
index 13be88e..3394d49 100644
--- a/pkgs/ffigen/test/native_test/config.yaml
+++ b/pkgs/ffigen/test/native_test/config.yaml
@@ -9,6 +9,8 @@
name: NativeLibrary
description: 'Native tests.'
output: '_expected_native_test_bindings.dart'
+ffi-native:
+ asset-id: 'package:ffigen/native_test'
headers:
entry-points:
- 'native_test.c'
diff --git a/pkgs/ffigen/test/native_test/native_test.dart b/pkgs/ffigen/test/native_test/native_test.dart
index e825268..08af977 100644
--- a/pkgs/ffigen/test/native_test/native_test.dart
+++ b/pkgs/ffigen/test/native_test/native_test.dart
@@ -3,7 +3,6 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:ffi';
-import 'dart:io';
import 'dart:math';
import 'package:ffigen/src/header_parser.dart' show parse;
@@ -12,20 +11,15 @@
import '../test_utils.dart';
import '_expected_native_test_bindings.dart';
+@Native<Void Function()>(
+ symbol: 'Function1Bool',
+ assetId: 'package:ffigen/native_test',
+)
+external void loadLibrary();
+
void main() {
- late NativeLibrary bindings;
group('native_test', () {
- setUpAll(() {
- var dylibName = 'test/native_test/native_test.so';
- if (Platform.isMacOS) {
- dylibName = 'test/native_test/native_test.dylib';
- } else if (Platform.isWindows) {
- dylibName = r'test\native_test\native_test.dll';
- }
- final dylib = File(path.join(packagePathForTests, dylibName));
- verifySetupFile(dylib);
- bindings = NativeLibrary(DynamicLibrary.open(dylib.absolute.path));
- });
+ setUpAll(loadLibrary);
test('generate_bindings', () {
final context = testContext(
@@ -43,64 +37,52 @@
});
test('bool', () {
- expect(bindings.Function1Bool(true), false);
- expect(bindings.Function1Bool(false), true);
+ expect(Function1Bool(true), false);
+ expect(Function1Bool(false), true);
});
test('uint8_t', () {
- expect(bindings.Function1Uint8(pow(2, 8).toInt()), 42);
+ expect(Function1Uint8(pow(2, 8).toInt()), 42);
});
test('uint16_t', () {
- expect(bindings.Function1Uint16(pow(2, 16).toInt()), 42);
+ expect(Function1Uint16(pow(2, 16).toInt()), 42);
});
test('uint32_t', () {
- expect(bindings.Function1Uint32(pow(2, 32).toInt()), 42);
+ expect(Function1Uint32(pow(2, 32).toInt()), 42);
});
test('uint64_t', () {
- expect(bindings.Function1Uint64(pow(2, 64).toInt()), 42);
+ expect(Function1Uint64(pow(2, 64).toInt()), 42);
});
test('int8_t', () {
- expect(
- bindings.Function1Int8(pow(2, 7).toInt()),
- -pow(2, 7).toInt() + 42,
- );
+ expect(Function1Int8(pow(2, 7).toInt()), -pow(2, 7).toInt() + 42);
});
test('int16_t', () {
- expect(
- bindings.Function1Int16(pow(2, 15).toInt()),
- -pow(2, 15).toInt() + 42,
- );
+ expect(Function1Int16(pow(2, 15).toInt()), -pow(2, 15).toInt() + 42);
});
test('int32_t', () {
- expect(
- bindings.Function1Int32(pow(2, 31).toInt()),
- -pow(2, 31).toInt() + 42,
- );
+ expect(Function1Int32(pow(2, 31).toInt()), -pow(2, 31).toInt() + 42);
});
test('int64_t', () {
- expect(
- bindings.Function1Int64(pow(2, 63).toInt()),
- -pow(2, 63).toInt() + 42,
- );
+ expect(Function1Int64(pow(2, 63).toInt()), -pow(2, 63).toInt() + 42);
});
test('intptr_t', () {
- expect(bindings.Function1IntPtr(0), 42);
+ expect(Function1IntPtr(0), 42);
});
test('float', () {
- expect(bindings.Function1Float(0), 42.0);
+ expect(Function1Float(0), 42.0);
});
test('double', () {
- expect(bindings.Function1Double(0), 42.0);
+ expect(Function1Double(0), 42.0);
});
test('array global', () {
- bindings.globalArray[0] = 1;
- bindings.globalArray[1] = 2;
- expect(bindings.globalArray[0], 1);
- expect(bindings.globalArray[1], 2);
- bindings.globalArray[1] = 3;
- expect(bindings.globalArray[1], 3);
+ globalArray[0] = 1;
+ globalArray[1] = 2;
+ expect(globalArray[0], 1);
+ expect(globalArray[1], 2);
+ globalArray[1] = 3;
+ expect(globalArray[1], 3);
});
test('Array Test: Order of access', () {
- final struct1 = bindings.getStruct1();
+ final struct1 = getStruct1();
var expectedValue = 1;
final dimensions = [3, 1, 2];
for (var i = 0; i < dimensions[0]; i++) {
@@ -114,7 +96,7 @@
});
test('Array Workaround: Range Errors', () {
- final struct1 = bindings.getStruct1();
+ final struct1 = getStruct1();
// Index (get) above range.
expect(
() => struct1.ref.data[4][0][0],
@@ -172,13 +154,13 @@
test('Struct By Value', () {
final r = Random();
final a = r.nextInt(100), b = r.nextInt(100), c = r.nextInt(100);
- final s = bindings.Function1StructReturnByValue(a, b, c);
- expect(bindings.Function1StructPassByValue(s), a + b + c);
+ final s = Function1StructReturnByValue(a, b, c);
+ expect(Function1StructPassByValue(s), a + b + c);
});
test('Enum1 is a Dart enum', () {
final enum1 = Enum1.enum1Value1;
- final result = bindings.funcWithEnum1(enum1);
+ final result = funcWithEnum1(enum1);
expect(enum1, isA<Enum1>());
expect(enum1.value, isA<int>());
expect(result, enum1);
@@ -186,13 +168,13 @@
test('Enum2 is a Dart integer', () {
final enum2 = Enum2.enum2Value1;
- final result = bindings.funcWithEnum2(enum2);
+ final result = funcWithEnum2(enum2);
expect(enum2, isA<int>());
expect(result, enum2);
});
test('Enum in a struct', () {
- final struct1 = bindings.getStructWithEnums();
+ final struct1 = getStructWithEnums();
Enum1 enum1;
enum1 = struct1.enum1;
expect(enum1, Enum1.enum1Value1);
diff --git a/pkgs/ffigen/test/setup.dart b/pkgs/ffigen/test/setup.dart
deleted file mode 100644
index 812765a..0000000
--- a/pkgs/ffigen/test/setup.dart
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Runs all the test setup scripts. Usage:
-// dart run test/setup.dart
-
-import 'dart:async';
-import 'dart:io';
-
-Future<void> _run(String subdir, String script, List<String> flags) async {
- final dir = Platform.script.resolve('$subdir/');
- print('\nRunning $script in ${dir.toFilePath()}');
- final args = [
- '--enable-asserts',
- 'run',
- dir.resolve(script).toFilePath(),
- ...flags,
- ];
- final process = await Process.start(
- Platform.executable,
- args,
- workingDirectory: dir.toFilePath(),
- );
- unawaited(stdout.addStream(process.stdout));
- unawaited(stderr.addStream(process.stderr));
- final result = await process.exitCode;
- if (result != 0) {
- throw ProcessException(Platform.executable, args, '$script failed', result);
- }
-}
-
-Future<void> main(List<String> arguments) async {
- await _run('native_test', 'build_test_dylib.dart', []);
- if (Platform.isMacOS) {
- await _run('native_objc_test', 'setup.dart', []);
- }
- print('\nSuccess :)\n');
-}
diff --git a/pkgs/ffigen/test/test_utils.dart b/pkgs/ffigen/test/test_utils.dart
index 4a7b394..7ab77f3 100644
--- a/pkgs/ffigen/test/test_utils.dart
+++ b/pkgs/ffigen/test/test_utils.dart
@@ -92,17 +92,6 @@
}
}
-/// Check whether a file generated by test/setup.dart exists and throw a helpful
-/// exception if it does not.
-void verifySetupFile(File file) {
- if (!file.existsSync()) {
- throw NotFoundException(
- 'The file ${file.path} does not exist.\n\n'
- 'You may need to run: dart run test/setup.dart\n',
- );
- }
-}
-
// Remove '\r' for Windows compatibility, then apply user's normalizer.
String _normalizeGeneratedCode(
String generated,
diff --git a/pkgs/objective_c/hook/build.dart b/pkgs/objective_c/hook/build.dart
index cc6434a..36f4096 100644
--- a/pkgs/objective_c/hook/build.dart
+++ b/pkgs/objective_c/hook/build.dart
@@ -55,9 +55,7 @@
}
}
- final includeTestUtils =
- input.userDefines['include_test_utils'] as bool? ?? false;
- if (includeTestUtils) {
+ if (input.userDefines['include_test_utils'] == true) {
cFiles.add(input.packageRoot.resolve('test/util.c').toFilePath());
mFiles.add(input.packageRoot.resolve('test/gc_inject.m').toFilePath());
}