def process(self, verbose=False): """ Process the translation unit Generates an ast.TranslationUnit instance with all the translation unit data (AST, macro instances, etc). Also sets up the needed data for reflection code generation (See runJinja() method below) """ if verbose: self.logger.info('Parsing file: {} {} ...'.format( os.path.basename(self.filePath), ' '.join(self.compileArgs))) self.clang_tu = clang.cindex.Index.create().parse( self.filePath, args=self.compileArgs) if verbose: for d in self.clang_tu.diagnostics: GlobalLogger.error().step('Line {} (severity {}): {}'.format( d.location.line, d.severity, d.spelling)) if verbose: self.logger.info('Processing AST...') self.translation_unit = TranslationUnit(self.clang_tu.cursor, self.filePath) # This is the root of the AST. For easy visitation, check TranslationUnit.nodes() method, # it gives an iterable on the translation unit AST self.root = self.translation_unit.root # Print the processed AST and the full AST given by libclang if self.print_ast: if verbose: self.logger.info('Dumping AST to {}...'.format( self.ast_file_path)) with open(self.ast_file_path, 'w') as ast_file: import asciitree ast_file.write( asciitree.draw_tree(self.root, lambda n: list(n.get_children()), lambda n: n.print_ast_node())) ast_file.write('\n\n\nFULL AST BELLOW:\n\n\n') ast_file.write( asciitree.draw_tree( self.clang_tu.cursor, lambda c: list(c.get_children()), lambda c: 'File {}, line {}: \'{}\', {}'.format( c.location.file, c.location.line, c.displayname or c.spelling, c.kind)))
def process(self, verbose = False): """ Process the translation unit Generates an ast.TranslationUnit instance with all the translation unit data (AST, macro instances, etc). Also sets up the needed data for reflection code generation (See runJinja() method below) """ if verbose: self.logger.info('Parsing file: {} {} ...'.format( os.path.basename(self.filePath), ' '.join(self.compileArgs))) self.clang_tu = clang.cindex.Index.create().parse(self.filePath, args = self.compileArgs) if verbose: for d in self.clang_tu.diagnostics: GlobalLogger.error().step('Line {} (severity {}): {}'.format(d.location.line, d.severity, d.spelling)) if verbose: self.logger.info('Processing AST...') self.translation_unit = TranslationUnit(self.clang_tu.cursor, self.filePath) # This is the root of the AST. For easy visitation, check TranslationUnit.nodes() method, # it gives an iterable on the translation unit AST self.root = self.translation_unit.root # Print the processed AST and the full AST given by libclang if self.print_ast: if verbose: self.logger.info('Dumping AST to {}...'.format(self.ast_file_path)) with open(self.ast_file_path, 'w') as ast_file: import asciitree ast_file.write(asciitree.draw_tree(self.root, lambda n: list(n.get_children()), lambda n: n.print_ast_node() )) ast_file.write('\n\n\nFULL AST BELLOW:\n\n\n') ast_file.write(asciitree.draw_tree(self.clang_tu.cursor, lambda c: list(c.get_children()), lambda c: 'File {}, line {}: \'{}\', {}'.format(c.location.file, c.location.line, c.displayname or c.spelling, c.kind) ))
def process(self): """ Process the translation unit Generates an ast.TranslationUnit instance with all the translation unit data (AST, macro instances, etc). Also sets up the needed data for reflection code generation (See runJinja() method below) """ self.logger.info('Parsing file...') ast_options = clang.cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD self.clang_tu = self.index.parse(self.filePath, args = self.compileArgs, options = ast_options) for d in self.clang_tu.diagnostics: GlobalLogger.error().step('Line {} (severity {}): {}'.format(d.location.line, d.severity, d.spelling)) self.logger.info('Processing AST...') self.classes = [] self.namespace = [] self.translation_unit = TranslationUnit(self.clang_tu.cursor, self.filePath) print '\r' + ' '*100 + '\r', # Clean progress # This is the root of the AST. For easy visitation, check TranslationUnit.nodes() method, # it gives an iterable on the translation unit AST self.root = self.translation_unit.root # Print the processed AST and the full AST given by libclang. if self.print_ast: self.logger.info('Dumping AST to {}...'.format(self.ast_file_path)) with open(self.ast_file_path, 'w') as ast_file: import asciitree ast_file.write(asciitree.draw_tree(self.root, lambda n: list(n.get_children()), lambda n: n.print_ast_node() )) ast_file.write('\n\n\nFULL AST BELLOW:\n\n\n') ast_file.write(asciitree.draw_tree(self.clang_tu.cursor, lambda c: list(c.get_children()), lambda c: 'File {}, line {}: \'{}\', {}'.format(c.location.file, c.location.line, c.displayname or c.spelling, c.kind) ))
def create_child(nodeClass, **kwargs): """ Creates a child node of the given parent node, from the given libclang cursor If a mapping of the cursor kind is found (See Node class docstring above) an instance of the corresponding Node subclass is returned. Else None is returned. """ if hasattr(nodeClass, 'MEMBERS_MAPPING'): cursor = kwargs['cursor'] mapping = nodeClass.MEMBERS_MAPPING() if cursor.kind in mapping: class_ = mapping[cursor.kind] return class_.create_node(**kwargs) else: GlobalLogger.warning().step('{} has no {} mapping'.format(nodeClass.__name__, cursor.kind)) return None
def create_child(nodeClass, **kwargs): """ Creates a child node of the given parent node, from the given libclang cursor If a mapping of the cursor kind is found (See Node class docstring above) an instance of the corresponding Node subclass is returned. Else None is returned. """ if hasattr(nodeClass, 'MEMBERS_MAPPING'): cursor = kwargs['cursor'] mapping = nodeClass.MEMBERS_MAPPING() if cursor.kind in mapping: class_ = mapping[cursor.kind] return class_.create_node(**kwargs) else: GlobalLogger.warning().step('{} has no {} mapping'.format( nodeClass.__name__, cursor.kind)) return None