Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(173)

Side by Side Diff: mojo/public/tools/bindings/pylib/mojom/parse/ast.py

Issue 398553002: Mojo: Mojom: Add AST types for struct and struct body. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | mojo/public/tools/bindings/pylib/mojom/parse/parser.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 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 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Node classes for the AST for a Mojo IDL file.""" 5 """Node classes for the AST for a Mojo IDL file."""
6 6
7 # Note: For convenience of testing, you probably want to define __eq__() methods 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 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 9 # and lineno). You may also define __repr__() to help with analyzing test
10 # failures, especially for more complex types. 10 # failures, especially for more complex types.
11 11
12 12
13 class NodeBase(object): 13 class NodeBase(object):
14 """Base class for nodes in the AST.""" 14 """Base class for nodes in the AST."""
15 15
16 def __init__(self, filename=None, lineno=None): 16 def __init__(self, filename=None, lineno=None):
17 self.filename = filename 17 self.filename = filename
18 self.lineno = lineno 18 self.lineno = lineno
19 19
20 def __eq__(self, other): 20 def __eq__(self, other):
21 return type(self) == type(other) 21 return type(self) == type(other)
22 22
23 23
24 # TODO(vtl): Some of this is complicated enough that it should be tested. 24 # TODO(vtl): Some of this is complicated enough that it should be tested.
25 class NodeListBase(NodeBase): 25 class NodeListBase(NodeBase):
26 """Represents a list of other nodes, all having the same type. (This is meant 26 """Represents a list of other nodes, all having the same type. (This is meant
27 to be subclassed, with subclasses defining _list_item_type to be the class of 27 to be subclassed, with subclasses defining _list_item_type to be the class (or
28 the members of the list; _list_item_type should also be a NodeBase.)""" 28 classes, in a tuple) of the members of the list.)"""
29 29
30 def __init__(self, item_or_items=None, **kwargs): 30 def __init__(self, item_or_items=None, **kwargs):
31 assert issubclass(self._list_item_type, NodeBase)
32 super(NodeListBase, self).__init__(**kwargs) 31 super(NodeListBase, self).__init__(**kwargs)
32 self.items = []
33 if item_or_items is None: 33 if item_or_items is None:
34 self.elements = [] 34 pass
DaveMoore 2014/07/16 18:07:08 Nit: isn't this a noop?
viettrungluu 2014/07/16 18:17:59 Oops. Let me fix that separately, so that I don't
35 self.items = []
35 elif isinstance(item_or_items, list): 36 elif isinstance(item_or_items, list):
36 # TODO(vtl): Possibly we should assert that each element of the list is a 37 for item in item_or_items:
37 # |_list_item_type|. 38 assert isinstance(item, self._list_item_type)
38 self.elements = list(item_or_items) 39 self.Append(item)
39 else: 40 else:
40 assert isinstance(item_or_items, self._list_item_type) 41 assert isinstance(item_or_items, self._list_item_type)
41 self.elements = [item_or_items] 42 self.Append(item_or_items)
42 self._UpdateFilenameAndLineno()
43 43
44 # Support iteration. For everything else, users should just access |elements| 44 # Support iteration. For everything else, users should just access |items|
45 # directly. (We intentionally do NOT supply |__len__()| or |__nonzero__()|, so 45 # directly. (We intentionally do NOT supply |__len__()| or |__nonzero__()|, so
46 # |bool(NodeListBase())| is true.) 46 # |bool(NodeListBase())| is true.)
47 def __iter__(self): 47 def __iter__(self):
48 return self.elements.__iter__() 48 return self.items.__iter__()
49 49
50 def __eq__(self, other): 50 def __eq__(self, other):
51 return super(NodeListBase, self).__eq__(other) and \ 51 return super(NodeListBase, self).__eq__(other) and \
52 len(self.elements) == len(other.elements) and \ 52 len(self.items) == len(other.items) and \
53 all(self.elements[i] == other.elements[i] \ 53 all(self.items[i] == other.items[i] for i in xrange(len(self.items)))
54 for i in xrange(len(self.elements)))
55 54
56 # Implement this so that on failure, we get slightly more sensible output. 55 # Implement this so that on failure, we get slightly more sensible output.
57 def __repr__(self): 56 def __repr__(self):
58 return self.__class__.__name__ + "([" + \ 57 return self.__class__.__name__ + "([" + \
59 ", ".join([repr(elem) for elem in self.elements]) + "])" 58 ", ".join([repr(elem) for elem in self.items]) + "])"
59
60 def Insert(self, item):
61 """Inserts item at the front of the list."""
62
63 assert isinstance(item, self._list_item_type)
64 self.items.insert(0, item)
65 self._UpdateFilenameAndLineno()
60 66
61 def Append(self, item): 67 def Append(self, item):
68 """Appends item to the end of the list."""
69
62 assert isinstance(item, self._list_item_type) 70 assert isinstance(item, self._list_item_type)
63 self.elements.append(item) 71 self.items.append(item)
64 self._UpdateFilenameAndLineno() 72 self._UpdateFilenameAndLineno()
65 73
66 def _UpdateFilenameAndLineno(self): 74 def _UpdateFilenameAndLineno(self):
67 if self.elements: 75 if self.items:
68 self.filename = self.elements[0].filename 76 self.filename = self.items[0].filename
69 self.lineno = self.elements[0].lineno 77 self.lineno = self.items[0].lineno
70 78
71 79
72 class Definition(NodeBase): 80 class Definition(NodeBase):
73 """Represents a definition of anything that has a global name (e.g., enums, 81 """Represents a definition of anything that has a global name (e.g., enums,
74 enum values, consts, structs, struct fields, interfaces). (This does not 82 enum values, consts, structs, struct fields, interfaces). (This does not
75 include parameter definitions.) This class is meant to be subclassed.""" 83 include parameter definitions.) This class is meant to be subclassed."""
76 84
77 def __init__(self, name, **kwargs): 85 def __init__(self, name, **kwargs):
78 assert isinstance(name, str) 86 assert isinstance(name, str)
79 NodeBase.__init__(self, **kwargs) 87 NodeBase.__init__(self, **kwargs)
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 self.ordinal == other.ordinal and \ 256 self.ordinal == other.ordinal and \
249 self.typename == other.typename 257 self.typename == other.typename
250 258
251 259
252 class ParameterList(NodeListBase): 260 class ParameterList(NodeListBase):
253 """Represents a list of (method request or response) parameters.""" 261 """Represents a list of (method request or response) parameters."""
254 262
255 _list_item_type = Parameter 263 _list_item_type = Parameter
256 264
257 265
266 class Struct(Definition):
267 """Represents a struct definition."""
268
269 def __init__(self, name, attribute_list, body, **kwargs):
270 assert attribute_list is None or isinstance(attribute_list, AttributeList)
271 assert isinstance(body, StructBody)
272 super(Struct, self).__init__(name, **kwargs)
273 self.attribute_list = attribute_list
274 self.body = body
275
276 def __eq__(self, other):
277 return super(Struct, self).__eq__(other) and \
278 self.attribute_list == other.attribute_list and \
279 self.body == other.body
280
281
258 class StructField(Definition): 282 class StructField(Definition):
259 """Represents a struct field definition.""" 283 """Represents a struct field definition."""
260 284
261 def __init__(self, name, ordinal, typename, default_value, **kwargs): 285 def __init__(self, name, ordinal, typename, default_value, **kwargs):
262 assert isinstance(name, str) 286 assert isinstance(name, str)
263 assert ordinal is None or isinstance(ordinal, Ordinal) 287 assert ordinal is None or isinstance(ordinal, Ordinal)
264 assert isinstance(typename, str) 288 assert isinstance(typename, str)
265 # The optional default value is currently either a value as a string or a 289 # The optional default value is currently either a value as a string or a
266 # "wrapped identifier". 290 # "wrapped identifier".
267 assert default_value is None or isinstance(default_value, (str, tuple)) 291 assert default_value is None or isinstance(default_value, (str, tuple))
268 super(StructField, self).__init__(name, **kwargs) 292 super(StructField, self).__init__(name, **kwargs)
269 self.ordinal = ordinal 293 self.ordinal = ordinal
270 self.typename = typename 294 self.typename = typename
271 self.default_value = default_value 295 self.default_value = default_value
272 296
273 def __eq__(self, other): 297 def __eq__(self, other):
274 return super(StructField, self).__eq__(other) and \ 298 return super(StructField, self).__eq__(other) and \
275 self.ordinal == other.ordinal and \ 299 self.ordinal == other.ordinal and \
276 self.typename == other.typename and \ 300 self.typename == other.typename and \
277 self.default_value == other.default_value 301 self.default_value == other.default_value
302
303
304 # This needs to be declared after |StructField|.
305 class StructBody(NodeListBase):
306 """Represents the body of (i.e., list of definitions inside) a struct."""
307
308 _list_item_type = (Const, Enum, StructField)
OLDNEW
« no previous file with comments | « no previous file | mojo/public/tools/bindings/pylib/mojom/parse/parser.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698