| // Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| import '../code_generator.dart'; |
| import '../context.dart'; |
| import 'clang_bindings/clang_bindings.dart' as clang_types; |
| import 'sub_parsers/functiondecl_parser.dart'; |
| import 'sub_parsers/macro_parser.dart'; |
| import 'sub_parsers/objccategorydecl_parser.dart'; |
| import 'sub_parsers/objcprotocoldecl_parser.dart'; |
| import 'sub_parsers/var_parser.dart'; |
| import 'type_extractor/extractor.dart'; |
| import 'utils.dart'; |
| |
| /// Parses the translation unit and returns the generated bindings. |
| Set<Binding> parseTranslationUnit( |
| Context context, |
| clang_types.CXCursor translationUnitCursor, |
| ) { |
| final bindings = <Binding>{}; |
| final logger = context.logger; |
| final headers = <String, bool>{}; |
| |
| translationUnitCursor.visitChildren((cursor) { |
| final file = cursor.sourceFileName(); |
| if (file.isEmpty) return; |
| if (headers[file] ??= context.config.headers.include(Uri.file(file))) { |
| try { |
| logger.finest('rootCursorVisitor: ${cursor.completeStringRepr()}'); |
| switch (clang.clang_getCursorKind(cursor)) { |
| case clang_types.CXCursorKind.CXCursor_FunctionDecl: |
| bindings.addAll(parseFunctionDeclaration(context, cursor)); |
| break; |
| case clang_types.CXCursorKind.CXCursor_StructDecl: |
| case clang_types.CXCursorKind.CXCursor_UnionDecl: |
| case clang_types.CXCursorKind.CXCursor_EnumDecl: |
| case clang_types.CXCursorKind.CXCursor_ObjCInterfaceDecl: |
| case clang_types.CXCursorKind.CXCursor_TypedefDecl: |
| addToBindings(bindings, _getCodeGenTypeFromCursor(context, cursor)); |
| break; |
| case clang_types.CXCursorKind.CXCursor_ObjCCategoryDecl: |
| addToBindings( |
| bindings, |
| parseObjCCategoryDeclaration(context, cursor), |
| ); |
| break; |
| case clang_types.CXCursorKind.CXCursor_ObjCProtocolDecl: |
| addToBindings( |
| bindings, |
| parseObjCProtocolDeclaration(context, cursor), |
| ); |
| break; |
| case clang_types.CXCursorKind.CXCursor_MacroDefinition: |
| saveMacroDefinition(context, cursor); |
| break; |
| case clang_types.CXCursorKind.CXCursor_VarDecl: |
| addToBindings(bindings, parseVarDeclaration(context, cursor)); |
| break; |
| default: |
| logger.finer('rootCursorVisitor: CursorKind not implemented'); |
| } |
| } catch (e, s) { |
| logger.severe(e); |
| logger.severe(s); |
| rethrow; |
| } |
| } else { |
| logger.finest( |
| 'rootCursorVisitor:(not included) ${cursor.completeStringRepr()}', |
| ); |
| } |
| }); |
| |
| return bindings; |
| } |
| |
| /// Adds to binding if unseen and not null. |
| void addToBindings(Set<Binding> bindings, Binding? b) { |
| if (b != null) { |
| // This is a set, and hence will not have duplicates. |
| bindings.add(b); |
| } |
| } |
| |
| BindingType? _getCodeGenTypeFromCursor( |
| Context context, |
| clang_types.CXCursor cursor, |
| ) { |
| final t = getCodeGenType(context, cursor.type()); |
| return t is BindingType ? t : null; |
| } |
| |
| /// Visits all cursors and builds a map of usr and [clang_types.CXCursor]. |
| void buildUsrCursorDefinitionMap( |
| Context context, |
| clang_types.CXCursor translationUnitCursor, |
| ) { |
| final logger = context.logger; |
| translationUnitCursor.visitChildren((cursor) { |
| try { |
| context.cursorIndex.saveDefinition(cursor); |
| } catch (e, s) { |
| logger.severe(e); |
| logger.severe(s); |
| rethrow; |
| } |
| }); |
| } |