How to use the f90wrap.fortran.FortranTransformer function in f90wrap

To help you get started, we’ve selected a few f90wrap examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github jameskermode / f90wrap / f90wrap / fortran.py View on Github external
logging.debug('marking private symbol ' + node.name)
                    self.mod.private_symbols.append(node.name)
            else:
                # symbol should be marked as public if it's not already
                if node.name not in self.mod.public_symbols:
                    logging.debug('marking public symbol ' + node.name)
                    self.mod.public_symbols.append(node.name)

        else:
            raise ValueError('bad default access %s for module %s' %
                               (self.mod.default_access, self.mod.name))

        return node  # no need to recurse further


class PrivateSymbolsRemover(FortranTransformer):
    """
    Transform a tree by removing private symbols.
    """

    def __init__(self):
        self.mod = None

    def visit_Module(self, mod):
        # keep track of the current module
        self.mod = mod
        self.generic_visit(mod)
        self.mod = None

    def visit(self, node):
        if self.mod is None:
            return self.generic_visit(node)
github jameskermode / f90wrap / f90wrap / fortran.py View on Github external
def fix_argument_attributes(node):
    """
    Walk over all procedures in the tree starting at `node` and
    fix the argument attributes.
    """
    for mod, sub, arguments in walk_procedures(node):
        for arg in arguments:
            if not hasattr(arg, 'type'):
                arg.type = 'callback'
                arg.value = ''
                arg.attributes.append('callback')

    return node


class LowerCaseConverter(FortranTransformer):
    """
    Subclass of FortranTransformer which converts program, module,
    procedure, interface, type and declaration names and attributes to
    lower case. Original names are preserved in the *orig_name*
    attribute.
    """

    def visit_Program(self, node):
        node.orig_name = node.name
        node.name = node.name.lower()
        return self.generic_visit(node)

    def visit_Module(self, node):
        node.orig_name = node.name
        node.name = node.name.lower()
        node.default_access = node.default_access.lower()
github jameskermode / f90wrap / f90wrap / transform.py View on Github external
node.default_access = 'public'
        if 'private' in node.attributes:
            node.default_access = 'private'
        node = self.generic_visit(node)
        self.type = None
        return node

    def visit_Element(self, node):
        if self.type is not None:
            self.update_access(node, self.mod, self.type.default_access, in_type=True)
        else:
            self.update_access(node, self.mod, self.mod.default_access)
        return node


class PrivateSymbolsRemover(ft.FortranTransformer):
    """
    Transform a tree by removing private symbols
    """

    def __init__(self):
        self.mod = None

    def visit_Module(self, mod):
        # keep track of the current module
        self.mod = mod
        mod = self.generic_visit(mod)
        self.mod = None
        return mod

    def visit_Procedure(self, node):
        if self.mod is None:
github jameskermode / f90wrap / f90wrap / fortran.py View on Github external
node.orig_name = node.name
        node.name = node.name.lower()
        node.type = node.type.lower()
        node.attributes = [a.lower() for a in node.attributes]
        return self.generic_visit(node)

def strip_type(t):
    """Return type name from type declaration"""
    t = t.replace(' ', '')  # remove blanks
    if t.startswith('type('):
        t = t[t.index('(') + 1:t.index(')')]
    if t.startswith('class('):
        t = t[t.index('(') + 1:t.index(')')]
    return t.lower()

class AccessUpdater(FortranTransformer):
    """Visit module contents and update public_symbols and
       private_symbols lists to be consistent with (i) default module
       access; (ii) public and private statements at module level;
       (iii) public and private attibutes."""

    def __init__(self):
        self.mod = None

    def visit_Module(self, mod):
        # keep track of the current module
        self.mod = mod
        self.generic_visit(mod)
        self.mod = None

    def visit(self, node):
        if self.mod is None:
github jameskermode / f90wrap / f90wrap / transform.py View on Github external
def remove_private_symbols(node):
    """
    Walk the tree starting at *node*, removing all private symbols.

    This function first applies the AccessUpdater transformer to
    ensure module *public_symbols* and *private_symbols* are up to
    date with *default_access* and individual `public` and `private`
    attributes.
    """

    node = AccessUpdater().visit(node)
    node = PrivateSymbolsRemover().visit(node)
    return node


class UnwrappablesRemover(ft.FortranTransformer):
    def __init__(self, callbacks, types, constructors, destructors, remove_optional_arguments):
        self.callbacks = callbacks
        self.types = types
        self.constructors = constructors
        self.destructors = destructors
        self.remove_optional_arguments = remove_optional_arguments

    def visit_Interface(self, node):
        # don't wrap operator overloading routines
        if node.name.startswith('operator('):
            return None

        return self.generic_visit(node)

    def visit_Procedure(self, node):
        # special case: keep all constructors and destructors, although
github jameskermode / f90wrap / f90wrap / transform.py View on Github external
def collapse_single_interfaces(tree):
    """Collapse interfaces which contain only a single procedure."""

    class _InterfaceCollapser(ft.FortranTransformer):
        """Replace interfaces with only one procedure by that procedure"""

        def visit_Interface(self, node):
            if len(node.procedures) == 1:
                proc = node.procedures[0]
                proc.doc = node.doc + proc.doc
                logging.debug('collapsing single-component interface %s' % proc.name)
                return proc
            else:
                return node

    class _ProcedureRelocator(ft.FortranTransformer):
        """Filter interfaces and procedures into correct lists"""

        def visit_Type(self, node):
            logging.debug('visiting %r' % node)
github jameskermode / f90wrap / f90wrap / transform.py View on Github external
if 'intent(out)' not in arg.attributes:
                    dummy_arg.f2py_line = ('!f2py intent(hide), depend(%s) :: %s = shape(%s,%d)' %
                                           (arg.name, dummy_arg.name, arg.name, i))
                new_dummy_args.append(dummy_arg)
                new_ds.append(dummy_arg.name)
                n_dummy += 1

            if new_dummy_args != []:
                logging.debug('adding dummy arguments %r to %s' % (new_dummy_args, node.name))
                arg.attributes = ([attr for attr in arg.attributes if not attr.startswith('dimension')] +
                                  ['dimension(%s)' % ','.join(new_ds)])
                node.arguments.extend(new_dummy_args)


class MethodFinder(ft.FortranTransformer):
    def __init__(self, types, constructor_names, destructor_names, short_names,
                 move_methods, shorten_routine_names=True, modules_for_type=None):
        self.types = types
        self.constructor_names = constructor_names
        self.destructor_names = destructor_names
        self.short_names = short_names
        self.move_methods = move_methods
        self.shorten_routine_names = shorten_routine_names
        self.modules_for_type = modules_for_type

    def visit_Interface(self, node):
        new_procs = []
        for proc in node.procedures:
            if isinstance(proc, ft.Procedure):
                new_proc = self.visit_Procedure(proc, interface=node)
                if new_proc is not None:
github jameskermode / f90wrap / f90wrap / transform.py View on Github external
class ReorderOptionalArgumentsPython(ft.FortranVisitor):
    """
    Move optional arguments after non-optional arguments:
    in Fortran they can come in any order, but in Python
    optional arguments must come at the end of argument list.
    """

    def visit_Procedure(self, node):
        non_optional = [arg for arg in node.arguments if 'optional' not in arg.attributes]
        optional = [arg for arg in node.arguments if 'optional' in arg.attributes]
        node.arguments = non_optional + optional
        return node


class OnlyAndSkip(ft.FortranTransformer):
    """
    This class does the job of removing nodes from the tree
    which are not necessary to write wrappers for (given user-supplied
    values for only and skip).

    Currently it takes a list of subroutines and a list of modules to write
    wrappers for. If empty, it does all of them.
    """

    def __init__(self, kept_subs, kept_mods):
        self.kept_subs = kept_subs
        self.kept_mods = kept_mods

    def visit_Procedure(self, node):
        if len(self.kept_subs) > 0:
            if node not in self.kept_subs:
github jameskermode / f90wrap / f90wrap / transform.py View on Github external
[ft.Argument(name='this',  # self.prefix + 'this' would probably be safer
                                                  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


class FunctionToSubroutineConverter(ft.FortranTransformer):
    """Convert all functions to subroutines, with return value as an
       intent(out) argument after the last non-optional argument"""

    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,
github jameskermode / f90wrap / f90wrap / transform.py View on Github external
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


class IntentOutToReturnValues(ft.FortranTransformer):
    """
    Convert all Subroutine and Function intent(out) arguments to return values
    """

    def visit_Procedure(self, node):
        if 'constructor' in node.attributes:
            node.arguments[0].attributes = set_intent(node.arguments[0].attributes,
                                                      'intent(out)')

        ret_val = []
        ret_val_doc = None
        if isinstance(node, ft.Function) and node.ret_val is not None:
            ret_val.append(node.ret_val)
            if node.ret_val_doc is not None:
                ret_val_doc = node.ret_val_doc