Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 23 additions & 0 deletions src/code_generation/cpp/cpp_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,12 @@ def __init__(self, **properties):
# class enums
self.internal_enum_elements = []

# class using type definitions
self.internal_enum_elements = []

# class using type definitions
self.internal_using_type_elements = []

def _parent_class(self):
"""
@return: parent class object
Expand All @@ -352,6 +358,13 @@ def add_enum(self, enum):
enum.ref_to_parent = self
self.internal_enum_elements.append(enum)

def add_using_type(self, using):
"""
@param: enum CppEnum instance
"""
using.ref_to_parent = self
self.internal_using_type_elements.append(using)

def add_variable(self, cpp_variable):
"""
@param: cpp_variable CppVariable instance
Expand Down Expand Up @@ -405,6 +418,15 @@ def _render_enum_section(self, cpp):
enumItem.render_to_string(cpp)
cpp.newline()

def _render_using_type_section(self, cpp):
"""
Render to string all contained enums
Method is protected as it is used by CppClass only
"""
for using_typeItem in self.internal_using_type_elements:
using_typeItem.render_to_string(cpp)
cpp.newline()

def _render_variables_declaration(self, cpp):
"""
Render to string all contained variable class members
Expand Down Expand Up @@ -478,6 +500,7 @@ def class_interface(self, cpp):
Should be placed in 'public:' section
"""
self._render_enum_section(cpp)
self._render_using_type_section(cpp)
self._render_internal_classes_declaration(cpp)
self._render_methods_declaration(cpp)

Expand Down
82 changes: 82 additions & 0 deletions src/code_generation/cpp/cpp_using_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from code_generation.cpp.cpp_generator import CppLanguageElement, CppDeclaration, CppImplementation
from textwrap import dedent

__doc__ = """The module encapsulates C++ code generation logics for main C++ language primitives:
classes, methods and functions, variables, enums.
Every C++ element could render its current state to a string that could be evaluated as
a legal C++ construction.

For detailed information see code_generator.py documentation.
"""


# noinspection PyUnresolvedReferences
class CppUsingType(CppLanguageElement):
"""
The Python class that generates string representation for C++ variable (automatic or class member)
For example:
class MyClass
{
int m_var1;
double m_var2;
...
}
Available properties:
type - string, variable type
initialization_value - string, initialization_value to be initialized with.
'a = initialization_value;' for automatic variables, 'a(initialization_value)' for the class member
documentation - string, '/// Example doxygen'
is_class_member - boolean, for appropriate definition/declaration rendering
"""
availablePropertiesNames = {'type',
'documentation',
'is_class_member'} | CppLanguageElement.availablePropertiesNames

def __init__(self, **properties):
input_property_names = set(properties.keys())
self.check_input_properties_names(input_property_names)
super(CppUsingType, self).__init__(properties)
self.init_class_properties(current_class_properties=self.availablePropertiesNames,
input_properties_dict=properties)

def declaration(self):
"""
@return: CppDeclaration wrapper, that could be used
for declaration rendering using render_to_string(cpp) interface
"""
return CppDeclaration(self)

def definition(self):
"""
@return: CppImplementation wrapper, that could be used
for definition rendering using render_to_string(cpp) interface
"""
return CppImplementation(self)

def render_to_string(self, cpp):
"""
Only automatic variables or static const class members could be rendered using this method
Generates complete variable definition, e.g.
"""
if self.documentation:
cpp(dedent(self.documentation))
cpp(f'using {self.name} = {self.type};')

def render_to_string_declaration(self, cpp):
"""
Generates declaration for the class member variables, for example
int m_var;
"""
if not self.is_class_member:
raise RuntimeError(
'For automatic variable use its render_to_string() method')

if self.documentation and self.is_class_member:
cpp(dedent(self.documentation))
cpp(f'using {self.name} = {self.type};')

def render_to_string_implementation(self, cpp):
"""
Using has no implementation
"""
return None
21 changes: 9 additions & 12 deletions tests/create_assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@ def generate_func(output_dir='.'):
def function_body(_, cpp1):
cpp1('return 42;')

functions = [CppFunction(name='GetParam', ret_type='int'),
CppFunction(name='Calculate', ret_type='void'),
functions = [CppFunction(name='GetParam', ret_type='int', implementation_handle=lambda _, cpp: cpp("return 1;")),
CppFunction(name='Calculate', ret_type='void', implementation_handle=lambda _, cpp: cpp("return;")),
CppFunction(name='GetAnswer', ret_type='int', implementation_handle=function_body),
CppFunction(name='Help', ret_type='char *', documentation='/// Returns the help documentation.'),
CppFunction(name='Help', ret_type='char *', documentation='/// Returns the help documentation.', implementation_handle=lambda _, cpp: cpp("return nullptr;")),
]
for func in functions:
func.render_to_string(hpp)
Expand Down Expand Up @@ -195,30 +195,27 @@ def generate_class(output_dir='.'):
def method_body(_, cpp1):
cpp1('return m_var1;')

my_class.add_method(CppFunction(name="GetParam",
my_class.add_method(CppClass.CppMethod(name="GetParam",
ret_type="int",
is_method=True,
is_const=True,
implementation_handle=method_body))

my_class.add_method(CppFunction(name="VirtualMethod",
my_class.add_method(CppClass.CppMethod(name="VirtualMethod",
ret_type="int",
is_method=True,
is_virtual=True))
is_virtual=True, implementation_handle=method_body))

my_class.add_method(CppFunction(name="PureVirtualMethod",
my_class.add_method(CppClass.CppMethod(name="PureVirtualMethod",
ret_type="void",
is_method=True,
is_virtual=True,
is_pure_virtual=True))

example_class.add_method(CppFunction(
example_class.add_method(CppClass.CppMethod(
name="DoNothing",
documentation="""\
/**
* Example multiline documentation.
*/""",
ret_type="void"),
ret_type="void", implementation_handle=lambda _, cpp: cpp("return;")),
)

my_class.declaration().render_to_string(my_class_h)
Expand Down
3 changes: 3 additions & 0 deletions tests/test_cpp_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from code_generation.cpp.cpp_array import CppArray
from code_generation.cpp.cpp_function import CppFunction
from code_generation.cpp.cpp_class import CppClass
from code_generation.cpp.cpp_using_type import CppUsingType

__doc__ = """
Unit tests for C++ code generator
Expand Down Expand Up @@ -114,6 +115,8 @@ def static_method_body(_, cpp):
is_static=True,
implementation_handle=static_method_body))

my_class.add_using_type(CppUsingType(name='FooType', type='double'))

my_class.declaration().render_to_string(my_class_h)
my_class.definition().render_to_string(my_class_cpp)

Expand Down