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 |