Skip to content

Commit ca9e9c5

Browse files
authored
[ffigen] Remove Writer.usedEnumCTypes (#2521)
1 parent dc4aa33 commit ca9e9c5

File tree

3 files changed

+69
-22
lines changed

3 files changed

+69
-22
lines changed

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

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -264,10 +264,7 @@ class EnumClass extends BindingType {
264264
}
265265

266266
@override
267-
String getCType(Writer w) {
268-
w.usedEnumCTypes.add(this);
269-
return nativeType.getCType(w);
270-
}
267+
String getCType(Writer w) => nativeType.getCType(w);
271268

272269
@override
273270
String getFfiDartType(Writer w) => nativeType.getFfiDartType(w);

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

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:path/path.dart' as p;
77
import '../code_generator.dart';
88
import '../context.dart';
99
import '../strings.dart' as strings;
10+
import '../visitor/visitor.dart';
1011
import 'unique_namer.dart';
1112
import 'utils.dart';
1213

@@ -39,10 +40,6 @@ class Writer {
3940

4041
final List<String> nativeEntryPoints;
4142

42-
/// Tracks the enums for which enumType.getCType is called. Reset everytime
43-
/// [generate] is called.
44-
final usedEnumCTypes = <EnumClass>{};
45-
4643
String? _ffiLibraryPrefix;
4744
String get ffiLibraryPrefix {
4845
if (_ffiLibraryPrefix != null) {
@@ -228,9 +225,6 @@ class Writer {
228225
// Reset unique namers to initial state.
229226
_resetUniqueNamers();
230227

231-
// Reset [usedEnumCTypes].
232-
usedEnumCTypes.clear();
233-
234228
// Write file header (if any).
235229
if (header != null) {
236230
result.writeln(header);
@@ -325,17 +319,23 @@ class Writer {
325319
result.write(s);
326320

327321
// Warn about Enum usage in API surface.
328-
if (!silenceEnumWarning && usedEnumCTypes.isNotEmpty) {
329-
final names = usedEnumCTypes.map((e) => e.originalName).toList()..sort();
330-
context.logger.severe(
331-
'The integer type used for enums is '
332-
'implementation-defined. FFIgen tries to mimic the integer sizes '
333-
'chosen by the most common compilers for the various OS and '
334-
'architecture combinations. To prevent any crashes, remove the '
335-
'enums from your API surface. To rely on the (unsafe!) mimicking, '
336-
'you can silence this warning by adding silence-enum-warning: true '
337-
'to the FFIgen config. Affected enums:\n\t${names.join('\n\t')}',
322+
if (!silenceEnumWarning) {
323+
final notEnums = _allBindings.where(
324+
(b) => b is! Type || (b as Type).typealiasType is! EnumClass,
338325
);
326+
final usedEnums = visit(context, _FindEnumsVisitation(), notEnums).enums;
327+
if (usedEnums.isNotEmpty) {
328+
final names = usedEnums.map((e) => e.originalName).toList()..sort();
329+
context.logger.severe(
330+
'The integer type used for enums is '
331+
'implementation-defined. FFIgen tries to mimic the integer sizes '
332+
'chosen by the most common compilers for the various OS and '
333+
'architecture combinations. To prevent any crashes, remove the '
334+
'enums from your API surface. To rely on the (unsafe!) mimicking, '
335+
'you can silence this warning by adding silence-enum-warning: true '
336+
'to the FFIgen config. Affected enums:\n\t${names.join('\n\t')}',
337+
);
338+
}
339339
}
340340

341341
_canGenerateSymbolOutput = true;
@@ -583,3 +583,13 @@ class _SymbolAddressUnit {
583583

584584
_SymbolAddressUnit(this.type, this.name, this.ptrName, this.native);
585585
}
586+
587+
class _FindEnumsVisitation extends Visitation {
588+
final enums = <EnumClass>{};
589+
590+
@override
591+
void visitEnumClass(EnumClass node) {
592+
node.visitChildren(visitor);
593+
enums.add(node);
594+
}
595+
}

pkgs/ffigen/test/large_integration_tests/large_test.dart

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ void main() {
2424
'libclang',
2525
'include',
2626
);
27+
final logArr = <String>[];
28+
final logger = logToArray(logArr, Level.SEVERE);
2729
final config = FfiGen(
28-
Logger.root,
30+
logger,
2931
wrapperName: 'LibClang',
3032
wrapperDocComment: 'Bindings to LibClang.',
3133
output: Uri.file('unused'),
@@ -75,6 +77,44 @@ void main() {
7577
codeNormalizer: (code) =>
7678
code.replaceAll(RegExp('[^\n]*///[^\n]*@[^\n]*\n'), ''),
7779
);
80+
81+
const expectedEnumWarnings = [
82+
'CXAvailabilityKind',
83+
'CXCallingConv',
84+
'CXChildVisitResult',
85+
'CXCompletionChunkKind',
86+
'CXCursorKind',
87+
'CXDiagnosticSeverity',
88+
'CXErrorCode',
89+
'CXEvalResultKind',
90+
'CXIdxAttrKind',
91+
'CXIdxEntityCXXTemplateKind',
92+
'CXIdxEntityKind',
93+
'CXIdxEntityLanguage',
94+
'CXIdxEntityRefKind',
95+
'CXIdxObjCContainerKind',
96+
'CXLanguageKind',
97+
'CXLinkageKind',
98+
'CXLoadDiag_Error',
99+
'CXPrintingPolicyProperty',
100+
'CXRefQualifierKind',
101+
'CXResult',
102+
'CXSymbolRole',
103+
'CXTLSKind',
104+
'CXTUResourceUsageKind',
105+
'CXTemplateArgumentKind',
106+
'CXTokenKind',
107+
'CXTypeKind',
108+
'CXTypeNullabilityKind',
109+
'CXVisibilityKind',
110+
'CXVisitorResult',
111+
'CX_CXXAccessSpecifier',
112+
'CX_StorageClass',
113+
];
114+
final actualLogs = logArr.join('\n');
115+
for (final e in expectedEnumWarnings) {
116+
expect(actualLogs, contains(e));
117+
}
78118
});
79119

80120
test('CJSON test', () {

0 commit comments

Comments
 (0)