Reference Guide  2.5.0
container.py
1 # -----------------------------------------------------------------------------
2 # BSD 3-Clause License
3 #
4 # Copyright (c) 2017-2024, Science and Technology Facilities Council.
5 # All rights reserved.
6 #
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions are met:
9 #
10 # * Redistributions of source code must retain the above copyright notice, this
11 # list of conditions and the following disclaimer.
12 #
13 # * Redistributions in binary form must reproduce the above copyright notice,
14 # this list of conditions and the following disclaimer in the documentation
15 # and/or other materials provided with the distribution.
16 #
17 # * Neither the name of the copyright holder nor the names of its
18 # contributors may be used to endorse or promote products derived from
19 # this software without specific prior written permission.
20 #
21 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 # POSSIBILITY OF SUCH DAMAGE.
33 # -----------------------------------------------------------------------------
34 # Authors R. W. Ford, A. R. Porter and S. Siso, STFC Daresbury Lab
35 # I. Kavcic, Met Office
36 # J. Henrichs, Bureau of Meteorology
37 # -----------------------------------------------------------------------------
38 
39 ''' This module contains the Container node implementation.'''
40 
41 from psyclone.psyir.nodes.scoping_node import ScopingNode
42 from psyclone.psyir.nodes.routine import Routine
43 from psyclone.psyir.nodes.codeblock import CodeBlock
44 from psyclone.psyir.symbols import SymbolTable
45 from psyclone.errors import GenerationError
46 from psyclone.psyir.nodes.commentable_mixin import CommentableMixin
47 
48 
50  '''Node representing a set of Routine and/or Container nodes, as well
51  as a name and a SymbolTable. This construct can be used to scope
52  symbols of variables, Routine names and Container names. In
53  Fortran a container would naturally represent a module or a
54  submodule.
55 
56  :param str name: the name of the container.
57  :param parent: optional parent node of this Container in the PSyIR.
58  :type parent: :py:class:`psyclone.psyir.nodes.Node`
59  :param symbol_table: initialise the node with a given symbol table.
60  :type symbol_table: :py:class:`psyclone.psyir.symbols.SymbolTable` or \
61  NoneType
62 
63  '''
64  # Textual description of the node.
65  _children_valid_format = "[Container | Routine | CodeBlock]*"
66  _text_name = "Container"
67  _colour = "green"
68 
69  def __init__(self, name, **kwargs):
70  super().__init__(**kwargs)
71  self._name_name = name
72 
73  def __eq__(self, other):
74  '''Checks the equality of this Container with other. Containers are
75  equal if they are the same type, and have the same name.
76 
77  :param object other: the object to check equality to.
78 
79  :returns: whether other is equal to self.
80  :rtype: bool
81  '''
82  is_eq = super().__eq__(other)
83  is_eq = is_eq and self.namenamenamename == other.name
84  return is_eq
85 
86  @staticmethod
87  def _validate_child(position, child):
88  '''
89  :param int position: the position to be validated.
90  :param child: a child to be validated.
91  :type child: :py:class:`psyclone.psyir.nodes.Node`
92 
93  :return: whether the given child and position are valid for this node.
94  :rtype: bool
95 
96  '''
97  # pylint: disable=unused-argument
98  return isinstance(child, (Container, Routine, CodeBlock))
99 
100  @classmethod
101  def create(cls, name, symbol_table, children):
102  '''Create a Container instance given a name, a symbol table and a
103  list of child nodes.
104 
105  :param str name: the name of the Container.
106  :param symbol_table: the symbol table associated with this \
107  Container.
108  :type symbol_table: :py:class:`psyclone.psyir.symbols.SymbolTable`
109  :param children: a list of PSyIR nodes contained in the \
110  Container. These must be Containers or Routines.
111  :type children: list of :py:class:`psyclone.psyir.nodes.Container` \
112  or :py:class:`psyclone.psyir.nodes.Routine`
113 
114  :returns: an instance of `cls`.
115  :rtype: :py:class:`psyclone.psyir.nodes.Container` or subclass
116  thereof
117 
118  :raises GenerationError: if the arguments to the create method \
119  are not of the expected type.
120 
121  '''
122  if not isinstance(name, str):
123  raise GenerationError(
124  f"name argument in create method of Container class "
125  f"should be a string but found '{type(name).__name__}'.")
126  if not isinstance(symbol_table, SymbolTable):
127  raise GenerationError(
128  f"symbol_table argument in create method of Container class "
129  f"should be a SymbolTable but found "
130  f"'{type(symbol_table).__name__}'.")
131  if not isinstance(children, list):
132  raise GenerationError(
133  f"children argument in create method of Container class "
134  f"should be a list but found '{type(children).__name__}'.")
135 
136  container = cls(name, symbol_table=symbol_table)
137  container.children = children
138  return container
139 
140  @property
141  def name(self):
142  '''
143  :returns: name of the container.
144  :rtype: str
145 
146  '''
147  return self._name_name
148 
149  @name.setter
150  def name(self, new_name):
151  '''Sets a new name for the container.
152 
153  :param str new_name: new name for the container.
154 
155  '''
156  self._name_name = new_name
157 
158  def node_str(self, colour=True):
159  '''
160  Returns the name of this node with appropriate control codes
161  to generate coloured output in a terminal that supports it.
162 
163  :param bool colour: whether or not to include colour control codes.
164 
165  :returns: description of this node, possibly coloured.
166  :rtype: str
167  '''
168  return self.coloured_namecoloured_name(colour) + f"[{self.name}]"
169 
170  def __str__(self):
171  return f"Container[{self.name}]\n"
172 
173  def get_routine_psyir(self, name):
174  '''Returns the PSyIR for the routine with the given name, or None
175  if a routine with this name does not exist.
176 
177  :param str name: name of the routine to find.
178 
179  :returns: the PSyIR Routine instance of the subroutine, or None if
180  there is no routine with that name in this container.
181  :rtype: Union[None, psyclone.psyir.nodes.Routine]
182 
183  '''
184  name = name.lower()
185  for routine in self.walkwalk(Routine):
186  if routine.name.lower() == name:
187  return routine
188  return None
189 
190 
191 # For AutoAPI documentation generation
192 __all__ = ['Container']
def create(cls, name, symbol_table, children)
Definition: container.py:101
def coloured_name(self, colour=True)
Definition: node.py:453
def walk(self, my_type, stop_type=None, depth=None)
Definition: node.py:1075