39 ''' This module contains the ContainerSymbol and its interfaces.'''
41 from os
import listdir, path
48 ''' Symbol that represents a reference to a Container. The reference
49 is lazy evaluated, this means that the Symbol will be created without
50 parsing and importing the referenced container, but this can be imported
53 :param str name: name of the symbol.
54 :param bool wildcard_import: if all public Symbols of the Container are \
55 imported into the current scope. Defaults to False.
56 :param kwargs: additional keyword arguments provided by \
57 :py:class:`psyclone.psyir.symbols.Symbol`.
58 :type kwargs: unwrapped dict.
61 def __init__(self, name, wildcard_import=False, **kwargs):
62 super(ContainerSymbol, self).__init__(name)
69 def _process_arguments(self, **kwargs):
70 ''' Process the arguments for the constructor and the specialise
71 methods. In this case the wildcard_import and a change in default
72 value for the interface.
74 :param kwargs: keyword arguments which can be:\n
75 :param bool wildcard_import: if all public Symbols of the \
76 Container are imported into the current scope. Defaults to \
78 and the arguments in :py:class:`psyclone.psyir.symbols.Symbol`
79 :type kwargs: unwrapped dict.
81 :raises TypeError: if it is provided with an interface argument other \
82 then FortranModuleInterface.
85 if not hasattr(self,
'_reference'):
88 if "wildcard_import" in kwargs:
90 elif not hasattr(self,
'_has_wildcard_import'):
96 if "interface" not in kwargs
or kwargs[
"interface"]
is None:
98 elif not isinstance(kwargs[
"interface"], FortranModuleInterface):
99 raise TypeError(f
"A ContainerSymbol interface must be of type '"
100 f
"FortranModuleInterface' but found "
101 f
"'{type(kwargs['interface']).__name__}' for "
102 f
"Container '{self.name}'.")
103 super(ContainerSymbol, self)._process_arguments(**kwargs)
106 '''Create and return a copy of this object. Any references to the
107 original will not be affected so the copy will not be referred
108 to by any other object.
110 :returns: A symbol object with the same properties as this \
112 :rtype: :py:class:`psyclone.psyir.symbols.Symbol`
116 new_symbol = super(ContainerSymbol, self).
copy()
122 ''' Returns the referenced container. If it is not available, use
123 the interface to import the container
125 :returns: referenced container.
126 :rtype: :py:class:`psyclone.psyir.nodes.Container`
133 string = self.
_name_name +
": ContainerSymbol<"
137 string +=
"not linked>"
141 def wildcard_import(self):
143 :returns: whether or not there is a wildcard import of all public \
144 symbols from this Container.
150 @wildcard_import.setter
151 def wildcard_import(self, value):
153 Set whether or not there is a wildcard import of all public symbols
154 from this Container symbol.
156 :param bool value: whether there is or is not a wildcard import.
158 :raises TypeError: if the supplied `value` is not a bool.
161 if not isinstance(value, bool):
162 raise TypeError(f
"wildcard_import must be a bool but got: "
163 f
"'{type(value).__name__}'")
168 ''' Abstract implementation of the ContainerSymbol Interface '''
172 ''' Abstract method to import an external container, the specific
173 implementation depends on the language used.
175 :param str name: name of the external entity to be imported.
177 :raises NotImplementedError: this is an abstract method.
179 raise NotImplementedError(
"Abstract method")
183 ''' Implementation of ContainerSymbolInterface for Fortran modules '''
187 ''' Imports a Fortran module as a PSyIR container. The module is
188 expected to be found in a Fortran source file with the same name
189 as the module plus the '.[f|F]90' extension. The search
190 locations are provided in-order by the Config include_paths
191 attribute ('-I' in the psyclone script).
193 :param str name: name of the module to be imported.
195 :returns: container associated with the given name.
196 :rtype: :py:class:`psyclone.psyir.nodes.Container`
198 :raises SymbolError: the given Fortran module is not found on the \
204 for directory
in Config.get().include_paths:
205 for filename
in [name+
'.f90', name+
'.F90']:
206 if filename
in listdir(directory):
208 abspath = path.join(directory, filename)
209 fortran_reader = FortranReader()
210 file_container = fortran_reader.psyir_from_file(abspath)
212 for candidate
in file_container.children:
213 if candidate.name.lower() == name.lower():
216 f
"Error importing the Fortran module '{name}' into a "
217 f
"PSyIR container. The file with filename "
218 f
"'{filename}' does not contain the expected module.")
221 f
"Module '{name}' (expected to be found in '{name}.[f|F]90') not "
222 f
"found in any of the include_paths directories "
223 f
"{Config.get().include_paths}.")
227 __all__ = [
'ContainerSymbol',
'ContainerSymbolInterface',
228 'FortranModuleInterface']
def import_container(name)
def wildcard_import(self)
def wildcard_import(self, value)
def _process_arguments(self, **kwargs)
def import_container(name)
def _process_arguments(self, visibility=None, interface=None)