Mojo: Mojom: Add AST types for methods, interface bodies, and interfaces.

R=davemoore@chromium.org

Review URL: https://codereview.chromium.org/396783002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283439 0039d316-1c4b-4281-b951-d872f2087c98
parent 3824746b
...@@ -185,6 +185,50 @@ class ImportList(NodeListBase): ...@@ -185,6 +185,50 @@ class ImportList(NodeListBase):
_list_item_type = Import _list_item_type = Import
class Interface(Definition):
"""Represents an interface definition."""
def __init__(self, name, attribute_list, body, **kwargs):
assert attribute_list is None or isinstance(attribute_list, AttributeList)
assert isinstance(body, InterfaceBody)
super(Interface, self).__init__(name, **kwargs)
self.attribute_list = attribute_list
self.body = body
def __eq__(self, other):
return super(Interface, self).__eq__(other) and \
self.attribute_list == other.attribute_list and \
self.body == other.body
class Method(Definition):
"""Represents a method definition."""
def __init__(self, name, ordinal, parameter_list, response_parameter_list,
**kwargs):
assert ordinal is None or isinstance(ordinal, Ordinal)
assert isinstance(parameter_list, ParameterList)
assert response_parameter_list is None or \
isinstance(response_parameter_list, ParameterList)
super(Method, self).__init__(name, **kwargs)
self.ordinal = ordinal
self.parameter_list = parameter_list
self.response_parameter_list = response_parameter_list
def __eq__(self, other):
return super(Method, self).__eq__(other) and \
self.ordinal == other.ordinal and \
self.parameter_list == other.parameter_list and \
self.response_parameter_list == other.response_parameter_list
# This needs to be declared after |Method|.
class InterfaceBody(NodeListBase):
"""Represents the body of (i.e., list of definitions inside) an interface."""
_list_item_type = (Const, Enum, Method)
class Module(NodeBase): class Module(NodeBase):
"""Represents a module statement.""" """Represents a module statement."""
......
...@@ -197,25 +197,30 @@ class Parser(object): ...@@ -197,25 +197,30 @@ class Parser(object):
def p_interface(self, p): def p_interface(self, p):
"""interface : attribute_section INTERFACE NAME LBRACE interface_body \ """interface : attribute_section INTERFACE NAME LBRACE interface_body \
RBRACE SEMI""" RBRACE SEMI"""
p[0] = ('INTERFACE', p[3], p[1], p[5]) p[0] = ast.Interface(p[3], p[1], p[5])
def p_interface_body(self, p): def p_interface_body_1(self, p):
"""interface_body : method interface_body """interface_body : """
| enum interface_body p[0] = ast.InterfaceBody()
| const interface_body
| """ def p_interface_body_2(self, p):
if len(p) > 1: """interface_body : interface_body const
p[0] = _ListFromConcat(p[1], p[2]) | interface_body enum
| interface_body method"""
p[0] = p[1]
p[0].Append(p[2])
def p_response_1(self, p):
"""response : """
p[0] = None
def p_response(self, p): def p_response_2(self, p):
"""response : RESPONSE LPAREN parameter_list RPAREN """response : RESPONSE LPAREN parameter_list RPAREN"""
| """ p[0] = p[3]
if len(p) > 3:
p[0] = p[3]
def p_method(self, p): def p_method(self, p):
"""method : NAME ordinal LPAREN parameter_list RPAREN response SEMI""" """method : NAME ordinal LPAREN parameter_list RPAREN response SEMI"""
p[0] = ('METHOD', p[1], p[4], p[2], p[6]) p[0] = ast.Method(p[1], p[2], p[4], p[6])
def p_parameter_list_1(self, p): def p_parameter_list_1(self, p):
"""parameter_list : """ """parameter_list : """
......
...@@ -67,35 +67,7 @@ def _AttributeListToDict(attribute_list): ...@@ -67,35 +67,7 @@ def _AttributeListToDict(attribute_list):
return dict([(attribute.key, attribute.value) return dict([(attribute.key, attribute.value)
for attribute in attribute_list]) for attribute in attribute_list])
def _MapMethod(tree): def _EnumToDict(enum):
assert isinstance(tree[2], ast.ParameterList)
assert tree[3] is None or isinstance(tree[3], ast.Ordinal)
assert tree[4] is None or isinstance(tree[2], ast.ParameterList)
def ParameterToDict(param):
assert isinstance(param, ast.Parameter)
return {'name': param.name,
'kind': _MapKind(param.typename),
'ordinal': param.ordinal.value if param.ordinal else None}
method = {'name': tree[1],
'parameters': map(ParameterToDict, tree[2]),
'ordinal': tree[3].value if tree[3] else None}
if tree[4]:
method['response_parameters'] = map(ParameterToDict, tree[4])
return method
def _MapInterface(tree):
interface = {}
interface['name'] = tree[1]
interface['attributes'] = _AttributeListToDict(tree[2])
interface['client'] = interface['attributes'].get('Client')
interface['methods'] = _MapTreeForName(_MapMethod, tree[3], 'METHOD')
interface['enums'] = _MapTreeForType(_MapEnum, tree[3], ast.Enum)
interface['constants'] = _MapTreeForType(_MapConstant, tree[3], ast.Const)
return interface
def _MapEnum(enum):
def EnumValueToDict(enum_value): def EnumValueToDict(enum_value):
assert isinstance(enum_value, ast.EnumValue) assert isinstance(enum_value, ast.EnumValue)
return {'name': enum_value.name, return {'name': enum_value.name,
...@@ -105,7 +77,7 @@ def _MapEnum(enum): ...@@ -105,7 +77,7 @@ def _MapEnum(enum):
return {'name': enum.name, return {'name': enum.name,
'fields': map(EnumValueToDict, enum.enum_value_list)} 'fields': map(EnumValueToDict, enum.enum_value_list)}
def _MapConstant(const): def _ConstToDict(const):
assert isinstance(const, ast.Const) assert isinstance(const, ast.Const)
return {'name': const.name, return {'name': const.name,
'kind': _MapKind(const.typename), 'kind': _MapKind(const.typename),
...@@ -131,8 +103,36 @@ class _MojomBuilder(object): ...@@ -131,8 +103,36 @@ class _MojomBuilder(object):
'attributes': _AttributeListToDict(struct.attribute_list), 'attributes': _AttributeListToDict(struct.attribute_list),
'fields': _MapTreeForType(StructFieldToDict, struct.body, 'fields': _MapTreeForType(StructFieldToDict, struct.body,
ast.StructField), ast.StructField),
'enums': _MapTreeForType(_MapEnum, struct.body, ast.Enum), 'enums': _MapTreeForType(_EnumToDict, struct.body, ast.Enum),
'constants': _MapTreeForType(_MapConstant, struct.body, 'constants': _MapTreeForType(_ConstToDict, struct.body,
ast.Const)}
def InterfaceToDict(interface):
def MethodToDict(method):
def ParameterToDict(param):
assert isinstance(param, ast.Parameter)
return {'name': param.name,
'kind': _MapKind(param.typename),
'ordinal': param.ordinal.value if param.ordinal else None}
assert isinstance(method, ast.Method)
rv = {'name': method.name,
'parameters': map(ParameterToDict, method.parameter_list),
'ordinal': method.ordinal.value if method.ordinal else None}
if method.response_parameter_list is not None:
rv['response_parameters'] = map(ParameterToDict,
method.response_parameter_list)
return rv
assert isinstance(interface, ast.Interface)
attributes = _AttributeListToDict(interface.attribute_list)
return {'name': interface.name,
'attributes': attributes,
'client': attributes.get('Client'),
'methods': _MapTreeForType(MethodToDict, interface.body,
ast.Method),
'enums': _MapTreeForType(_EnumToDict, interface.body, ast.Enum),
'constants': _MapTreeForType(_ConstToDict, interface.body,
ast.Const)} ast.Const)}
assert isinstance(tree, ast.Mojom) assert isinstance(tree, ast.Mojom)
...@@ -145,11 +145,11 @@ class _MojomBuilder(object): ...@@ -145,11 +145,11 @@ class _MojomBuilder(object):
self.mojom['structs'] = \ self.mojom['structs'] = \
_MapTreeForType(StructToDict, tree.definition_list, ast.Struct) _MapTreeForType(StructToDict, tree.definition_list, ast.Struct)
self.mojom['interfaces'] = \ self.mojom['interfaces'] = \
_MapTreeForName(_MapInterface, tree.definition_list, 'INTERFACE') _MapTreeForType(InterfaceToDict, tree.definition_list, ast.Interface)
self.mojom['enums'] = \ self.mojom['enums'] = \
_MapTreeForType(_MapEnum, tree.definition_list, ast.Enum) _MapTreeForType(_EnumToDict, tree.definition_list, ast.Enum)
self.mojom['constants'] = \ self.mojom['constants'] = \
_MapTreeForType(_MapConstant, tree.definition_list, ast.Const) _MapTreeForType(_ConstToDict, tree.definition_list, ast.Const)
return self.mojom return self.mojom
......
...@@ -626,14 +626,15 @@ class ParserTest(unittest.TestCase): ...@@ -626,14 +626,15 @@ class ParserTest(unittest.TestCase):
expected1 = ast.Mojom( expected1 = ast.Mojom(
None, None,
ast.ImportList(), ast.ImportList(),
[('INTERFACE', [ast.Interface(
'MyInterface', 'MyInterface',
None,
[('METHOD',
'MyMethod',
ast.ParameterList(ast.Parameter('a', None, 'int32')),
None, None,
None)])]) ast.InterfaceBody(
ast.Method(
'MyMethod',
None,
ast.ParameterList(ast.Parameter('a', None, 'int32')),
None)))])
self.assertEquals(parser.Parse(source1, "my_file.mojom"), expected1) self.assertEquals(parser.Parse(source1, "my_file.mojom"), expected1)
source2 = """\ source2 = """\
...@@ -645,20 +646,23 @@ class ParserTest(unittest.TestCase): ...@@ -645,20 +646,23 @@ class ParserTest(unittest.TestCase):
expected2 = ast.Mojom( expected2 = ast.Mojom(
None, None,
ast.ImportList(), ast.ImportList(),
[('INTERFACE', [ast.Interface(
'MyInterface', 'MyInterface',
None, None,
[('METHOD', ast.InterfaceBody([
'MyMethod1', ast.Method(
ast.ParameterList([ast.Parameter('a', ast.Ordinal(0), 'int32'), 'MyMethod1',
ast.Parameter('b', ast.Ordinal(1), 'int64')]), ast.Ordinal(0),
ast.Ordinal(0), ast.ParameterList([ast.Parameter('a', ast.Ordinal(0),
None), 'int32'),
('METHOD', ast.Parameter('b', ast.Ordinal(1),
'MyMethod2', 'int64')]),
ast.ParameterList(), None),
ast.Ordinal(1), ast.Method(
ast.ParameterList())])]) 'MyMethod2',
ast.Ordinal(1),
ast.ParameterList(),
ast.ParameterList())]))])
self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2) self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2)
source3 = """\ source3 = """\
...@@ -669,15 +673,16 @@ class ParserTest(unittest.TestCase): ...@@ -669,15 +673,16 @@ class ParserTest(unittest.TestCase):
expected3 = ast.Mojom( expected3 = ast.Mojom(
None, None,
ast.ImportList(), ast.ImportList(),
[('INTERFACE', [ast.Interface(
'MyInterface', 'MyInterface',
None,
[('METHOD',
'MyMethod',
ast.ParameterList(ast.Parameter('a', None, 'string')),
None, None,
ast.ParameterList([ast.Parameter('a', None, 'int32'), ast.InterfaceBody(
ast.Parameter('b', None, 'bool')]))])]) ast.Method(
'MyMethod',
None,
ast.ParameterList(ast.Parameter('a', None, 'string')),
ast.ParameterList([ast.Parameter('a', None, 'int32'),
ast.Parameter('b', None, 'bool')]))))])
self.assertEquals(parser.Parse(source3, "my_file.mojom"), expected3) self.assertEquals(parser.Parse(source3, "my_file.mojom"), expected3)
def testInvalidMethods(self): def testInvalidMethods(self):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment