[ffigen] Fix `sort: true` not working, remove //+ from full comments. (#187)
diff --git a/pkgs/ffigen/CHANGELOG.md b/pkgs/ffigen/CHANGELOG.md index 4a849f3..abc7d7b 100644 --- a/pkgs/ffigen/CHANGELOG.md +++ b/pkgs/ffigen/CHANGELOG.md
@@ -1,3 +1,7 @@ +# 2.2.4 +- Fix `sort: true` not working. +- Fix extra `//` or `///` in comments when using `comments -> style`: `full`. + # 2.2.3 - Added new subkey `dependency-only` (options - `full (default) | opaque`) under `structs`. When set to `opaque`, ffigen will generate empty `Opaque` structs if structs
diff --git a/pkgs/ffigen/example/libclang-example/pubspec.yaml b/pkgs/ffigen/example/libclang-example/pubspec.yaml index 9c67f6b..fe0f30b 100644 --- a/pkgs/ffigen/example/libclang-example/pubspec.yaml +++ b/pkgs/ffigen/example/libclang-example/pubspec.yaml
@@ -13,7 +13,9 @@ ffigen: output: 'generated_bindings.dart' - sort: true + + # This will sort the bindings alphabetically. + # sort: true # This is required if LLVM can't be found in default locations by ffigen. # llvm-lib: '/usr/local/opt/llvm/lib'
diff --git a/pkgs/ffigen/lib/src/code_generator/library.dart b/pkgs/ffigen/lib/src/code_generator/library.dart index 893289d..d83a19d 100644 --- a/pkgs/ffigen/lib/src/code_generator/library.dart +++ b/pkgs/ffigen/lib/src/code_generator/library.dart
@@ -27,7 +27,10 @@ required this.bindings, String? header, bool dartBool = true, + bool sort = false, }) { + if (sort) _sort(); + // Seperate bindings which require lookup. final lookUpBindings = bindings.whereType<LookUpBinding>().toList(); final noLookUpBindings = bindings.whereType<NoLookUpBinding>().toList(); @@ -79,7 +82,7 @@ } /// Sort all bindings in alphabetical order. - void sort() { + void _sort() { bindings.sort((b1, b2) => b1.name.compareTo(b2.name)); }
diff --git a/pkgs/ffigen/lib/src/header_parser/parser.dart b/pkgs/ffigen/lib/src/header_parser/parser.dart index 3d4c5f0..a8473af 100644 --- a/pkgs/ffigen/lib/src/header_parser/parser.dart +++ b/pkgs/ffigen/lib/src/header_parser/parser.dart
@@ -29,11 +29,9 @@ description: config.wrapperDocComment, header: config.preamble, dartBool: config.dartBool, + sort: config.sort, ); - if (config.sort) { - library.sort(); - } return library; }
diff --git a/pkgs/ffigen/lib/src/header_parser/utils.dart b/pkgs/ffigen/lib/src/header_parser/utils.dart index ef91924..e1b205c 100644 --- a/pkgs/ffigen/lib/src/header_parser/utils.dart +++ b/pkgs/ffigen/lib/src/header_parser/utils.dart
@@ -193,15 +193,21 @@ } final sb = StringBuffer(); - // Remove comment identifiers. - string = string.replaceAll('/*', ''); - string = string.replaceAll('*/', ''); + // Remove comment identifiers (`/** * */`, `///`, `//`) from lines. + if (string.contains(RegExp(r'^\s*\/\*+'))) { + string = string.replaceFirst(RegExp(r'^\s*\/\*+\s*'), ''); + string = string.replaceFirst(RegExp(r'\s*\*+\/$'), ''); + string.split('\n').forEach((element) { + element = element.replaceFirst(RegExp(r'^\s*\**\s*'), ''); + sb.writeln(element); + }); + } else if (string.contains(RegExp(r'^\s*\/\/\/?\s*'))) { + string.split('\n').forEach((element) { + element = element.replaceFirst(RegExp(r'^\s*\/\/\/?\s*'), ''); + sb.writeln(element); + }); + } - // Remove any *'s in the beginning of a every line. - string.split('\n').forEach((element) { - element = element.trim().replaceFirst(RegExp(r'\**'), '').trim(); - sb.writeln(element); - }); return sb.toString().trim(); }
diff --git a/pkgs/ffigen/pubspec.yaml b/pkgs/ffigen/pubspec.yaml index 21c65c3..e986dfd 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: 2.2.3 +version: 2.2.4 homepage: https://github.com/dart-lang/ffigen description: Generator for FFI bindings, using LibClang to parse C header files.
diff --git a/pkgs/ffigen/test/code_generator_tests/code_generator_test.dart b/pkgs/ffigen/test/code_generator_tests/code_generator_test.dart index 350b799..806ae22 100644 --- a/pkgs/ffigen/test/code_generator_tests/code_generator_test.dart +++ b/pkgs/ffigen/test/code_generator_tests/code_generator_test.dart
@@ -365,6 +365,19 @@ ); _matchLib(library, 'boolean_no_dartbool'); }); + test('sort bindings', () { + final library = Library( + name: 'Bindings', + sort: true, + bindings: [ + Func(name: 'b', returnType: Type.nativeType(SupportedNativeType.Void)), + Func(name: 'a', returnType: Type.nativeType(SupportedNativeType.Void)), + Struc(name: 'd'), + Struc(name: 'c'), + ], + ); + _matchLib(library, 'sort_bindings'); + }); } /// Utility to match expected bindings to the generated bindings.
diff --git a/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_sort_bindings_bindings.dart b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_sort_bindings_bindings.dart new file mode 100644 index 0000000..aaa8f2d --- /dev/null +++ b/pkgs/ffigen/test/code_generator_tests/expected_bindings/_expected_sort_bindings_bindings.dart
@@ -0,0 +1,45 @@ +// AUTO GENERATED FILE, DO NOT EDIT. +// +// Generated by `package:ffigen`. +import 'dart:ffi' as ffi; + +class Bindings { + /// Holds the symbol lookup function. + final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName) + _lookup; + + /// The symbols are looked up in [dynamicLibrary]. + Bindings(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup; + + /// The symbols are looked up with [lookup]. + Bindings.fromLookup( + ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName) + lookup) + : _lookup = lookup; + + void a() { + return _a(); + } + + late final _a_ptr = _lookup<ffi.NativeFunction<_c_a>>('a'); + late final _dart_a _a = _a_ptr.asFunction<_dart_a>(); + + void b() { + return _b(); + } + + late final _b_ptr = _lookup<ffi.NativeFunction<_c_b>>('b'); + late final _dart_b _b = _b_ptr.asFunction<_dart_b>(); +} + +class c extends ffi.Opaque {} + +class d extends ffi.Opaque {} + +typedef _c_a = ffi.Void Function(); + +typedef _dart_a = void Function(); + +typedef _c_b = ffi.Void Function(); + +typedef _dart_b = void Function();
diff --git a/pkgs/ffigen/test/example_tests/libclang_example_test.dart b/pkgs/ffigen/test/example_tests/libclang_example_test.dart index e7cbc56..f385b00 100644 --- a/pkgs/ffigen/test/example_tests/libclang_example_test.dart +++ b/pkgs/ffigen/test/example_tests/libclang_example_test.dart
@@ -19,7 +19,6 @@ test('libclang-example', () { final config = Config.fromYaml(loadYaml(''' ${strings.output}: 'generated_bindings.dart' -${strings.sort}: true ${strings.headers}: ${strings.entryPoints}: - third_party/libclang/include/clang-c/Index.h
diff --git a/pkgs/ffigen/test/header_parser_tests/comment_markup.h b/pkgs/ffigen/test/header_parser_tests/comment_markup.h new file mode 100644 index 0000000..1201e87 --- /dev/null +++ b/pkgs/ffigen/test/header_parser_tests/comment_markup.h
@@ -0,0 +1,26 @@ +// Copyright (c) 2021, 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. + +/// This is a single line test comment. +void com1(); + +/// This is a multi-line +/// test comment. +void com2(); + +/** This is a multi-line + * doxygen style + * test comment. + */ +void com3(); + +// Test comment for struct. +struct com4{ + /// Muli-line test comment for struct field + // With multiple line and both // and ///. + int a; + + /* Single line field comment. */ + float b; +};
diff --git a/pkgs/ffigen/test/header_parser_tests/comment_markup_test.dart b/pkgs/ffigen/test/header_parser_tests/comment_markup_test.dart new file mode 100644 index 0000000..6d3f8ba --- /dev/null +++ b/pkgs/ffigen/test/header_parser_tests/comment_markup_test.dart
@@ -0,0 +1,48 @@ +// Copyright (c) 2021, 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/src/code_generator.dart'; +import 'package:ffigen/src/header_parser.dart' as parser; +import 'package:ffigen/src/config_provider.dart'; +import 'package:logging/logging.dart'; +import 'package:test/test.dart'; +import 'package:yaml/yaml.dart' as yaml; +import 'package:ffigen/src/strings.dart' as strings; + +import '../test_utils.dart'; + +late Library actual; +void main() { + group('comment_markup_test', () { + setUpAll(() { + logWarnings(Level.SEVERE); + actual = parser.parse( + Config.fromYaml(yaml.loadYaml(''' +${strings.name}: 'NativeLibrary' +${strings.description}: 'Comment Markup Test' +${strings.output}: 'unused' +${strings.headers}: + ${strings.entryPoints}: + - 'test/header_parser_tests/comment_markup.h' +${strings.comments}: + ${strings.style}: ${strings.any} + ${strings.length}: ${strings.full} + ''') as yaml.YamlMap), + ); + }); + + test('Expected bindings', () { + matchLibraryWithExpected(actual, [ + 'test', + 'debug_generated', + 'comment_markup_test_output.dart' + ], [ + 'test', + 'header_parser_tests', + 'expected_bindings', + '_expected_comment_markup_bindings.dart' + ]); + }); + }); +}
diff --git a/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_comment_markup_bindings.dart b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_comment_markup_bindings.dart new file mode 100644 index 0000000..75bc7c7 --- /dev/null +++ b/pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_comment_markup_bindings.dart
@@ -0,0 +1,72 @@ +// AUTO GENERATED FILE, DO NOT EDIT. +// +// Generated by `package:ffigen`. +import 'dart:ffi' as ffi; + +/// Comment Markup Test +class NativeLibrary { + /// Holds the symbol lookup function. + final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName) + _lookup; + + /// The symbols are looked up in [dynamicLibrary]. + NativeLibrary(ffi.DynamicLibrary dynamicLibrary) + : _lookup = dynamicLibrary.lookup; + + /// The symbols are looked up with [lookup]. + NativeLibrary.fromLookup( + ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName) + lookup) + : _lookup = lookup; + + /// This is a single line test comment. + void com1() { + return _com1(); + } + + late final _com1_ptr = _lookup<ffi.NativeFunction<_c_com1>>('com1'); + late final _dart_com1 _com1 = _com1_ptr.asFunction<_dart_com1>(); + + /// This is a multi-line + /// test comment. + void com2() { + return _com2(); + } + + late final _com2_ptr = _lookup<ffi.NativeFunction<_c_com2>>('com2'); + late final _dart_com2 _com2 = _com2_ptr.asFunction<_dart_com2>(); + + /// This is a multi-line + /// doxygen style + /// test comment. + void com3() { + return _com3(); + } + + late final _com3_ptr = _lookup<ffi.NativeFunction<_c_com3>>('com3'); + late final _dart_com3 _com3 = _com3_ptr.asFunction<_dart_com3>(); +} + +/// Test comment for struct. +class com4 extends ffi.Struct { + /// Muli-line test comment for struct field + /// With multiple line and both // and ///. + @ffi.Int32() + external int a; + + /// Single line field comment. + @ffi.Float() + external double b; +} + +typedef _c_com1 = ffi.Void Function(); + +typedef _dart_com1 = void Function(); + +typedef _c_com2 = ffi.Void Function(); + +typedef _dart_com2 = void Function(); + +typedef _c_com3 = ffi.Void Function(); + +typedef _dart_com3 = void Function();
diff --git a/pkgs/ffigen/test/native_test/config.yaml b/pkgs/ffigen/test/native_test/config.yaml index 3933518..7abdce4 100644 --- a/pkgs/ffigen/test/native_test/config.yaml +++ b/pkgs/ffigen/test/native_test/config.yaml
@@ -9,7 +9,6 @@ name: NativeLibrary description: 'Native tests.' output: 'test/native_test/native_test_bindings.dart' -sort: true headers: entry-points: - 'test/native_test/native_test.c'