[ffigen] Add a registry for ObjC built in interfaces (#358)
* ObjC interface registry
* Don't remove trailing underscores from method names
* Move isInSystemHeader to cursor utils
* Fix analysis
* Merge
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart b/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart
index ebb48aa..23cbb7a 100644
--- a/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart
+++ b/pkgs/ffigen/lib/src/code_generator/objc_built_in_functions.dart
@@ -172,6 +172,11 @@
}
}
+ final _interfaceRegistry = <String, ObjCInterface>{};
+ void registerInterface(ObjCInterface interface) {
+ _interfaceRegistry[interface.originalName] = interface;
+ }
+
void generateNSStringUtils(Writer w, StringBuffer s) {
// Generate a constructor that wraps stringWithCString.
s.write(' factory NSString(${w.className} _lib, String str) {\n');
diff --git a/pkgs/ffigen/lib/src/code_generator/objc_interface.dart b/pkgs/ffigen/lib/src/code_generator/objc_interface.dart
index 0879e94..e92b4e3 100644
--- a/pkgs/ffigen/lib/src/code_generator/objc_interface.dart
+++ b/pkgs/ffigen/lib/src/code_generator/objc_interface.dart
@@ -42,6 +42,7 @@
bool filled = false;
final ObjCBuiltInFunctions builtInFunctions;
+ final bool isBuiltIn;
late final ObjCInternalGlobal _classObject;
ObjCInterface({
@@ -50,6 +51,7 @@
required String name,
String? dartDoc,
required this.builtInFunctions,
+ required this.isBuiltIn,
}) : super(
usr: usr,
originalName: originalName,
@@ -57,7 +59,7 @@
dartDoc: dartDoc,
);
- bool get isNSString => name == "NSString";
+ bool get isNSString => isBuiltIn && originalName == "NSString";
@override
BindingString toBindingString(Writer w) {
@@ -207,6 +209,10 @@
dependencies.add(this);
builtInFunctions.addDependencies(dependencies);
+ if (isBuiltIn) {
+ builtInFunctions.registerInterface(this);
+ }
+
_classObject = ObjCInternalGlobal(
PointerType(objCObjectType),
'_class_$originalName',
diff --git a/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart b/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart
index 9191f67..9077b89 100644
--- a/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart
+++ b/pkgs/ffigen/lib/src/header_parser/clang_bindings/clang_bindings.dart
@@ -143,6 +143,22 @@
late final _clang_getFileName =
_clang_getFileNamePtr.asFunction<CXString Function(CXFile)>();
+ /// Returns non-zero if the given source location is in a system header.
+ int clang_Location_isInSystemHeader(
+ CXSourceLocation location,
+ ) {
+ return _clang_Location_isInSystemHeader(
+ location,
+ );
+ }
+
+ late final _clang_Location_isInSystemHeaderPtr =
+ _lookup<ffi.NativeFunction<pkg_ffi.Int Function(CXSourceLocation)>>(
+ 'clang_Location_isInSystemHeader');
+ late final _clang_Location_isInSystemHeader =
+ _clang_Location_isInSystemHeaderPtr
+ .asFunction<int Function(CXSourceLocation)>();
+
/// Determine whether two ranges are equivalent.
///
/// \returns non-zero if the ranges are the same, zero if they differ.
diff --git a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart
index 03d7325..be660df 100644
--- a/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart
+++ b/pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart
@@ -53,6 +53,7 @@
name: config.objcInterfaces.renameUsingConfig(name),
dartDoc: getCursorDocComment(cursor),
builtInFunctions: objCBuiltInFunctions,
+ isBuiltIn: cursor.isInSystemHeader(),
);
}
diff --git a/pkgs/ffigen/lib/src/header_parser/utils.dart b/pkgs/ffigen/lib/src/header_parser/utils.dart
index e8c60cf..7352642 100644
--- a/pkgs/ffigen/lib/src/header_parser/utils.dart
+++ b/pkgs/ffigen/lib/src/header_parser/utils.dart
@@ -101,24 +101,25 @@
return clang.clang_getResultType(type());
}
+ /// Returns the file name of the file that the cursor is inside.
String sourceFileName() {
final cxsource = clang.clang_getCursorLocation(this);
final cxfilePtr = calloc<Pointer<Void>>();
- final line = calloc<UnsignedInt>();
- final column = calloc<UnsignedInt>();
- final offset = calloc<UnsignedInt>();
// Puts the values in these pointers.
- clang.clang_getFileLocation(cxsource, cxfilePtr, line, column, offset);
+ clang.clang_getFileLocation(cxsource, cxfilePtr, nullptr, nullptr, nullptr);
final s = clang.clang_getFileName(cxfilePtr.value).toStringAndDispose();
calloc.free(cxfilePtr);
- calloc.free(line);
- calloc.free(column);
- calloc.free(offset);
return s;
}
+ /// Returns whether the file that the cursor is inside is a system header.
+ bool isInSystemHeader() {
+ final location = clang.clang_getCursorLocation(this);
+ return clang.clang_Location_isInSystemHeader(location) != 0;
+ }
+
/// Recursively print the AST, for debugging.
void printAst([int maxDepth = 3]) {
_printAstVisitorMaxDepth = maxDepth;