Skip to content

Commit

Permalink
Resolved Main Scope issue
Browse files Browse the repository at this point in the history
  • Loading branch information
Ananya2003Gupta committed Aug 25, 2023
1 parent d6c6e86 commit ca88691
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 85 deletions.
2 changes: 1 addition & 1 deletion python/podio/generator_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def get_julia_type(cpp_type=None, is_array=False, array_type=None, array_size=No
if '::' in array_type:
array_type = array_type.split('::')[1]
if array_type not in builtin_types_map.values():
array_type = 'Main.' + array_type + 'Struct'
array_type = array_type + 'Struct'
return f"MVector{{{array_size}, {array_type}}}"

return cpp_type
Expand Down
79 changes: 22 additions & 57 deletions python/podio_class_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,44 +113,23 @@ def __init__(self, yamlfile, install_dir, package_name, io_handlers, verbose, dr
self.generated_files = []
self.any_changes = False

def _get_namespace_dict(self):
"""generate the dictionary of parent namespaces"""
namespace = {}
for component_name in self.datamodel.components.keys():
component = DataType(component_name)
parent_namespace, child = component.namespace, component.bare_type
if parent_namespace not in namespace:
namespace[parent_namespace] = {'Components': [], 'Datatypes': [], 'Collections': []}
namespace[parent_namespace]['Components'].append(child)

for datatype_name in self.datamodel.datatypes.keys():
datatype = DataType(datatype_name)
parent_namespace, child = datatype.namespace, datatype.bare_type
if parent_namespace not in namespace:
namespace[parent_namespace] = {'Components': [], 'Datatypes': [], 'Collections': []}
namespace[parent_namespace]['Datatypes'].append(child)
namespace[parent_namespace]['Collections'].append(child + 'Collection')

namespace_dict = {}
namespace_dict['class'] = DataType(self.package_name.capitalize())
namespace_dict['children'] = []
for parent, child in namespace.items():
if parent != "":
namespace_dict['children'].append({'parent': parent, 'child': child})
else:
namespace_dict['children'].append({'parent': self.package_name, 'child': child})
self._fill_templates("ParentModule", namespace_dict)
def _process_parent_module(self, datamodel):
self._fill_templates("ParentModule", datamodel)

def process(self):
"""Run the actual generation"""
datamodel = {}
datamodel['class'] = DataType(self.package_name.capitalize())
datamodel['components'] = []
datamodel['datatypes'] = []
for name, component in self.datamodel.components.items():
self._process_component(name, component)
datamodel['components'].append(self._process_component(name, component))

for name, datatype in self.datamodel.datatypes.items():
self._process_datatype(name, datatype)
datamodel['datatypes'].append(self._process_datatype(name, datatype))

self._write_edm_def_file()
self._get_namespace_dict()
self._process_parent_module(datamodel)

if 'ROOT' in self.io_handlers:
self._create_selection_xml()
Expand Down Expand Up @@ -233,8 +212,7 @@ def get_fn_format(tmpl):
'SIOBlock': 'SIOBlock',
'Collection': 'Collection',
'CollectionData': 'CollectionData',
'MutableStruct': 'Struct',
'JuliaCollection': 'Collection'
'MutableStruct': 'Struct'
}

return f'{prefix.get(tmpl, "")}{{name}}{postfix.get(tmpl, "")}.{{end}}'
Expand All @@ -244,8 +222,6 @@ def get_fn_format(tmpl):
'Component': ('h',),
'PrintInfo': ('h',),
'MutableStruct': ('jl',),
'Constructor': ('jl',),
'JuliaCollection': ('jl',),
'ParentModule': ('jl',),
}.get(template_base, ('h', 'cc'))

Expand Down Expand Up @@ -283,12 +259,12 @@ def _process_component(self, name, component):
includes.update(component.get("ExtraCode", {}).get("includes", "").split('\n'))

component['includes'] = self._sort_includes(includes)
component['includes_jl'] = {'struct': includes_jl, 'constructor': includes_jl}
component['includes_jl'] = {'struct': includes_jl}
component['class'] = DataType(name)

self._fill_templates('Component', component)
self._fill_templates('MutableStruct', component)
self._fill_templates('Constructor', component)
return component

def _process_datatype(self, name, definition):
"""Process one datatype"""
Expand All @@ -300,26 +276,18 @@ def _process_datatype(self, name, definition):
self._fill_templates('Collection', datatype)
self._fill_templates('CollectionData', datatype)
self._fill_templates('MutableStruct', datatype)
self._fill_templates('Constructor', datatype)
self._fill_templates('JuliaCollection', datatype)

if 'SIO' in self.io_handlers:
self._fill_templates('SIOBlock', datatype)

return datatype

def _preprocess_for_julia(self, datatype):
"""Do the preprocessing that is necessary for Julia code generation"""
includes_jl, includes_jl_struct = set(), set()
for relation in datatype['OneToManyRelations'] + datatype['OneToOneRelations']:
includes_jl.add(self._build_julia_include(relation, is_struct=True))
includes_jl_struct = set()
for member in datatype['VectorMembers']:
if not member.is_builtin:
includes_jl_struct.add(self._build_julia_include(member, is_struct=True))
includes_jl.add(self._build_julia_include(member))
try:
includes_jl.remove(self._build_julia_include(datatype['class'], is_struct=True))
except KeyError:
pass
datatype['includes_jl']['constructor'].update((includes_jl))
includes_jl_struct.add(self._build_julia_include(member))
datatype['includes_jl']['struct'].update((includes_jl_struct))

@staticmethod
Expand Down Expand Up @@ -462,8 +430,7 @@ def _preprocess_datatype(self, name, definition):
data = deepcopy(definition)
data['class'] = DataType(name)
data['includes_data'] = self._get_member_includes(definition["Members"])
data['includes_jl'] = {'constructor': self._get_member_includes(definition["Members"], julia=True),
'struct': self._get_member_includes(definition["Members"], julia=True)}
data['includes_jl'] = {'struct': self._get_member_includes(definition["Members"], julia=True)}
data['params_jl'] = self._get_julia_params(data)
self._preprocess_for_class(data)
self._preprocess_for_obj(data)
Expand Down Expand Up @@ -580,11 +547,11 @@ def _build_include_for_class(self, classname, include_from: IncludeFrom) -> str:
# the generated code)
return ''

def _build_julia_include(self, member, is_struct=False) -> str:
def _build_julia_include(self, member) -> str:
"""Return the include statement for julia"""
return self._build_julia_include_for_class(member.bare_type, self._needs_include(member.full_type), is_struct)
return self._build_julia_include_for_class(member.bare_type, self._needs_include(member.full_type))

def _build_julia_include_for_class(self, classname, include_from: IncludeFrom, is_struct=False) -> str:
def _build_julia_include_for_class(self, classname, include_from: IncludeFrom) -> str:
"""Return the include statement for julia for this specific class"""
if include_from == IncludeFrom.INTERNAL:
# If we have an internal include all includes should be relative
Expand All @@ -594,10 +561,8 @@ def _build_julia_include_for_class(self, classname, include_from: IncludeFrom, i
if include_from == IncludeFrom.NOWHERE:
# We don't need an include in this case
return ''

if is_struct:
return f'include("{inc_folder}{classname}Struct.jl")'
return f'include("{inc_folder}{classname}.jl")\nusing .{classname}Module: {classname}'

return f'include("{inc_folder}{classname}Struct.jl")'

def _sort_includes(self, includes):
"""Sort the includes in order to try to have the std includes at the bottom"""
Expand Down
4 changes: 2 additions & 2 deletions python/templates/MutableStruct.jl.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ mutable struct {{ class.bare_type }}Struct{{ params.julia_parameters(params_jl,"
{% if member.is_array or member.is_builtin %}
{{ member.name }}::{{ member.julia_type }}
{% else %}
{{ member.name }}::Main.{{ member.julia_type }}Struct
{{ member.name }}::{{ member.julia_type }}Struct
{% endif %}
{% endfor %}
{% for relation in OneToManyRelations %}
Expand All @@ -20,7 +20,7 @@ mutable struct {{ class.bare_type }}Struct{{ params.julia_parameters(params_jl,"
{% if member.is_builtin %}
{{ member.name }}::Vector{ {{ member.julia_type }} }
{% else %}
{{ member.name }}::Vector{ Main.{{ member.julia_type }}Struct }
{{ member.name }}::Vector{ {{ member.julia_type }}Struct }
{% endif %}
{% endfor %}
end
106 changes: 98 additions & 8 deletions python/templates/ParentModule.jl.jinja2
Original file line number Diff line number Diff line change
@@ -1,15 +1,105 @@
{% for value in children %}
{% for childvalue in value['child']['Components'] + value['child']['Datatypes'] + value['child']['Collections'] %}
include("{{ childvalue }}.jl")
{% import "macros/params.jinja2" as params %}
module {{ class.bare_type }}
{% for component in components %}
export {{ component['class'].bare_type }}
{% endfor %}
{% for datatype in datatypes %}
export {{ datatype['class'].bare_type }}
export {{ datatype['class'].bare_type }}Collection
{% endfor %}

{% for value in children %}
module {{ value['parent']|capitalize }}
{% for childvalue in value['child']['Components'] + value['child']['Datatypes'] %}
using ..{{childvalue}}Module: {{childvalue}}
export {{childvalue}}
{% for component in components %}
include("{{ component['class'].bare_type }}Struct.jl")
{% endfor %}
{% for datatype in datatypes %}
include("{{ datatype['class'].bare_type }}Struct.jl")
{% endfor %}

{% for component in components %}
function {{ component['class'].bare_type }}(
{% for member in component['Members'] %}
{% if member.is_array %}
{{ member.name }}::{{ member.julia_type }} = {{ member.julia_type }}(undef),
{% elif member.is_builtin %}
{{ member.name }}::{{ member.julia_type }} = {{ member.julia_type }}(0),
{% else %}
{{ member.name }}::{{ member.julia_type }}Struct = {{ member.julia_type }}(),
{% endif %}
{% endfor %}
{% for relation in component['OneToManyRelations'] %}
{{ relation.name }}::Vector{ {{ relation.julia_type }}Struct } = Vector{ {{ relation.julia_type }}Struct }(),
{% endfor %}
{% for relation in component['OneToOneRelations'] %}
{{ relation.name }}::Union{Nothing, {{ relation.julia_type }}Struct } = nothing,
{% endfor %}
{% for member in component['VectorMembers'] %}
{% if member.is_builtin %}
{{ member.name }}::Vector{ {{ member.julia_type }} } = Vector{ {{ member.julia_type }} }([]),
{% else %}
{{ member.name }}::Vector{ {{ member.julia_type }}Struct } = Vector{ {{ member.julia_type }}Struct }([]),
{% endif %}
{% endfor %}
)
return {{ component['class'].bare_type }}Struct{{ params.julia_parameters(component['params_jl'], "", "Struct") }}(
{% for member in component['Members'] %}
{{ member.name }},
{% endfor %}
{% for relation in component['OneToManyRelations'] %}
{{ relation.name }},
{% endfor %}
{% for relation in component['OneToOneRelations'] %}
{{ relation.name }},
{% endfor %}
{% for member in component['VectorMembers'] %}
{{ member.name }},
{% endfor %}
)
end

{% endfor %}

{% for datatype in datatypes %}
function {{ datatype['class'].bare_type }}(
{% for member in datatype['Members'] %}
{% if member.is_array %}
{{ member.name }}::{{ member.julia_type }} = {{ member.julia_type }}(undef),
{% elif member.is_builtin %}
{{ member.name }}::{{ member.julia_type }} = {{ member.julia_type }}(0),
{% else %}
{{ member.name }}::{{ member.julia_type }}Struct = {{ member.julia_type }}(),
{% endif %}
{% endfor %}
{% for relation in datatype['OneToManyRelations'] %}
{{ relation.name }}::Vector{ {{ relation.julia_type }}Struct } = Vector{ {{ relation.julia_type }}Struct }(),
{% endfor %}
{% for relation in datatype['OneToOneRelations'] %}
{{ relation.name }}::Union{Nothing, {{ relation.julia_type }}Struct } = nothing,
{% endfor %}
{% for member in datatype['VectorMembers'] %}
{% if member.is_builtin %}
{{ member.name }}::Vector{ {{ member.julia_type }} } = Vector{ {{ member.julia_type }} }([]),
{% else %}
{{ member.name }}::Vector{ {{ member.julia_type }}Struct } = Vector{ {{ member.julia_type }}Struct }([]),
{% endif %}
{% endfor %}
)
return {{ datatype['class'].bare_type }}Struct{{ params.julia_parameters(datatype['params_jl'], "", "Struct") }}(
{% for member in datatype['Members'] %}
{{ member.name }},
{% endfor %}
{% for relation in datatype['OneToManyRelations'] %}
{{ relation.name }},
{% endfor %}
{% for relation in datatype['OneToOneRelations'] %}
{{ relation.name }},
{% endfor %}
{% for member in datatype['VectorMembers'] %}
{{ member.name }},
{% endfor %}
)
end

{{ datatype['class'].bare_type }}Collection = Vector{ {{ datatype['class'].bare_type }}Struct{{ params.julia_parameters(datatype['params_jl'], prefix="", suffix="Struct") }} }

{% endfor %}
end
19 changes: 2 additions & 17 deletions tests/unittest.jl
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
include("datamodel/ExampleWithVectorMember.jl")
using .ExampleWithVectorMemberModule: ExampleWithVectorMember
include("datamodel/ExampleForCyclicDependency1.jl")
using .ExampleForCyclicDependency1Module: ExampleForCyclicDependency1
include("datamodel/ExampleForCyclicDependency2.jl")
using .ExampleForCyclicDependency2Module: ExampleForCyclicDependency2
include("datamodel/ExampleWithOneRelation.jl")
using .ExampleWithOneRelationModule: ExampleWithOneRelation
include("datamodel/ExampleCluster.jl")
using .ExampleClusterModule: ExampleCluster
include("datamodel/ExampleMCCollection.jl")
include("datamodel/Datamodel.jl")

using .Datamodel
using Test
@testset "Julia Bindings" begin
@testset "Relations" begin
Expand Down Expand Up @@ -103,17 +92,13 @@ using Test

@testset "Namespaces" begin

using .Ex2: NamespaceStruct, NamespaceInNamespaceStruct

s1 = NamespaceStruct()
s1.x = Int32(1)
s1.y = Int32(2)

s2 = NamespaceInNamespaceStruct()
s2.data = s1

using .Ex42: ExampleWithNamespace, ExampleWithARelation

s3 = NamespaceStruct()
s3.x = Int32(2)
s3.y = Int32(3)
Expand All @@ -137,4 +122,4 @@ using Test
@test ex3.ref.component.x == Int32(2)
@test ex3.ref.component.y == Int32(3)
end
end;
end;

0 comments on commit ca88691

Please sign in to comment.