| Index: mojo/public/tools/bindings/pylib/mojom/generate/data.py
|
| diff --git a/mojo/public/tools/bindings/pylib/mojom/generate/data.py b/mojo/public/tools/bindings/pylib/mojom/generate/data.py
|
| deleted file mode 100644
|
| index 6d34a403a67e9218d565160b7357ed891e9eac7e..0000000000000000000000000000000000000000
|
| --- a/mojo/public/tools/bindings/pylib/mojom/generate/data.py
|
| +++ /dev/null
|
| @@ -1,420 +0,0 @@
|
| -# Copyright 2013 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.
|
| -
|
| -# TODO(vtl): "data" is a pretty vague name. Rename it?
|
| -
|
| -import copy
|
| -
|
| -import module as mojom
|
| -
|
| -# This module provides a mechanism to turn mojom Modules to dictionaries and
|
| -# back again. This can be used to persist a mojom Module created progromatically
|
| -# or to read a dictionary from code or a file.
|
| -# Example:
|
| -# test_dict = {
|
| -# 'name': 'test',
|
| -# 'namespace': 'testspace',
|
| -# 'structs': [{
|
| -# 'name': 'teststruct',
|
| -# 'fields': [
|
| -# {'name': 'testfield1', 'kind': 'i32'},
|
| -# {'name': 'testfield2', 'kind': 'a:i32', 'ordinal': 42}]}],
|
| -# 'interfaces': [{
|
| -# 'name': 'Server',
|
| -# 'methods': [{
|
| -# 'name': 'Foo',
|
| -# 'parameters': [{
|
| -# 'name': 'foo', 'kind': 'i32'},
|
| -# {'name': 'bar', 'kind': 'a:x:teststruct'}],
|
| -# 'ordinal': 42}]}]
|
| -# }
|
| -# test_module = data.ModuleFromData(test_dict)
|
| -
|
| -# Used to create a subclass of str that supports sorting by index, to make
|
| -# pretty printing maintain the order.
|
| -def istr(index, string):
|
| - class IndexedString(str):
|
| - def __lt__(self, other):
|
| - return self.__index__ < other.__index__
|
| -
|
| - rv = IndexedString(string)
|
| - rv.__index__ = index
|
| - return rv
|
| -
|
| -builtin_values = frozenset([
|
| - "double.INFINITY",
|
| - "double.NEGATIVE_INFINITY",
|
| - "double.NAN",
|
| - "float.INFINITY",
|
| - "float.NEGATIVE_INFINITY",
|
| - "float.NAN"])
|
| -
|
| -def IsBuiltinValue(value):
|
| - return value in builtin_values
|
| -
|
| -def LookupKind(kinds, spec, scope):
|
| - """Tries to find which Kind a spec refers to, given the scope in which its
|
| - referenced. Starts checking from the narrowest scope to most general. For
|
| - example, given a struct field like
|
| - Foo.Bar x;
|
| - Foo.Bar could refer to the type 'Bar' in the 'Foo' namespace, or an inner
|
| - type 'Bar' in the struct 'Foo' in the current namespace.
|
| -
|
| - |scope| is a tuple that looks like (namespace, struct/interface), referring
|
| - to the location where the type is referenced."""
|
| - if spec.startswith('x:'):
|
| - name = spec[2:]
|
| - for i in xrange(len(scope), -1, -1):
|
| - test_spec = 'x:'
|
| - if i > 0:
|
| - test_spec += '.'.join(scope[:i]) + '.'
|
| - test_spec += name
|
| - kind = kinds.get(test_spec)
|
| - if kind:
|
| - return kind
|
| -
|
| - return kinds.get(spec)
|
| -
|
| -def LookupValue(values, name, scope, kind):
|
| - """Like LookupKind, but for constant values."""
|
| - # If the type is an enum, the value can be specified as a qualified name, in
|
| - # which case the form EnumName.ENUM_VALUE must be used. We use the presence
|
| - # of a '.' in the requested name to identify this. Otherwise, we prepend the
|
| - # enum name.
|
| - if isinstance(kind, mojom.Enum) and '.' not in name:
|
| - name = '%s.%s' % (kind.spec.split(':', 1)[1], name)
|
| - for i in reversed(xrange(len(scope) + 1)):
|
| - test_spec = '.'.join(scope[:i])
|
| - if test_spec:
|
| - test_spec += '.'
|
| - test_spec += name
|
| - value = values.get(test_spec)
|
| - if value:
|
| - return value
|
| -
|
| - return values.get(name)
|
| -
|
| -def FixupExpression(module, value, scope, kind):
|
| - """Translates an IDENTIFIER into a built-in value or structured NamedValue
|
| - object."""
|
| - if isinstance(value, tuple) and value[0] == 'IDENTIFIER':
|
| - # Allow user defined values to shadow builtins.
|
| - result = LookupValue(module.values, value[1], scope, kind)
|
| - if result:
|
| - if isinstance(result, tuple):
|
| - raise Exception('Unable to resolve expression: %r' % value[1])
|
| - return result
|
| - if IsBuiltinValue(value[1]):
|
| - return mojom.BuiltinValue(value[1])
|
| - return value
|
| -
|
| -def KindToData(kind):
|
| - return kind.spec
|
| -
|
| -def KindFromData(kinds, data, scope):
|
| - kind = LookupKind(kinds, data, scope)
|
| - if kind:
|
| - return kind
|
| -
|
| - if data.startswith('?'):
|
| - kind = KindFromData(kinds, data[1:], scope).MakeNullableKind()
|
| - elif data.startswith('a:'):
|
| - kind = mojom.Array(KindFromData(kinds, data[2:], scope))
|
| - elif data.startswith('a'):
|
| - colon = data.find(':')
|
| - length = int(data[1:colon])
|
| - kind = mojom.Array(KindFromData(kinds, data[colon+1:], scope), length)
|
| - elif data.startswith('r:'):
|
| - kind = mojom.InterfaceRequest(KindFromData(kinds, data[2:], scope))
|
| - elif data.startswith('m['):
|
| - # Isolate the two types from their brackets.
|
| -
|
| - # It is not allowed to use map as key, so there shouldn't be nested ']'s
|
| - # inside the key type spec.
|
| - key_end = data.find(']')
|
| - assert key_end != -1 and key_end < len(data) - 1
|
| - assert data[key_end+1] == '[' and data[-1] == ']'
|
| -
|
| - first_kind = data[2:key_end]
|
| - second_kind = data[key_end+2:-1]
|
| -
|
| - kind = mojom.Map(KindFromData(kinds, first_kind, scope),
|
| - KindFromData(kinds, second_kind, scope))
|
| - else:
|
| - kind = mojom.Kind(data)
|
| -
|
| - kinds[data] = kind
|
| - return kind
|
| -
|
| -def KindFromImport(original_kind, imported_from):
|
| - """Used with 'import module' - clones the kind imported from the given
|
| - module's namespace. Only used with Structs, Unions, Interfaces and Enums."""
|
| - kind = copy.copy(original_kind)
|
| - # |shared_definition| is used to store various properties (see
|
| - # |AddSharedProperty()| in module.py), including |imported_from|. We don't
|
| - # want the copy to share these with the original, so copy it if necessary.
|
| - if hasattr(original_kind, 'shared_definition'):
|
| - kind.shared_definition = copy.copy(original_kind.shared_definition)
|
| - kind.imported_from = imported_from
|
| - return kind
|
| -
|
| -def ImportFromData(module, data):
|
| - import_module = data['module']
|
| -
|
| - import_item = {}
|
| - import_item['module_name'] = import_module.name
|
| - import_item['namespace'] = import_module.namespace
|
| - import_item['module'] = import_module
|
| -
|
| - # Copy the struct kinds from our imports into the current module.
|
| - importable_kinds = (mojom.Struct, mojom.Union, mojom.Enum, mojom.Interface)
|
| - for kind in import_module.kinds.itervalues():
|
| - if (isinstance(kind, importable_kinds) and
|
| - kind.imported_from is None):
|
| - kind = KindFromImport(kind, import_item)
|
| - module.kinds[kind.spec] = kind
|
| - # Ditto for values.
|
| - for value in import_module.values.itervalues():
|
| - if value.imported_from is None:
|
| - # Values don't have shared definitions (since they're not nullable), so no
|
| - # need to do anything special.
|
| - value = copy.copy(value)
|
| - value.imported_from = import_item
|
| - module.values[value.GetSpec()] = value
|
| -
|
| - return import_item
|
| -
|
| -def StructToData(struct):
|
| - return {
|
| - istr(0, 'name'): struct.name,
|
| - istr(1, 'fields'): map(FieldToData, struct.fields)
|
| - }
|
| -
|
| -def StructFromData(module, data):
|
| - struct = mojom.Struct(module=module)
|
| - struct.name = data['name']
|
| - struct.attributes = data['attributes']
|
| - struct.spec = 'x:' + module.namespace + '.' + struct.name
|
| - module.kinds[struct.spec] = struct
|
| - struct.enums = map(lambda enum:
|
| - EnumFromData(module, enum, struct), data['enums'])
|
| - struct.constants = map(lambda constant:
|
| - ConstantFromData(module, constant, struct), data['constants'])
|
| - # Stash fields data here temporarily.
|
| - struct.fields_data = data['fields']
|
| - return struct
|
| -
|
| -def UnionToData(union):
|
| - return {
|
| - istr(0, 'name'): union.name,
|
| - istr(1, 'fields'): map(FieldToData, union.fields)
|
| - }
|
| -
|
| -def UnionFromData(module, data):
|
| - union = mojom.Union(module=module)
|
| - union.name = data['name']
|
| - union.spec = 'x:' + module.namespace + '.' + union.name
|
| - module.kinds[union.spec] = union
|
| - # Stash fields data here temporarily.
|
| - union.fields_data = data['fields']
|
| - return union
|
| -
|
| -def FieldToData(field):
|
| - data = {
|
| - istr(0, 'name'): field.name,
|
| - istr(1, 'kind'): KindToData(field.kind)
|
| - }
|
| - if field.ordinal != None:
|
| - data[istr(2, 'ordinal')] = field.ordinal
|
| - if field.default != None:
|
| - data[istr(3, 'default')] = field.default
|
| - return data
|
| -
|
| -def FieldFromData(module, data, struct):
|
| - field = mojom.Field()
|
| - field.name = data['name']
|
| - field.kind = KindFromData(
|
| - module.kinds, data['kind'], (module.namespace, struct.name))
|
| - field.ordinal = data.get('ordinal')
|
| - field.default = FixupExpression(
|
| - module, data.get('default'), (module.namespace, struct.name), field.kind)
|
| - return field
|
| -
|
| -def ParameterToData(parameter):
|
| - data = {
|
| - istr(0, 'name'): parameter.name,
|
| - istr(1, 'kind'): parameter.kind.spec
|
| - }
|
| - if parameter.ordinal != None:
|
| - data[istr(2, 'ordinal')] = parameter.ordinal
|
| - if parameter.default != None:
|
| - data[istr(3, 'default')] = parameter.default
|
| - return data
|
| -
|
| -def ParameterFromData(module, data, interface):
|
| - parameter = mojom.Parameter()
|
| - parameter.name = data['name']
|
| - parameter.kind = KindFromData(
|
| - module.kinds, data['kind'], (module.namespace, interface.name))
|
| - parameter.ordinal = data.get('ordinal')
|
| - parameter.default = data.get('default')
|
| - return parameter
|
| -
|
| -def MethodToData(method):
|
| - data = {
|
| - istr(0, 'name'): method.name,
|
| - istr(1, 'parameters'): map(ParameterToData, method.parameters)
|
| - }
|
| - if method.ordinal != None:
|
| - data[istr(2, 'ordinal')] = method.ordinal
|
| - if method.response_parameters != None:
|
| - data[istr(3, 'response_parameters')] = map(
|
| - ParameterToData, method.response_parameters)
|
| - return data
|
| -
|
| -def MethodFromData(module, data, interface):
|
| - method = mojom.Method(interface, data['name'], ordinal=data.get('ordinal'))
|
| - method.default = data.get('default')
|
| - method.parameters = map(lambda parameter:
|
| - ParameterFromData(module, parameter, interface), data['parameters'])
|
| - if data.has_key('response_parameters'):
|
| - method.response_parameters = map(
|
| - lambda parameter: ParameterFromData(module, parameter, interface),
|
| - data['response_parameters'])
|
| - return method
|
| -
|
| -def InterfaceToData(interface):
|
| - return {
|
| - istr(0, 'name'): interface.name,
|
| - istr(1, 'client'): interface.client,
|
| - istr(2, 'methods'): map(MethodToData, interface.methods)
|
| - }
|
| -
|
| -def InterfaceFromData(module, data):
|
| - interface = mojom.Interface(module=module)
|
| - interface.name = data['name']
|
| - interface.spec = 'x:' + module.namespace + '.' + interface.name
|
| - interface.client = data['client'] if data.has_key('client') else None
|
| - module.kinds[interface.spec] = interface
|
| - interface.enums = map(lambda enum:
|
| - EnumFromData(module, enum, interface), data['enums'])
|
| - interface.constants = map(lambda constant:
|
| - ConstantFromData(module, constant, interface), data['constants'])
|
| - # Stash methods data here temporarily.
|
| - interface.methods_data = data['methods']
|
| - return interface
|
| -
|
| -def EnumFieldFromData(module, enum, data, parent_kind):
|
| - field = mojom.EnumField()
|
| - field.name = data['name']
|
| - # TODO(mpcomplete): FixupExpression should be done in the second pass,
|
| - # so constants and enums can refer to each other.
|
| - # TODO(mpcomplete): But then, what if constants are initialized to an enum? Or
|
| - # vice versa?
|
| - if parent_kind:
|
| - field.value = FixupExpression(
|
| - module, data['value'], (module.namespace, parent_kind.name), enum)
|
| - else:
|
| - field.value = FixupExpression(
|
| - module, data['value'], (module.namespace, ), enum)
|
| - value = mojom.EnumValue(module, enum, field)
|
| - module.values[value.GetSpec()] = value
|
| - return field
|
| -
|
| -def EnumFromData(module, data, parent_kind):
|
| - enum = mojom.Enum(module=module)
|
| - enum.name = data['name']
|
| - name = enum.name
|
| - if parent_kind:
|
| - name = parent_kind.name + '.' + name
|
| - enum.spec = 'x:%s.%s' % (module.namespace, name)
|
| - enum.parent_kind = parent_kind
|
| -
|
| - enum.fields = map(
|
| - lambda field: EnumFieldFromData(module, enum, field, parent_kind),
|
| - data['fields'])
|
| - module.kinds[enum.spec] = enum
|
| - return enum
|
| -
|
| -def ConstantFromData(module, data, parent_kind):
|
| - constant = mojom.Constant()
|
| - constant.name = data['name']
|
| - if parent_kind:
|
| - scope = (module.namespace, parent_kind.name)
|
| - else:
|
| - scope = (module.namespace, )
|
| - # TODO(mpcomplete): maybe we should only support POD kinds.
|
| - constant.kind = KindFromData(module.kinds, data['kind'], scope)
|
| - constant.value = FixupExpression(module, data.get('value'), scope, None)
|
| -
|
| - value = mojom.ConstantValue(module, parent_kind, constant)
|
| - module.values[value.GetSpec()] = value
|
| - return constant
|
| -
|
| -def ModuleToData(module):
|
| - return {
|
| - istr(0, 'name'): module.name,
|
| - istr(1, 'namespace'): module.namespace,
|
| - istr(2, 'structs'): map(StructToData, module.structs),
|
| - istr(3, 'interfaces'): map(InterfaceToData, module.interfaces),
|
| - istr(4, 'unions'): map(UnionToData, module.unions),
|
| - }
|
| -
|
| -def ModuleFromData(data):
|
| - module = mojom.Module()
|
| - module.kinds = {}
|
| - for kind in mojom.PRIMITIVES:
|
| - module.kinds[kind.spec] = kind
|
| -
|
| - module.values = {}
|
| -
|
| - module.name = data['name']
|
| - module.namespace = data['namespace']
|
| - module.attributes = data['attributes']
|
| - # Imports must come first, because they add to module.kinds which is used
|
| - # by by the others.
|
| - module.imports = map(
|
| - lambda import_data: ImportFromData(module, import_data),
|
| - data['imports'])
|
| -
|
| - # First pass collects kinds.
|
| - module.enums = map(
|
| - lambda enum: EnumFromData(module, enum, None), data['enums'])
|
| - module.structs = map(
|
| - lambda struct: StructFromData(module, struct), data['structs'])
|
| - module.unions = map(
|
| - lambda union: UnionFromData(module, struct), data.get('unions', []))
|
| - module.interfaces = map(
|
| - lambda interface: InterfaceFromData(module, interface),
|
| - data['interfaces'])
|
| - module.constants = map(
|
| - lambda constant: ConstantFromData(module, constant, None),
|
| - data['constants'])
|
| -
|
| - # Second pass expands fields and methods. This allows fields and parameters
|
| - # to refer to kinds defined anywhere in the mojom.
|
| - for struct in module.structs:
|
| - struct.fields = map(lambda field:
|
| - FieldFromData(module, field, struct), struct.fields_data)
|
| - del struct.fields_data
|
| - for union in module.unions:
|
| - union.fields = map(lambda field:
|
| - FieldFromData(module, field, union), union.fields_data)
|
| - del union.fields_data
|
| - for interface in module.interfaces:
|
| - interface.methods = map(lambda method:
|
| - MethodFromData(module, method, interface), interface.methods_data)
|
| - del interface.methods_data
|
| -
|
| - return module
|
| -
|
| -def OrderedModuleFromData(data):
|
| - module = ModuleFromData(data)
|
| - for interface in module.interfaces:
|
| - next_ordinal = 0
|
| - for method in interface.methods:
|
| - if method.ordinal is None:
|
| - method.ordinal = next_ordinal
|
| - next_ordinal = method.ordinal + 1
|
| - return module
|
|
|