Skip to content

Commit

Permalink
Improve parent finding in aggregation list preparation
Browse files Browse the repository at this point in the history
  • Loading branch information
thibault authored and thibault committed Dec 1, 2024
1 parent 0f72d6e commit 793e219
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 24 deletions.
6 changes: 3 additions & 3 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@
# built documents.
#
# The short X.Y version.
version = u'v' + u'0.8.5'
version = u'v' + u'0.8.6'
# The full version, including alpha/beta/rc tags.
release = u'v' + u'0.8.5'
release = u'v' + u'0.8.6'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down Expand Up @@ -155,7 +155,7 @@
# The name for this set of Sphinx documents.
# "<project> v<release> documentation" by default.
#
# html_title = u'hpp2plantuml ' + u'v' + u'0.8.5'
# html_title = u'hpp2plantuml ' + u'v' + u'0.8.6'

# A shorter title for the navigation bar. Default is the same as html_title.
#
Expand Down
64 changes: 54 additions & 10 deletions doc/source/org-doc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The current version of the code is:
::
:name: hpp2plantuml-version

0.8.5
0.8.6


The source code can be found on GitHub:
Expand Down Expand Up @@ -1541,17 +1541,24 @@ be used to avoid this sorting step.
parent = parent_s[-1]
obj_ns_list = obj_ns_list_base + parent_s[:-1]
parent_obj = None
found = False
pi = 0
while not found and pi <= len(obj_ns_list):
while pi <= len(obj_ns_list):
ns_list_trunc = -pi if pi > 0 else None
obj_ns_c = obj_ns_list[:ns_list_trunc]
obj_match_list = []
for c, c_n, c_ns in zip(class_list_obj, class_list,
class_list_ns):
obj_other_ns = c_ns.split('::')[:-1]
if obj_ns_c == obj_other_ns and (f_cmp(parent, c_n) or
f_cmp(parent, c_ns)):
return c['obj']
obj_match_list.append([c, c_n, c_ns])
if len(obj_match_list) == 1:
return obj_match_list[0][0]['obj']
elif len(obj_match_list) > 1:
obj_match_list = sorted(obj_match_list, key=lambda x:
re.search(r'\b{}\b'.format(x[1]),
parent).span()[0])
return obj_match_list[0][0]['obj']
pi += 1
return None
Expand Down Expand Up @@ -1618,7 +1625,7 @@ be used to avoid this sorting step.
if s != '']
p_cl_plist = [s for s in var_obj.name.split('::')
if s != '']
if '{}*'.format(var_obj.name) in var_in:
if is_ptr(var_obj.name, var_in):
rel_type = 'aggregation'
else:
rel_type = 'composition'
Expand Down Expand Up @@ -1951,6 +1958,41 @@ block.
return ''
return '.'.join(namespace.split('::'))
Pointer type check
^^^^^^^^^^^^^^^^^^

.. code:: python
:name: py-help-pointer-type
def is_ptr(obj_name, obj):
"""Determine if object type represents a pointer
Parameters
----------
obj_name : str
Object base name
obj : str
Full type
Returns
-------
bool
True if ``obj`` is determined to represent a point to an object of type
``obj_name``
Examples
--------
>>> is_ptr('Object', 'Object*')
True
>>> is_ptr('Object', 'unique_ptr<Object>')
True
>>> is_ptr('Object', 'unique_ptr<AnotherObject>')
False
"""
return ('{}*'.format(obj_name) in obj or
any('{}_ptr<{}>'.format(ptr_type, obj_name) in obj
for ptr_type in ['unique', 'shared', 'weak']))
.. _sec-module-create-uml:

Main function: create PlantUML from C++
Expand Down Expand Up @@ -2109,7 +2151,7 @@ to parse input arguments. The function passes the command line arguments to the
required=False, default=None, metavar='JINJA-FILE',
help='path to jinja2 template file')
parser.add_argument('--version', action='version',
version='%(prog)s ' + '0.8.5')
version='%(prog)s ' + '0.8.6')
args = parser.parse_args()
if len(args.input_files) > 0:
CreatePlantUMLFile(args.input_files, args.output_file,
Expand Down Expand Up @@ -3430,7 +3472,7 @@ obtained using the source block described `sec-org-el-version`_.
__title__ = "hpp2plantuml"
__description__ = "Convert C++ header files to PlantUML"
__version__ = '0.8.5'
__version__ = '0.8.6'
__uri__ = "https://github.com/thibaultmarin/hpp2plantuml"
__doc__ = __description__ + " <" + __uri__ + ">"
__author__ = "Thibault Marin"
Expand Down Expand Up @@ -3941,9 +3983,9 @@ content of the file is mostly following the defaults, with a few exceptions:
# built documents.
#
# The short X.Y version.
version = u'v' + u'0.8.5'
version = u'v' + u'0.8.6'
# The full version, including alpha/beta/rc tags.
release = u'v' + u'0.8.5'
release = u'v' + u'0.8.6'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down Expand Up @@ -4017,7 +4059,7 @@ content of the file is mostly following the defaults, with a few exceptions:
# The name for this set of Sphinx documents.
# "<project> v<release> documentation" by default.
#
# html_title = u'hpp2plantuml ' + u'v' + u'0.8.5'
# html_title = u'hpp2plantuml ' + u'v' + u'0.8.6'
# A shorter title for the navigation bar. Default is the same as html_title.
#
Expand Down Expand Up @@ -4400,6 +4442,8 @@ file is added for the ``numpydoc`` package.

python:
install:
- method: pip
path: .
- requirements: doc/source/readthedocs-requirements.txt

Org-mode setup
Expand Down
52 changes: 47 additions & 5 deletions hpp2plantuml.org
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ this single org-file.

The current version of the code is:
#+NAME: hpp2plantuml-version
: 0.8.5
: 0.8.6

The source code can be found on GitHub:
https://github.com/thibaultmarin/hpp2plantuml.
Expand Down Expand Up @@ -1518,17 +1518,24 @@ class Diagram(object):
parent = parent_s[-1]
obj_ns_list = obj_ns_list_base + parent_s[:-1]
parent_obj = None
found = False
pi = 0
while not found and pi <= len(obj_ns_list):
while pi <= len(obj_ns_list):
ns_list_trunc = -pi if pi > 0 else None
obj_ns_c = obj_ns_list[:ns_list_trunc]
obj_match_list = []
for c, c_n, c_ns in zip(class_list_obj, class_list,
class_list_ns):
obj_other_ns = c_ns.split('::')[:-1]
if obj_ns_c == obj_other_ns and (f_cmp(parent, c_n) or
f_cmp(parent, c_ns)):
return c['obj']
obj_match_list.append([c, c_n, c_ns])
if len(obj_match_list) == 1:
return obj_match_list[0][0]['obj']
elif len(obj_match_list) > 1:
obj_match_list = sorted(obj_match_list, key=lambda x:
re.search(r'\b{}\b'.format(x[1]),
parent).span()[0])
return obj_match_list[0][0]['obj']
pi += 1
return None

Expand Down Expand Up @@ -1595,7 +1602,7 @@ class Diagram(object):
if s != '']
p_cl_plist = [s for s in var_obj.name.split('::')
if s != '']
if '{}*'.format(var_obj.name) in var_in:
if is_ptr(var_obj.name, var_in):
rel_type = 'aggregation'
else:
rel_type = 'composition'
Expand Down Expand Up @@ -1928,6 +1935,41 @@ def get_namespace_link_name(namespace):
#+END_SRC


*** Pointer type check

#+NAME: py-help-pointer-type
#+BEGIN_SRC python
def is_ptr(obj_name, obj):
"""Determine if object type represents a pointer

Parameters
----------
obj_name : str
Object base name
obj : str
Full type

Returns
-------
bool
True if ``obj`` is determined to represent a point to an object of type
``obj_name``

Examples
--------
>>> is_ptr('Object', 'Object*')
True
>>> is_ptr('Object', 'unique_ptr<Object>')
True
>>> is_ptr('Object', 'unique_ptr<AnotherObject>')
False
"""
return ('{}*'.format(obj_name) in obj or
any('{}_ptr<{}>'.format(ptr_type, obj_name) in obj
for ptr_type in ['unique', 'shared', 'weak']))
#+END_SRC


** DONE Main function: create PlantUML from C++
:PROPERTIES:
:CUSTOM_ID: sec-module-create-uml
Expand Down
2 changes: 1 addition & 1 deletion src/hpp2plantuml/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@

__title__ = "hpp2plantuml"
__description__ = "Convert C++ header files to PlantUML"
__version__ = '0.8.5'
__version__ = '0.8.6'
__uri__ = "https://github.com/thibaultmarin/hpp2plantuml"
__doc__ = __description__ + " <" + __uri__ + ">"
__author__ = "Thibault Marin"
Expand Down
46 changes: 41 additions & 5 deletions src/hpp2plantuml/hpp2plantuml.py
Original file line number Diff line number Diff line change
Expand Up @@ -1118,17 +1118,24 @@ def find_parent(self, parent_in, obj_ns_list_base, f_cmp=None):
parent = parent_s[-1]
obj_ns_list = obj_ns_list_base + parent_s[:-1]
parent_obj = None
found = False
pi = 0
while not found and pi <= len(obj_ns_list):
while pi <= len(obj_ns_list):
ns_list_trunc = -pi if pi > 0 else None
obj_ns_c = obj_ns_list[:ns_list_trunc]
obj_match_list = []
for c, c_n, c_ns in zip(class_list_obj, class_list,
class_list_ns):
obj_other_ns = c_ns.split('::')[:-1]
if obj_ns_c == obj_other_ns and (f_cmp(parent, c_n) or
f_cmp(parent, c_ns)):
return c['obj']
obj_match_list.append([c, c_n, c_ns])
if len(obj_match_list) == 1:
return obj_match_list[0][0]['obj']
elif len(obj_match_list) > 1:
obj_match_list = sorted(obj_match_list, key=lambda x:
re.search(r'\b{}\b'.format(x[1]),
parent).span()[0])
return obj_match_list[0][0]['obj']
pi += 1
return None

Expand Down Expand Up @@ -1195,7 +1202,7 @@ def build_aggregation_list(self):
if s != '']
p_cl_plist = [s for s in var_obj.name.split('::')
if s != '']
if '{}*'.format(var_obj.name) in var_in:
if is_ptr(var_obj.name, var_in):
rel_type = 'aggregation'
else:
rel_type = 'composition'
Expand Down Expand Up @@ -1488,6 +1495,35 @@ def get_namespace_link_name(namespace):
return ''
return '.'.join(namespace.split('::'))

def is_ptr(obj_name, obj):
"""Determine if object type represents a pointer
Parameters
----------
obj_name : str
Object base name
obj : str
Full type
Returns
-------
bool
True if ``obj`` is determined to represent a point to an object of type
``obj_name``
Examples
--------
>>> is_ptr('Object', 'Object*')
True
>>> is_ptr('Object', 'unique_ptr<Object>')
True
>>> is_ptr('Object', 'unique_ptr<AnotherObject>')
False
"""
return ('{}*'.format(obj_name) in obj or
any('{}_ptr<{}>'.format(ptr_type, obj_name) in obj
for ptr_type in ['unique', 'shared', 'weak']))

# %% Main function


Expand Down Expand Up @@ -1548,7 +1584,7 @@ def main():
required=False, default=None, metavar='JINJA-FILE',
help='path to jinja2 template file')
parser.add_argument('--version', action='version',
version='%(prog)s ' + '0.8.5')
version='%(prog)s ' + '0.8.6')
args = parser.parse_args()
if len(args.input_files) > 0:
CreatePlantUMLFile(args.input_files, args.output_file,
Expand Down

0 comments on commit 793e219

Please sign in to comment.