OLD | NEW |
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 """Translates parse tree to Mojom IR.""" | 5 """Translates parse tree to Mojom IR.""" |
6 | 6 |
7 | 7 |
8 import ast | 8 import ast |
9 import re | 9 import re |
10 | 10 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 typename = kind[0:lbracket] | 44 typename = kind[0:lbracket] |
45 if typename.find('[') != -1: | 45 if typename.find('[') != -1: |
46 raise Exception("Fixed sized arrays of arrays not supported") | 46 raise Exception("Fixed sized arrays of arrays not supported") |
47 return 'a' + kind[lbracket+1:-1] + ':' + _MapKind(typename) | 47 return 'a' + kind[lbracket+1:-1] + ':' + _MapKind(typename) |
48 if kind.endswith('&'): | 48 if kind.endswith('&'): |
49 return 'r:' + _MapKind(kind[0:-1]) | 49 return 'r:' + _MapKind(kind[0:-1]) |
50 if kind in map_to_kind: | 50 if kind in map_to_kind: |
51 return map_to_kind[kind] | 51 return map_to_kind[kind] |
52 return 'x:' + kind | 52 return 'x:' + kind |
53 | 53 |
54 def _MapAttributes(attributes): | 54 def _AttributeListToDict(attribute_list): |
55 if not attributes: | 55 if attribute_list is None: |
56 return {} | 56 return {} |
57 return dict([(attribute[1], attribute[2]) | 57 assert isinstance(attribute_list, ast.AttributeList) |
58 for attribute in attributes if attribute[0] == 'ATTRIBUTE']) | 58 # TODO(vtl): Check for duplicate keys here. |
59 | 59 return dict([(attribute.key, attribute.value) |
60 def _GetAttribute(attributes, name): | 60 for attribute in attribute_list]) |
61 out = None | |
62 if attributes: | |
63 for attribute in attributes: | |
64 if attribute[0] == 'ATTRIBUTE' and attribute[1] == name: | |
65 out = attribute[2] | |
66 return out | |
67 | 61 |
68 def _MapField(tree): | 62 def _MapField(tree): |
69 assert isinstance(tree[3], ast.Ordinal) | 63 assert isinstance(tree[3], ast.Ordinal) |
70 return {'name': tree[2], | 64 return {'name': tree[2], |
71 'kind': _MapKind(tree[1]), | 65 'kind': _MapKind(tree[1]), |
72 'ordinal': tree[3].value, | 66 'ordinal': tree[3].value, |
73 'default': tree[4]} | 67 'default': tree[4]} |
74 | 68 |
75 def _MapMethod(tree): | 69 def _MapMethod(tree): |
76 assert isinstance(tree[2], ast.ParameterList) | 70 assert isinstance(tree[2], ast.ParameterList) |
(...skipping 13 matching lines...) Expand all Loading... |
90 method['response_parameters'] = map(ParameterToDict, tree[4]) | 84 method['response_parameters'] = map(ParameterToDict, tree[4]) |
91 return method | 85 return method |
92 | 86 |
93 def _MapEnumField(tree): | 87 def _MapEnumField(tree): |
94 return {'name': tree[1], | 88 return {'name': tree[1], |
95 'value': tree[2]} | 89 'value': tree[2]} |
96 | 90 |
97 def _MapStruct(tree): | 91 def _MapStruct(tree): |
98 struct = {} | 92 struct = {} |
99 struct['name'] = tree[1] | 93 struct['name'] = tree[1] |
100 struct['attributes'] = _MapAttributes(tree[2]) | 94 struct['attributes'] = _AttributeListToDict(tree[2]) |
101 struct['fields'] = _MapTree(_MapField, tree[3], 'FIELD') | 95 struct['fields'] = _MapTree(_MapField, tree[3], 'FIELD') |
102 struct['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM') | 96 struct['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM') |
103 struct['constants'] = _MapTree(_MapConstant, tree[3], 'CONST') | 97 struct['constants'] = _MapTree(_MapConstant, tree[3], 'CONST') |
104 return struct | 98 return struct |
105 | 99 |
106 def _MapInterface(tree): | 100 def _MapInterface(tree): |
107 interface = {} | 101 interface = {} |
108 interface['name'] = tree[1] | 102 interface['name'] = tree[1] |
109 interface['client'] = _GetAttribute(tree[2], 'Client') | 103 interface['attributes'] = _AttributeListToDict(tree[2]) |
| 104 interface['client'] = interface['attributes'].get('Client') |
110 interface['methods'] = _MapTree(_MapMethod, tree[3], 'METHOD') | 105 interface['methods'] = _MapTree(_MapMethod, tree[3], 'METHOD') |
111 interface['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM') | 106 interface['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM') |
112 interface['constants'] = _MapTree(_MapConstant, tree[3], 'CONST') | 107 interface['constants'] = _MapTree(_MapConstant, tree[3], 'CONST') |
113 return interface | 108 return interface |
114 | 109 |
115 def _MapEnum(tree): | 110 def _MapEnum(tree): |
116 enum = {} | 111 enum = {} |
117 enum['name'] = tree[1] | 112 enum['name'] = tree[1] |
118 enum['fields'] = _MapTree(_MapEnumField, tree[2], 'ENUM_FIELD') | 113 enum['fields'] = _MapTree(_MapEnumField, tree[2], 'ENUM_FIELD') |
119 return enum | 114 return enum |
120 | 115 |
121 def _MapConstant(tree): | 116 def _MapConstant(tree): |
122 constant = {} | 117 constant = {} |
123 constant['name'] = tree[2] | 118 constant['name'] = tree[2] |
124 constant['kind'] = _MapKind(tree[1]) | 119 constant['kind'] = _MapKind(tree[1]) |
125 constant['value'] = tree[3] | 120 constant['value'] = tree[3] |
126 return constant | 121 return constant |
127 | 122 |
128 def _MapModule(tree, name): | 123 def _MapModule(tree, name): |
129 mojom = {} | 124 mojom = {} |
130 mojom['name'] = name | 125 mojom['name'] = name |
131 mojom['namespace'] = tree[1] | 126 mojom['namespace'] = tree[1] |
132 mojom['attributes'] = _MapAttributes(tree[2]) | 127 mojom['attributes'] = _AttributeListToDict(tree[2]) |
133 mojom['structs'] = _MapTree(_MapStruct, tree[3], 'STRUCT') | 128 mojom['structs'] = _MapTree(_MapStruct, tree[3], 'STRUCT') |
134 mojom['interfaces'] = _MapTree(_MapInterface, tree[3], 'INTERFACE') | 129 mojom['interfaces'] = _MapTree(_MapInterface, tree[3], 'INTERFACE') |
135 mojom['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM') | 130 mojom['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM') |
136 mojom['constants'] = _MapTree(_MapConstant, tree[3], 'CONST') | 131 mojom['constants'] = _MapTree(_MapConstant, tree[3], 'CONST') |
137 return mojom | 132 return mojom |
138 | 133 |
139 def _MapImport(tree): | 134 def _MapImport(tree): |
140 import_item = {} | 135 import_item = {} |
141 import_item['filename'] = tree[1] | 136 import_item['filename'] = tree[1] |
142 return import_item | 137 return import_item |
143 | 138 |
144 | 139 |
145 class _MojomBuilder(object): | 140 class _MojomBuilder(object): |
146 def __init__(self): | 141 def __init__(self): |
147 self.mojom = {} | 142 self.mojom = {} |
148 | 143 |
149 def Build(self, tree, name): | 144 def Build(self, tree, name): |
150 modules = [_MapModule(item, name) for item in tree if item[0] == 'MODULE'] | 145 modules = [_MapModule(item, name) for item in tree if item[0] == 'MODULE'] |
151 if len(modules) != 1: | 146 if len(modules) != 1: |
152 raise Exception('A mojom file must contain exactly 1 module.') | 147 raise Exception('A mojom file must contain exactly 1 module.') |
153 self.mojom = modules[0] | 148 self.mojom = modules[0] |
154 self.mojom['imports'] = _MapTree(_MapImport, tree, 'IMPORT') | 149 self.mojom['imports'] = _MapTree(_MapImport, tree, 'IMPORT') |
155 return self.mojom | 150 return self.mojom |
156 | 151 |
157 | 152 |
158 def Translate(tree, name): | 153 def Translate(tree, name): |
159 return _MojomBuilder().Build(tree, name) | 154 return _MojomBuilder().Build(tree, name) |
OLD | NEW |