Skip to content
This repository has been archived by the owner on Jan 28, 2024. It is now read-only.

Updated parsing of typedef enclosed declarations #83

Merged
merged 8 commits into from
Aug 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# 0.2.2
- Fixed multiple generation/skipping of typedef enclosed declarations.
- Typedef names are now given higher preference over inner names, See [#83](https://github.com/dart-lang/ffigen/pull/83).

# 0.2.1+1
- Added FAQ to readme.

Expand Down
5 changes: 5 additions & 0 deletions lib/src/clang_library/wrapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,4 +358,9 @@ unsigned clang_Cursor_isAnonymousRecordDecl_wrap(CXCursor *cursor)
return clang_Cursor_isAnonymousRecordDecl(*cursor);
}

CXString *clang_getCursorUSR_wrap(CXCursor *cursor)
{
return ptrToCXString(clang_getCursorUSR(*cursor));
}

// END ===== WRAPPER FUNCTIONS =====================
1 change: 1 addition & 0 deletions lib/src/clang_library/wrapper.def
Original file line number Diff line number Diff line change
Expand Up @@ -358,3 +358,4 @@ clang_Cursor_isMacroBuiltin_wrap
clang_Cursor_Evaluate_wrap
clang_Cursor_isAnonymous_wrap
clang_Cursor_isAnonymousRecordDecl_wrap
clang_getCursorUSR_wrap
32 changes: 27 additions & 5 deletions lib/src/code_generator/binding.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,23 @@ import 'writer.dart';
///
/// Do not extend directly, use [LookUpBinding] or [NoLookUpBinding].
abstract class Binding {
/// Holds the Unified Symbol Resolution string obtained from libclang.
final String usr;

/// The name as it was in C.
final String originalName;

/// Binding name to generate, may get changed to resolve name conflicts.
String name;

final String dartDoc;

Binding({@required this.originalName, @required this.name, this.dartDoc});
Binding({
@required this.usr,
@required this.originalName,
@required this.name,
this.dartDoc,
});

/// Return typedef dependencies.
List<Typedef> getTypedefDependencies(Writer w);
Expand All @@ -33,17 +43,29 @@ abstract class Binding {
/// Base class for bindings which look up symbols in dynamic library.
abstract class LookUpBinding extends Binding {
LookUpBinding({
@required String originalName,
String usr,
String originalName,
@required String name,
String dartDoc,
}) : super(originalName: originalName, name: name, dartDoc: dartDoc);
}) : super(
usr: usr ?? name,
originalName: originalName ?? name,
name: name,
dartDoc: dartDoc,
);
}

/// Base class for bindings which don't look up symbols in dynamic library.
abstract class NoLookUpBinding extends Binding {
NoLookUpBinding({
@required String originalName,
String usr,
String originalName,
@required String name,
String dartDoc,
}) : super(originalName: originalName, name: name, dartDoc: dartDoc);
}) : super(
usr: usr ?? name,
originalName: originalName ?? name,
name: name,
dartDoc: dartDoc,
);
}
8 changes: 7 additions & 1 deletion lib/src/code_generator/constant.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,18 @@ class Constant extends NoLookUpBinding {
final String rawValue;

Constant({
String usr,
String originalName,
@required String name,
String dartDoc,
@required this.rawType,
@required this.rawValue,
}) : super(originalName: originalName ?? name, name: name, dartDoc: dartDoc);
}) : super(
usr: usr,
originalName: originalName,
name: name,
dartDoc: dartDoc,
);

@override
BindingString toBindingString(Writer w) {
Expand Down
8 changes: 7 additions & 1 deletion lib/src/code_generator/enum_class.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,18 @@ class EnumClass extends NoLookUpBinding {
final List<EnumConstant> enumConstants;

EnumClass({
String usr,
String originalName,
@required String name,
String dartDoc,
List<EnumConstant> enumConstants,
}) : enumConstants = enumConstants ?? [],
super(originalName: originalName ?? name, name: name, dartDoc: dartDoc);
super(
usr: usr,
originalName: originalName,
name: name,
dartDoc: dartDoc,
);

@override
BindingString toBindingString(Writer w) {
Expand Down
7 changes: 6 additions & 1 deletion lib/src/code_generator/func.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,19 @@ class Func extends LookUpBinding {
/// [originalName] is looked up in dynamic library, if not
/// provided, takes the value of [name].
Func({
String usr,
@required String name,
String originalName,
String dartDoc,
@required this.returnType,
List<Parameter> parameters,
}) : parameters = parameters ?? [],
super(
originalName: originalName ?? name, name: name, dartDoc: dartDoc) {
usr: usr,
originalName: originalName,
name: name,
dartDoc: dartDoc,
) {
for (var i = 0; i < this.parameters.length; i++) {
if (this.parameters[i].name == null ||
this.parameters[i].name.trim() == '') {
Expand Down
8 changes: 7 additions & 1 deletion lib/src/code_generator/global.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,17 @@ class Global extends LookUpBinding {
final Type type;

Global({
String usr,
String originalName,
@required String name,
@required this.type,
String dartDoc,
}) : super(originalName: originalName ?? name, name: name, dartDoc: dartDoc);
}) : super(
usr: usr,
originalName: originalName,
name: name,
dartDoc: dartDoc,
);

@override
BindingString toBindingString(Writer w) {
Expand Down
8 changes: 7 additions & 1 deletion lib/src/code_generator/struc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,18 @@ class Struc extends NoLookUpBinding {
List<Member> members;

Struc({
String usr,
String originalName,
@required String name,
String dartDoc,
List<Member> members,
}) : members = members ?? [],
super(originalName: originalName ?? name, name: name, dartDoc: dartDoc);
super(
usr: usr,
originalName: originalName,
name: name,
dartDoc: dartDoc,
);

List<int> _getArrayDimensionLengths(Type type) {
final array = <int>[];
Expand Down
29 changes: 25 additions & 4 deletions lib/src/header_parser/clang_bindings/clang_bindings.dart
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ class Clang {
/// instead of cxcursor by default.
int clang_visitChildren_wrap(
ffi.Pointer<CXCursor> parent,
ffi.Pointer<ffi.NativeFunction<ModifiedCXCursorVisitor_1>> _modifiedVisitor,
ffi.Pointer<ffi.NativeFunction<ModifiedCXCursorVisitor>> _modifiedVisitor,
int uid,
) {
_clang_visitChildren_wrap ??= _dylib.lookupFunction<
Expand Down Expand Up @@ -778,6 +778,19 @@ class Clang {

_dart_clang_Cursor_isAnonymousRecordDecl_wrap
_clang_Cursor_isAnonymousRecordDecl_wrap;

ffi.Pointer<CXString> clang_getCursorUSR_wrap(
ffi.Pointer<CXCursor> cursor,
) {
_clang_getCursorUSR_wrap ??= _dylib.lookupFunction<
_c_clang_getCursorUSR_wrap,
_dart_clang_getCursorUSR_wrap>('clang_getCursorUSR_wrap');
return _clang_getCursorUSR_wrap(
cursor,
);
}

_dart_clang_getCursorUSR_wrap _clang_getCursorUSR_wrap;
}

/// A character string.
Expand Down Expand Up @@ -2451,21 +2464,21 @@ typedef _dart_clang_formatDiagnostic_wrap = ffi.Pointer<CXString> Function(
int opts,
);

typedef ModifiedCXCursorVisitor_1 = ffi.Int32 Function(
typedef ModifiedCXCursorVisitor = ffi.Int32 Function(
ffi.Pointer<CXCursor>,
ffi.Pointer<CXCursor>,
ffi.Pointer<ffi.Void>,
);

typedef _c_clang_visitChildren_wrap = ffi.Uint32 Function(
ffi.Pointer<CXCursor> parent,
ffi.Pointer<ffi.NativeFunction<ModifiedCXCursorVisitor_1>> _modifiedVisitor,
ffi.Pointer<ffi.NativeFunction<ModifiedCXCursorVisitor>> _modifiedVisitor,
ffi.Int64 uid,
);

typedef _dart_clang_visitChildren_wrap = int Function(
ffi.Pointer<CXCursor> parent,
ffi.Pointer<ffi.NativeFunction<ModifiedCXCursorVisitor_1>> _modifiedVisitor,
ffi.Pointer<ffi.NativeFunction<ModifiedCXCursorVisitor>> _modifiedVisitor,
int uid,
);

Expand Down Expand Up @@ -2641,3 +2654,11 @@ typedef _c_clang_Cursor_isAnonymousRecordDecl_wrap = ffi.Uint32 Function(
typedef _dart_clang_Cursor_isAnonymousRecordDecl_wrap = int Function(
ffi.Pointer<CXCursor> cursor,
);

typedef _c_clang_getCursorUSR_wrap = ffi.Pointer<CXString> Function(
ffi.Pointer<CXCursor> cursor,
);

typedef _dart_clang_getCursorUSR_wrap = ffi.Pointer<CXString> Function(
ffi.Pointer<CXCursor> cursor,
);
4 changes: 2 additions & 2 deletions lib/src/header_parser/data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ IncrementalNamer _incrementalNamer;
final uid = Isolate.current.controlPort.nativePort;

/// Saved macros, Key: prefixedName, Value originalName.
Map<String, String> get savedMacros => _savedMacros;
Map<String, String> _savedMacros;
Map<String, Macro> get savedMacros => _savedMacros;
Map<String, Macro> _savedMacros;

/// Saved unnamed EnumConstants.
List<Constant> get unnamedEnumConstants => _unnamedEnumConstants;
Expand Down
16 changes: 8 additions & 8 deletions lib/src/header_parser/includer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import 'data.dart';
/// Utility functions to check whether a binding should be parsed or not
/// based on filters.

bool shouldIncludeStruct(String name) {
if (bindingsIndex.isSeenStruct(name) || name == '') {
bool shouldIncludeStruct(String usr, String name) {
if (bindingsIndex.isSeenStruct(usr) || name == '') {
return false;
} else if (config.structDecl == null ||
config.structDecl.shouldInclude(name)) {
Expand All @@ -18,8 +18,8 @@ bool shouldIncludeStruct(String name) {
}
}

bool shouldIncludeFunc(String name) {
if (bindingsIndex.isSeenFunc(name) || name == '') {
bool shouldIncludeFunc(String usr, String name) {
if (bindingsIndex.isSeenFunc(usr) || name == '') {
return false;
} else if (config.functionDecl == null ||
config.functionDecl.shouldInclude(name)) {
Expand All @@ -29,8 +29,8 @@ bool shouldIncludeFunc(String name) {
}
}

bool shouldIncludeEnumClass(String name) {
if (bindingsIndex.isSeenEnumClass(name) || name == '') {
bool shouldIncludeEnumClass(String usr, String name) {
if (bindingsIndex.isSeenEnumClass(usr) || name == '') {
return false;
} else if (config.enumClassDecl == null ||
config.enumClassDecl.shouldInclude(name)) {
Expand All @@ -40,8 +40,8 @@ bool shouldIncludeEnumClass(String name) {
}
}

bool shouldIncludeMacro(String name) {
if (bindingsIndex.isSeenMacro(name) || name == '') {
bool shouldIncludeMacro(String usr, String name) {
if (bindingsIndex.isSeenMacro(usr) || name == '') {
return false;
} else if (config.macroDecl == null || config.macroDecl.shouldInclude(name)) {
return true;
Expand Down
6 changes: 3 additions & 3 deletions lib/src/header_parser/parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ List<Binding> parseToBindings() {
cmdLen = config.compilerOpts.length;
}

// Contains all bindings.
final bindings = <Binding>[];
// Contains all bindings. A set ensures we never have duplicates.
final bindings = <Binding>{};

// Log all headers for user.
_logger.info('Input Headers: ${config.headers.entryPoints}');
Expand Down Expand Up @@ -130,5 +130,5 @@ List<Binding> parseToBindings() {
clangCmdArgs.dispose(config.compilerOpts.length);
}
clang.clang_disposeIndex(index);
return bindings;
return bindings.toList();
}
16 changes: 12 additions & 4 deletions lib/src/header_parser/sub_parsers/enumdecl_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ final _stack = Stack<_ParsedEnum>();
EnumClass parseEnumDeclaration(
Pointer<clang_types.CXCursor> cursor, {

/// Optionally provide name to use (useful in case struct is inside a typedef).
/// Optionally provide name to use (useful in case enum is inside a typedef).
String name,
}) {
_stack.push(_ParsedEnum());
final enumUsr = cursor.usr();
final enumName = name ?? cursor.spelling();
if (enumName == '') {
// Save this unnamed enum if it is anonymous (therefore not in a typedef).
Expand All @@ -42,17 +43,24 @@ EnumClass parseEnumDeclaration(
} else {
_logger.fine('Unnamed enum inside a typedef.');
}
} else if (shouldIncludeEnumClass(enumName) &&
!bindingsIndex.isSeenEnumClass(enumName)) {
} else if (shouldIncludeEnumClass(enumUsr, enumName)) {
_logger.fine('++++ Adding Enum: ${cursor.completeStringRepr()}');
_stack.top.enumClass = EnumClass(
usr: enumUsr,
dartDoc: getCursorDocComment(cursor),
originalName: enumName,
name: config.enumClassDecl.renameUsingConfig(enumName),
);
bindingsIndex.addEnumClassToSeen(enumName, _stack.top.enumClass);
bindingsIndex.addEnumClassToSeen(enumUsr, _stack.top.enumClass);
_addEnumConstant(cursor);
}
if (bindingsIndex.isSeenEnumClass(enumUsr)) {
_stack.top.enumClass = bindingsIndex.getSeenEnumClass(enumUsr);

// If enum is seen, update it's name.
_stack.top.enumClass.name =
config.enumClassDecl.renameUsingConfig(enumName);
}

return _stack.pop().enumClass;
}
Expand Down
8 changes: 6 additions & 2 deletions lib/src/header_parser/sub_parsers/functiondecl_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ Func parseFunctionDeclaration(Pointer<clang_types.CXCursor> cursor) {
_stack.top.structByValueParameter = false;
_stack.top.unimplementedParameterType = false;

final funcUsr = cursor.usr();
final funcName = cursor.spelling();
if (shouldIncludeFunc(funcName) && !bindingsIndex.isSeenFunc(funcName)) {
if (shouldIncludeFunc(funcUsr, funcName)) {
_logger.fine('++++ Adding Function: ${cursor.completeStringRepr()}');

final rt = _getFunctionReturnType(cursor);
Expand Down Expand Up @@ -65,12 +66,15 @@ Func parseFunctionDeclaration(Pointer<clang_types.CXCursor> cursor) {
cursor,
nesting.length + commentPrefix.length,
),
usr: funcUsr,
name: config.functionDecl.renameUsingConfig(funcName),
originalName: funcName,
returnType: rt,
parameters: parameters,
);
bindingsIndex.addFuncToSeen(funcName, _stack.top.func);
bindingsIndex.addFuncToSeen(funcUsr, _stack.top.func);
} else if (bindingsIndex.isSeenFunc(funcUsr)) {
_stack.top.func = bindingsIndex.getSeenFunc(funcUsr);
}

return _stack.pop().func;
Expand Down
Loading