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):
_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):
"""Represents a module statement."""
......
......@@ -197,25 +197,30 @@ class Parser(object):
def p_interface(self, p):
"""interface : attribute_section INTERFACE NAME LBRACE interface_body \
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):
"""interface_body : method interface_body
| enum interface_body
| const interface_body
| """
if len(p) > 1:
p[0] = _ListFromConcat(p[1], p[2])
def p_interface_body_1(self, p):
"""interface_body : """
p[0] = ast.InterfaceBody()
def p_interface_body_2(self, p):
"""interface_body : interface_body const
| 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):
"""response : RESPONSE LPAREN parameter_list RPAREN
| """
if len(p) > 3:
p[0] = p[3]
def p_response_2(self, p):
"""response : RESPONSE LPAREN parameter_list RPAREN"""
p[0] = p[3]
def p_method(self, p):
"""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):
"""parameter_list : """
......
......@@ -67,35 +67,7 @@ def _AttributeListToDict(attribute_list):
return dict([(attribute.key, attribute.value)
for attribute in attribute_list])
def _MapMethod(tree):
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 _EnumToDict(enum):
def EnumValueToDict(enum_value):
assert isinstance(enum_value, ast.EnumValue)
return {'name': enum_value.name,
......@@ -105,7 +77,7 @@ def _MapEnum(enum):
return {'name': enum.name,
'fields': map(EnumValueToDict, enum.enum_value_list)}
def _MapConstant(const):
def _ConstToDict(const):
assert isinstance(const, ast.Const)
return {'name': const.name,
'kind': _MapKind(const.typename),
......@@ -131,8 +103,36 @@ class _MojomBuilder(object):
'attributes': _AttributeListToDict(struct.attribute_list),
'fields': _MapTreeForType(StructFieldToDict, struct.body,
ast.StructField),
'enums': _MapTreeForType(_MapEnum, struct.body, ast.Enum),
'constants': _MapTreeForType(_MapConstant, struct.body,
'enums': _MapTreeForType(_EnumToDict, struct.body, ast.Enum),
'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)}
assert isinstance(tree, ast.Mojom)
......@@ -145,11 +145,11 @@ class _MojomBuilder(object):
self.mojom['structs'] = \
_MapTreeForType(StructToDict, tree.definition_list, ast.Struct)
self.mojom['interfaces'] = \
_MapTreeForName(_MapInterface, tree.definition_list, 'INTERFACE')
_MapTreeForType(InterfaceToDict, tree.definition_list, ast.Interface)
self.mojom['enums'] = \
_MapTreeForType(_MapEnum, tree.definition_list, ast.Enum)
_MapTreeForType(_EnumToDict, tree.definition_list, ast.Enum)
self.mojom['constants'] = \
_MapTreeForType(_MapConstant, tree.definition_list, ast.Const)
_MapTreeForType(_ConstToDict, tree.definition_list, ast.Const)
return self.mojom
......
......@@ -626,14 +626,15 @@ class ParserTest(unittest.TestCase):
expected1 = ast.Mojom(
None,
ast.ImportList(),
[('INTERFACE',
'MyInterface',
None,
[('METHOD',
'MyMethod',
ast.ParameterList(ast.Parameter('a', None, 'int32')),
[ast.Interface(
'MyInterface',
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)
source2 = """\
......@@ -645,20 +646,23 @@ class ParserTest(unittest.TestCase):
expected2 = ast.Mojom(
None,
ast.ImportList(),
[('INTERFACE',
'MyInterface',
None,
[('METHOD',
'MyMethod1',
ast.ParameterList([ast.Parameter('a', ast.Ordinal(0), 'int32'),
ast.Parameter('b', ast.Ordinal(1), 'int64')]),
ast.Ordinal(0),
None),
('METHOD',
'MyMethod2',
ast.ParameterList(),
ast.Ordinal(1),
ast.ParameterList())])])
[ast.Interface(
'MyInterface',
None,
ast.InterfaceBody([
ast.Method(
'MyMethod1',
ast.Ordinal(0),
ast.ParameterList([ast.Parameter('a', ast.Ordinal(0),
'int32'),
ast.Parameter('b', ast.Ordinal(1),
'int64')]),
None),
ast.Method(
'MyMethod2',
ast.Ordinal(1),
ast.ParameterList(),
ast.ParameterList())]))])
self.assertEquals(parser.Parse(source2, "my_file.mojom"), expected2)
source3 = """\
......@@ -669,15 +673,16 @@ class ParserTest(unittest.TestCase):
expected3 = ast.Mojom(
None,
ast.ImportList(),
[('INTERFACE',
'MyInterface',
None,
[('METHOD',
'MyMethod',
ast.ParameterList(ast.Parameter('a', None, 'string')),
[ast.Interface(
'MyInterface',
None,
ast.ParameterList([ast.Parameter('a', None, 'int32'),
ast.Parameter('b', None, 'bool')]))])])
ast.InterfaceBody(
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)
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