Index: mojo/public/tools/bindings/pylib/mojom/parse/ast.py |
diff --git a/mojo/public/tools/bindings/pylib/mojom/parse/ast.py b/mojo/public/tools/bindings/pylib/mojom/parse/ast.py |
index be8d20e634dd9987a57a41c23ae9a406c1c0545b..78017e56a645aecc25fae1e960942f9796981269 100644 |
--- a/mojo/public/tools/bindings/pylib/mojom/parse/ast.py |
+++ b/mojo/public/tools/bindings/pylib/mojom/parse/ast.py |
@@ -9,7 +9,7 @@ |
# and lineno). |
-class BaseNode(object): |
+class NodeBase(object): |
"""Base class for nodes in the AST.""" |
def __init__(self, filename=None, lineno=None): |
@@ -17,23 +17,23 @@ class BaseNode(object): |
self.lineno = lineno |
-class Ordinal(BaseNode): |
+class Ordinal(NodeBase): |
"""Represents an ordinal value labeling, e.g., a struct field.""" |
def __init__(self, value, **kwargs): |
- BaseNode.__init__(self, **kwargs) |
+ NodeBase.__init__(self, **kwargs) |
self.value = value |
def __eq__(self, other): |
return self.value == other.value |
-class Parameter(BaseNode): |
+class Parameter(NodeBase): |
"""Represents a method request or response parameter.""" |
def __init__(self, typename, name, ordinal, **kwargs): |
assert isinstance(ordinal, Ordinal) |
- BaseNode.__init__(self, **kwargs) |
+ NodeBase.__init__(self, **kwargs) |
self.typename = typename |
self.name = name |
self.ordinal = ordinal |
@@ -42,3 +42,53 @@ class Parameter(BaseNode): |
return self.typename == other.typename and \ |
self.name == other.name and \ |
self.ordinal == other.ordinal |
+ |
+ |
+class NodeListBase(NodeBase): |
+ """Represents a list of other nodes, all having the same type. (This is meant |
+ to be subclassed, with subclasses defining _list_item_type to be the class of |
+ the members of the list; _list_item_type should also be a NodeBase.)""" |
+ |
+ def __init__(self, item_or_items=None, **kwargs): |
+ assert issubclass(self._list_item_type, NodeBase) |
+ NodeBase.__init__(self, **kwargs) |
+ if item_or_items is None: |
+ self.elements = [] |
+ elif isinstance(item_or_items, list): |
+ # TODO(vtl): Possibly we should assert that each element of the list is a |
+ # |_list_item_type|. |
+ self.elements = list(item_or_items) |
+ else: |
+ assert isinstance(item_or_items, self._list_item_type) |
+ self.elements = [item_or_items] |
+ self._UpdateFilenameAndLineno() |
+ |
+ # Support iteration. For everything else, users should just access |elements| |
+ # directly. (We intentionally do NOT supply |__len__()| or |__nonzero__()|, so |
+ # |bool(NodeListBase())| is true.) |
+ def __iter__(self): |
+ return self.elements.__iter__() |
+ |
+ def __eq__(self, other): |
+ if type(self) != type(other): |
+ return False |
+ for element in self.elements: |
+ if self.elements != other.elements: |
+ return False |
+ return True |
+ |
+ def Append(self, item): |
+ assert isinstance(item, self._list_item_type) |
+ self.elements.append(item) |
+ self._UpdateFilenameAndLineno() |
+ |
+ def _UpdateFilenameAndLineno(self): |
+ if self.elements: |
+ self.filename = self.elements[0].filename |
+ self.lineno = self.elements[0].lineno |
+ |
+ |
+class ParameterList(NodeListBase): |
+ """Represents a list of (method request or response) parameters.""" |
+ |
+ _list_item_type = Parameter |