def add_missing_destructors(tree): for node in ft.walk(tree): if not isinstance(node, ft.Type): continue for child in ft.iter_child_nodes(node): if isinstance(child, ft.Procedure): if 'destructor' in child.attributes: logging.info('found destructor %s' % child.name) break else: logging.info('adding missing destructor for %s' % node.name) new_node = ft.Subroutine( '%s_finalise' % node.name, node.filename, ['Automatically generated destructor for %s' % node.name], node.lineno, [ ft.Argument(name='this', filename=node.filename, doc=['Object to be destructed'], lineno=node.lineno, attributes=['intent(inout)'], type='type(%s)' % node.name) ], node.uses, ['destructor', 'skip_call'], mod_name=node.mod_name, type_name=node.name) new_node.method_name = '__del__' node.procedures.append(new_node) return tree
def visit_Function(self, node): # insert ret_val after last non-optional argument arguments = node.arguments[:] i = 0 for i, arg in enumerate(arguments): if 'optional' in arg.attributes: break arguments.insert(i, node.ret_val) arguments[i].name = 'ret_' + arguments[i].name arguments[i].attributes.append('intent(out)') new_node = ft.Subroutine(node.name, node.filename, node.doc, node.lineno, arguments, node.uses, node.attributes, mod_name=node.mod_name) if hasattr(node, 'call_name'): new_node.call_name = node.call_name if hasattr(node, 'type'): new_node.type = node.type new_node.orig_name = node.orig_name new_node.orig_node = node # keep a reference to the original node return new_node