Skip to content

Commit 00991b9

Browse files
authored
[ffigen] More config convenience utils (#2775)
1 parent 1bcb45c commit 00991b9

File tree

4 files changed

+152
-61
lines changed

4 files changed

+152
-61
lines changed

pkgs/ffigen/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
- Add `xcodeUri`, `iosSdkUri`, and `macSdkUri`, to mirror `xcodePath`,
44
`iosSdkPath`, and `macSdkPath`.
55
- Export some missing elements from the config API.
6+
- Provide more convenience utils for building FFIgen configs:
7+
`Declarations.excludeAll`, `Declarations.includeAll`,
8+
`Declarations.includeSet`, `Declarations.includeAllMembers`,
9+
`Declarations.includeMemberSet`, `Declarations.useOriginalName`,
10+
`Declarations.renameWithMap`, `Declarations.useMemberOriginalName`, and
11+
`Declarations.renameMemberWithMap`.
612

713
## 20.0.0
814

pkgs/ffigen/lib/ffigen.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export 'src/config_provider.dart'
2323
CommentType,
2424
CompoundDependencies,
2525
Declaration,
26+
Declarations,
2627
DynamicLibraryBindings,
2728
EnumStyle,
2829
Enums,

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

Lines changed: 97 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -158,40 +158,86 @@ final class Declarations {
158158
/// Checks if a name is allowed by a filter.
159159
final bool Function(Declaration declaration) include;
160160

161+
/// A function to pass to [include] that excludes all declarations.
162+
static bool excludeAll(Declaration declaration) => false;
163+
164+
/// A function to pass to [include] that includes all declarations.
165+
static bool includeAll(Declaration declaration) => true;
166+
167+
/// Returns a function to pass to [include] that includes all declarations
168+
/// whose `originalName`s are in [names].
169+
static bool Function(Declaration) includeSet(Set<String> names) =>
170+
(Declaration decl) => names.contains(decl.originalName);
171+
161172
/// Whether a member of a declaration should be included.
162173
///
163174
/// Only used for [Categories], [Interfaces], and [Protocols] methods and
164175
/// properties.
165176
final bool Function(Declaration declaration, String member) includeMember;
166177

167-
static bool _includeAllMembers(Declaration declaration, String member) =>
168-
true;
178+
/// A function to pass to [includeMember] that includes all members of all
179+
/// declarations.
180+
static bool includeAllMembers(Declaration declaration, String member) => true;
181+
182+
/// A function to pass to [includeMember] that includes specific members.
183+
///
184+
/// The map key is the declaration's `originalName`, and the value is the set
185+
/// of member names to include. If the declaration is not in the map, all its
186+
/// members are included.
187+
static bool Function(Declaration, String) includeMemberSet(
188+
Map<String, Set<String>> members,
189+
) =>
190+
(Declaration decl, String member) =>
191+
members[decl.originalName]?.contains(member) ?? true;
169192

170193
/// Checks if the symbol address should be included for this name.
171194
final bool Function(Declaration declaration) includeSymbolAddress;
172195

173196
/// Applies renaming and returns the result.
174197
final String Function(Declaration declaration) rename;
175198

176-
static String _useOriginalName(Declaration declaration) =>
199+
/// A function to pass to [rename] that doesn't rename the declaration.
200+
static String useOriginalName(Declaration declaration) =>
177201
declaration.originalName;
178202

203+
/// A function to pass to [rename] that applies a rename map.
204+
///
205+
/// The key of the map is the declaration's `originalName`, and the value is
206+
/// the new name to use. If the declaration is not in the map, it is not
207+
/// renamed.
208+
static String Function(Declaration) renameWithMap(
209+
Map<String, String> renames,
210+
) =>
211+
(Declaration declaration) =>
212+
renames[declaration.originalName] ?? declaration.originalName;
213+
179214
/// Applies member renaming and returns the result. Used for struct/union
180215
/// fields, enum elements, function params, and ObjC
181216
/// interface/protocol/category methods/properties.
182217
final String Function(Declaration declaration, String member) renameMember;
183218

184-
static String _useMemberOriginalName(
185-
Declaration declaration,
186-
String member,
187-
) => member;
219+
/// A function to pass to [renameMember] that doesn't rename the member.
220+
static String useMemberOriginalName(Declaration declaration, String member) =>
221+
member;
222+
223+
/// A function to pass to [renameMember] that applies a rename map.
224+
///
225+
/// The key of the map is the declaration's `originalName`, and the value is
226+
/// a map from member name to renamed member name. If the declaration is not
227+
/// in the map, or the member isn't in the declaration's map, the member is
228+
/// not renamed.
229+
static String Function(Declaration, String) renameMemberWithMap(
230+
Map<String, Map<String, String>> renames,
231+
) =>
232+
(Declaration declaration, String member) =>
233+
renames[declaration.originalName]?[member] ?? member;
188234

189235
const Declarations({
190-
this.include = _excludeAll,
191-
this.includeMember = _includeAllMembers,
192-
this.includeSymbolAddress = _excludeAll,
193-
this.rename = _useOriginalName,
194-
this.renameMember = _useMemberOriginalName,
236+
this.include = excludeAll,
237+
this.includeMember = includeAllMembers,
238+
this.includeSymbolAddress = excludeAll,
239+
this.rename = useOriginalName,
240+
this.renameMember = useMemberOriginalName,
195241
});
196242
}
197243

@@ -221,12 +267,12 @@ final class Enums extends Declarations {
221267
this.silenceWarning = false,
222268
});
223269

224-
static const excludeAll = Enums(include: _excludeAll);
270+
static const excludeAll = Enums(include: Declarations.excludeAll);
225271

226-
static const includeAll = Enums(include: _includeAll);
272+
static const includeAll = Enums(include: Declarations.includeAll);
227273

228274
static Enums includeSet(Set<String> names) =>
229-
Enums(include: (Declaration decl) => names.contains(decl.originalName));
275+
Enums(include: Declarations.includeSet(names));
230276
}
231277

232278
/// Configuration for how to generate enums.
@@ -265,25 +311,24 @@ final class Functions extends Declarations {
265311
this.varArgs = const <String, List<VarArgFunction>>{},
266312
});
267313

268-
static const excludeAll = Functions(include: _excludeAll);
314+
static const excludeAll = Functions(include: Declarations.excludeAll);
269315

270-
static const includeAll = Functions(include: _includeAll);
316+
static const includeAll = Functions(include: Declarations.includeAll);
271317

272-
static Functions includeSet(Set<String> names) => Functions(
273-
include: (Declaration decl) => names.contains(decl.originalName),
274-
);
318+
static Functions includeSet(Set<String> names) =>
319+
Functions(include: Declarations.includeSet(names));
275320
}
276321

277322
/// Configuration for globals.
278323
final class Globals extends Declarations {
279324
const Globals({super.rename, super.include, super.includeSymbolAddress});
280325

281-
static const excludeAll = Globals(include: _excludeAll);
326+
static const excludeAll = Globals(include: Declarations.excludeAll);
282327

283-
static const includeAll = Globals(include: _includeAll);
328+
static const includeAll = Globals(include: Declarations.includeAll);
284329

285330
static Globals includeSet(Set<String> names) =>
286-
Globals(include: (Declaration decl) => names.contains(decl.originalName));
331+
Globals(include: Declarations.includeSet(names));
287332
}
288333

289334
/// Configuration for integer types.
@@ -309,12 +354,12 @@ final class Integers {
309354
final class Macros extends Declarations {
310355
const Macros({super.rename, super.include});
311356

312-
static const excludeAll = Macros(include: _excludeAll);
357+
static const excludeAll = Macros(include: Declarations.excludeAll);
313358

314-
static const includeAll = Macros(include: _includeAll);
359+
static const includeAll = Macros(include: Declarations.includeAll);
315360

316361
static Macros includeSet(Set<String> names) =>
317-
Macros(include: (Declaration decl) => names.contains(decl.originalName));
362+
Macros(include: Declarations.includeSet(names));
318363
}
319364

320365
/// Configuration for struct declarations.
@@ -348,12 +393,12 @@ final class Structs extends Declarations {
348393
this.packingOverride = _packingOverrideDefault,
349394
});
350395

351-
static const excludeAll = Structs(include: _excludeAll);
396+
static const excludeAll = Structs(include: Declarations.excludeAll);
352397

353-
static const includeAll = Structs(include: _includeAll);
398+
static const includeAll = Structs(include: Declarations.includeAll);
354399

355400
static Structs includeSet(Set<String> names) =>
356-
Structs(include: (Declaration decl) => names.contains(decl.originalName));
401+
Structs(include: Declarations.includeSet(names));
357402
}
358403

359404
/// Configuration for typedefs.
@@ -383,13 +428,12 @@ final class Typedefs extends Declarations {
383428
this.useSupportedTypedefs = true,
384429
});
385430

386-
static const Typedefs excludeAll = Typedefs(include: _excludeAll);
431+
static const Typedefs excludeAll = Typedefs(include: Declarations.excludeAll);
387432

388-
static const Typedefs includeAll = Typedefs(include: _includeAll);
433+
static const Typedefs includeAll = Typedefs(include: Declarations.includeAll);
389434

390-
static Typedefs includeSet(Set<String> names) => Typedefs(
391-
include: (Declaration decl) => names.contains(decl.originalName),
392-
);
435+
static Typedefs includeSet(Set<String> names) =>
436+
Typedefs(include: Declarations.includeSet(names));
393437
}
394438

395439
/// Configuration for union declarations.
@@ -416,25 +460,24 @@ final class Unions extends Declarations {
416460
this.imported = const <ImportedType>[],
417461
});
418462

419-
static const excludeAll = Unions(include: _excludeAll);
463+
static const excludeAll = Unions(include: Declarations.excludeAll);
420464

421-
static const includeAll = Unions(include: _includeAll);
465+
static const includeAll = Unions(include: Declarations.includeAll);
422466

423467
static Unions includeSet(Set<String> names) =>
424-
Unions(include: (Declaration decl) => names.contains(decl.originalName));
468+
Unions(include: Declarations.includeSet(names));
425469
}
426470

427471
/// Configuration for unnamed enum constants.
428472
final class UnnamedEnums extends Declarations {
429473
const UnnamedEnums({super.include, super.rename, super.renameMember});
430474

431-
static const excludeAll = UnnamedEnums(include: _excludeAll);
475+
static const excludeAll = UnnamedEnums(include: Declarations.excludeAll);
432476

433-
static const includeAll = UnnamedEnums(include: _includeAll);
477+
static const includeAll = UnnamedEnums(include: Declarations.includeAll);
434478

435-
static UnnamedEnums includeSet(Set<String> names) => UnnamedEnums(
436-
include: (Declaration decl) => names.contains(decl.originalName),
437-
);
479+
static UnnamedEnums includeSet(Set<String> names) =>
480+
UnnamedEnums(include: Declarations.includeSet(names));
438481
}
439482

440483
/// Configuration for Objective-C.
@@ -487,13 +530,12 @@ final class Categories extends Declarations {
487530
this.includeTransitive = true,
488531
});
489532

490-
static const excludeAll = Categories(include: _excludeAll);
533+
static const excludeAll = Categories(include: Declarations.excludeAll);
491534

492-
static const includeAll = Categories(include: _includeAll);
535+
static const includeAll = Categories(include: Declarations.includeAll);
493536

494-
static Categories includeSet(Set<String> names) => Categories(
495-
include: (Declaration decl) => names.contains(decl.originalName),
496-
);
537+
static Categories includeSet(Set<String> names) =>
538+
Categories(include: Declarations.includeSet(names));
497539
}
498540

499541
/// Configuration for Objective-C interfaces.
@@ -517,13 +559,12 @@ final class Interfaces extends Declarations {
517559
this.module = noModule,
518560
});
519561

520-
static const excludeAll = Interfaces(include: _excludeAll);
562+
static const excludeAll = Interfaces(include: Declarations.excludeAll);
521563

522-
static const includeAll = Interfaces(include: _includeAll);
564+
static const includeAll = Interfaces(include: Declarations.includeAll);
523565

524-
static Interfaces includeSet(Set<String> names) => Interfaces(
525-
include: (Declaration decl) => names.contains(decl.originalName),
526-
);
566+
static Interfaces includeSet(Set<String> names) =>
567+
Interfaces(include: Declarations.includeSet(names));
527568

528569
static String? noModule(Declaration declaration) => null;
529570
}
@@ -549,13 +590,12 @@ final class Protocols extends Declarations {
549590
this.module = noModule,
550591
});
551592

552-
static const excludeAll = Protocols(include: _excludeAll);
593+
static const excludeAll = Protocols(include: Declarations.excludeAll);
553594

554-
static const includeAll = Protocols(include: _includeAll);
595+
static const includeAll = Protocols(include: Declarations.includeAll);
555596

556-
static Protocols includeSet(Set<String> names) => Protocols(
557-
include: (Declaration decl) => names.contains(decl.originalName),
558-
);
597+
static Protocols includeSet(Set<String> names) =>
598+
Protocols(include: Declarations.includeSet(names));
559599

560600
static String? noModule(Declaration declaration) => null;
561601
}
@@ -758,7 +798,3 @@ extension type Config(FfiGenerator ffiGen) implements FfiGenerator {
758798

759799
Language get language => objectiveC != null ? Language.objc : Language.c;
760800
}
761-
762-
bool _excludeAll(Declaration declaration) => false;
763-
764-
bool _includeAll(Declaration d) => true;
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:ffigen/ffigen.dart';
6+
import 'package:test/test.dart';
7+
8+
Declaration decl(String name) => Declaration(usr: '', originalName: name);
9+
10+
void main() {
11+
group('Declarations utils', () {
12+
test('includeSet', () {
13+
final includer = Declarations.includeSet({'foo', 'bar'});
14+
expect(includer(decl('foo')), isTrue);
15+
expect(includer(decl('bar')), isTrue);
16+
expect(includer(decl('baz')), isFalse);
17+
});
18+
19+
test('includeMemberSet', () {
20+
final includer = Declarations.includeMemberSet({
21+
'foo': {'bar'},
22+
});
23+
expect(includer(decl('foo'), 'bar'), isTrue);
24+
expect(includer(decl('foo'), 'baz'), isFalse);
25+
expect(includer(decl('goo'), 'bar'), isTrue);
26+
expect(includer(decl('goo'), 'baz'), isTrue);
27+
});
28+
29+
test('renameWithMap', () {
30+
final renamer = Declarations.renameWithMap({'foo': 'bar'});
31+
expect(renamer(decl('foo')), 'bar');
32+
expect(renamer(decl('bar')), 'bar');
33+
expect(renamer(decl('baz')), 'baz');
34+
});
35+
36+
test('renameMemberWithMap', () {
37+
final renamer = Declarations.renameMemberWithMap({
38+
'foo': {'bar': 'baz'},
39+
});
40+
expect(renamer(decl('foo'), 'bar'), 'baz');
41+
expect(renamer(decl('foo'), 'baz'), 'baz');
42+
expect(renamer(decl('foo'), 'bop'), 'bop');
43+
expect(renamer(decl('goo'), 'bar'), 'bar');
44+
expect(renamer(decl('goo'), 'baz'), 'baz');
45+
expect(renamer(decl('goo'), 'bop'), 'bop');
46+
});
47+
});
48+
}

0 commit comments

Comments
 (0)