Commit c53bf4ab authored by qsr's avatar qsr Committed by Commit bot

mojo: Start generating structs for python bindings

R=pkl@chromium.org,cmasone@chromium.org

Review URL: https://codereview.chromium.org/538613005

Cr-Commit-Position: refs/heads/master@{#294161}
parent c6484806
...@@ -18,6 +18,7 @@ class MojoEnumType(type): ...@@ -18,6 +18,7 @@ class MojoEnumType(type):
This will define a enum with 3 values, A = 0, B = 1 and C = 5. This will define a enum with 3 values, A = 0, B = 1 and C = 5.
""" """
def __new__(mcs, name, bases, dictionary): def __new__(mcs, name, bases, dictionary):
class_members = { class_members = {
'__new__': None, '__new__': None,
...@@ -37,3 +38,55 @@ class MojoEnumType(type): ...@@ -37,3 +38,55 @@ class MojoEnumType(type):
def __delattr__(mcs, key): def __delattr__(mcs, key):
raise AttributeError, 'can\'t delete attribute' raise AttributeError, 'can\'t delete attribute'
class MojoStructType(type):
"""Meta class for structs.
Usage:
class MyStruct(object):
__metaclass__ = MojoStructType
DESCRIPTOR = {
'constants': {
'C1': 1,
'C2': 2,
},
'enums': {
'ENUM1': [
('V1', 1),
'V2',
],
'ENUM2': [
('V1', 1),
'V2',
],
},
}
This will define an struct, with 2 constants C1 and C2, and 2 enums ENUM1
and ENUM2, each of those having 2 values, V1 and V2.
"""
def __new__(mcs, name, bases, dictionary):
class_members = {
'__slots__': [],
}
descriptor = dictionary.pop('DESCRIPTOR', {})
# Add constants
class_members.update(descriptor.get('constants', {}))
# Add enums
enums = descriptor.get('enums', {})
for key in enums:
class_members[key] = MojoEnumType(key,
(object,),
{ 'VALUES': enums[key] })
return type.__new__(mcs, name, bases, class_members)
def __setattr__(mcs, key, value):
raise AttributeError, 'can\'t set attribute'
def __delattr__(mcs, key):
raise AttributeError, 'can\'t delete attribute'
...@@ -35,6 +35,9 @@ def ConstantStyle(name): ...@@ -35,6 +35,9 @@ def ConstantStyle(name):
return '_'.join([x.upper() for x in components]) return '_'.join([x.upper() for x in components])
def GetNameForElement(element): def GetNameForElement(element):
if (mojom.IsEnumKind(element) or mojom.IsInterfaceKind(element) or
mojom.IsStructKind(element)):
return UpperCamelCase(element.name)
if isinstance(element, mojom.EnumValue): if isinstance(element, mojom.EnumValue):
return (GetNameForElement(element.enum) + '.' + return (GetNameForElement(element.enum) + '.' +
ConstantStyle(element.name)) ConstantStyle(element.name))
...@@ -129,6 +132,7 @@ class Generator(generator.Generator): ...@@ -129,6 +132,7 @@ class Generator(generator.Generator):
'imports': self.GetImports(), 'imports': self.GetImports(),
'enums': self.module.enums, 'enums': self.module.enums,
'module': ComputeConstantValues(self.module), 'module': ComputeConstantValues(self.module),
'structs': self.GetStructs(),
} }
def GenerateFiles(self, args): def GenerateFiles(self, args):
......
{% from "module_macros.tmpl" import enum_values %}
# Copyright 2014 The Chromium Authors. All rights reserved. # Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be # Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file. # found in the LICENSE file.
...@@ -18,11 +19,28 @@ import {{import.python_module}} ...@@ -18,11 +19,28 @@ import {{import.python_module}}
{% endif %} {% endif %}
{% for enum in module.enums %} {% for enum in module.enums %}
class {{enum.name}}(object): class {{enum|name}}(object):
__metaclass__ = _reflection.MojoEnumType __metaclass__ = _reflection.MojoEnumType
VALUES = [ VALUES = {{enum_values(enum)|indent(2)}}
{% for field in enum.fields %} {% endfor %}
('{{field.name}}', {{field.computed_value}}), {% for struct in module.structs %}
{% endfor %}
] class {{struct|name}}(object):
__metaclass__ = _reflection.MojoStructType
DESCRIPTOR = {
{% if struct.constants %}
'constants': {
{% for constant in struct.constants %}
'{{constant|name}}': {{constant.value|expression_to_text}},
{% endfor %}
},
{% endif %}
{% if struct.enums %}
'enums': {
{% for enum in struct.enums %}
'{{enum|name}}': {{enum_values(enum)|indent(6)}},
{% endfor %}
},
{% endif %}
}
{% endfor %} {% endfor %}
# 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.
{%- macro enum_values(enum) -%}
[
{% for field in enum.fields %}
('{{field.name}}', {{field.computed_value}}),
{% endfor %}
]
{%- endmacro -%}
...@@ -47,6 +47,7 @@ template("mojom") { ...@@ -47,6 +47,7 @@ template("mojom") {
"$generator_root/generators/js_templates/interface_definition.tmpl", "$generator_root/generators/js_templates/interface_definition.tmpl",
"$generator_root/generators/js_templates/module.js.tmpl", "$generator_root/generators/js_templates/module.js.tmpl",
"$generator_root/generators/js_templates/struct_definition.tmpl", "$generator_root/generators/js_templates/struct_definition.tmpl",
"$generator_root/generators/python_templates/module_macros.tmpl",
"$generator_root/generators/python_templates/module.py.tmpl", "$generator_root/generators/python_templates/module.py.tmpl",
"$generator_root/generators/mojom_cpp_generator.py", "$generator_root/generators/mojom_cpp_generator.py",
"$generator_root/generators/mojom_js_generator.py", "$generator_root/generators/mojom_js_generator.py",
......
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
'<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl', '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/interface_definition.tmpl',
'<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl', '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/module.js.tmpl',
'<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl', '<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/struct_definition.tmpl',
'<(DEPTH)/mojo/public/tools/bindings/generators/python_templates/module_macros.tmpl',
'<(DEPTH)/mojo/public/tools/bindings/generators/python_templates/module.py.tmpl', '<(DEPTH)/mojo/public/tools/bindings/generators/python_templates/module.py.tmpl',
'<(DEPTH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py', '<(DEPTH)/mojo/public/tools/bindings/generators/mojom_cpp_generator.py',
'<(DEPTH)/mojo/public/tools/bindings/generators/mojom_java_generator.py', '<(DEPTH)/mojo/public/tools/bindings/generators/mojom_java_generator.py',
......
...@@ -26,3 +26,14 @@ class ConstantBindingsTest(unittest.TestCase): ...@@ -26,3 +26,14 @@ class ConstantBindingsTest(unittest.TestCase):
self.assertEquals(sample_service_mojom.FLOAT_NEGATIVE_INFINITY, self.assertEquals(sample_service_mojom.FLOAT_NEGATIVE_INFINITY,
float('-inf')) float('-inf'))
self.assertTrue(math.isnan(sample_service_mojom.FLOAT_NA_N)) self.assertTrue(math.isnan(sample_service_mojom.FLOAT_NA_N))
def testConstantOnStructGeneration(self):
self.assertEquals(sample_service_mojom.Foo.FOOBY, "Fooby")
def testStructImmutability(self):
with self.assertRaises(AttributeError):
sample_service_mojom.Foo.FOOBY = 0
with self.assertRaises(AttributeError):
del sample_service_mojom.Foo.FOOBY
with self.assertRaises(AttributeError):
sample_service_mojom.Foo.BAR = 1
...@@ -7,6 +7,7 @@ import unittest ...@@ -7,6 +7,7 @@ import unittest
# Generated files # Generated files
# pylint: disable=F0401 # pylint: disable=F0401
import sample_import_mojom import sample_import_mojom
import sample_service_mojom
class EnumBindingsTest(unittest.TestCase): class EnumBindingsTest(unittest.TestCase):
...@@ -27,6 +28,13 @@ class EnumBindingsTest(unittest.TestCase): ...@@ -27,6 +28,13 @@ class EnumBindingsTest(unittest.TestCase):
self.assertEquals(sample_import_mojom.YetAnotherShape.CIRCLE, 21) self.assertEquals(sample_import_mojom.YetAnotherShape.CIRCLE, 21)
self.assertEquals(sample_import_mojom.YetAnotherShape.TRIANGLE, 22) self.assertEquals(sample_import_mojom.YetAnotherShape.TRIANGLE, 22)
# Testing that internal enum class have expected constant values.
def testInternalEnumGeneration(self):
self.assertEquals(sample_service_mojom.Bar.Type.VERTICAL, 1)
self.assertEquals(sample_service_mojom.Bar.Type.HORIZONTAL, 2)
self.assertEquals(sample_service_mojom.Bar.Type.BOTH, 3)
self.assertEquals(sample_service_mojom.Bar.Type.INVALID, 4)
# Testing an enum class cannot be instantiated. # Testing an enum class cannot be instantiated.
def testNonInstantiableEnum(self): def testNonInstantiableEnum(self):
with self.assertRaises(TypeError): with self.assertRaises(TypeError):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment