summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorqsr@chromium.org <qsr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-03 08:43:37 +0000
committerqsr@chromium.org <qsr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-03 08:43:37 +0000
commit21075b5dc4f91266175d92b46c004c24bf69f73e (patch)
tree6dc8c72ca5c5648fed0e76d74c2e77776b4969c5
parentc4c9c8cf4af14e6944375330bd12712ce4eb5479 (diff)
downloadchromium_src-21075b5dc4f91266175d92b46c004c24bf69f73e.zip
chromium_src-21075b5dc4f91266175d92b46c004c24bf69f73e.tar.gz
chromium_src-21075b5dc4f91266175d92b46c004c24bf69f73e.tar.bz2
Generate java bindings for constants.
This CL is the first CL introducing java bindings. It only generates constants. This is a reland of https://codereview.chromium.org/291903003 with a custom DEPS file to fix bot issue. TBR=viettrungluu@chromium.org,rmcilroy@chromium.org Review URL: https://codereview.chromium.org/312643003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@274431 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--mojo/android/javatests/DEPS4
-rw-r--r--mojo/android/javatests/src/org/chromium/mojo/bindings/BindingsTest.java33
-rw-r--r--mojo/public/tools/bindings/generators/java_templates/constant_definition.tmpl5
-rw-r--r--mojo/public/tools/bindings/generators/java_templates/constants.java.tmpl12
-rw-r--r--mojo/public/tools/bindings/generators/java_templates/header.java.tmpl11
-rw-r--r--mojo/public/tools/bindings/generators/java_templates/java_macros.tmpl3
-rw-r--r--mojo/public/tools/bindings/generators/mojom_java_generator.py182
-rw-r--r--mojo/public/tools/bindings/mojom_bindings_generator.gypi14
-rwxr-xr-xmojo/public/tools/bindings/mojom_bindings_generator.py5
9 files changed, 267 insertions, 2 deletions
diff --git a/mojo/android/javatests/DEPS b/mojo/android/javatests/DEPS
new file mode 100644
index 0000000..78cf465
--- /dev/null
+++ b/mojo/android/javatests/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ # out should be allowed by default, but bots are failing on this.
+ "+out",
+]
diff --git a/mojo/android/javatests/src/org/chromium/mojo/bindings/BindingsTest.java b/mojo/android/javatests/src/org/chromium/mojo/bindings/BindingsTest.java
new file mode 100644
index 0000000..1c4807b
--- /dev/null
+++ b/mojo/android/javatests/src/org/chromium/mojo/bindings/BindingsTest.java
@@ -0,0 +1,33 @@
+// 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.
+
+package org.chromium.mojo.bindings;
+
+import android.test.suitebuilder.annotation.SmallTest;
+
+import junit.framework.TestCase;
+
+import org.chromium.mojo.bindings.test.sample.SampleServiceConstants;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+/**
+ * Testing generated classes and associated features.
+ */
+public class BindingsTest extends TestCase {
+
+ /**
+ * Testing constants are correctly generated.
+ */
+ @SmallTest
+ public void testConstants() throws NoSuchFieldException, SecurityException {
+ assertEquals(3, SampleServiceConstants.THREE);
+ Field threeField = SampleServiceConstants.class.getField("THREE");
+ assertEquals(byte.class, threeField.getType());
+ assertEquals(Modifier.FINAL, threeField.getModifiers() & Modifier.FINAL);
+ assertEquals(Modifier.STATIC, threeField.getModifiers() & Modifier.STATIC);
+ }
+
+}
diff --git a/mojo/public/tools/bindings/generators/java_templates/constant_definition.tmpl b/mojo/public/tools/bindings/generators/java_templates/constant_definition.tmpl
new file mode 100644
index 0000000..f69f657
--- /dev/null
+++ b/mojo/public/tools/bindings/generators/java_templates/constant_definition.tmpl
@@ -0,0 +1,5 @@
+{% from "java_macros.tmpl" import build_default %}
+
+{% macro constant_def(constant) %}
+public static final {{constant.kind|java_type}} {{constant|name}} = {{build_default(module, constant.kind, constant.value)|indent(4)}};
+{% endmacro %}
diff --git a/mojo/public/tools/bindings/generators/java_templates/constants.java.tmpl b/mojo/public/tools/bindings/generators/java_templates/constants.java.tmpl
new file mode 100644
index 0000000..0a4e299
--- /dev/null
+++ b/mojo/public/tools/bindings/generators/java_templates/constants.java.tmpl
@@ -0,0 +1,12 @@
+{% from "constant_definition.tmpl" import constant_def %}
+{% include "header.java.tmpl" %}
+
+public final class {{main_entity}} {
+{% for constant in constants %}
+
+ {{constant_def(constant)|indent(4)}}
+{% endfor %}
+
+ private {{main_entity}}() {}
+
+}
diff --git a/mojo/public/tools/bindings/generators/java_templates/header.java.tmpl b/mojo/public/tools/bindings/generators/java_templates/header.java.tmpl
new file mode 100644
index 0000000..ec6a88b
--- /dev/null
+++ b/mojo/public/tools/bindings/generators/java_templates/header.java.tmpl
@@ -0,0 +1,11 @@
+// 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.
+
+// This file is autogenerated by:
+// mojo/public/tools/bindings/mojom_bindings_generator.py
+// For:
+// {{module.path}}
+//
+
+package {{package}};
diff --git a/mojo/public/tools/bindings/generators/java_templates/java_macros.tmpl b/mojo/public/tools/bindings/generators/java_templates/java_macros.tmpl
new file mode 100644
index 0000000..a8745d2
--- /dev/null
+++ b/mojo/public/tools/bindings/generators/java_templates/java_macros.tmpl
@@ -0,0 +1,3 @@
+{% macro build_default(module, kind, value) %}
+({{kind|java_type}}) {{value|expression_to_text(module)}}
+{% endmacro %}
diff --git a/mojo/public/tools/bindings/generators/mojom_java_generator.py b/mojo/public/tools/bindings/generators/mojom_java_generator.py
new file mode 100644
index 0000000..0b38127
--- /dev/null
+++ b/mojo/public/tools/bindings/generators/mojom_java_generator.py
@@ -0,0 +1,182 @@
+# 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 java source files from a mojom.Module."""
+
+import argparse
+import os
+import re
+
+import mojom.generate.generator as generator
+import mojom.generate.module as mojom
+from mojom.generate.template_expander import UseJinja
+
+
+GENERATOR_PREFIX = 'java'
+
+_spec_to_java_type = {
+ 'b': 'boolean',
+ 'd': 'double',
+ 'f': 'float',
+ 'h:d:c': 'org.chromium.mojo.system.DataPipe.ConsumerHandle',
+ 'h:d:p': 'org.chromium.mojo.system.DataPipe.ProducerHandle',
+ 'h:m': 'org.chromium.mojo.system.MessagePipeHandle',
+ 'h': 'org.chromium.mojo.system.UntypedHandle',
+ 'h:s': 'org.chromium.mojo.system.SharedBufferHandle',
+ 'i16': 'short',
+ 'i32': 'int',
+ 'i64': 'long',
+ 'i8': 'byte',
+ 's': 'String',
+ 'u16': 'short',
+ 'u32': 'int',
+ 'u64': 'long',
+ 'u8': 'byte',
+}
+
+
+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 CapitalizeFirst(string):
+ return string[0].upper() + string[1:]
+
+def UpperCamelCase(name):
+ return ''.join([CapitalizeFirst(x) 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.Enum) or
+ isinstance(element, mojom.Interface) or
+ isinstance(element, mojom.Struct)):
+ return UpperCamelCase(element.name)
+ if (isinstance(element, mojom.Method) or
+ isinstance(element, mojom.Parameter) or
+ isinstance(element, mojom.Field)):
+ return CamelCase(element.name)
+ if isinstance(element, mojom.EnumValue):
+ return (UpperCamelCase(element.enum_name) + '.' +
+ ConstantStyle(element.name))
+ if (isinstance(element, mojom.NamedValue) or
+ isinstance(element, mojom.Constant)):
+ return ConstantStyle(element.name)
+ raise Exception("Unexpected element: " % element)
+
+def GetPackage(module):
+ if 'JavaPackage' in module.attributes:
+ package = module.attributes['JavaPackage']
+ if isinstance(package, basestring):
+ return package
+ assert package[0] == 'EXPRESSION'
+ assert len(package[1]) == 1
+ return package[1][0][1:-1].encode('string_escape')
+ # Default package.
+ return "org.chromium.mojom." + module.namespace
+
+def GetNameForKind(kind):
+ def _GetNameHierachy(kind):
+ hierachy = []
+ if kind.parent_kind:
+ hierachy = _GetNameHierachy(kind.parent_kind)
+ hierachy.append(kind.name)
+ return hierachy
+
+ elements = [GetPackage(kind.module)]
+ elements += _GetNameHierachy(kind)
+ return '.'.join(elements)
+
+def GetJavaType(kind):
+ if isinstance(kind, (mojom.Struct, mojom.Interface)):
+ return GetNameForKind(kind)
+ if isinstance(kind, mojom.Array):
+ return "%s[]" % GetJavaType(kind.kind)
+ if isinstance(kind, mojom.Enum):
+ return "int"
+ return _spec_to_java_type[kind.spec]
+
+def TranslateConstants(token, module):
+ def _TranslateNamedValue(named_value):
+ entity_name = GetNameForElement(named_value)
+ if named_value.parent_kind:
+ return GetJavaType(named_value.parent_kind) + '.' + entity_name
+ # Handle the case where named_value is a module level constant:
+ if not isinstance(named_value, mojom.EnumValue):
+ entity_name = (GetConstantsMainEntityName(named_value.module) + '.' +
+ entity_name)
+ return GetPackage(named_value.module) + '.' + entity_name
+
+ if isinstance(token, mojom.NamedValue):
+ return _TranslateNamedValue(token)
+ # Add Long suffix to all number literals.
+ if re.match('^[0-9]+$', token):
+ return token + 'L'
+ return token
+
+def ExpressionToText(value, module):
+ if value[0] != "EXPRESSION":
+ raise Exception("Expected EXPRESSION, got" + value)
+ return "".join(generator.ExpressionMapper(value,
+ lambda token: TranslateConstants(token, module)))
+
+def GetConstantsMainEntityName(module):
+ # This constructs the name of the embedding classes for module level constants
+ # by extracting the mojom's filename and prepending it to Constants.
+ return (UpperCamelCase(module.path.split('/')[-1].rsplit('.', 1)[0]) +
+ 'Constants')
+
+class Generator(generator.Generator):
+
+ java_filters = {
+ "expression_to_text": ExpressionToText,
+ "java_type": GetJavaType,
+ "name": GetNameForElement,
+ "verify_token_type": generator.VerifyTokenType,
+ }
+
+ def GetJinjaExports(self):
+ return {
+ "module": self.module,
+ "package": GetPackage(self.module),
+ }
+
+ @UseJinja("java_templates/constants.java.tmpl", filters=java_filters,
+ lstrip_blocks=True, trim_blocks=True)
+ def GenerateConstantsSource(self, module):
+ exports = self.GetJinjaExports()
+ exports.update({"main_entity": GetConstantsMainEntityName(module),
+ "constants": module.constants})
+ return exports
+
+ def GenerateFiles(self, unparsed_args):
+ parser = argparse.ArgumentParser()
+ parser.add_argument("--java_output_directory", dest="java_output_directory")
+ args = parser.parse_args(unparsed_args)
+ if self.output_dir and args.java_output_directory:
+ self.output_dir = os.path.join(args.java_output_directory,
+ GetPackage(self.module).replace('.', '/'))
+ if not os.path.exists(self.output_dir):
+ try:
+ os.makedirs(self.output_dir)
+ except:
+ # Ignore errors on directory creation.
+ pass
+
+ if self.module.constants:
+ self.Write(self.GenerateConstantsSource(self.module),
+ "%s.java" % GetConstantsMainEntityName(self.module))
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator.gypi b/mojo/public/tools/bindings/mojom_bindings_generator.gypi
index 3fe0c63..dcb273dd 100644
--- a/mojo/public/tools/bindings/mojom_bindings_generator.gypi
+++ b/mojo/public/tools/bindings/mojom_bindings_generator.gypi
@@ -5,13 +5,14 @@
{
'rules': [
{
- 'rule_name': 'Generate C++ source files from mojom files',
+ 'rule_name': 'Generate C++, JS and Java source files from mojom files',
'extension': 'mojom',
'variables': {
'mojom_base_output_dir':
'<!(python <(DEPTH)/build/inverse_depth.py <(DEPTH))',
'mojom_bindings_generator':
'<(DEPTH)/mojo/public/tools/bindings/mojom_bindings_generator.py',
+ 'java_out_dir': '<(PRODUCT_DIR)/java_mojo/<(_target_name)/src',
},
'inputs': [
'<(mojom_bindings_generator)',
@@ -34,11 +35,16 @@
'<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/struct_serialization_definition.tmpl',
'<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_declaration.tmpl',
'<(DEPTH)/mojo/public/tools/bindings/generators/cpp_templates/wrapper_class_definition.tmpl',
+ '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/constant_definition.tmpl',
+ '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/constants.java.tmpl',
+ '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/header.java.tmpl',
+ '<(DEPTH)/mojo/public/tools/bindings/generators/java_templates/java_macros.tmpl',
'<(DEPTH)/mojo/public/tools/bindings/generators/js_templates/enum_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/struct_definition.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/pylib/mojom/__init__.py',
'<(DEPTH)/mojo/public/tools/bindings/pylib/mojom/error.py',
@@ -66,6 +72,7 @@
'--use_chromium_bundled_pylibs',
'-d', '<(DEPTH)',
'-o', '<(SHARED_INTERMEDIATE_DIR)/<(mojom_base_output_dir)/<(RULE_INPUT_DIRNAME)',
+ '--java_output_directory=<(java_out_dir)',
],
'message': 'Generating Mojo bindings from <(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).mojom',
'process_outputs_as_sources': 1,
@@ -80,6 +87,11 @@
'<(DEPTH)',
'<(SHARED_INTERMEDIATE_DIR)',
],
+ 'variables': {
+ 'generated_src_dirs': [
+ '<(PRODUCT_DIR)/java_mojo/<(_target_name)/src',
+ ],
+ },
},
'hard_dependency': 1,
}
diff --git a/mojo/public/tools/bindings/mojom_bindings_generator.py b/mojo/public/tools/bindings/mojom_bindings_generator.py
index aee3b8c..9332576 100755
--- a/mojo/public/tools/bindings/mojom_bindings_generator.py
+++ b/mojo/public/tools/bindings/mojom_bindings_generator.py
@@ -53,6 +53,9 @@ def LoadGenerators(generators_string):
elif generator_name.lower() == "javascript":
generator_name = os.path.join(script_dir, "generators",
"mojom_js_generator.py")
+ elif generator_name.lower() == "java":
+ generator_name = os.path.join(script_dir, "generators",
+ "mojom_java_generator.py")
# Specified generator python module:
elif generator_name.endswith(".py"):
pass
@@ -153,7 +156,7 @@ 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",
+ metavar="GENERATORS", default="c++,javascript,java",
help="comma-separated list of generators")
parser.add_argument("--debug_print_intermediate", action="store_true",
help="print the intermediate representation")