commit
						5bb69f7223
					
				|  | @ -10,7 +10,7 @@ Parser classes and rules for parsing C++ classes. | |||
| Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellaert | ||||
| """ | ||||
| 
 | ||||
| from typing import Iterable, List, Union | ||||
| from typing import Any, Iterable, List, Union | ||||
| 
 | ||||
| from pyparsing import Literal, Optional, ZeroOrMore  # type: ignore | ||||
| 
 | ||||
|  | @ -48,12 +48,12 @@ class Method: | |||
|                                       args_list, t.is_const)) | ||||
| 
 | ||||
|     def __init__(self, | ||||
|                  template: str, | ||||
|                  template: Union[Template, Any], | ||||
|                  name: str, | ||||
|                  return_type: ReturnType, | ||||
|                  args: ArgumentList, | ||||
|                  is_const: str, | ||||
|                  parent: Union[str, "Class"] = ''): | ||||
|                  parent: Union["Class", Any] = ''): | ||||
|         self.template = template | ||||
|         self.name = name | ||||
|         self.return_type = return_type | ||||
|  | @ -98,7 +98,7 @@ class StaticMethod: | |||
|                  name: str, | ||||
|                  return_type: ReturnType, | ||||
|                  args: ArgumentList, | ||||
|                  parent: Union[str, "Class"] = ''): | ||||
|                  parent: Union["Class", Any] = ''): | ||||
|         self.name = name | ||||
|         self.return_type = return_type | ||||
|         self.args = args | ||||
|  | @ -129,7 +129,7 @@ class Constructor: | |||
|     def __init__(self, | ||||
|                  name: str, | ||||
|                  args: ArgumentList, | ||||
|                  parent: Union["Class", str] = ''): | ||||
|                  parent: Union["Class", Any] = ''): | ||||
|         self.name = name | ||||
|         self.args = args | ||||
| 
 | ||||
|  | @ -167,7 +167,7 @@ class Operator: | |||
|                  return_type: ReturnType, | ||||
|                  args: ArgumentList, | ||||
|                  is_const: str, | ||||
|                  parent: Union[str, "Class"] = ''): | ||||
|                  parent: Union["Class", Any] = ''): | ||||
|         self.name = name | ||||
|         self.operator = operator | ||||
|         self.return_type = return_type | ||||
|  | @ -284,7 +284,7 @@ class Class: | |||
|         properties: List[Variable], | ||||
|         operators: List[Operator], | ||||
|         enums: List[Enum], | ||||
|         parent: str = '', | ||||
|         parent: Any = '', | ||||
|     ): | ||||
|         self.template = template | ||||
|         self.is_virtual = is_virtual | ||||
|  |  | |||
|  | @ -169,7 +169,7 @@ class GlobalFunction: | |||
|                  return_type: ReturnType, | ||||
|                  args_list: ArgumentList, | ||||
|                  template: Template, | ||||
|                  parent: str = ''): | ||||
|                  parent: Any = ''): | ||||
|         self.name = name | ||||
|         self.return_type = return_type | ||||
|         self.args = args_list | ||||
|  |  | |||
|  | @ -12,7 +12,7 @@ Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellae | |||
| 
 | ||||
| # pylint: disable=unnecessary-lambda, expression-not-assigned | ||||
| 
 | ||||
| from typing import Iterable, List, Union | ||||
| from typing import List, Sequence, Union | ||||
| 
 | ||||
| from pyparsing import (Forward, Optional, Or, ParseResults,  # type: ignore | ||||
|                        delimitedList) | ||||
|  | @ -49,12 +49,12 @@ class Typename: | |||
| 
 | ||||
|     def __init__(self, | ||||
|                  t: ParseResults, | ||||
|                  instantiations: Iterable[ParseResults] = ()): | ||||
|                  instantiations: Sequence[ParseResults] = ()): | ||||
|         self.name = t[-1]  # the name is the last element in this list | ||||
|         self.namespaces = t[:-1] | ||||
| 
 | ||||
|         if instantiations: | ||||
|             if isinstance(instantiations, Iterable): | ||||
|             if isinstance(instantiations, Sequence): | ||||
|                 self.instantiations = instantiations  # type: ignore | ||||
|             else: | ||||
|                 self.instantiations = instantiations.asList() | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| """Mixins for reducing the amount of boilerplate in the main wrapper class.""" | ||||
| 
 | ||||
| from typing import Any, Tuple, Union | ||||
| 
 | ||||
| import gtwrap.interface_parser as parser | ||||
| import gtwrap.template_instantiator as instantiator | ||||
| 
 | ||||
|  | @ -7,13 +9,14 @@ import gtwrap.template_instantiator as instantiator | |||
| class CheckMixin: | ||||
|     """Mixin to provide various checks.""" | ||||
|     # Data types that are primitive types | ||||
|     not_ptr_type = ['int', 'double', 'bool', 'char', 'unsigned char', 'size_t'] | ||||
|     not_ptr_type: Tuple = ('int', 'double', 'bool', 'char', 'unsigned char', | ||||
|                            'size_t') | ||||
|     # Ignore the namespace for these datatypes | ||||
|     ignore_namespace = ['Matrix', 'Vector', 'Point2', 'Point3'] | ||||
|     ignore_namespace: Tuple = ('Matrix', 'Vector', 'Point2', 'Point3') | ||||
|     # Methods that should be ignored | ||||
|     ignore_methods = ['pickle'] | ||||
|     ignore_methods: Tuple = ('pickle', ) | ||||
|     # Methods that should not be wrapped directly | ||||
|     whitelist = ['serializable', 'serialize'] | ||||
|     whitelist: Tuple = ('serializable', 'serialize') | ||||
|     # Datatypes that do not need to be checked in methods | ||||
|     not_check_type: list = [] | ||||
| 
 | ||||
|  | @ -23,7 +26,7 @@ class CheckMixin: | |||
|                 return True | ||||
|         return False | ||||
| 
 | ||||
|     def is_shared_ptr(self, arg_type): | ||||
|     def is_shared_ptr(self, arg_type: parser.Type): | ||||
|         """ | ||||
|         Determine if the `interface_parser.Type` should be treated as a | ||||
|         shared pointer in the wrapper. | ||||
|  | @ -33,7 +36,7 @@ class CheckMixin: | |||
|             and arg_type.typename.name not in self.ignore_namespace | ||||
|             and arg_type.typename.name != 'string') | ||||
| 
 | ||||
|     def is_ptr(self, arg_type): | ||||
|     def is_ptr(self, arg_type: parser.Type): | ||||
|         """ | ||||
|         Determine if the `interface_parser.Type` should be treated as a | ||||
|         raw pointer in the wrapper. | ||||
|  | @ -43,7 +46,7 @@ class CheckMixin: | |||
|             and arg_type.typename.name not in self.ignore_namespace | ||||
|             and arg_type.typename.name != 'string') | ||||
| 
 | ||||
|     def is_ref(self, arg_type): | ||||
|     def is_ref(self, arg_type: parser.Type): | ||||
|         """ | ||||
|         Determine if the `interface_parser.Type` should be treated as a | ||||
|         reference in the wrapper. | ||||
|  | @ -55,7 +58,14 @@ class CheckMixin: | |||
| 
 | ||||
| class FormatMixin: | ||||
|     """Mixin to provide formatting utilities.""" | ||||
|     def _clean_class_name(self, instantiated_class): | ||||
| 
 | ||||
|     ignore_namespace: tuple | ||||
|     data_type: Any | ||||
|     data_type_param: Any | ||||
|     _return_count: Any | ||||
| 
 | ||||
|     def _clean_class_name(self, | ||||
|                           instantiated_class: instantiator.InstantiatedClass): | ||||
|         """Reformatted the C++ class name to fit Matlab defined naming | ||||
|         standards | ||||
|         """ | ||||
|  | @ -65,23 +75,23 @@ class FormatMixin: | |||
|         return instantiated_class.name | ||||
| 
 | ||||
|     def _format_type_name(self, | ||||
|                           type_name, | ||||
|                           separator='::', | ||||
|                           include_namespace=True, | ||||
|                           constructor=False, | ||||
|                           method=False): | ||||
|                           type_name: parser.Typename, | ||||
|                           separator: str = '::', | ||||
|                           include_namespace: bool = True, | ||||
|                           is_constructor: bool = False, | ||||
|                           is_method: bool = False): | ||||
|         """ | ||||
|         Args: | ||||
|             type_name: an interface_parser.Typename to reformat | ||||
|             separator: the statement to add between namespaces and typename | ||||
|             include_namespace: whether to include namespaces when reformatting | ||||
|             constructor: if the typename will be in a constructor | ||||
|             method: if the typename will be in a method | ||||
|             is_constructor: if the typename will be in a constructor | ||||
|             is_method: if the typename will be in a method | ||||
| 
 | ||||
|         Raises: | ||||
|             constructor and method cannot both be true | ||||
|         """ | ||||
|         if constructor and method: | ||||
|         if is_constructor and is_method: | ||||
|             raise ValueError( | ||||
|                 'Constructor and method parameters cannot both be True') | ||||
| 
 | ||||
|  | @ -93,9 +103,9 @@ class FormatMixin: | |||
|                 if name not in self.ignore_namespace and namespace != '': | ||||
|                     formatted_type_name += namespace + separator | ||||
| 
 | ||||
|         if constructor: | ||||
|         if is_constructor: | ||||
|             formatted_type_name += self.data_type.get(name) or name | ||||
|         elif method: | ||||
|         elif is_method: | ||||
|             formatted_type_name += self.data_type_param.get(name) or name | ||||
|         else: | ||||
|             formatted_type_name += name | ||||
|  | @ -106,8 +116,8 @@ class FormatMixin: | |||
|                 template = '{}'.format( | ||||
|                     self._format_type_name(type_name.instantiations[idx], | ||||
|                                            include_namespace=include_namespace, | ||||
|                                            constructor=constructor, | ||||
|                                            method=method)) | ||||
|                                            is_constructor=is_constructor, | ||||
|                                            is_method=is_method)) | ||||
|                 templates.append(template) | ||||
| 
 | ||||
|             if len(templates) > 0:  # If there are no templates | ||||
|  | @ -119,15 +129,15 @@ class FormatMixin: | |||
|                     self._format_type_name(type_name.instantiations[idx], | ||||
|                                            separator=separator, | ||||
|                                            include_namespace=False, | ||||
|                                            constructor=constructor, | ||||
|                                            method=method)) | ||||
|                                            is_constructor=is_constructor, | ||||
|                                            is_method=is_method)) | ||||
| 
 | ||||
|         return formatted_type_name | ||||
| 
 | ||||
|     def _format_return_type(self, | ||||
|                             return_type, | ||||
|                             include_namespace=False, | ||||
|                             separator="::"): | ||||
|                             return_type: parser.function.ReturnType, | ||||
|                             include_namespace: bool = False, | ||||
|                             separator: str = "::"): | ||||
|         """Format return_type. | ||||
| 
 | ||||
|         Args: | ||||
|  | @ -154,18 +164,15 @@ class FormatMixin: | |||
| 
 | ||||
|         return return_wrap | ||||
| 
 | ||||
|     def _format_class_name(self, instantiated_class, separator=''): | ||||
|     def _format_class_name(self, | ||||
|                            instantiated_class: instantiator.InstantiatedClass, | ||||
|                            separator: str = ''): | ||||
|         """Format a template_instantiator.InstantiatedClass name.""" | ||||
|         if instantiated_class.parent == '': | ||||
|             parent_full_ns = [''] | ||||
|         else: | ||||
|             parent_full_ns = instantiated_class.parent.full_namespaces() | ||||
|         # class_name = instantiated_class.parent.name | ||||
|         # | ||||
|         # if class_name != '': | ||||
|         #     class_name += separator | ||||
|         # | ||||
|         # class_name += instantiated_class.name | ||||
| 
 | ||||
|         parentname = "".join([separator + x | ||||
|                               for x in parent_full_ns]) + separator | ||||
| 
 | ||||
|  | @ -175,10 +182,12 @@ class FormatMixin: | |||
| 
 | ||||
|         return class_name | ||||
| 
 | ||||
|     def _format_static_method(self, static_method, separator=''): | ||||
|         """Example: | ||||
| 
 | ||||
|                 gtsamPoint3.staticFunction | ||||
|     def _format_static_method(self, | ||||
|                               static_method: parser.StaticMethod, | ||||
|                               separator: str = ''): | ||||
|         """ | ||||
|         Example: | ||||
|                 gtsam.Point3.staticFunction() | ||||
|         """ | ||||
|         method = '' | ||||
| 
 | ||||
|  | @ -188,35 +197,17 @@ class FormatMixin: | |||
| 
 | ||||
|         return method[2 * len(separator):] | ||||
| 
 | ||||
|     def _format_instance_method(self, instance_method, separator=''): | ||||
|     def _format_global_function(self, | ||||
|                                 function: Union[parser.GlobalFunction, Any], | ||||
|                                 separator: str = ''): | ||||
|         """Example: | ||||
| 
 | ||||
|                 gtsamPoint3.staticFunction | ||||
|         """ | ||||
|         method = '' | ||||
| 
 | ||||
|         if isinstance(instance_method, instantiator.InstantiatedMethod): | ||||
|             method_list = [ | ||||
|                 separator + x | ||||
|                 for x in instance_method.parent.parent.full_namespaces() | ||||
|             ] | ||||
|             method += "".join(method_list) + separator | ||||
| 
 | ||||
|             method += instance_method.parent.name + separator | ||||
|             method += instance_method.original.name | ||||
|             method += "<" + instance_method.instantiations.to_cpp() + ">" | ||||
| 
 | ||||
|         return method[2 * len(separator):] | ||||
| 
 | ||||
|     def _format_global_method(self, static_method, separator=''): | ||||
|         """Example: | ||||
| 
 | ||||
|                 gtsamPoint3.staticFunction | ||||
|         """ | ||||
|         method = '' | ||||
| 
 | ||||
|         if isinstance(static_method, parser.GlobalFunction): | ||||
|             method += "".join([separator + x for x in static_method.parent.full_namespaces()]) + \ | ||||
|         if isinstance(function, parser.GlobalFunction): | ||||
|             method += "".join([separator + x for x in function.parent.full_namespaces()]) + \ | ||||
|                       separator | ||||
| 
 | ||||
|         return method[2 * len(separator):] | ||||
|  |  | |||
|  | @ -11,8 +11,6 @@ import textwrap | |||
| from functools import partial, reduce | ||||
| from typing import Dict, Iterable, List, Union | ||||
| 
 | ||||
| from loguru import logger | ||||
| 
 | ||||
| import gtwrap.interface_parser as parser | ||||
| import gtwrap.template_instantiator as instantiator | ||||
| from gtwrap.matlab_wrapper.mixins import CheckMixin, FormatMixin | ||||
|  | @ -200,7 +198,7 @@ class MatlabWrapper(CheckMixin, FormatMixin): | |||
|                 check_type = self._format_type_name( | ||||
|                     arg.ctype.typename, | ||||
|                     separator='.', | ||||
|                     constructor=not wrap_datatypes) | ||||
|                     is_constructor=not wrap_datatypes) | ||||
| 
 | ||||
|             var_arg_wrap += " && isa(varargin{{{num}}},'{data_type}')".format( | ||||
|                 num=i, data_type=check_type) | ||||
|  | @ -1090,11 +1088,10 @@ class MatlabWrapper(CheckMixin, FormatMixin): | |||
|             if method.instantiations: | ||||
|                 # method_name += '<{}>'.format( | ||||
|                 #     self._format_type_name(method.instantiations)) | ||||
|                 # method_name = self._format_instance_method(method, '::') | ||||
|                 method = method.to_cpp() | ||||
| 
 | ||||
|         elif isinstance(method, parser.GlobalFunction): | ||||
|             method_name = self._format_global_method(method, '::') | ||||
|             method_name = self._format_global_function(method, '::') | ||||
|             method_name += method.name | ||||
| 
 | ||||
|         else: | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
| 
 | ||||
| import itertools | ||||
| from copy import deepcopy | ||||
| from typing import Iterable, List | ||||
| from typing import Any, Iterable, List, Sequence | ||||
| 
 | ||||
| import gtwrap.interface_parser as parser | ||||
| 
 | ||||
|  | @ -214,17 +214,17 @@ class InstantiatedMethod(parser.Method): | |||
|     } | ||||
|     """ | ||||
|     def __init__(self, | ||||
|                  original, | ||||
|                  original: parser.Method, | ||||
|                  instantiations: Iterable[parser.Typename] = ()): | ||||
|         self.original = original | ||||
|         self.instantiations = instantiations | ||||
|         self.template = '' | ||||
|         self.template: Any = '' | ||||
|         self.is_const = original.is_const | ||||
|         self.parent = original.parent | ||||
| 
 | ||||
|         # Check for typenames if templated. | ||||
|         # This way, we can gracefully handle both templated and non-templated methods. | ||||
|         typenames = self.original.template.typenames if self.original.template else [] | ||||
|         typenames: Sequence = self.original.template.typenames if self.original.template else [] | ||||
|         self.name = instantiate_name(original.name, self.instantiations) | ||||
|         self.return_type = instantiate_return_type( | ||||
|             original.return_type, | ||||
|  | @ -348,13 +348,12 @@ class InstantiatedClass(parser.Class): | |||
|         return "{virtual}Class {cpp_class} : {parent_class}\n"\ | ||||
|             "{ctors}\n{static_methods}\n{methods}\n{operators}".format( | ||||
|                virtual="virtual " if self.is_virtual else '', | ||||
|                name=self.name, | ||||
|                cpp_class=self.to_cpp(), | ||||
|                parent_class=self.parent, | ||||
|                ctors="\n".join([repr(ctor) for ctor in self.ctors]), | ||||
|                methods="\n".join([repr(m) for m in self.methods]), | ||||
|                static_methods="\n".join([repr(m) | ||||
|                                          for m in self.static_methods]), | ||||
|                 methods="\n".join([repr(m) for m in self.methods]), | ||||
|                operators="\n".join([repr(op) for op in self.operators]) | ||||
|             ) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,3 +1,2 @@ | |||
| pyparsing | ||||
| pytest | ||||
| loguru | ||||
|  | @ -11,8 +11,6 @@ import os.path as osp | |||
| import sys | ||||
| import unittest | ||||
| 
 | ||||
| from loguru import logger | ||||
| 
 | ||||
| sys.path.append(osp.dirname(osp.dirname(osp.abspath(__file__)))) | ||||
| 
 | ||||
| from gtwrap.matlab_wrapper import MatlabWrapper | ||||
|  | @ -44,10 +42,6 @@ class TestWrap(unittest.TestCase): | |||
|         # Create the `actual/matlab` directory | ||||
|         os.makedirs(self.MATLAB_ACTUAL_DIR, exist_ok=True) | ||||
| 
 | ||||
|         # set the log level to INFO by default | ||||
|         logger.remove()  # remove the default sink | ||||
|         logger.add(sys.stderr, format="{time} {level} {message}", level="INFO") | ||||
| 
 | ||||
|     def compare_and_diff(self, file): | ||||
|         """ | ||||
|         Compute the comparison between the expected and actual file, | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue