[ffigen] Remove ignoreFilter from typedef parsing. (#462)
diff --git a/pkgs/ffigen/CHANGELOG.md b/pkgs/ffigen/CHANGELOG.md index 28b0435..9801108 100644 --- a/pkgs/ffigen/CHANGELOG.md +++ b/pkgs/ffigen/CHANGELOG.md
@@ -1,3 +1,8 @@ +# 7.0.0 + +- Fix typedef include/exclude config. +- Return `ObjCBlock` wrapper instead of raw pointer in more cases. + # 7.0.0-dev - Relative paths in ffigen config files are now assumed to be relative to the
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_interface.dart b/pkgs/ffigen/lib/src/code_generator/objc_interface.dart index 68da95d..cda85ca 100644 --- a/pkgs/ffigen/lib/src/code_generator/objc_interface.dart +++ b/pkgs/ffigen/lib/src/code_generator/objc_interface.dart
@@ -5,6 +5,7 @@ import 'package:ffigen/src/code_generator.dart'; import 'package:logging/logging.dart'; +import '../strings.dart' as strings; import 'binding_string.dart'; import 'utils.dart'; import 'writer.dart'; @@ -341,7 +342,7 @@ bool _isInstanceType(Type type) => type is Typealias && - type.originalName == 'instancetype' && + type.originalName == strings.objcInstanceType && _isObject(type.type); // Utils for converting between the internal types passed to native code, and
diff --git a/pkgs/ffigen/lib/src/header_parser/includer.dart b/pkgs/ffigen/lib/src/header_parser/includer.dart index 05bfa54..4cb1662 100644 --- a/pkgs/ffigen/lib/src/header_parser/includer.dart +++ b/pkgs/ffigen/lib/src/header_parser/includer.dart
@@ -59,6 +59,10 @@ } bool shouldIncludeTypealias(String usr, String name) { + // Objective C has some core typedefs that are important to keep. + if (config.language == Language.objc && name == strings.objcInstanceType) { + return true; + } return _shouldIncludeDecl( usr, name, bindingsIndex.isSeenType, config.typedefs.shouldInclude); }
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart index 22767ed..988a45e 100644 --- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart +++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/typedefdecl_parser.dart
@@ -34,12 +34,11 @@ /// by the config. Typealias? parseTypedefDeclaration( clang_types.CXCursor cursor, { - bool ignoreFilter = false, bool pointerReference = false, }) { final typedefName = cursor.spelling(); final typedefUsr = cursor.usr(); - if (ignoreFilter || shouldIncludeTypealias(typedefUsr, typedefName)) { + if (shouldIncludeTypealias(typedefUsr, typedefName)) { final ct = clang.clang_getTypedefDeclUnderlyingType(cursor); final s = getCodeGenType(ct, pointerReference: pointerReference);
diff --git a/pkgs/ffigen/lib/src/header_parser/type_extractor/extractor.dart b/pkgs/ffigen/lib/src/header_parser/type_extractor/extractor.dart index 1590d73..065e789 100644 --- a/pkgs/ffigen/lib/src/header_parser/type_extractor/extractor.dart +++ b/pkgs/ffigen/lib/src/header_parser/type_extractor/extractor.dart
@@ -192,8 +192,8 @@ } } - final typealias = parseTypedefDeclaration(cursor, - ignoreFilter: ignoreFilter, pointerReference: pointerReference); + final typealias = + parseTypedefDeclaration(cursor, pointerReference: pointerReference); if (typealias != null) { return _CreateTypeFromCursorResult(typealias);
diff --git a/pkgs/ffigen/lib/src/strings.dart b/pkgs/ffigen/lib/src/strings.dart index 96e3c34..735dc13 100644 --- a/pkgs/ffigen/lib/src/strings.dart +++ b/pkgs/ffigen/lib/src/strings.dart
@@ -39,7 +39,10 @@ const clangLangObjC = ['-x', 'objective-c']; const clangObjCBoolDefine = '__OBJC_BOOL_IS_BOOL'; const clangInclude = '-include'; + +// Special objective C types. const objcBOOL = 'BOOL'; +const objcInstanceType = 'instancetype'; // Internal objective C directories that are automatically pulled in by clang, // and should be excluded from output (unless explicitly used).
diff --git a/pkgs/ffigen/pubspec.yaml b/pkgs/ffigen/pubspec.yaml index 302f458..3ac3822 100644 --- a/pkgs/ffigen/pubspec.yaml +++ b/pkgs/ffigen/pubspec.yaml
@@ -3,7 +3,7 @@ # BSD-style license that can be found in the LICENSE file. name: ffigen -version: 7.0.0-dev +version: 7.0.0 description: Generator for FFI bindings, using LibClang to parse C header files. repository: https://github.com/dart-lang/ffigen
diff --git a/pkgs/ffigen/test/config_tests/include_exclude.h b/pkgs/ffigen/test/config_tests/include_exclude.h new file mode 100644 index 0000000..b62e8f3 --- /dev/null +++ b/pkgs/ffigen/test/config_tests/include_exclude.h
@@ -0,0 +1,28 @@ +// 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. + +typedef int Typedef; + +void func(Typedef s); + +struct Struct { + int a; +}; + +union Union { + int a; +}; + +int global; + +#define MACRO 123 + +enum Enum { + zero = 0, +}; + +enum { + unnamedEnum = 123, +}; +
diff --git a/pkgs/ffigen/test/config_tests/include_exclude_test.dart b/pkgs/ffigen/test/config_tests/include_exclude_test.dart new file mode 100644 index 0000000..5cc1156 --- /dev/null +++ b/pkgs/ffigen/test/config_tests/include_exclude_test.dart
@@ -0,0 +1,74 @@ +// 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 'package:ffigen/ffigen.dart'; +import 'package:ffigen/src/strings.dart' as strings; +import 'package:test/test.dart'; +import 'package:yaml/yaml.dart' as yaml; + +import '../test_utils.dart'; + +void main() { + group('include_exclude', () { + const fieldsAndNameMap = { + strings.functions: 'func', + strings.structs: 'Struct', + strings.unions: 'Union', + strings.enums: 'Enum', + strings.unnamedEnums: 'unnamedEnum', + strings.macros: 'MACRO', + strings.globals: 'global', + strings.typedefs: 'Typedef', + }; + for (final f in fieldsAndNameMap.keys) { + test('include $f', () { + final config = _makeFieldIncludeExcludeConfig( + field: f, include: fieldsAndNameMap[f]); + final library = parse(config); + expect(library.getBinding(fieldsAndNameMap[f]!), isNotNull); + }); + test('exclude $f', () { + final config = _makeFieldIncludeExcludeConfig( + field: f, exclude: fieldsAndNameMap[f]); + final library = parse(config); + expect(() => library.getBinding(fieldsAndNameMap[f]!), throwsException); + }); + } + }); +} + +Config _makeFieldIncludeExcludeConfig({ + required String field, + String? include, + String? exclude, +}) { + var templateString = ''' +${strings.name}: 'NativeLibrary' +${strings.description}: 'include_exclude test' +${strings.output}: 'unused' +${strings.headers}: + ${strings.entryPoints}: + - 'test/config_tests/include_exclude.h' +'''; + if (include != null || exclude != null) { + templateString += ''' +$field: +'''; + if (include != null) { + templateString += ''' + ${strings.include}: + - $include +'''; + } + if (exclude != null) { + templateString += ''' + ${strings.exclude}: + - $exclude +'''; + } + } + + final config = Config.fromYaml(yaml.loadYaml(templateString) as yaml.YamlMap); + return config; +}
diff --git a/pkgs/ffigen/test/native_objc_test/block_test.dart b/pkgs/ffigen/test/native_objc_test/block_test.dart index 99d1460..92e6fe7 100644 --- a/pkgs/ffigen/test/native_objc_test/block_test.dart +++ b/pkgs/ffigen/test/native_objc_test/block_test.dart
@@ -53,7 +53,7 @@ test('Block from function pointer', () { final block = ObjCBlock.fromFunctionPointer( lib, Pointer.fromFunction(_add100, 999)); - final blockTester = BlockTester.makeFromBlock_(lib, block.pointer); + final blockTester = BlockTester.makeFromBlock_(lib, block); blockTester.pokeBlock(); expect(blockTester.call_(123), 223); expect(block(123), 223); @@ -65,7 +65,7 @@ test('Block from function', () { final block = ObjCBlock.fromFunction(lib, makeAdder(4000)); - final blockTester = BlockTester.makeFromBlock_(lib, block.pointer); + final blockTester = BlockTester.makeFromBlock_(lib, block); blockTester.pokeBlock(); expect(blockTester.call_(123), 4123); expect(block(123), 4123); @@ -74,7 +74,7 @@ Pointer<Void> funcPointerBlockRefCountTest() { final block = ObjCBlock.fromFunctionPointer( lib, Pointer.fromFunction(_add100, 999)); - expect(BlockTester.getBlockRetainCount_(lib, block.pointer), 1); + expect(BlockTester.getBlockRetainCount_(lib, block.pointer.cast()), 1); return block.pointer.cast(); } @@ -86,7 +86,7 @@ Pointer<Void> funcBlockRefCountTest() { final block = ObjCBlock.fromFunction(lib, makeAdder(4000)); - expect(BlockTester.getBlockRetainCount_(lib, block.pointer), 1); + expect(BlockTester.getBlockRetainCount_(lib, block.pointer.cast()), 1); return block.pointer.cast(); }
diff --git a/pkgs/ffigen/test/native_objc_test/block_test.m b/pkgs/ffigen/test/native_objc_test/block_test.m index c0052e3..bdd37a7 100644 --- a/pkgs/ffigen/test/native_objc_test/block_test.m +++ b/pkgs/ffigen/test/native_objc_test/block_test.m
@@ -13,7 +13,7 @@ } + (BlockTester*)makeFromBlock:(IntBlock)block; + (BlockTester*)makeFromMultiplier:(int32_t)mult; -+ (uint64_t)getBlockRetainCount:(IntBlock)block; ++ (uint64_t)getBlockRetainCount:(void*)block; - (int32_t)call:(int32_t)x; - (IntBlock)getBlock; - (void)pokeBlock; @@ -41,7 +41,7 @@ } BlockRefCountExtractor; void* valid_block_isa = NULL; -+ (uint64_t)getBlockRetainCount:(IntBlock)block { ++ (uint64_t)getBlockRetainCount:(void*)block { BlockRefCountExtractor* b = (BlockRefCountExtractor*)block; // HACK: The only way I can find to reliably figure out that a block has been // deleted is to check the isa field (the lower bits of the flags field seem
diff --git a/pkgs/ffigen/test/native_objc_test/swift_class_test_.dart b/pkgs/ffigen/test/native_objc_test/swift_class_test.dart similarity index 100% rename from pkgs/ffigen/test/native_objc_test/swift_class_test_.dart rename to pkgs/ffigen/test/native_objc_test/swift_class_test.dart