From ca88691e2474903412b54ef9195a73c0bf3d2c1f Mon Sep 17 00:00:00 2001 From: Ananya2003Gupta Date: Fri, 25 Aug 2023 13:32:39 +0530 Subject: [PATCH] Resolved Main Scope issue --- python/podio/generator_utils.py | 2 +- python/podio_class_generator.py | 79 +++++------------ python/templates/MutableStruct.jl.jinja2 | 4 +- python/templates/ParentModule.jl.jinja2 | 106 +++++++++++++++++++++-- tests/unittest.jl | 19 +--- 5 files changed, 125 insertions(+), 85 deletions(-) diff --git a/python/podio/generator_utils.py b/python/podio/generator_utils.py index 4f0606e7a..b7277c038 100644 --- a/python/podio/generator_utils.py +++ b/python/podio/generator_utils.py @@ -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 diff --git a/python/podio_class_generator.py b/python/podio_class_generator.py index 3764b0249..2ba251a9a 100755 --- a/python/podio_class_generator.py +++ b/python/podio_class_generator.py @@ -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() @@ -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}}' @@ -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')) @@ -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""" @@ -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 @@ -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) @@ -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 @@ -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""" diff --git a/python/templates/MutableStruct.jl.jinja2 b/python/templates/MutableStruct.jl.jinja2 index f9f8dd55b..8ddc13cb2 100644 --- a/python/templates/MutableStruct.jl.jinja2 +++ b/python/templates/MutableStruct.jl.jinja2 @@ -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 %} @@ -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 diff --git a/python/templates/ParentModule.jl.jinja2 b/python/templates/ParentModule.jl.jinja2 index 902524b9c..232a928e5 100644 --- a/python/templates/ParentModule.jl.jinja2 +++ b/python/templates/ParentModule.jl.jinja2 @@ -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 \ No newline at end of file diff --git a/tests/unittest.jl b/tests/unittest.jl index 31acf4337..40f14ad76 100644 --- a/tests/unittest.jl +++ b/tests/unittest.jl @@ -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 @@ -103,8 +92,6 @@ using Test @testset "Namespaces" begin - using .Ex2: NamespaceStruct, NamespaceInNamespaceStruct - s1 = NamespaceStruct() s1.x = Int32(1) s1.y = Int32(2) @@ -112,8 +99,6 @@ using Test s2 = NamespaceInNamespaceStruct() s2.data = s1 - using .Ex42: ExampleWithNamespace, ExampleWithARelation - s3 = NamespaceStruct() s3.x = Int32(2) s3.y = Int32(3) @@ -137,4 +122,4 @@ using Test @test ex3.ref.component.x == Int32(2) @test ex3.ref.component.y == Int32(3) end -end; +end; \ No newline at end of file