Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parsing Julia types from c++ types in yaml description #310

Merged
merged 24 commits into from
Jul 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
2facaf4
running pre-commit locally
soumilbaldota Jun 3, 2022
38824d8
removing trailing whitespace
soumilbaldota Jun 4, 2022
14636c6
replace brew with pip
soumilbaldota Jun 4, 2022
5d3b1c2
Fix a few smaller issues flagged by newer versions of clang-tidy (#299)
tmadlener Jun 13, 2022
b0b7c12
Pylint configuration fixes for newer versions of pylint (#300)
tmadlener Jun 13, 2022
99d0ece
changed readme file
Jun 13, 2022
20c8bf4
Make prepareForWrite thread safe and mark it as const (#295)
tmadlener Jun 14, 2022
d5a216e
Make sure vector member buffers point to the correct place even if a …
tmadlener Jun 14, 2022
b39a915
Default initialize array (#303)
tmadlener Jun 15, 2022
bbb07af
Fetch the Catch2 3.0.1 release now that it is available (#304)
tmadlener Jun 15, 2022
1a3b2ff
Release Notes for v00-14-02
tmadlener Jun 16, 2022
e327b6b
Updating version to v00-14-02
tmadlener Jun 16, 2022
fe94c1f
Add std::string deprecation warning and make sure warnings are printe…
tmadlener Jun 16, 2022
37a6520
Make SIO collection id writing independent of EventStore (#294)
tmadlener Jun 16, 2022
d540fbe
Add option to toggle the formatting via clang-format in the generator…
tmadlener Jun 21, 2022
f23dfa8
hotfix for https://github.com/AIDASoft/podio/issues/290 (#307)
vvolkl Jun 22, 2022
281b763
adding cpp type parsing functionality to generator_utils
soumilbaldota Jun 28, 2022
379aa21
Merge branch 'AIDASoft:master' into parsing_types
soumilbaldota Jun 28, 2022
c720f31
fixing problem whitespaces and removing jl loading from class generator
soumilbaldota Jun 28, 2022
d3e5fd3
update parse_julia_type to get_julia_type
soumilbaldota Jun 30, 2022
8bea575
small_Change
soumilbaldota Jun 30, 2022
904b9e3
fixing precommit-pylint
soumilbaldota Jun 30, 2022
77d3ed3
adding tests with minor changes to generator_utils
soumilbaldota Jun 30, 2022
7296122
fixing GlobalType test and updating generator_utils
soumilbaldota Jun 30, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions python/generator_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,33 @@ def _prefix_name(name, prefix):
return name


def get_julia_type(cpp_type=None, is_array=False, array_type=None, array_size=None):
"""Parse the given c++ type to a Julia type"""
builtin_types_map = {"int": "Int32", "float": "Float32", "double": "Float64",
"bool": "Bool", "long": "Int32", "unsigned int": "UInt32",
"unsigned long": "UInt32", "char": "Char", "short": "Int16",
"long long": "Int64", "unsigned long long": "UInt64"}
# is a global type as described in test_MemberParser.py #L121
if cpp_type and cpp_type.startswith("::"):
cpp_type = cpp_type[2:]
if cpp_type in builtin_types_map:
return builtin_types_map[cpp_type]

if not is_array:
if cpp_type.startswith('std::'):
cpp_type = cpp_type[5:]
if cpp_type in ALLOWED_FIXED_WIDTH_TYPES:
regex_string = re.split("(u|)int(8|16|32|64)_t", cpp_type)
cpp_type = regex_string[1].upper() + "Int" + regex_string[2]
return cpp_type

else:
array_type = get_julia_type(cpp_type=array_type)
return f"MVector{{{array_size}, {array_type}}}"

return cpp_type


class DefinitionError(Exception):
"""Exception raised by the ClassDefinitionValidator for invalid definitions.
Mainly here to distinguish it from plain exceptions that are otherwise raised.
Expand Down Expand Up @@ -95,6 +122,7 @@ def __init__(self, name, **kwargs):
self.is_array = False
# ensure that this will break somewhere if requested but not set
self.namespace, self.bare_type = None, None
self.julia_type = None
self.array_namespace, self.array_bare_type = None, None

self.array_type = kwargs.pop('array_type', None)
Expand Down Expand Up @@ -148,6 +176,9 @@ def __init__(self, name, **kwargs):
else:
self.namespace, self.bare_type = _get_namespace_class(self.full_type)

self.julia_type = get_julia_type(cpp_type=self.bare_type, is_array=self.is_array,
array_type=self.array_type, array_size=self.array_size)

def __str__(self):
"""string representation"""
# Make sure to include scope-operator if necessary
Expand Down
2 changes: 1 addition & 1 deletion python/podio_class_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def get_fn_format(tmpl):
endings = {
'Data': ('h',),
'Component': ('h',),
'PrintInfo': ('h',)
'PrintInfo': ('h',),
}.get(template_base, ('h', 'cc'))

fn_templates = []
Expand Down
20 changes: 20 additions & 0 deletions python/test_MemberParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,25 @@ def test_parse_valid(self): # pylint: disable=too-many-statements
self.assertEqual(parsed.full_type, r'float')
self.assertEqual(parsed.name, r'someFloat')
self.assertEqual(parsed.description, r'with an additional comment')
self.assertEqual(parsed.julia_type, r'Float32')

parsed = parser.parse(r'float float2 // with numbers')
self.assertEqual(parsed.full_type, r'float')
self.assertEqual(parsed.name, r'float2')
self.assertEqual(parsed.description, r'with numbers')
self.assertEqual(parsed.julia_type, r'Float32')

parsed = parser.parse(r' float spacefloat // whitespace everywhere ')
self.assertEqual(parsed.full_type, r'float')
self.assertEqual(parsed.name, r'spacefloat')
self.assertEqual(parsed.description, 'whitespace everywhere')
self.assertEqual(parsed.julia_type, r'Float32')

parsed = parser.parse(r'int snake_case // snake case')
self.assertEqual(parsed.full_type, r'int')
self.assertEqual(parsed.name, r'snake_case')
self.assertEqual(parsed.description, r'snake case')
self.assertEqual(parsed.julia_type, r'Int32')

parsed = parser.parse(r'std::string mixed_UglyCase_12 // who wants this')
self.assertEqual(parsed.full_type, r'std::string')
Expand All @@ -46,11 +50,13 @@ def test_parse_valid(self): # pylint: disable=too-many-statements
self.assertEqual(parsed.full_type, r'unsigned long long')
self.assertEqual(parsed.name, r'uVar')
self.assertEqual(parsed.description, r'an unsigned long variable')
self.assertEqual(parsed.julia_type, r'UInt64')

parsed = parser.parse(r'unsigned int uInt // an unsigned integer')
self.assertEqual(parsed.full_type, r'unsigned int')
self.assertEqual(parsed.name, r'uInt')
self.assertEqual(parsed.description, r'an unsigned integer')
self.assertEqual(parsed.julia_type, r'UInt32')

# Fixed width integers in their various forms that they can be spelled out
# and be considered valid in our case
Expand All @@ -59,24 +65,28 @@ def test_parse_valid(self): # pylint: disable=too-many-statements
self.assertEqual(parsed.name, r'qualified')
self.assertEqual(parsed.description, r'qualified fixed width ints work')
self.assertTrue(parsed.is_builtin)
self.assertEqual(parsed.julia_type, r'Int16')

parsed = parser.parse(r'std::uint64_t bits // fixed width integer types should work')
self.assertEqual(parsed.full_type, r'std::uint64_t')
self.assertEqual(parsed.name, r'bits')
self.assertEqual(parsed.description, r'fixed width integer types should work')
self.assertTrue(parsed.is_builtin)
self.assertEqual(parsed.julia_type, r'UInt64')

parsed = parser.parse(r'int32_t fixedInt // fixed width signed integer should work')
self.assertEqual(parsed.full_type, r'std::int32_t')
self.assertEqual(parsed.name, r'fixedInt')
self.assertEqual(parsed.description, r'fixed width signed integer should work')
self.assertTrue(parsed.is_builtin)
self.assertEqual(parsed.julia_type, r'Int32')

parsed = parser.parse(r'uint16_t fixedUInt // fixed width unsigned int with 16 bits')
self.assertEqual(parsed.full_type, r'std::uint16_t')
self.assertEqual(parsed.name, r'fixedUInt')
self.assertEqual(parsed.description, r'fixed width unsigned int with 16 bits')
self.assertTrue(parsed.is_builtin)
self.assertEqual(parsed.julia_type, r'UInt16')

# an array definition with space everywhere it is allowed
parsed = parser.parse(r' std::array < double , 4 > someArray // a comment ')
Expand All @@ -87,38 +97,44 @@ def test_parse_valid(self): # pylint: disable=too-many-statements
self.assertTrue(parsed.is_builtin_array)
self.assertEqual(int(parsed.array_size), 4)
self.assertEqual(parsed.array_type, r'double')
self.assertEqual(parsed.julia_type, r'MVector{4, Float64}')

# an array definition as terse as possible
parsed = parser.parse(r'std::array<int,2>anArray//with a comment')
self.assertEqual(parsed.full_type, r'std::array<int, 2>')
self.assertEqual(parsed.name, r'anArray')
self.assertEqual(parsed.description, r'with a comment')
self.assertEqual(parsed.julia_type, r'MVector{2, Int32}')

parsed = parser.parse('::TopLevelNamespaceType aValidType // hopefully')
self.assertEqual(parsed.full_type, '::TopLevelNamespaceType')
self.assertEqual(parsed.name, r'aValidType')
self.assertEqual(parsed.description, 'hopefully')
self.assertEqual(parsed.julia_type, r'TopLevelNamespaceType')

parsed = parser.parse(r'std::array<::GlobalType, 1> anArray // with a top level type')
self.assertEqual(parsed.full_type, r'std::array<::GlobalType, 1>')
self.assertEqual(parsed.name, r'anArray')
self.assertEqual(parsed.description, r'with a top level type')
self.assertTrue(not parsed.is_builtin_array)
self.assertEqual(parsed.array_type, r'::GlobalType')
self.assertEqual(parsed.julia_type, r'MVector{1, GlobalType}')

parsed = parser.parse(r'std::array<std::int16_t, 42> fixedWidthArray // a fixed width type array')
self.assertEqual(parsed.full_type, r'std::array<std::int16_t, 42>')
self.assertEqual(parsed.name, r'fixedWidthArray')
self.assertEqual(parsed.description, r'a fixed width type array')
self.assertTrue(parsed.is_builtin_array)
self.assertEqual(parsed.array_type, r'std::int16_t')
self.assertEqual(parsed.julia_type, r'MVector{42, Int16}')

parsed = parser.parse(r'std::array<uint32_t, 42> fixedWidthArray // a fixed width type array without namespace')
self.assertEqual(parsed.full_type, r'std::array<std::uint32_t, 42>')
self.assertEqual(parsed.name, r'fixedWidthArray')
self.assertEqual(parsed.description, r'a fixed width type array without namespace')
self.assertTrue(parsed.is_builtin_array)
self.assertEqual(parsed.array_type, r'std::uint32_t')
self.assertEqual(parsed.julia_type, r'MVector{42, UInt32}')

def test_parse_invalid(self):
"""Test that invalid member variable definitions indeed fail during parsing"""
Expand Down Expand Up @@ -161,22 +177,26 @@ def test_parse_valid_no_description(self):
parsed = parser.parse('unsigned long long aLongWithoutDescription', False)
self.assertEqual(parsed.full_type, 'unsigned long long')
self.assertEqual(parsed.name, 'aLongWithoutDescription')
self.assertEqual(parsed.julia_type, r'UInt64')

parsed = parser.parse('std::array<unsigned long, 123> unDescribedArray', False)
self.assertEqual(parsed.full_type, 'std::array<unsigned long, 123>')
self.assertEqual(parsed.name, 'unDescribedArray')
self.assertEqual(parsed.array_type, 'unsigned long')
self.assertTrue(parsed.is_builtin_array)
self.assertEqual(parsed.julia_type, r'MVector{123, UInt32}')

parsed = parser.parse('unsigned long longWithReallyStupidName', False)
self.assertEqual(parsed.full_type, 'unsigned long')
self.assertEqual(parsed.name, 'longWithReallyStupidName')
self.assertEqual(parsed.julia_type, r'UInt32')

parsed = parser.parse('NonBuiltIn aType // descriptions are not ignored even though they are not required', False)
self.assertEqual(parsed.full_type, 'NonBuiltIn')
self.assertEqual(parsed.name, 'aType')
self.assertEqual(parsed.description, 'descriptions are not ignored even though they are not required')
self.assertTrue(not parsed.is_builtin)
self.assertEqual(parsed.julia_type, r'NonBuiltIn')

def test_string_representation(self):
"""Test that the string representation that is used in the jinja2 templates
Expand Down