| OLD | NEW |
| (Empty) |
| 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 """Translates parse tree to Mojom IR.""" | |
| 6 | |
| 7 | |
| 8 from . import ast | |
| 9 | |
| 10 | |
| 11 def _MapTreeForType(func, tree, type_to_map): | |
| 12 assert isinstance(type_to_map, type) | |
| 13 if not tree: | |
| 14 return [] | |
| 15 return [func(subtree) for subtree in tree if isinstance(subtree, type_to_map)] | |
| 16 | |
| 17 def _MapKind(kind): | |
| 18 map_to_kind = {'bool': 'b', | |
| 19 'int8': 'i8', | |
| 20 'int16': 'i16', | |
| 21 'int32': 'i32', | |
| 22 'int64': 'i64', | |
| 23 'uint8': 'u8', | |
| 24 'uint16': 'u16', | |
| 25 'uint32': 'u32', | |
| 26 'uint64': 'u64', | |
| 27 'float': 'f', | |
| 28 'double': 'd', | |
| 29 'string': 's', | |
| 30 'handle': 'h', | |
| 31 'handle<data_pipe_consumer>': 'h:d:c', | |
| 32 'handle<data_pipe_producer>': 'h:d:p', | |
| 33 'handle<message_pipe>': 'h:m', | |
| 34 'handle<shared_buffer>': 'h:s'} | |
| 35 if kind.endswith('?'): | |
| 36 base_kind = _MapKind(kind[0:-1]) | |
| 37 # NOTE: This doesn't rule out enum types. Those will be detected later, when | |
| 38 # cross-reference is established. | |
| 39 reference_kinds = ('m', 's', 'h', 'a', 'r', 'x') | |
| 40 if base_kind[0] not in reference_kinds: | |
| 41 raise Exception( | |
| 42 'A type (spec "%s") cannot be made nullable' % base_kind) | |
| 43 return '?' + base_kind | |
| 44 if kind.endswith('}'): | |
| 45 lbracket = kind.rfind('{') | |
| 46 value = kind[0:lbracket] | |
| 47 return 'm[' + _MapKind(kind[lbracket+1:-1]) + '][' + _MapKind(value) + ']' | |
| 48 if kind.endswith(']'): | |
| 49 lbracket = kind.rfind('[') | |
| 50 typename = kind[0:lbracket] | |
| 51 return 'a' + kind[lbracket+1:-1] + ':' + _MapKind(typename) | |
| 52 if kind.endswith('&'): | |
| 53 return 'r:' + _MapKind(kind[0:-1]) | |
| 54 if kind in map_to_kind: | |
| 55 return map_to_kind[kind] | |
| 56 return 'x:' + kind | |
| 57 | |
| 58 def _AttributeListToDict(attribute_list): | |
| 59 if attribute_list is None: | |
| 60 return {} | |
| 61 assert isinstance(attribute_list, ast.AttributeList) | |
| 62 # TODO(vtl): Check for duplicate keys here. | |
| 63 return dict([(attribute.key, attribute.value) | |
| 64 for attribute in attribute_list]) | |
| 65 | |
| 66 def _EnumToDict(enum): | |
| 67 def EnumValueToDict(enum_value): | |
| 68 assert isinstance(enum_value, ast.EnumValue) | |
| 69 return {'name': enum_value.name, | |
| 70 'value': enum_value.value} | |
| 71 | |
| 72 assert isinstance(enum, ast.Enum) | |
| 73 return {'name': enum.name, | |
| 74 'fields': map(EnumValueToDict, enum.enum_value_list)} | |
| 75 | |
| 76 def _ConstToDict(const): | |
| 77 assert isinstance(const, ast.Const) | |
| 78 return {'name': const.name, | |
| 79 'kind': _MapKind(const.typename), | |
| 80 'value': const.value} | |
| 81 | |
| 82 | |
| 83 class _MojomBuilder(object): | |
| 84 def __init__(self): | |
| 85 self.mojom = {} | |
| 86 | |
| 87 def Build(self, tree, name): | |
| 88 def StructToDict(struct): | |
| 89 def StructFieldToDict(struct_field): | |
| 90 assert isinstance(struct_field, ast.StructField) | |
| 91 return {'name': struct_field.name, | |
| 92 'kind': _MapKind(struct_field.typename), | |
| 93 'ordinal': struct_field.ordinal.value \ | |
| 94 if struct_field.ordinal else None, | |
| 95 'default': struct_field.default_value} | |
| 96 | |
| 97 assert isinstance(struct, ast.Struct) | |
| 98 return {'name': struct.name, | |
| 99 'attributes': _AttributeListToDict(struct.attribute_list), | |
| 100 'fields': _MapTreeForType(StructFieldToDict, struct.body, | |
| 101 ast.StructField), | |
| 102 'enums': _MapTreeForType(_EnumToDict, struct.body, ast.Enum), | |
| 103 'constants': _MapTreeForType(_ConstToDict, struct.body, | |
| 104 ast.Const)} | |
| 105 | |
| 106 def UnionToDict(union): | |
| 107 def UnionFieldToDict(union_field): | |
| 108 assert isinstance(union_field, ast.UnionField) | |
| 109 return {'name': union_field.name, | |
| 110 'kind': _MapKind(union_field.typename), | |
| 111 'ordinal': union_field.ordinal.value \ | |
| 112 if union_field.ordinal else None} | |
| 113 assert isinstance(union, ast.Union) | |
| 114 return {'name': union.name, | |
| 115 'fields': _MapTreeForType(UnionFieldToDict, union.body, | |
| 116 ast.UnionField)} | |
| 117 | |
| 118 def InterfaceToDict(interface): | |
| 119 def MethodToDict(method): | |
| 120 def ParameterToDict(param): | |
| 121 assert isinstance(param, ast.Parameter) | |
| 122 return {'name': param.name, | |
| 123 'kind': _MapKind(param.typename), | |
| 124 'ordinal': param.ordinal.value if param.ordinal else None} | |
| 125 | |
| 126 assert isinstance(method, ast.Method) | |
| 127 rv = {'name': method.name, | |
| 128 'parameters': map(ParameterToDict, method.parameter_list), | |
| 129 'ordinal': method.ordinal.value if method.ordinal else None} | |
| 130 if method.response_parameter_list is not None: | |
| 131 rv['response_parameters'] = map(ParameterToDict, | |
| 132 method.response_parameter_list) | |
| 133 return rv | |
| 134 | |
| 135 assert isinstance(interface, ast.Interface) | |
| 136 attributes = _AttributeListToDict(interface.attribute_list) | |
| 137 return {'name': interface.name, | |
| 138 'attributes': attributes, | |
| 139 'client': attributes.get('Client'), | |
| 140 'methods': _MapTreeForType(MethodToDict, interface.body, | |
| 141 ast.Method), | |
| 142 'enums': _MapTreeForType(_EnumToDict, interface.body, ast.Enum), | |
| 143 'constants': _MapTreeForType(_ConstToDict, interface.body, | |
| 144 ast.Const)} | |
| 145 | |
| 146 assert isinstance(tree, ast.Mojom) | |
| 147 self.mojom['name'] = name | |
| 148 self.mojom['namespace'] = tree.module.name[1] if tree.module else '' | |
| 149 self.mojom['imports'] = \ | |
| 150 [{'filename': imp.import_filename} for imp in tree.import_list] | |
| 151 self.mojom['attributes'] = \ | |
| 152 _AttributeListToDict(tree.module.attribute_list) if tree.module else {} | |
| 153 self.mojom['structs'] = \ | |
| 154 _MapTreeForType(StructToDict, tree.definition_list, ast.Struct) | |
| 155 self.mojom['union'] = \ | |
| 156 _MapTreeForType(UnionToDict, tree.definition_list, ast.Union) | |
| 157 self.mojom['interfaces'] = \ | |
| 158 _MapTreeForType(InterfaceToDict, tree.definition_list, ast.Interface) | |
| 159 self.mojom['enums'] = \ | |
| 160 _MapTreeForType(_EnumToDict, tree.definition_list, ast.Enum) | |
| 161 self.mojom['constants'] = \ | |
| 162 _MapTreeForType(_ConstToDict, tree.definition_list, ast.Const) | |
| 163 return self.mojom | |
| 164 | |
| 165 | |
| 166 def Translate(tree, name): | |
| 167 return _MojomBuilder().Build(tree, name) | |
| OLD | NEW |