Skip to content

Commit

Permalink
[ffigen] Add a registry for ObjC built in interfaces (dart-lang#358)
Browse files Browse the repository at this point in the history
* ObjC interface registry

* Don't remove trailing underscores from method names

* Move isInSystemHeader to cursor utils

* Fix analysis

* Merge
  • Loading branch information
liamappelbe authored May 11, 2022
1 parent 9148781 commit 3216293
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@ class _ObjCWrapper {
}
}

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');
Expand Down
8 changes: 7 additions & 1 deletion pkgs/ffigen/lib/src/code_generator/objc_interface.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class ObjCInterface extends BindingType {
bool filled = false;

final ObjCBuiltInFunctions builtInFunctions;
final bool isBuiltIn;
late final ObjCInternalGlobal _classObject;

ObjCInterface({
Expand All @@ -50,14 +51,15 @@ class ObjCInterface extends BindingType {
required String name,
String? dartDoc,
required this.builtInFunctions,
required this.isBuiltIn,
}) : super(
usr: usr,
originalName: originalName,
name: name,
dartDoc: dartDoc,
);

bool get isNSString => name == "NSString";
bool get isNSString => isBuiltIn && originalName == "NSString";

@override
BindingString toBindingString(Writer w) {
Expand Down Expand Up @@ -207,6 +209,10 @@ class ObjCInterface extends BindingType {
dependencies.add(this);
builtInFunctions.addDependencies(dependencies);

if (isBuiltIn) {
builtInFunctions.registerInterface(this);
}

_classObject = ObjCInternalGlobal(
PointerType(objCObjectType),
'_class_$originalName',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,22 @@ class Clang {
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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ Type? parseObjCInterfaceDeclaration(
name: config.objcInterfaces.renameUsingConfig(name),
dartDoc: getCursorDocComment(cursor),
builtInFunctions: objCBuiltInFunctions,
isBuiltIn: cursor.isInSystemHeader(),
);
}

Expand Down
15 changes: 8 additions & 7 deletions pkgs/ffigen/lib/src/header_parser/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -101,24 +101,25 @@ extension CXCursorExt on clang_types.CXCursor {
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;
Expand Down

0 comments on commit 3216293

Please sign in to comment.