Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def create_super_types(tree, types):
# YANN: Gather all the dimensions of arrays of type in arguments and module variables
# Add here any other elements where arrays of derived types may appear
append_type_dimension(tree, types)
# Then create a super-type for each type for each of those dimension, inside the module where
# the type is declared in the first place.
modules_indexes = dict(
(mod.name, i) for (i, mod) in enumerate(tree.modules)) # name to index map, compatible python 2.6
containers = []
for ty in types.values():
for dimensions_attribute in ty.super_types_dimensions:
# each type might have many "dimension" attributes since "append_type_dimension"
dimensions = ArrayDimensionConverter.split_dimensions(dimensions_attribute)
if len(dimensions) == 1: # at this point, only 1D arrays are supported
d = dimensions[0]
if str(d) == ':':
continue # at this point, only fixed-length arrays are supported
# populate the super type with the array of types
el = ft.Element(name='items', attributes=[dimensions_attribute], type='type(' + ty.name + ')')
name = ty.name + '_x' + str(d) + '_array'
# populate the tree with the super-type
if name not in (t.name for t in tree.modules[modules_indexes[ty.mod_name]].types):
super_type = ft.Type(name=name, filename=ty.filename, lineno=ty.lineno,
doc=['super-type',
'Automatically generated to handle derived type arrays as a new derived type'],
elements=[el], mod_name=ty.mod_name)
# uses clauses from the base type
# super_type.uses = ty.uses # this causes unwanted growth of the normal type "uses" when we add parameters to the super-type in the next step
super_type.uses = set([(ty.mod_name, (ty.name,))])
def fix_subroutine_type_arrays(tree, types):
# YANN: replace dimension(x) :: type() arguments of routines by scalar super-types
from itertools import chain
# For each top-level procedure and module procedures:
for proc in chain(tree.procedures, *(mod.procedures for mod in tree.modules)):
for arg in proc.arguments:
dimensions_attribute = [attr for attr in arg.attributes if attr.startswith('dimension')]
if arg.type.startswith('type') and len(dimensions_attribute) == 1:
# an argument should only have 0 or 1 "dimension" attributes
# If the argument is an 1D-array of types, convert it to super-type:
d = ArrayDimensionConverter.split_dimensions(dimensions_attribute[0])[0]
if str(d) == ':':
continue
# change the type to super-type
arg.type = arg.type[:-1] + '_x' + str(d) + '_array)'
# if the dimension is a parameter somewhere, add it to the uses clauses
param = extract_dimensions_parameters(d, tree)
if param:
proc.uses.add((param[0], (param[1],)))
# ... then remove the dimension, since we now use a scalar super-type ...
arg.attributes = [attr for attr in arg.attributes if not attr.startswith('dimension')]
# ... and brand it for the final call
arg.doc.append('super-type')
self.write_uses_lines(t, {t.name: ['%s_%s => %s' % (t.name, el.name, el.name)]})
else:
self.write_uses_lines(t)
self.write('implicit none')
if isinstance(t, ft.Type):
self.write_type_lines(t.name)
self.write('integer, intent(in) :: this(%d)' % sizeof_fortran_t)
self.write('type(%s_ptr_type) :: this_ptr' % t.name)
else:
self.write('integer, intent(in) :: dummy_this(%d)' % sizeof_fortran_t)
self.write('integer, intent(out) :: nd')
self.write('integer, intent(out) :: dtype')
try:
rank = len(ArrayDimensionConverter.split_dimensions(dims))
if el.type.startswith('character'):
rank += 1
except ValueError:
rank = 1
self.write('integer, dimension(10), intent(out) :: dshape')
self.write('integer*%d, intent(out) :: dloc' % np.dtype('O').itemsize)
self.write()
self.write('nd = %d' % rank)
self.write('dtype = %s' % ft.fortran_array_type(el.type, self.kind_map))
if isinstance(t, ft.Type):
self.write('this_ptr = transfer(this, this_ptr)')
array_name = 'this_ptr%%p%%%s' % el.orig_name
else:
array_name = '%s_%s' % (t.name, el.orig_name)
if 'allocatable' in el.attributes: