Skip to content

Commit 3216293

Browse files
authored
[ffigen] Add a registry for ObjC built in interfaces (dart-lang#358)
* ObjC interface registry * Don't remove trailing underscores from method names * Move isInSystemHeader to cursor utils * Fix analysis * Merge
1 parent 9148781 commit 3216293

File tree

5 files changed

+37
-8
lines changed

5 files changed

+37
-8
lines changed

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ class _ObjCWrapper {
172172
}
173173
}
174174

175+
final _interfaceRegistry = <String, ObjCInterface>{};
176+
void registerInterface(ObjCInterface interface) {
177+
_interfaceRegistry[interface.originalName] = interface;
178+
}
179+
175180
void generateNSStringUtils(Writer w, StringBuffer s) {
176181
// Generate a constructor that wraps stringWithCString.
177182
s.write(' factory NSString(${w.className} _lib, String str) {\n');

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class ObjCInterface extends BindingType {
4242
bool filled = false;
4343

4444
final ObjCBuiltInFunctions builtInFunctions;
45+
final bool isBuiltIn;
4546
late final ObjCInternalGlobal _classObject;
4647

4748
ObjCInterface({
@@ -50,14 +51,15 @@ class ObjCInterface extends BindingType {
5051
required String name,
5152
String? dartDoc,
5253
required this.builtInFunctions,
54+
required this.isBuiltIn,
5355
}) : super(
5456
usr: usr,
5557
originalName: originalName,
5658
name: name,
5759
dartDoc: dartDoc,
5860
);
5961

60-
bool get isNSString => name == "NSString";
62+
bool get isNSString => isBuiltIn && originalName == "NSString";
6163

6264
@override
6365
BindingString toBindingString(Writer w) {
@@ -207,6 +209,10 @@ class ObjCInterface extends BindingType {
207209
dependencies.add(this);
208210
builtInFunctions.addDependencies(dependencies);
209211

212+
if (isBuiltIn) {
213+
builtInFunctions.registerInterface(this);
214+
}
215+
210216
_classObject = ObjCInternalGlobal(
211217
PointerType(objCObjectType),
212218
'_class_$originalName',

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,22 @@ class Clang {
143143
late final _clang_getFileName =
144144
_clang_getFileNamePtr.asFunction<CXString Function(CXFile)>();
145145

146+
/// Returns non-zero if the given source location is in a system header.
147+
int clang_Location_isInSystemHeader(
148+
CXSourceLocation location,
149+
) {
150+
return _clang_Location_isInSystemHeader(
151+
location,
152+
);
153+
}
154+
155+
late final _clang_Location_isInSystemHeaderPtr =
156+
_lookup<ffi.NativeFunction<pkg_ffi.Int Function(CXSourceLocation)>>(
157+
'clang_Location_isInSystemHeader');
158+
late final _clang_Location_isInSystemHeader =
159+
_clang_Location_isInSystemHeaderPtr
160+
.asFunction<int Function(CXSourceLocation)>();
161+
146162
/// Determine whether two ranges are equivalent.
147163
///
148164
/// \returns non-zero if the ranges are the same, zero if they differ.

pkgs/ffigen/lib/src/header_parser/sub_parsers/objcinterfacedecl_parser.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ Type? parseObjCInterfaceDeclaration(
5353
name: config.objcInterfaces.renameUsingConfig(name),
5454
dartDoc: getCursorDocComment(cursor),
5555
builtInFunctions: objCBuiltInFunctions,
56+
isBuiltIn: cursor.isInSystemHeader(),
5657
);
5758
}
5859

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -101,24 +101,25 @@ extension CXCursorExt on clang_types.CXCursor {
101101
return clang.clang_getResultType(type());
102102
}
103103

104+
/// Returns the file name of the file that the cursor is inside.
104105
String sourceFileName() {
105106
final cxsource = clang.clang_getCursorLocation(this);
106107
final cxfilePtr = calloc<Pointer<Void>>();
107-
final line = calloc<UnsignedInt>();
108-
final column = calloc<UnsignedInt>();
109-
final offset = calloc<UnsignedInt>();
110108

111109
// Puts the values in these pointers.
112-
clang.clang_getFileLocation(cxsource, cxfilePtr, line, column, offset);
110+
clang.clang_getFileLocation(cxsource, cxfilePtr, nullptr, nullptr, nullptr);
113111
final s = clang.clang_getFileName(cxfilePtr.value).toStringAndDispose();
114112

115113
calloc.free(cxfilePtr);
116-
calloc.free(line);
117-
calloc.free(column);
118-
calloc.free(offset);
119114
return s;
120115
}
121116

117+
/// Returns whether the file that the cursor is inside is a system header.
118+
bool isInSystemHeader() {
119+
final location = clang.clang_getCursorLocation(this);
120+
return clang.clang_Location_isInSystemHeader(location) != 0;
121+
}
122+
122123
/// Recursively print the AST, for debugging.
123124
void printAst([int maxDepth = 3]) {
124125
_printAstVisitorMaxDepth = maxDepth;

0 commit comments

Comments
 (0)