summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/json_schema_compiler/cc_generator.py79
-rw-r--r--tools/json_schema_compiler/cpp_type_generator.py7
-rwxr-xr-xtools/json_schema_compiler/cpp_type_generator_test.py13
-rw-r--r--tools/json_schema_compiler/h_generator.py4
-rwxr-xr-xtools/json_schema_compiler/idl_schema.py2
-rw-r--r--tools/json_schema_compiler/test/BUILD.gn1
-rw-r--r--tools/json_schema_compiler/test/json_schema_compiler_tests.gyp1
-rw-r--r--tools/json_schema_compiler/test/objects_movable.idl23
-rw-r--r--tools/json_schema_compiler/test/objects_unittest.cc40
-rw-r--r--tools/json_schema_compiler/util.h25
10 files changed, 188 insertions, 7 deletions
diff --git a/tools/json_schema_compiler/cc_generator.py b/tools/json_schema_compiler/cc_generator.py
index ac1679b..499671f 100644
--- a/tools/json_schema_compiler/cc_generator.py
+++ b/tools/json_schema_compiler/cc_generator.py
@@ -126,8 +126,17 @@ class _Generator(object):
(c.Append('%s::%s()' % (classname_in_namespace, classname))
.Cblock(self._GenerateInitializersAndBody(type_))
.Append('%s::~%s() {}' % (classname_in_namespace, classname))
- .Append()
)
+ if 'use_movable_types' in type_.namespace.compiler_options:
+ # Note: we use 'rhs' because some API objects have a member 'other'.
+ (c.Append('%s::%s(%s&& rhs)' %
+ (classname_in_namespace, classname, classname))
+ .Cblock(self._GenerateMoveCtor(type_))
+ .Append('%s& %s::operator=(%s&& rhs)' %
+ (classname_in_namespace, classname_in_namespace,
+ classname))
+ .Cblock(self._GenerateMoveAssignOperator(type_))
+ )
if type_.origin.from_json:
c.Cblock(self._GenerateTypePopulate(classname_in_namespace, type_))
if cpp_namespace is None: # only generate for top-level types
@@ -178,12 +187,78 @@ class _Generator(object):
raise TypeError(t)
if items:
- s = ': %s' % (', '.join(items))
+ s = ': %s' % (',\n'.join(items))
else:
s = ''
s = s + ' {}'
return Code().Append(s)
+ def _GetMoveProps(self, type_, copy_str, move_str):
+ """Returns a tuple of (props, dicts) for the type.
+
+ |props| is a list of all the copyable or movable properties generated using
+ the copy_str and move_str, and |dicts| is a list of all the dictionary
+ properties by name.
+
+ Properties:
+ - |type_| the Type to get the properties from
+ - |copy_str| the string to use when copying a value; should have two
+ placeholders to take the property name.
+ - |move_str| the string to use when moving a value; should have two
+ placeholders to take the property name.
+ """
+ props = []
+ dicts = []
+ for prop in type_.properties.values():
+ t = prop.type_
+
+ real_t = self._type_helper.FollowRef(t)
+ if (prop.optional or
+ t.property_type == PropertyType.ANY or
+ t.property_type == PropertyType.ARRAY or
+ t.property_type == PropertyType.BINARY or
+ t.property_type == PropertyType.CHOICES or
+ t.property_type == PropertyType.OBJECT or
+ t.property_type == PropertyType.REF or
+ t.property_type == PropertyType.STRING):
+ props.append(move_str % (prop.unix_name, prop.unix_name))
+ elif t.property_type == PropertyType.FUNCTION:
+ dicts.append(prop.unix_name)
+ elif (real_t.property_type == PropertyType.ENUM or
+ t.property_type == PropertyType.INTEGER or
+ t.property_type == PropertyType.DOUBLE or
+ t.property_type == PropertyType.BOOLEAN):
+ props.append(copy_str % (prop.unix_name, prop.unix_name))
+ else:
+ raise TypeError(t)
+
+ return (props, dicts)
+
+ def _GenerateMoveCtor(self, type_):
+ props, dicts = self._GetMoveProps(type_, '%s(rhs.%s)',
+ '%s(std::move(rhs.%s))')
+ s = ''
+ if props:
+ s = s + ': %s' % (',\n'.join(props))
+ s = s + '{'
+ for item in dicts:
+ s = s + ('\n%s.Swap(&rhs.%s);' % (item, item))
+ s = s + '\n}'
+
+ return Code().Append(s)
+
+ def _GenerateMoveAssignOperator(self, type_):
+ props, dicts = self._GetMoveProps(type_, '%s = rhs.%s;',
+ '%s = std::move(rhs.%s);')
+ s = '{\n'
+ if props:
+ s = s + '\n'.join(props)
+ for item in dicts:
+ s = s + ('\n%s.Swap(&rhs.%s);' % (item, item))
+ s = s + '\nreturn *this;\n}'
+
+ return Code().Append(s)
+
def _GenerateTypePopulate(self, cpp_namespace, type_):
"""Generates the function for populating a type given a pointer to it.
diff --git a/tools/json_schema_compiler/cpp_type_generator.py b/tools/json_schema_compiler/cpp_type_generator.py
index 3d307a9..24cbf61 100644
--- a/tools/json_schema_compiler/cpp_type_generator.py
+++ b/tools/json_schema_compiler/cpp_type_generator.py
@@ -121,7 +121,12 @@ class CppTypeGenerator(object):
# TODO(kalman): change this - but it's an exceedingly far-reaching change.
if not self.FollowRef(type_).property_type == PropertyType.ENUM:
if is_in_container and (is_ptr or not self.IsCopyable(type_)):
- cpp_type = 'linked_ptr<%s>' % cpp_util.PadForGenerics(cpp_type)
+ # Only wrap the object in a linked_ptr if this API isn't using movable
+ # types. Since base::Values aren't yet movable, wrap them too.
+ # TODO(devlin): Eventually, movable types should be the default.
+ if (not 'use_movable_types' in type_.namespace.compiler_options or
+ cpp_type == 'base::Value' or cpp_type == 'base::DictionaryValue'):
+ cpp_type = 'linked_ptr<%s>' % cpp_util.PadForGenerics(cpp_type)
elif is_ptr:
cpp_type = 'scoped_ptr<%s>' % cpp_util.PadForGenerics(cpp_type)
diff --git a/tools/json_schema_compiler/cpp_type_generator_test.py b/tools/json_schema_compiler/cpp_type_generator_test.py
index 51fcfe9..69d80dc 100755
--- a/tools/json_schema_compiler/cpp_type_generator_test.py
+++ b/tools/json_schema_compiler/cpp_type_generator_test.py
@@ -6,6 +6,7 @@
from cpp_namespace_environment import CppNamespaceEnvironment
from cpp_type_generator import CppTypeGenerator
from json_schema import CachedLoad
+import idl_schema
import model
import unittest
@@ -49,6 +50,10 @@ class CppTypeGeneratorTest(unittest.TestCase):
self.content_settings_json = CachedLoad('test/content_settings.json')
self.content_settings = self.models['content_settings'].AddNamespace(
self.content_settings_json[0], 'path/to/content_settings.json')
+ self.objects_movable_idl = idl_schema.Load('test/objects_movable.idl')
+ self.objects_movable = self.models['objects_movable'].AddNamespace(
+ self.objects_movable_idl[0], 'path/to/objects_movable.idl',
+ include_compiler_options=True)
def testGenerateIncludesAndForwardDeclarations(self):
m = model.Model()
@@ -153,6 +158,14 @@ class CppTypeGeneratorTest(unittest.TestCase):
manager.GetCppType(
self.permissions.types['Permissions'].properties['origins'].type_))
+ manager = CppTypeGenerator(self.models.get('objects_movable'),
+ _FakeSchemaLoader(None))
+ self.assertEquals(
+ 'std::vector<MovablePod>',
+ manager.GetCppType(
+ self.objects_movable.types['MovableParent'].
+ properties['pods'].type_))
+
def testGetCppTypeLocalRef(self):
manager = CppTypeGenerator(self.models.get('tabs'), _FakeSchemaLoader(None))
self.assertEquals(
diff --git a/tools/json_schema_compiler/h_generator.py b/tools/json_schema_compiler/h_generator.py
index 173e549..5452885 100644
--- a/tools/json_schema_compiler/h_generator.py
+++ b/tools/json_schema_compiler/h_generator.py
@@ -228,6 +228,10 @@ class _Generator(object):
.Append('%(classname)s();')
.Append('~%(classname)s();')
)
+ if 'use_movable_types' in type_.namespace.compiler_options:
+ (c.Append('%(classname)s(%(classname)s&& rhs);')
+ .Append('%(classname)s& operator=(%(classname)s&& rhs);')
+ )
if type_.origin.from_json:
(c.Append()
.Comment('Populates a %s object from a base::Value. Returns'
diff --git a/tools/json_schema_compiler/idl_schema.py b/tools/json_schema_compiler/idl_schema.py
index 58efe28..5fda70e 100755
--- a/tools/json_schema_compiler/idl_schema.py
+++ b/tools/json_schema_compiler/idl_schema.py
@@ -500,6 +500,8 @@ class IDLSchema(object):
compiler_options['implemented_in'] = node.value
elif node.name == 'camel_case_enum_to_string':
compiler_options['camel_case_enum_to_string'] = node.value
+ elif node.name == 'use_movable_types':
+ compiler_options['use_movable_types'] = node.value
elif node.name == 'deprecated':
deprecated = str(node.value)
elif node.name == 'documentation_title':
diff --git a/tools/json_schema_compiler/test/BUILD.gn b/tools/json_schema_compiler/test/BUILD.gn
index 33e6219..e12493f 100644
--- a/tools/json_schema_compiler/test/BUILD.gn
+++ b/tools/json_schema_compiler/test/BUILD.gn
@@ -23,6 +23,7 @@ json_schema_api("api") {
"idl_other_namespace.idl",
"idl_other_namespace_sub_namespace.idl",
"objects.json",
+ "objects_movable.idl",
"simple_api.json",
]
diff --git a/tools/json_schema_compiler/test/json_schema_compiler_tests.gyp b/tools/json_schema_compiler/test/json_schema_compiler_tests.gyp
index 404e9b0..a0203dc 100644
--- a/tools/json_schema_compiler/test/json_schema_compiler_tests.gyp
+++ b/tools/json_schema_compiler/test/json_schema_compiler_tests.gyp
@@ -25,6 +25,7 @@
'idl_other_namespace_sub_namespace.idl',
'idl_object_types.idl',
'objects.json',
+ 'objects_movable.idl',
'simple_api.json',
'error_generation.json'
],
diff --git a/tools/json_schema_compiler/test/objects_movable.idl b/tools/json_schema_compiler/test/objects_movable.idl
new file mode 100644
index 0000000..b09f1a8
--- /dev/null
+++ b/tools/json_schema_compiler/test/objects_movable.idl
@@ -0,0 +1,23 @@
+// Copyright 2016 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.
+
+// Movable Objects.
+[use_movable_types=true] namespace objectsMovable {
+ enum Foo {
+ BAR,
+ BAZ
+ };
+
+ dictionary MovablePod {
+ Foo foo;
+ DOMString str;
+ long num;
+ boolean b;
+ };
+
+ dictionary MovableParent {
+ MovablePod[] pods;
+ DOMString[] strs;
+ };
+};
diff --git a/tools/json_schema_compiler/test/objects_unittest.cc b/tools/json_schema_compiler/test/objects_unittest.cc
index 5e28386..2cb6fc6 100644
--- a/tools/json_schema_compiler/test/objects_unittest.cc
+++ b/tools/json_schema_compiler/test/objects_unittest.cc
@@ -2,14 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "tools/json_schema_compiler/test/objects.h"
-
#include <stddef.h>
#include "base/json/json_writer.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "tools/json_schema_compiler/test/objects.h"
+#include "tools/json_schema_compiler/test/objects_movable.h"
using namespace test::api::objects;
+using namespace test::api::objects_movable;
TEST(JsonSchemaCompilerObjectsTest, ObjectParamParamsCreate) {
{
@@ -71,3 +72,38 @@ TEST(JsonSchemaCompilerObjectsTest, OnObjectFiredCreate) {
ASSERT_TRUE(results->GetDictionary(0, &result));
ASSERT_TRUE(result->Equals(&expected));
}
+TEST(JsonSchemaCompilerMovableObjectsTest, MovableObjectsTest) {
+ std::vector<MovablePod> pods;
+ {
+ MovablePod pod;
+ pod.foo = FOO_BAR;
+ pod.str = "str1";
+ pod.num = 42;
+ pod.b = true;
+ pods.push_back(std::move(pod));
+ }
+ {
+ MovablePod pod;
+ pod.foo = FOO_BAZ;
+ pod.str = "str2";
+ pod.num = 45;
+ pod.b = false;
+ pods.push_back(std::move(pod));
+ }
+ MovableParent parent;
+ parent.pods = std::move(pods);
+ parent.strs.push_back("pstr");
+
+ MovableParent parent2(std::move(parent));
+ ASSERT_EQ(2u, parent2.pods.size());
+ EXPECT_EQ(FOO_BAR, parent2.pods[0].foo);
+ EXPECT_EQ("str1", parent2.pods[0].str);
+ EXPECT_EQ(42, parent2.pods[0].num);
+ EXPECT_TRUE(parent2.pods[0].b);
+ EXPECT_EQ(FOO_BAZ, parent2.pods[1].foo);
+ EXPECT_EQ("str2", parent2.pods[1].str);
+ EXPECT_EQ(45, parent2.pods[1].num);
+ EXPECT_FALSE(parent2.pods[1].b);
+ ASSERT_EQ(1u, parent2.strs.size());
+ EXPECT_EQ("pstr", parent2.strs[0]);
+}
diff --git a/tools/json_schema_compiler/util.h b/tools/json_schema_compiler/util.h
index 59d65d0..945f061 100644
--- a/tools/json_schema_compiler/util.h
+++ b/tools/json_schema_compiler/util.h
@@ -57,6 +57,19 @@ bool PopulateItem(const base::Value& from, linked_ptr<T>* out) {
return true;
}
+// This template is used for types generated by tools/json_schema_compiler.
+template <class T>
+bool PopulateItem(const base::Value& from, T* out) {
+ const base::DictionaryValue* dict = nullptr;
+ if (!from.GetAsDictionary(&dict))
+ return false;
+ T obj;
+ if (!T::Populate(*dict, &obj))
+ return false;
+ *out = std::move(obj);
+ return true;
+}
+
// This template is used for types generated by tools/json_schema_compiler with
// error generation enabled.
template <class T>
@@ -82,7 +95,9 @@ bool PopulateArrayFromList(const base::ListValue& list, std::vector<T>* out) {
for (const base::Value* value : list) {
if (!PopulateItem(*value, &item))
return false;
- out->push_back(item);
+ // T might not be movable, but in that case it should be copyable, and this
+ // will still work.
+ out->push_back(std::move(item));
}
return true;
@@ -148,12 +163,18 @@ void AddItemToList(const linked_ptr<T>& from, base::ListValue* out) {
out->Append(from->ToValue().release());
}
+// This template is used for types generated by tools/json_schema_compiler.
+template <class T>
+void AddItemToList(const T& from, base::ListValue* out) {
+ out->Append(from.ToValue());
+}
+
// Set |out| to the the contents of |from|. Requires PopulateItem to be
// implemented for |T|.
template <class T>
void PopulateListFromArray(const std::vector<T>& from, base::ListValue* out) {
out->Clear();
- for (const auto& item : from)
+ for (const T& item : from)
AddItemToList(item, out);
}