Skip to content

Commit

Permalink
Add support for generating Doxygen comments for the enum definitions
Browse files Browse the repository at this point in the history
  • Loading branch information
jasujm committed Jan 9, 2020
1 parent ddccfd4 commit 784e2ca
Show file tree
Hide file tree
Showing 17 changed files with 80 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Added
- Add :cpp:func:`enhanced_enum::enum_base::ssize()`
- Add :cpp:func:`enhanced_enum::enum_base::begin()` and
:cpp:func:`enhanced_enum::enum_base::end()`
- Add support for generating Doxygen comments

Changed:
- Implement :cpp:func:`enhanced_enum::enum_base::all()` in terms
Expand Down
2 changes: 1 addition & 1 deletion cxx/tests/generate_status_hh.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
def main(filename):
status_definitions = generate(STATUS_DEFINITION_DICT)
nested_enum_definitions = generate(
NESTED_ENUM_DEFINITION_DICT, primary_type="enhanced"
NESTED_ENUM_DEFINITION_DICT, primary_type="enhanced", documentation="doxygen",
)
status_hh = _STATUS_HH_TEMPLATE.render(
status_definitions=status_definitions,
Expand Down
13 changes: 13 additions & 0 deletions docs/enumecglib.rst
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,19 @@ applied when creating the enum definition.

.. _enumecg-high-level-api:

Including comments in the generator output
..........................................

Doxygen comments can be included by using the ``documentation``
option:

.. doctest::

>>> enumecg.generate(Status, documentation="doxygen")
'/** \\brief ...'

Currently "doxygen" is the only supported documentation style.

High level API
--------------

Expand Down
2 changes: 1 addition & 1 deletion python/enumecg/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,4 @@ def generate(enum, **options) -> str:
Returns:
The enhanced enum definition created from the ``enum`` description.
"""
return str(generator(enum, **options).generate_enum_definitions())
return str(generator(enum, **options).generate_enum_definitions(**options))
13 changes: 11 additions & 2 deletions python/enumecg/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class CodeGenerator:
"""

_JINJA_ENV = _create_jinja_env()
_DOCUMENTATION_CHOICES = {"doxygen"}

def __init__(self, enum_definition: "definitions.EnumDefinition"):
"""
Expand All @@ -53,10 +54,18 @@ def __init__(self, enum_definition: "definitions.EnumDefinition"):
"enum_definitions.hh.in"
)

def generate_enum_definitions(self):
def generate_enum_definitions(self, **options):
"""Generate the C++ definitions needed for an enhanced enum
Parameters:
options: The code generation options
Returns:
The generated code
"""
return self._enum_definitions_template.render(d=self.enum_definition)
documentation = options.get("documentation")
if documentation and documentation not in self._DOCUMENTATION_CHOICES:
raise ValueError(f"Unsupported documentation style: {documentation!r}")
return self._enum_definitions_template.render(
d=self.enum_definition, documentation=documentation,
)
2 changes: 2 additions & 0 deletions python/enumecg/templates/doxygen/associate_namespace.doc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/** \brief Associate namespace for \ref {{ d.enhanced_enum_typename }}
*/
6 changes: 6 additions & 0 deletions python/enumecg/templates/doxygen/enhance.doc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** \brief Promote \ref {{ d.label_enum_typename }} to \ref {{ d.enhanced_enum_typename }}
*
* \param e Label enumerator
*
* \return The enhanced enumerator corresponding to \p e
*/
5 changes: 5 additions & 0 deletions python/enumecg/templates/doxygen/enhanced_enum.doc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/** \brief Enhanced enum from label \ref {{ d.label_enum_typename }}
*
* This enum was autogenerated for the enhanced enum library. Please see the
* documentation for more information: https://enhanced-enum.readthedocs.io/
*/
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// \brief Enumerator of \ref {{ d.enhanced_enum_typename }}
1 change: 1 addition & 0 deletions python/enumecg/templates/doxygen/internal_begin.doc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// \cond internal
1 change: 1 addition & 0 deletions python/enumecg/templates/doxygen/internal_end.doc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// \endcond
2 changes: 2 additions & 0 deletions python/enumecg/templates/doxygen/label_enum.doc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/** \brief Label enum for \ref {{ d.enhanced_enum_typename }}
*/
1 change: 1 addition & 0 deletions python/enumecg/templates/doxygen/value_constant.doc.in
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// \brief Value of enumerator \ref {{ member.enumerator_name }}
16 changes: 15 additions & 1 deletion python/enumecg/templates/enum_definitions.hh.in
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
{%- set values_array_name = "values" -%}
{%- set enhance_function_name = "enhance" -%}

{%- macro include_documentation(fragment, member) -%}
{%- if documentation -%}
{%- set filename = documentation ~ "/" ~ fragment ~ ".doc.in" -%}
{%- include filename %}
{% endif -%}
{%- endmacro -%}

{%- macro enum_base_class() -%}
::{{ enhanced_enum_namespace_name }}::{{ enum_base_class_name }}<{{ d.enhanced_enum_typename }}, {{ d.label_enum_typename }}, {{ d.value_type_typename }}>
{%- endmacro -%}
Expand All @@ -12,31 +19,38 @@
{{ d.enhanced_enum_typename }}::{{ identifier }}
{%- endmacro -%}

{{ include_documentation("label_enum") -}}
enum class {{ d.label_enum_typename }} {
{%- for member in d.members %}
{{ member.enumerator_name }},
{%- endfor %}
};

{{ include_documentation("enhanced_enum") -}}
struct {{ d.enhanced_enum_typename }} : {{ enum_base_class() }} {
using {{ enum_base_class() }}::{{ enum_base_class_name }};
{{ include_documentation("internal_begin") }} using {{ enum_base_class() }}::{{ enum_base_class_name }};
static constexpr std::array {{ values_array_name }} {
{%- for member in d.members %}
{{ value_type_alias }} {{ member.enumerator_value_initializers | initializer_list }},
{%- endfor %}
};
{{ include_documentation("internal_end") -}}
};

{{ include_documentation("enhance") -}}
constexpr {{ d.enhanced_enum_typename }} {{ enhance_function_name }}({{ d.label_enum_typename }} e) noexcept
{
return e;
}

{{ include_documentation("associate_namespace") -}}
namespace {{ d.associate_namespace_name }} {
{%- for member in d.members %}
{{ include_documentation("value_constant", member) -}}
inline constexpr const {{ qualify_with_enhanced_enum(value_type_alias) }}& {{ member.enumerator_value_constant_name }} { std::get<{{ loop.index0 }}>({{ qualify_with_enhanced_enum(values_array_name) }}) };
{%- endfor %}
{%- for member in d.members %}
{{ include_documentation("enumerator_constant", member) -}}
inline constexpr {{ d.enhanced_enum_typename }} {{ member.enumerator_name }} { {{ d.label_enum_typename }}::{{ member.enumerator_name }} };
{%- endfor %}
}
2 changes: 1 addition & 1 deletion python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def get_package_dunder(name):
license="MIT",
url="https://github.com/jasujm/enhanced-enum",
packages=["enumecg"],
package_data={"enumecg": ["templates/*.in"]},
package_data={"enumecg": ["templates/*.in", "templates/doxygen/*.in"]},
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
Expand Down
6 changes: 4 additions & 2 deletions python/tests/test_enumecg.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ def test_generator_function_should_return_code_generator(self):

def test_generate_should_return_code(self):
self.assertEqual(
generate(STATUS_DEFINITION),
CodeGenerator(STATUS_DEFINITION).generate_enum_definitions(),
generate(STATUS_DEFINITION, documentation="doxygen"),
CodeGenerator(STATUS_DEFINITION).generate_enum_definitions(
documentation="doxygen"
),
)
14 changes: 14 additions & 0 deletions python/tests/test_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,17 @@ def test_enum_definitions_should_contain_value_constants(self):

def test_enum_definitions_should_contain_associate_namespace(self):
self.assertIn("namespace Statuses", self.gen.generate_enum_definitions())

def test_enum_definitions_should_not_contain_documentation_if_not_requested(self):
self.assertNotIn("/**", self.gen.generate_enum_definitions(documentation=None))

def test_enum_definitions_should_contain_documentation_if_requested(self):
self.assertIn(
"/**", self.gen.generate_enum_definitions(documentation="doxygen")
)
print(self.gen.generate_enum_definitions(documentation="doxygen"))

def test_unsupported_documentation_style(self):
self.assertRaises(
ValueError, self.gen.generate_enum_definitions, documentation="invalid"
)

0 comments on commit 784e2ca

Please sign in to comment.