Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / mojo / public / tools / bindings / pylib / mojom / parse / ast.py
1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Node classes for the AST for a Mojo IDL file."""
6
7 # Note: For convenience of testing, you probably want to define __eq__() methods
8 # for all node types; it's okay to be slightly lax (e.g., not compare filename
9 # and lineno). You may also define __repr__() to help with analyzing test
10 # failures, especially for more complex types.
11
12
13 class NodeBase(object):
14   """Base class for nodes in the AST."""
15
16   def __init__(self, filename=None, lineno=None):
17     self.filename = filename
18     self.lineno = lineno
19
20   def __eq__(self, other):
21     return type(self) == type(other)
22
23   # Make != the inverse of ==. (Subclasses shouldn't have to override this.)
24   def __ne__(self, other):
25     return not self == other
26
27
28 # TODO(vtl): Some of this is complicated enough that it should be tested.
29 class NodeListBase(NodeBase):
30   """Represents a list of other nodes, all having the same type. (This is meant
31   to be subclassed, with subclasses defining _list_item_type to be the class (or
32   classes, in a tuple) of the members of the list.)"""
33
34   def __init__(self, item_or_items=None, **kwargs):
35     super(NodeListBase, self).__init__(**kwargs)
36     self.items = []
37     if item_or_items is None:
38       pass
39     elif isinstance(item_or_items, list):
40       for item in item_or_items:
41         assert isinstance(item, self._list_item_type)
42         self.Append(item)
43     else:
44       assert isinstance(item_or_items, self._list_item_type)
45       self.Append(item_or_items)
46
47   # Support iteration. For everything else, users should just access |items|
48   # directly. (We intentionally do NOT supply |__len__()| or |__nonzero__()|, so
49   # |bool(NodeListBase())| is true.)
50   def __iter__(self):
51     return self.items.__iter__()
52
53   def __eq__(self, other):
54     return super(NodeListBase, self).__eq__(other) and \
55            self.items == other.items
56
57   # Implement this so that on failure, we get slightly more sensible output.
58   def __repr__(self):
59     return self.__class__.__name__ + "([" + \
60            ", ".join([repr(elem) for elem in self.items]) + "])"
61
62   def Insert(self, item):
63     """Inserts item at the front of the list."""
64
65     assert isinstance(item, self._list_item_type)
66     self.items.insert(0, item)
67     self._UpdateFilenameAndLineno()
68
69   def Append(self, item):
70     """Appends item to the end of the list."""
71
72     assert isinstance(item, self._list_item_type)
73     self.items.append(item)
74     self._UpdateFilenameAndLineno()
75
76   def _UpdateFilenameAndLineno(self):
77     if self.items:
78       self.filename = self.items[0].filename
79       self.lineno = self.items[0].lineno
80
81
82 class Definition(NodeBase):
83   """Represents a definition of anything that has a global name (e.g., enums,
84   enum values, consts, structs, struct fields, interfaces). (This does not
85   include parameter definitions.) This class is meant to be subclassed."""
86
87   def __init__(self, name, **kwargs):
88     assert isinstance(name, str)
89     NodeBase.__init__(self, **kwargs)
90     self.name = name
91
92
93 ################################################################################
94
95
96 class Attribute(NodeBase):
97   """Represents an attribute."""
98
99   def __init__(self, key, value, **kwargs):
100     assert isinstance(key, str)
101     super(Attribute, self).__init__(**kwargs)
102     self.key = key
103     self.value = value
104
105   def __eq__(self, other):
106     return super(Attribute, self).__eq__(other) and \
107            self.key == other.key and \
108            self.value == other.value
109
110
111 class AttributeList(NodeListBase):
112   """Represents a list attributes."""
113
114   _list_item_type = Attribute
115
116
117 class Const(Definition):
118   """Represents a const definition."""
119
120   def __init__(self, name, typename, value, **kwargs):
121     # The typename is currently passed through as a string.
122     assert isinstance(typename, str)
123     # The value is either a literal (currently passed through as a string) or a
124     # "wrapped identifier".
125     assert isinstance(value, str) or isinstance(value, tuple)
126     super(Const, self).__init__(name, **kwargs)
127     self.typename = typename
128     self.value = value
129
130   def __eq__(self, other):
131     return super(Const, self).__eq__(other) and \
132            self.typename == other.typename and \
133            self.value == other.value
134
135
136 class Enum(Definition):
137   """Represents an enum definition."""
138
139   def __init__(self, name, enum_value_list, **kwargs):
140     assert isinstance(enum_value_list, EnumValueList)
141     super(Enum, self).__init__(name, **kwargs)
142     self.enum_value_list = enum_value_list
143
144   def __eq__(self, other):
145     return super(Enum, self).__eq__(other) and \
146            self.enum_value_list == other.enum_value_list
147
148
149 class EnumValue(Definition):
150   """Represents a definition of an enum value."""
151
152   def __init__(self, name, value, **kwargs):
153     # The optional value is either an int (which is current a string) or a
154     # "wrapped identifier".
155     assert value is None or isinstance(value, (str, tuple))
156     super(EnumValue, self).__init__(name, **kwargs)
157     self.value = value
158
159   def __eq__(self, other):
160     return super(EnumValue, self).__eq__(other) and \
161            self.value == other.value
162
163
164 class EnumValueList(NodeListBase):
165   """Represents a list of enum value definitions (i.e., the "body" of an enum
166   definition)."""
167
168   _list_item_type = EnumValue
169
170
171 class Import(NodeBase):
172   """Represents an import statement."""
173
174   def __init__(self, import_filename, **kwargs):
175     assert isinstance(import_filename, str)
176     super(Import, self).__init__(**kwargs)
177     self.import_filename = import_filename
178
179   def __eq__(self, other):
180     return super(Import, self).__eq__(other) and \
181            self.import_filename == other.import_filename
182
183
184 class ImportList(NodeListBase):
185   """Represents a list (i.e., sequence) of import statements."""
186
187   _list_item_type = Import
188
189
190 class Interface(Definition):
191   """Represents an interface definition."""
192
193   def __init__(self, name, attribute_list, body, **kwargs):
194     assert attribute_list is None or isinstance(attribute_list, AttributeList)
195     assert isinstance(body, InterfaceBody)
196     super(Interface, self).__init__(name, **kwargs)
197     self.attribute_list = attribute_list
198     self.body = body
199
200   def __eq__(self, other):
201     return super(Interface, self).__eq__(other) and \
202            self.attribute_list == other.attribute_list and \
203            self.body == other.body
204
205
206 class Method(Definition):
207   """Represents a method definition."""
208
209   def __init__(self, name, ordinal, parameter_list, response_parameter_list,
210                **kwargs):
211     assert ordinal is None or isinstance(ordinal, Ordinal)
212     assert isinstance(parameter_list, ParameterList)
213     assert response_parameter_list is None or \
214            isinstance(response_parameter_list, ParameterList)
215     super(Method, self).__init__(name, **kwargs)
216     self.ordinal = ordinal
217     self.parameter_list = parameter_list
218     self.response_parameter_list = response_parameter_list
219
220   def __eq__(self, other):
221     return super(Method, self).__eq__(other) and \
222            self.ordinal == other.ordinal and \
223            self.parameter_list == other.parameter_list and \
224            self.response_parameter_list == other.response_parameter_list
225
226
227 # This needs to be declared after |Method|.
228 class InterfaceBody(NodeListBase):
229   """Represents the body of (i.e., list of definitions inside) an interface."""
230
231   _list_item_type = (Const, Enum, Method)
232
233
234 class Module(NodeBase):
235   """Represents a module statement."""
236
237   def __init__(self, name, attribute_list, **kwargs):
238     # |name| is either none or a "wrapped identifier".
239     assert name is None or isinstance(name, tuple)
240     assert attribute_list is None or isinstance(attribute_list, AttributeList)
241     super(Module, self).__init__(**kwargs)
242     self.name = name
243     self.attribute_list = attribute_list
244
245   def __eq__(self, other):
246     return super(Module, self).__eq__(other) and \
247            self.name == other.name and \
248            self.attribute_list == other.attribute_list
249
250
251 class Mojom(NodeBase):
252   """Represents an entire .mojom file. (This is the root node.)"""
253
254   def __init__(self, module, import_list, definition_list, **kwargs):
255     assert module is None or isinstance(module, Module)
256     assert isinstance(import_list, ImportList)
257     assert isinstance(definition_list, list)
258     super(Mojom, self).__init__(**kwargs)
259     self.module = module
260     self.import_list = import_list
261     self.definition_list = definition_list
262
263   def __eq__(self, other):
264     return super(Mojom, self).__eq__(other) and \
265            self.module == other.module and \
266            self.import_list == other.import_list and \
267            self.definition_list == other.definition_list
268
269   def __repr__(self):
270     return "%s(%r, %r, %r)" % (self.__class__.__name__, self.module,
271                                self.import_list, self.definition_list)
272
273
274 class Ordinal(NodeBase):
275   """Represents an ordinal value labeling, e.g., a struct field."""
276
277   def __init__(self, value, **kwargs):
278     assert isinstance(value, int)
279     super(Ordinal, self).__init__(**kwargs)
280     self.value = value
281
282   def __eq__(self, other):
283     return super(Ordinal, self).__eq__(other) and \
284            self.value == other.value
285
286
287 class Parameter(NodeBase):
288   """Represents a method request or response parameter."""
289
290   def __init__(self, name, ordinal, typename, **kwargs):
291     assert isinstance(name, str)
292     assert ordinal is None or isinstance(ordinal, Ordinal)
293     assert isinstance(typename, str)
294     super(Parameter, self).__init__(**kwargs)
295     self.name = name
296     self.ordinal = ordinal
297     self.typename = typename
298
299   def __eq__(self, other):
300     return super(Parameter, self).__eq__(other) and \
301            self.name == other.name and \
302            self.ordinal == other.ordinal and \
303            self.typename == other.typename
304
305
306 class ParameterList(NodeListBase):
307   """Represents a list of (method request or response) parameters."""
308
309   _list_item_type = Parameter
310
311
312 class Struct(Definition):
313   """Represents a struct definition."""
314
315   def __init__(self, name, attribute_list, body, **kwargs):
316     assert attribute_list is None or isinstance(attribute_list, AttributeList)
317     assert isinstance(body, StructBody)
318     super(Struct, self).__init__(name, **kwargs)
319     self.attribute_list = attribute_list
320     self.body = body
321
322   def __eq__(self, other):
323     return super(Struct, self).__eq__(other) and \
324            self.attribute_list == other.attribute_list and \
325            self.body == other.body
326
327
328 class StructField(Definition):
329   """Represents a struct field definition."""
330
331   def __init__(self, name, ordinal, typename, default_value, **kwargs):
332     assert isinstance(name, str)
333     assert ordinal is None or isinstance(ordinal, Ordinal)
334     assert isinstance(typename, str)
335     # The optional default value is currently either a value as a string or a
336     # "wrapped identifier".
337     assert default_value is None or isinstance(default_value, (str, tuple))
338     super(StructField, self).__init__(name, **kwargs)
339     self.ordinal = ordinal
340     self.typename = typename
341     self.default_value = default_value
342
343   def __eq__(self, other):
344     return super(StructField, self).__eq__(other) and \
345            self.ordinal == other.ordinal and \
346            self.typename == other.typename and \
347            self.default_value == other.default_value
348
349
350 # This needs to be declared after |StructField|.
351 class StructBody(NodeListBase):
352   """Represents the body of (i.e., list of definitions inside) a struct."""
353
354   _list_item_type = (Const, Enum, StructField)