Skip to content

Commit 4f361b6

Browse files
authored
[ffigen] support generate unused typedefs (#1266)
1 parent cd8eddf commit 4f361b6

File tree

11 files changed

+74
-9
lines changed

11 files changed

+74
-9
lines changed

pkgs/ffigen/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
`objc-protocols` config option to generate bindings for a protocol.
2828
- Fix some bugs where ObjC interface/protocol methods could collide with Dart
2929
built-in methods, or with types declared elsewhere in the generated bindings.
30+
- Add `include-unused-typedefs` to allow generating typedefs that are not
31+
referred to anywhere, the default option is `false`.
3032

3133
## 12.0.0
3234

pkgs/ffigen/README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ globals:
279279
Options -<br>
280280
- Include/Exclude (referred typedefs only).<br>
281281
- Rename typedefs.<br><br>
282-
Note: Typedefs that are not referred to anywhere will not be generated.
282+
Note: By default, typedefs that are not referred to anywhere will not be generated.
283283
</td>
284284
<td>
285285
@@ -291,6 +291,20 @@ typedefs:
291291
rename:
292292
# Removes '_' from beginning of a typedef.
293293
'_(.*)': '$1'
294+
```
295+
</td>
296+
</tr>
297+
<tr>
298+
<td>include-unused-typedefs</td>
299+
<td>
300+
Also generate typedefs that are not referred to anywhere.
301+
<br>
302+
<b>Default: false</b>
303+
</td>
304+
<td>
305+
306+
```yaml
307+
include-unused-typedefs: true
294308
```
295309
</td>
296310
</tr>

pkgs/ffigen/ffigen.schema.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,9 @@
391391
"exclude-all-by-default": {
392392
"type": "boolean"
393393
},
394+
"include-unused-typedefs": {
395+
"type": "boolean"
396+
},
394397
"generate-for-package-objective-c": {
395398
"type": "boolean"
396399
},

pkgs/ffigen/lib/src/code_generator/typealias.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,19 @@ class Typealias extends BindingType {
195195

196196
@override
197197
String? getDefaultValue(Writer w) => type.getDefaultValue(w);
198+
199+
// Used to compare whether two Typealias are same symbols and ensure that they
200+
// are unique when adding to a [Set].
201+
@override
202+
operator ==(Object other) {
203+
if (other is! Typealias) return false;
204+
if (identical(this, other)) return true;
205+
return other.usr == usr;
206+
}
207+
208+
// [usr] is unique for specific symbols.
209+
@override
210+
int get hashCode => usr.hashCode;
198211
}
199212

200213
/// Objective C's instancetype.

pkgs/ffigen/lib/src/config_provider/config.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ class Config {
106106
bool get excludeAllByDefault => _excludeAllByDefault;
107107
late bool _excludeAllByDefault;
108108

109+
/// If enabled, unused typedefs will also be generated.
110+
bool get includeUnusedTypedefs => _includeUnusedTypedefs;
111+
late bool _includeUnusedTypedefs;
112+
109113
/// Undocumented option that changes code generation for package:objective_c.
110114
/// The main difference is whether NSObject etc are imported from
111115
/// package:objective_c (the default) or code genned like any other class.
@@ -649,6 +653,13 @@ class Config {
649653
defaultValue: (node) => false,
650654
resultOrDefault: (node) => _excludeAllByDefault = node.value as bool,
651655
),
656+
HeterogeneousMapEntry(
657+
key: strings.includeUnusedTypedefs,
658+
valueConfigSpec: BoolConfigSpec(),
659+
defaultValue: (node) => false,
660+
resultOrDefault: (node) =>
661+
_includeUnusedTypedefs = node.value as bool,
662+
),
652663
HeterogeneousMapEntry(
653664
key: strings.generateForPackageObjectiveC,
654665
valueConfigSpec: BoolConfigSpec(),

pkgs/ffigen/lib/src/header_parser/translation_unit_parser.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import 'package:ffigen/src/code_generator.dart';
66
import 'package:ffigen/src/header_parser/sub_parsers/macro_parser.dart';
77
import 'package:ffigen/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart';
88
import 'package:ffigen/src/header_parser/sub_parsers/objcprotocoldecl_parser.dart';
9+
import 'package:ffigen/src/header_parser/sub_parsers/typedefdecl_parser.dart';
910
import 'package:ffigen/src/header_parser/sub_parsers/var_parser.dart';
1011
import 'package:logging/logging.dart';
1112

@@ -48,6 +49,11 @@ Set<Binding> parseTranslationUnit(clang_types.CXCursor translationUnitCursor) {
4849
case clang_types.CXCursorKind.CXCursor_VarDecl:
4950
addToBindings(bindings, parseVarDeclaration(cursor));
5051
break;
52+
case clang_types.CXCursorKind.CXCursor_TypedefDecl:
53+
if (config.includeUnusedTypedefs) {
54+
addToBindings(bindings, parseTypedefDeclaration(cursor));
55+
}
56+
break;
5157
default:
5258
_logger.finer('rootCursorVisitor: CursorKind not implemented');
5359
}

pkgs/ffigen/lib/src/strings.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ const objcInterfaces = 'objc-interfaces';
7676
const objcProtocols = 'objc-protocols';
7777

7878
const excludeAllByDefault = 'exclude-all-by-default';
79+
const includeUnusedTypedefs = 'include-unused-typedefs';
7980
const generateForPackageObjectiveC = 'generate-for-package-objective-c';
8081

8182
// Sub-fields of Declarations.

pkgs/ffigen/test/collision_tests/expected_bindings/_expected_decl_decl_collision_bindings.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,6 @@ const int Test_Macro1 = 0;
6565

6666
typedef testAlias = ffi.Void;
6767
typedef DarttestAlias = void;
68-
typedef testAlias1 = ffi.Void;
69-
typedef DarttestAlias1 = void;
7068

7169
final class testCrossDecl extends ffi.Opaque {}
7270

pkgs/ffigen/test/header_parser_tests/expected_bindings/_expected_typedef_bindings.dart

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,26 +85,31 @@ class Bindings {
8585
_func4Ptr.asFunction<bool Function(ffi.Pointer<ffi.Bool>)>();
8686
}
8787

88+
typedef NamedFunctionProto
89+
= ffi.Pointer<ffi.NativeFunction<NamedFunctionProtoFunction>>;
90+
typedef NamedFunctionProtoFunction = ffi.Void Function();
91+
typedef DartNamedFunctionProtoFunction = void Function();
92+
8893
final class Struct1 extends ffi.Struct {
8994
external NamedFunctionProto named;
9095

9196
external ffi.Pointer<ffi.NativeFunction<ffi.Void Function()>> unnamed;
9297
}
9398

94-
typedef NamedFunctionProto
95-
= ffi.Pointer<ffi.NativeFunction<NamedFunctionProtoFunction>>;
96-
typedef NamedFunctionProtoFunction = ffi.Void Function();
97-
typedef DartNamedFunctionProtoFunction = void Function();
98-
9999
final class AnonymousStructInTypedef extends ffi.Opaque {}
100100

101+
typedef Typeref1 = AnonymousStructInTypedef;
102+
typedef Typeref2 = AnonymousStructInTypedef;
103+
101104
final class _NamedStructInTypedef extends ffi.Opaque {}
102105

103-
typedef NTyperef1 = ExcludedStruct;
106+
typedef NamedStructInTypedef = _NamedStructInTypedef;
104107
typedef ExcludedStruct = _ExcludedStruct;
105108

106109
final class _ExcludedStruct extends ffi.Opaque {}
107110

111+
typedef NTyperef1 = ExcludedStruct;
112+
108113
enum AnonymousEnumInTypedef {
109114
a(0);
110115

@@ -131,12 +136,18 @@ enum _NamedEnumInTypedef {
131136
};
132137
}
133138

139+
typedef SpecifiedTypeAsIntPtr = ffi.Char;
140+
typedef DartSpecifiedTypeAsIntPtr = int;
134141
typedef NestingASpecifiedType = ffi.IntPtr;
135142
typedef DartNestingASpecifiedType = int;
136143

137144
final class Struct2 extends ffi.Opaque {}
138145

146+
typedef Struct3 = Struct2;
147+
139148
final class WithBoolAlias extends ffi.Struct {
140149
@ffi.Bool()
141150
external bool b;
142151
}
152+
153+
typedef IncludedTypedef = ffi.Pointer<ffi.Void>;

pkgs/ffigen/test/header_parser_tests/typedef.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,5 @@ BoolAlias func4(BoolAlias *a);
6969
struct WithBoolAlias{
7070
BoolAlias b;
7171
};
72+
73+
typedef void* IncludedTypedef;

pkgs/ffigen/test/header_parser_tests/typedef_test.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ ${strings.structs}:
3131
${strings.exclude}:
3232
- ExcludedStruct
3333
- _ExcludedStruct
34+
${strings.includeUnusedTypedefs}: true
35+
${strings.typedefs}:
36+
${strings.exclude}:
37+
- pStruct.*
3438
${strings.typeMap}:
3539
${strings.typeMapTypedefs}:
3640
'SpecifiedTypeAsIntPtr':

0 commit comments

Comments
 (0)