diff options
Diffstat (limited to 'chromium/mojo/public/tools/bindings/pylib/mojom/parse/translate.py')
-rw-r--r-- | chromium/mojo/public/tools/bindings/pylib/mojom/parse/translate.py | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/chromium/mojo/public/tools/bindings/pylib/mojom/parse/translate.py b/chromium/mojo/public/tools/bindings/pylib/mojom/parse/translate.py new file mode 100644 index 00000000000..8407a088c6b --- /dev/null +++ b/chromium/mojo/public/tools/bindings/pylib/mojom/parse/translate.py @@ -0,0 +1,144 @@ +# Copyright 2014 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Translates parse tree to Mojom IR.""" + + +import ast + + +def _MapTree(func, tree, name): + if not tree: + return [] + return [func(subtree) for subtree in tree if subtree[0] == name] + +def _MapKind(kind): + map_to_kind = { 'bool': 'b', + 'int8': 'i8', + 'int16': 'i16', + 'int32': 'i32', + 'int64': 'i64', + 'uint8': 'u8', + 'uint16': 'u16', + 'uint32': 'u32', + 'uint64': 'u64', + 'float': 'f', + 'double': 'd', + 'string': 's', + 'handle': 'h', + 'handle<data_pipe_consumer>': 'h:d:c', + 'handle<data_pipe_producer>': 'h:d:p', + 'handle<message_pipe>': 'h:m', + 'handle<shared_buffer>': 'h:s'} + if kind.endswith('[]'): + return 'a:' + _MapKind(kind[0:len(kind)-2]) + if kind.endswith('&'): + return 'r:' + _MapKind(kind[0:len(kind)-1]) + if kind in map_to_kind: + return map_to_kind[kind] + return 'x:' + kind + +def _MapAttributes(attributes): + if not attributes: + return {} + return dict([(attribute[1], attribute[2]) + for attribute in attributes if attribute[0] == 'ATTRIBUTE']) + +def _GetAttribute(attributes, name): + out = None + if attributes: + for attribute in attributes: + if attribute[0] == 'ATTRIBUTE' and attribute[1] == name: + out = attribute[2] + return out + +def _MapField(tree): + assert type(tree[3]) is ast.Ordinal + return {'name': tree[2], + 'kind': _MapKind(tree[1]), + 'ordinal': tree[3].value, + 'default': tree[4]} + +def _MapParameter(tree): + assert type(tree[3]) is ast.Ordinal + return {'name': tree[2], + 'kind': _MapKind(tree[1]), + 'ordinal': tree[3].value} + +def _MapMethod(tree): + assert type(tree[3]) is ast.Ordinal + method = {'name': tree[1], + 'parameters': _MapTree(_MapParameter, tree[2], 'PARAM'), + 'ordinal': tree[3].value} + if tree[4] != None: + method['response_parameters'] = _MapTree(_MapParameter, tree[4], 'PARAM') + return method + +def _MapEnumField(tree): + return {'name': tree[1], + 'value': tree[2]} + +def _MapStruct(tree): + struct = {} + struct['name'] = tree[1] + struct['attributes'] = _MapAttributes(tree[2]) + struct['fields'] = _MapTree(_MapField, tree[3], 'FIELD') + struct['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM') + struct['constants'] = _MapTree(_MapConstant, tree[3], 'CONST') + return struct + +def _MapInterface(tree): + interface = {} + interface['name'] = tree[1] + interface['client'] = _GetAttribute(tree[2], 'Client') + interface['methods'] = _MapTree(_MapMethod, tree[3], 'METHOD') + interface['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM') + interface['constants'] = _MapTree(_MapConstant, tree[3], 'CONST') + return interface + +def _MapEnum(tree): + enum = {} + enum['name'] = tree[1] + enum['fields'] = _MapTree(_MapEnumField, tree[2], 'ENUM_FIELD') + return enum + +def _MapConstant(tree): + constant = {} + constant['name'] = tree[2] + constant['kind'] = _MapKind(tree[1]) + constant['value'] = tree[3] + return constant + +def _MapModule(tree, name): + mojom = {} + mojom['name'] = name + mojom['namespace'] = tree[1] + mojom['attributes'] = _MapAttributes(tree[2]) + mojom['structs'] = _MapTree(_MapStruct, tree[3], 'STRUCT') + mojom['interfaces'] = _MapTree(_MapInterface, tree[3], 'INTERFACE') + mojom['enums'] = _MapTree(_MapEnum, tree[3], 'ENUM') + mojom['constants'] = _MapTree(_MapConstant, tree[3], 'CONST') + return mojom + +def _MapImport(tree): + import_item = {} + import_item['filename'] = tree[1] + return import_item + + +class _MojomBuilder(object): + def __init__(self): + self.mojom = {} + + def Build(self, tree, name): + modules = [_MapModule(item, name) for item in tree if item[0] == 'MODULE'] + if len(modules) != 1: + raise Exception('A mojom file must contain exactly 1 module.') + self.mojom = modules[0] + self.mojom['imports'] = _MapTree(_MapImport, tree, 'IMPORT') + return self.mojom + + +def Translate(tree, name): + return _MojomBuilder().Build(tree, name) |