interface_parser/classes.py
Go to the documentation of this file.
1 """
2 GTSAM Copyright 2010-2020, Georgia Tech Research Corporation,
3 Atlanta, Georgia 30332-0415
4 All Rights Reserved
5 
6 See LICENSE for the license information
7 
8 Parser classes and rules for parsing C++ classes.
9 
10 Author: Duy Nguyen Ta, Fan Jiang, Matthew Sklar, Varun Agrawal, and Frank Dellaert
11 """
12 
13 from typing import Any, Iterable, List, Union
14 
15 from pyparsing import ZeroOrMore # type: ignore
16 from pyparsing import Literal, Optional, Word, alphas
17 
18 from .enum import Enum
19 from .function import ArgumentList, ReturnType
20 from .template import Template
21 from .tokens import (CLASS, COLON, CONST, DUNDER, IDENT, LBRACE, LPAREN,
22  OPERATOR, RBRACE, RPAREN, SEMI_COLON, STATIC, VIRTUAL)
23 from .type import TemplatedType, Typename
24 from .utils import collect_namespaces
25 from .variable import Variable
26 
27 
28 class Method:
29  """
30  Rule to parse a method in a class.
31 
32  E.g.
33  ```
34  class Hello {
35  void sayHello() const;
36  };
37  ```
38  """
39  rule = (
40  Optional(Template.rule("template")) #
41  + ReturnType.rule("return_type") #
42  + IDENT("name") #
43  + LPAREN #
44  + ArgumentList.rule("args_list") #
45  + RPAREN #
46  + Optional(CONST("is_const")) #
47  + SEMI_COLON # BR
48  ).setParseAction(lambda t: Method(t.template, t.name, t.return_type, t.
49  args_list, t.is_const))
50 
51  def __init__(self,
52  template: Union[Template, Any],
53  name: str,
54  return_type: ReturnType,
55  args: ArgumentList,
56  is_const: str,
57  parent: Union["Class", Any] = ''):
58  self.template = template
59  self.name = name
60  self.return_type = return_type
61  self.args = args
62  self.is_const = is_const
63 
64  self.parent = parent
65 
66  def to_cpp(self) -> str:
67  """Generate the C++ code for wrapping."""
68  return self.name
69 
70  def __repr__(self) -> str:
71  return "Method: {} {} {}({}){}".format(
72  self.template,
73  self.return_type,
74  self.name,
75  self.args,
76  self.is_const,
77  )
78 
79 
81  """
82  Rule to parse all the static methods in a class.
83 
84  E.g.
85  ```
86  class Hello {
87  static void changeGreeting();
88  };
89  ```
90  """
91  rule = (
92  Optional(Template.rule("template")) #
93  + STATIC #
94  + ReturnType.rule("return_type") #
95  + IDENT("name") #
96  + LPAREN #
97  + ArgumentList.rule("args_list") #
98  + RPAREN #
99  + SEMI_COLON # BR
100  ).setParseAction(
101  lambda t: StaticMethod(t.name, t.return_type, t.args_list, t.template))
102 
103  def __init__(self,
104  name: str,
105  return_type: ReturnType,
106  args: ArgumentList,
107  template: Union[Template, Any] = None,
108  parent: Union["Class", Any] = ''):
109  self.name = name
110  self.return_type = return_type
111  self.args = args
112  self.template = template
113 
114  self.parent = parent
115 
116  def __repr__(self) -> str:
117  return "static {} {}{}".format(self.return_type, self.name, self.args)
118 
119  def to_cpp(self) -> str:
120  """Generate the C++ code for wrapping."""
121  return self.name
122 
123 
125  """
126  Rule to parse the class constructor.
127  Can have 0 or more arguments.
128  """
129  rule = (
130  Optional(Template.rule("template")) #
131  + IDENT("name") #
132  + LPAREN #
133  + ArgumentList.rule("args_list") #
134  + RPAREN #
135  + SEMI_COLON # BR
136  ).setParseAction(lambda t: Constructor(t.name, t.args_list, t.template))
137 
138  def __init__(self,
139  name: str,
140  args: ArgumentList,
141  template: Union[Template, Any],
142  parent: Union["Class", Any] = ''):
143  self.name = name
144  self.args = args
145  self.template = template
146 
147  self.parent = parent
148 
149  def __repr__(self) -> str:
150  return "Constructor: {}{}".format(self.name, self.args)
151 
152 
153 class Operator:
154  """
155  Rule for parsing operator overloads.
156 
157  E.g.
158  ```
159  class Overload {
160  Vector2 operator+(const Vector2 &v) const;
161  };
162  """
163  rule = (
164  ReturnType.rule("return_type") #
165  + Literal("operator")("name") #
166  + OPERATOR("operator") #
167  + LPAREN #
168  + ArgumentList.rule("args_list") #
169  + RPAREN #
170  + CONST("is_const") #
171  + SEMI_COLON # BR
172  ).setParseAction(lambda t: Operator(t.name, t.operator, t.return_type, t.
173  args_list, t.is_const))
174 
175  def __init__(self,
176  name: str,
177  operator: str,
178  return_type: ReturnType,
179  args: ArgumentList,
180  is_const: str,
181  parent: Union["Class", Any] = ''):
182  self.name = name
183  self.operator = operator
184  self.return_type = return_type
185  self.args = args
186  self.is_const = is_const
187  self.is_unary = len(args) == 0
188 
189  self.parent = parent
190 
191  # Check for valid unary operators
192  if self.is_unary and self.operator not in ('+', '-'):
193  raise ValueError("Invalid unary operator {} used for {}".format(
194  self.operator, self))
195 
196  # Check that number of arguments are either 0 or 1
197  assert 0 <= len(args) < 2, \
198  "Operator overload should be at most 1 argument, " \
199  "{} arguments provided".format(len(args))
200 
201  # Check to ensure arg and return type are the same.
202  if len(args) == 1 and self.operator not in ("()", "[]"):
203  assert args.list()[0].ctype.typename.name == return_type.type1.typename.name, \
204  "Mixed type overloading not supported. Both arg and return type must be the same."
205 
206  def __repr__(self) -> str:
207  return "Operator: {}{}{}({}) {}".format(
208  self.return_type,
209  self.name,
210  self.operator,
211  self.args,
212  self.is_const,
213  )
214 
215 
217  """Special Python double-underscore (dunder) methods, e.g. __iter__, __contains__"""
218  rule = (
219  DUNDER #
220  + (Word(alphas))("name") #
221  + DUNDER #
222  + LPAREN #
223  + ArgumentList.rule("args_list") #
224  + RPAREN #
225  + SEMI_COLON # BR
226  ).setParseAction(lambda t: DunderMethod(t.name, t.args_list))
227 
228  def __init__(self, name: str, args: ArgumentList):
229  self.name = name
230  self.args = args
231 
232  def __repr__(self) -> str:
233  return f"DunderMethod: __{self.name}__({self.args})"
234 
235 
236 class Class:
237  """
238  Rule to parse a class defined in the interface file.
239 
240  E.g.
241  ```
242  class Hello {
243  ...
244  };
245  ```
246  """
247 
248  class Members:
249  """
250  Rule for all the members within a class.
251  """
252  rule = ZeroOrMore(DunderMethod.rule #
253  ^ Constructor.rule #
254  ^ Method.rule #
255  ^ StaticMethod.rule #
256  ^ Variable.rule #
257  ^ Operator.rule #
258  ^ Enum.rule #
259  ).setParseAction(lambda t: Class.Members(t.asList()))
260 
261  def __init__(self, members: List[Union[Constructor, Method,
262  StaticMethod, Variable,
263  Operator, Enum, DunderMethod]]):
264  self.ctors = []
265  self.methods = []
266  self.dunder_methods = []
267  self.static_methods = []
268  self.properties = []
269  self.operators = []
270  self.enums: List[Enum] = []
271  for m in members:
272  if isinstance(m, Constructor):
273  self.ctors.append(m)
274  elif isinstance(m, Method):
275  self.methods.append(m)
276  elif isinstance(m, StaticMethod):
277  self.static_methods.append(m)
278  elif isinstance(m, DunderMethod):
279  self.dunder_methods.append(m)
280  elif isinstance(m, Variable):
281  self.properties.append(m)
282  elif isinstance(m, Operator):
283  self.operators.append(m)
284  elif isinstance(m, Enum):
285  self.enums.append(m)
286 
287  _parent = COLON + (TemplatedType.rule ^ Typename.rule)("parent_class")
288  rule = (
289  Optional(Template.rule("template")) #
290  + Optional(VIRTUAL("is_virtual")) #
291  + CLASS #
292  + IDENT("name") #
293  + Optional(_parent) #
294  + LBRACE #
295  + Members.rule("members") #
296  + RBRACE #
297  + SEMI_COLON # BR
298  ).setParseAction(lambda t: Class(
299  t.template, t.is_virtual, t.name, t.parent_class, t.members.ctors, t.
300  members.methods, t.members.static_methods, t.members.dunder_methods, t.
301  members.properties, t.members.operators, t.members.enums))
302 
303  def __init__(
304  self,
305  template: Union[Template, None],
306  is_virtual: str,
307  name: str,
308  parent_class: list,
309  ctors: List[Constructor],
310  methods: List[Method],
311  static_methods: List[StaticMethod],
312  dunder_methods: List[DunderMethod],
313  properties: List[Variable],
314  operators: List[Operator],
315  enums: List[Enum],
316  parent: Any = '',
317  ):
318  self.template = template
319  self.is_virtual = is_virtual
320  self.name = name
321  if parent_class:
322  # If it is in an iterable, extract the parent class.
323  if isinstance(parent_class, Iterable):
324  parent_class = parent_class[0] # type: ignore
325 
326  # If the base class is a TemplatedType,
327  # we want the instantiated Typename
328  if isinstance(parent_class, TemplatedType):
329  pass # Note: this must get handled in InstantiatedClass
330 
331  self.parent_class = parent_class
332  else:
333  self.parent_class = '' # type: ignore
334 
335  self.ctors = ctors
336  self.methods = methods
337  self.static_methods = static_methods
338  self.dunder_methods = dunder_methods
339  self.properties = properties
340  self.operators = operators
341  self.enums = enums
342 
343  self.parent = parent
344 
345  # Make sure ctors' names and class name are the same.
346  for ctor in self.ctors:
347  if ctor.name != self.name:
348  raise ValueError("Error in constructor name! {} != {}".format(
349  ctor.name, self.name))
350 
351  for ctor in self.ctors:
352  ctor.parent = self
353  for method in self.methods:
354  method.parent = self
355  for static_method in self.static_methods:
356  static_method.parent = self
357  for dunder_method in self.dunder_methods:
358  dunder_method.parent = self
359  for _property in self.properties:
360  _property.parent = self
361 
362  def namespaces(self) -> list:
363  """Get the namespaces which this class is nested under as a list."""
364  return collect_namespaces(self)
365 
366  def __repr__(self):
367  return "Class: {self.name}".format(self=self)
gtwrap.interface_parser.classes.DunderMethod.args
args
Definition: interface_parser/classes.py:230
gtwrap.interface_parser.classes.Method.args
args
Definition: interface_parser/classes.py:55
gtwrap.interface_parser.classes.Class.namespaces
list namespaces(self)
Definition: interface_parser/classes.py:362
gtwrap.interface_parser.tokens.OPERATOR
OPERATOR
Definition: tokens.py:71
gtwrap.interface_parser.classes.StaticMethod.template
template
Definition: interface_parser/classes.py:107
format
std::string format(const std::string &str, const std::vector< std::string > &find, const std::vector< std::string > &replace)
Definition: openglsupport.cpp:226
gtwrap.interface_parser.classes.Operator.args
args
Definition: interface_parser/classes.py:179
gtwrap.interface_parser.classes.Method.is_const
is_const
Definition: interface_parser/classes.py:56
gtwrap.interface_parser.classes.Class.name
name
Definition: interface_parser/classes.py:306
gtwrap.interface_parser.classes.Constructor.__repr__
str __repr__(self)
Definition: interface_parser/classes.py:149
gtwrap.interface_parser.classes.StaticMethod.__init__
def __init__(self, str name, ReturnType return_type, ArgumentList args, Union[Template, Any] template=None, Union["Class", Any] parent='')
Definition: interface_parser/classes.py:103
gtwrap.interface_parser.classes.Method.name
name
Definition: interface_parser/classes.py:53
gtwrap.interface_parser.classes.DunderMethod.__init__
def __init__(self, str name, ArgumentList args)
Definition: interface_parser/classes.py:228
gtwrap.interface_parser.classes.Class
Definition: interface_parser/classes.py:236
gtwrap.interface_parser.classes.Class.template
template
Definition: interface_parser/classes.py:304
gtwrap.interface_parser.classes.Class.Members.__init__
def __init__(self, List[Union[Constructor, Method, StaticMethod, Variable, Operator, Enum, DunderMethod]] members)
Definition: interface_parser/classes.py:261
gtwrap.interface_parser.classes.Operator.__init__
def __init__(self, str name, str operator, ReturnType return_type, ArgumentList args, str is_const, Union["Class", Any] parent='')
Definition: interface_parser/classes.py:175
gtwrap.interface_parser.classes.Class.parent
parent
Definition: interface_parser/classes.py:329
gtwrap.interface_parser.classes.Class.methods
methods
Definition: interface_parser/classes.py:322
gtwrap.interface_parser.classes.Operator.operator
operator
Definition: interface_parser/classes.py:177
gtwrap.interface_parser.classes.Class.enums
enums
Definition: interface_parser/classes.py:327
gtwrap.interface_parser.classes.StaticMethod.return_type
return_type
Definition: interface_parser/classes.py:105
gtwrap.interface_parser.classes.DunderMethod.name
name
Definition: interface_parser/classes.py:229
gtwrap.interface_parser.classes.Operator.parent
parent
Definition: interface_parser/classes.py:183
gtwrap.interface_parser.classes.Class.Members.ctors
ctors
Definition: interface_parser/classes.py:262
gtwrap.interface_parser.tokens.IDENT
IDENT
Definition: tokens.py:19
isinstance
bool isinstance(handle obj)
Definition: pytypes.h:842
gtwrap.interface_parser.classes.Class.is_virtual
is_virtual
Definition: interface_parser/classes.py:305
gtwrap.interface_parser.classes.Constructor.parent
parent
Definition: interface_parser/classes.py:143
gtwrap.interface_parser.classes.StaticMethod.__repr__
str __repr__(self)
Definition: interface_parser/classes.py:116
gtwrap.interface_parser.utils.collect_namespaces
def collect_namespaces(obj)
Definition: utils.py:14
gtwrap.interface_parser.classes.Method.template
template
Definition: interface_parser/classes.py:52
gtwrap.interface_parser.classes.StaticMethod.to_cpp
str to_cpp(self)
Definition: interface_parser/classes.py:119
gtwrap.interface_parser.classes.Class.Members.static_methods
static_methods
Definition: interface_parser/classes.py:265
gtwrap.interface_parser.classes.Method.__init__
def __init__(self, Union[Template, Any] template, str name, ReturnType return_type, ArgumentList args, str is_const, Union["Class", Any] parent='')
Definition: interface_parser/classes.py:51
gtwrap.interface_parser.classes.Constructor.__init__
def __init__(self, str name, ArgumentList args, Union[Template, Any] template, Union["Class", Any] parent='')
Definition: interface_parser/classes.py:138
gtwrap.interface_parser.classes.StaticMethod.args
args
Definition: interface_parser/classes.py:106
gtwrap.interface_parser.classes.Class.operators
operators
Definition: interface_parser/classes.py:326
gtwrap.interface_parser.classes.Operator.is_const
is_const
Definition: interface_parser/classes.py:180
gtwrap.interface_parser.classes.Constructor.template
template
Definition: interface_parser/classes.py:141
gtwrap.interface_parser.classes.Class.__init__
def __init__(self, Union[Template, None] template, str is_virtual, str name, list parent_class, List[Constructor] ctors, List[Method] methods, List[StaticMethod] static_methods, List[DunderMethod] dunder_methods, List[Variable] properties, List[Operator] operators, List[Enum] enums, Any parent='')
Definition: interface_parser/classes.py:303
gtwrap.interface_parser.classes.Class.__repr__
def __repr__(self)
Definition: interface_parser/classes.py:366
gtwrap.interface_parser.classes.Class.dunder_methods
dunder_methods
Definition: interface_parser/classes.py:324
gtwrap.interface_parser.classes.DunderMethod.__repr__
str __repr__(self)
Definition: interface_parser/classes.py:232
gtwrap.interface_parser.classes.Class.properties
properties
Definition: interface_parser/classes.py:325
gtwrap.interface_parser.classes.Method.parent
parent
Definition: interface_parser/classes.py:58
gtwrap.interface_parser.classes.Method.return_type
return_type
Definition: interface_parser/classes.py:54
gtwrap.interface_parser.classes.StaticMethod
Definition: interface_parser/classes.py:80
gtwrap.interface_parser.tokens.CONST
CONST
Definition: tokens.py:42
gtwrap.interface_parser.classes.Constructor
Definition: interface_parser/classes.py:124
gtwrap.interface_parser.classes.Operator.name
name
Definition: interface_parser/classes.py:176
gtwrap.interface_parser.classes.Class.Members.operators
operators
Definition: interface_parser/classes.py:267
gtwrap.interface_parser.classes.DunderMethod
Definition: interface_parser/classes.py:216
gtwrap.interface_parser.classes.Class.Members
Definition: interface_parser/classes.py:248
gtwrap.interface_parser.classes.Class.static_methods
static_methods
Definition: interface_parser/classes.py:323
gtwrap.interface_parser.classes.Operator.is_unary
is_unary
Definition: interface_parser/classes.py:181
gtwrap.interface_parser.classes.Class.Members.dunder_methods
dunder_methods
Definition: interface_parser/classes.py:264
gtwrap.interface_parser.classes.Method
Definition: interface_parser/classes.py:28
gtwrap.interface_parser.classes.StaticMethod.parent
parent
Definition: interface_parser/classes.py:109
gtwrap.interface_parser.classes.StaticMethod.name
name
Definition: interface_parser/classes.py:104
gtwrap.interface_parser.classes.Class.Members.properties
properties
Definition: interface_parser/classes.py:266
gtwrap.interface_parser.classes.Method.__repr__
str __repr__(self)
Definition: interface_parser/classes.py:70
len
size_t len(handle h)
Get the length of a Python object.
Definition: pytypes.h:2446
gtwrap.interface_parser.classes.Operator.return_type
return_type
Definition: interface_parser/classes.py:178
gtwrap.interface_parser.classes.Operator
Definition: interface_parser/classes.py:153
gtwrap.interface_parser.classes.Constructor.name
name
Definition: interface_parser/classes.py:139
gtwrap.interface_parser.classes.Class.parent_class
parent_class
Definition: interface_parser/classes.py:317
gtwrap.interface_parser.classes.Operator.__repr__
str __repr__(self)
Definition: interface_parser/classes.py:206
gtwrap.interface_parser.classes.Method.to_cpp
str to_cpp(self)
Definition: interface_parser/classes.py:66
gtwrap.interface_parser.classes.Constructor.args
args
Definition: interface_parser/classes.py:140
gtwrap.interface_parser.tokens.VIRTUAL
VIRTUAL
Definition: tokens.py:42
gtwrap.interface_parser.classes.Class.ctors
ctors
Definition: interface_parser/classes.py:321
gtwrap.interface_parser.classes.Class.Members.methods
methods
Definition: interface_parser/classes.py:263


gtsam
Author(s):
autogenerated on Sat Nov 16 2024 04:01:58