Commit 352a3ed7 authored by qsr's avatar qsr Committed by Commit bot

mojo: Starting generator for python bindings.

This generates constants for the python bindings.

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

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

Cr-Commit-Position: refs/heads/master@{#293105}
parent 4739e4f3
......@@ -95,11 +95,8 @@ def NameToComponent(name):
name = re.sub('([^A-Z_])([A-Z])', r'\1_\2', name)
return [x.lower() for x in name.split('_')]
def CapitalizeFirst(string):
return string[0].upper() + string[1:]
def UpperCamelCase(name):
return ''.join([CapitalizeFirst(x) for x in NameToComponent(name)])
return ''.join([x.capitalize() for x in NameToComponent(name)])
def CamelCase(name):
uccc = UpperCamelCase(name)
......
# 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.
"""Generates Python source files from a mojom.Module."""
import re
import mojom.generate.generator as generator
import mojom.generate.module as mojom
from mojom.generate.template_expander import UseJinja
def NameToComponent(name):
# insert '_' between anything and a Title name (e.g, HTTPEntry2FooBar ->
# HTTP_Entry2_FooBar)
name = re.sub('([^_])([A-Z][^A-Z_]+)', r'\1_\2', name)
# insert '_' between non upper and start of upper blocks (e.g.,
# HTTP_Entry2_FooBar -> HTTP_Entry2_Foo_Bar)
name = re.sub('([^A-Z_])([A-Z])', r'\1_\2', name)
return [x.lower() for x in name.split('_')]
def UpperCamelCase(name):
return ''.join([x.capitalize() for x in NameToComponent(name)])
def CamelCase(name):
uccc = UpperCamelCase(name)
return uccc[0].lower() + uccc[1:]
def ConstantStyle(name):
components = NameToComponent(name)
if components[0] == 'k':
components = components[1:]
return '_'.join([x.upper() for x in components])
def GetNameForElement(element):
if isinstance(element, (mojom.NamedValue,
mojom.Constant)):
return ConstantStyle(element.name)
raise Exception('Unexpected element: ' % element)
def TranslateConstants(token):
if isinstance(token, (mojom.EnumValue, mojom.NamedValue)):
# Both variable and enum constants are constructed like:
# NamespaceUid.Struct[.Enum].CONSTANT_NAME
name = []
if token.imported_from:
name.append(token.imported_from['python_module'])
if token.parent_kind:
name.append(GetNameForElement(token.parent_kind))
if isinstance(token, mojom.EnumValue):
name.append(GetNameForElement(token))
else:
name.append(token.name)
return '.'.join(name)
if isinstance(token, mojom.BuiltinValue):
if token.value == 'double.INFINITY' or token.value == 'float.INFINITY':
return 'float(\'inf\')';
if (token.value == 'double.NEGATIVE_INFINITY' or
token.value == 'float.NEGATIVE_INFINITY'):
return 'float(\'-inf\')'
if token.value == 'double.NAN' or token.value == 'float.NAN':
return 'float(\'nan\')';
return token
def ExpressionToText(value):
return TranslateConstants(value)
class Generator(generator.Generator):
python_filters = {
'expression_to_text': ExpressionToText,
'name': GetNameForElement,
}
@UseJinja('python_templates/module.py.tmpl', filters=python_filters)
def GeneratePythonModule(self):
return {
'imports': self.GetImports(),
'module': self.module,
}
def GenerateFiles(self, args):
self.Write(self.GeneratePythonModule(),
'%s.py' % self.module.name.replace('.mojom', '_mojom'))
def GetImports(self):
for each in self.module.imports:
each['python_module'] = each['module_name'].replace('.mojom', '_mojom')
return self.module.imports
def GetJinjaParameters(self):
return {
'lstrip_blocks': True,
'trim_blocks': True,
}
# 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.
{% if imports %}
{% for import in imports %}
import {{import.python_module}}
{% endfor %}
{% endif %}
{#--- Constants #}
{% if module.constants %}
{% for constant in module.constants %}
{{constant|name}} = {{constant.value|expression_to_text}}
{% endfor %}
{% endif %}
......@@ -45,8 +45,10 @@ template("mojom") {
"$generator_root/generators/js_templates/interface_definition.tmpl",
"$generator_root/generators/js_templates/module.js.tmpl",
"$generator_root/generators/js_templates/struct_definition.tmpl",
"$generator_root/generators/python_templates/module.py.tmpl",
"$generator_root/generators/mojom_cpp_generator.py",
"$generator_root/generators/mojom_js_generator.py",
"$generator_root/generators/mojom_python_generator.py",
"$generator_root/pylib/mojom/__init__.py",
"$generator_root/pylib/mojom/error.py",
"$generator_root/pylib/mojom/generate/__init__.py",
......@@ -69,6 +71,9 @@ template("mojom") {
generator_js_outputs = [
"{{source_gen_dir}}/{{source_name_part}}.mojom.js",
]
generator_python_outputs = [
"{{source_gen_dir}}/{{source_name_part}}_mojom.py",
]
target_visibility = ":$target_name"
......@@ -78,7 +83,9 @@ template("mojom") {
script = generator_script
inputs = generator_sources
sources = invoker.sources
outputs = generator_cpp_outputs + generator_js_outputs
outputs = generator_cpp_outputs +
generator_js_outputs +
generator_python_outputs
args = [
"{{source}}",
"--use_chromium_bundled_pylibs",
......
......@@ -52,9 +52,11 @@
'<(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/struct_definition.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_java_generator.py',
'<(DEPTH)/mojo/public/tools/bindings/generators/mojom_js_generator.py',
'<(DEPTH)/mojo/public/tools/bindings/generators/mojom_python_generator.py',
'<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/__init__.py',
'<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/error.py',
'<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/generate/__init__.py',
......@@ -73,6 +75,7 @@
'<(SHARED_INTERMEDIATE_DIR)/<(mojom_base_output_dir)/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).mojom.cc',
'<(SHARED_INTERMEDIATE_DIR)/<(mojom_base_output_dir)/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).mojom.h',
'<(SHARED_INTERMEDIATE_DIR)/<(mojom_base_output_dir)/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).mojom.js',
'<(SHARED_INTERMEDIATE_DIR)/<(mojom_base_output_dir)/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).mojom.py',
'<(SHARED_INTERMEDIATE_DIR)/<(mojom_base_output_dir)/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).mojom-internal.h',
],
'action': [
......
......@@ -56,6 +56,9 @@ def LoadGenerators(generators_string):
elif generator_name.lower() == "java":
generator_name = os.path.join(script_dir, "generators",
"mojom_java_generator.py")
elif generator_name.lower() == "python":
generator_name = os.path.join(script_dir, "generators",
"mojom_python_generator.py")
# Specified generator python module:
elif generator_name.endswith(".py"):
pass
......@@ -166,7 +169,8 @@ def main():
parser.add_argument("-o", "--output_dir", dest="output_dir", default=".",
help="output directory for generated files")
parser.add_argument("-g", "--generators", dest="generators_string",
metavar="GENERATORS", default="c++,javascript,java",
metavar="GENERATORS",
default="c++,javascript,java,python",
help="comma-separated list of generators")
parser.add_argument("--debug_print_intermediate", action="store_true",
help="print the intermediate representation")
......
# 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.
import math
import unittest
# Generated files
# pylint: disable=F0401
import sample_service_mojom
class ConstantBindingsTest(unittest.TestCase):
def test_constant_generation(self):
self.assertEquals(sample_service_mojom.TWELVE, 12)
self.assertEquals(sample_service_mojom.TOO_BIG_FOR_SIGNED_INT64,
9999999999999999999)
self.assertEquals(sample_service_mojom.DOUBLE_INFINITY,
float('inf'))
self.assertEquals(sample_service_mojom.DOUBLE_NEGATIVE_INFINITY,
float('-inf'))
self.assertTrue(math.isnan(sample_service_mojom.DOUBLE_NA_N))
self.assertEquals(sample_service_mojom.FLOAT_INFINITY,
float('inf'))
self.assertEquals(sample_service_mojom.FLOAT_NEGATIVE_INFINITY,
float('-inf'))
self.assertTrue(math.isnan(sample_service_mojom.FLOAT_NA_N))
......@@ -23,6 +23,12 @@ class PythonBindingsTestRunner(MojoPythonTestRunner):
python_build_dir = os.path.join(args.build_dir, 'python')
if python_build_dir not in sys.path:
sys.path.append(python_build_dir)
python_gen_dir = os.path.join(
args.build_dir,
'gen', 'mojo', 'public', 'interfaces', 'bindings', 'tests')
print python_gen_dir
if python_gen_dir not in sys.path:
sys.path.append(python_gen_dir)
def main():
......
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