| Index: tools/json_schema_compiler/cpp_type_generator.py
|
| diff --git a/tools/json_schema_compiler/cpp_type_generator.py b/tools/json_schema_compiler/cpp_type_generator.py
|
| index a60b6e5cb381491d845fedbc392d0171e81eff60..3bca92d9302203ce39f45e6eb4f5cac6e7606861 100644
|
| --- a/tools/json_schema_compiler/cpp_type_generator.py
|
| +++ b/tools/json_schema_compiler/cpp_type_generator.py
|
| @@ -35,32 +35,41 @@ class CppTypeGenerator(object):
|
| """
|
| return self._cpp_namespaces[namespace]
|
|
|
| - def GetCppNamespaceStart(self):
|
| + def GetRootNamespaceStart(self):
|
| """Get opening namespace declarations.
|
| """
|
| c = Code()
|
| for n in self._root_namespace:
|
| c.Append('namespace %s {' % n)
|
| - c.Append('namespace %s {' % self.GetCppNamespaceName(self._namespace))
|
| return c
|
|
|
| - def GetCppNamespaceEnd(self):
|
| + def GetRootNamespaceEnd(self):
|
| """Get closing namespace declarations.
|
| """
|
| c = Code()
|
| - c.Append('} // %s' % self.GetCppNamespaceName(self._namespace))
|
| for n in reversed(self._root_namespace):
|
| c.Append('} // %s' % n)
|
| return c
|
|
|
| + def GetNamespaceStart(self):
|
| + return Code().Append('namespace %s {' %
|
| + self.GetCppNamespaceName(self._namespace))
|
| +
|
| + def GetNamespaceEnd(self):
|
| + return Code().Append('} // %s' %
|
| + self.GetCppNamespaceName(self._namespace))
|
| +
|
| # TODO(calamity): Handle ANY
|
| - def GetType(self, prop, pad_for_generics=False):
|
| + def GetType(self, prop, pad_for_generics=False, wrap_optional=False):
|
| """Translates a model.Property into its C++ type.
|
|
|
| If REF types from different namespaces are referenced, will resolve
|
| using self._type_namespaces.
|
|
|
| Use pad_for_generics when using as a generic to avoid operator ambiguity.
|
| +
|
| + Use wrap_optional to wrap the type in a scoped_ptr<T> if the Property is
|
| + optional.
|
| """
|
| cpp_type = None
|
| if prop.type_ == PropertyType.REF:
|
| @@ -80,47 +89,69 @@ class CppTypeGenerator(object):
|
| cpp_type = 'double'
|
| elif prop.type_ == PropertyType.STRING:
|
| cpp_type = 'std::string'
|
| + elif prop.type_ == PropertyType.ANY:
|
| + cpp_type = 'linked_ptr<DictionaryValue> '
|
| elif prop.type_ == PropertyType.ARRAY:
|
| - cpp_type = 'std::vector<%s>' % self.GetType(
|
| + if prop.item_type.type_ == PropertyType.REF:
|
| + cpp_type = 'std::vector<linked_ptr<%s> > '
|
| + else:
|
| + cpp_type = 'std::vector<%s> '
|
| + cpp_type = cpp_type % self.GetType(
|
| prop.item_type, pad_for_generics=True)
|
| elif prop.type_ == PropertyType.OBJECT:
|
| - cpp_type = cpp_util.CppName(prop.name)
|
| + cpp_type = cpp_util.Classname(prop.name)
|
| # TODO(calamity): choices
|
| else:
|
| raise NotImplementedError
|
|
|
| - # Add a space to prevent operator ambiguity
|
| - if pad_for_generics and cpp_type[-1] == '>':
|
| - return '%s ' % cpp_type
|
| - return '%s' % cpp_type
|
| + if wrap_optional and prop.optional:
|
| + cpp_type = 'scoped_ptr<%s> ' % cpp_type
|
| + if pad_for_generics:
|
| + return '%s' % cpp_type
|
| + return cpp_type.strip()
|
|
|
| - def GenerateCppIncludes(self):
|
| + def GenerateForwardDeclarations(self):
|
| + dependencies = set()
|
| + c = Code()
|
| + for namespace, types in sorted(self._NamespaceTypeDependencies().items()):
|
| + c.Append('namespace %s {' % namespace.name)
|
| + for type_ in types:
|
| + c.Append('struct %s;' % type_)
|
| + c.Append('}')
|
| + return c
|
| +
|
| + def GenerateIncludes(self):
|
| """Returns the #include lines for self._namespace using the other
|
| namespaces in self._model.
|
| """
|
| + c = Code()
|
| + for dependency_namespace in sorted(self._NamespaceTypeDependencies().keys()):
|
| + c.Append('#include "%s/%s.h"' % (
|
| + dependency_namespace.source_file_dir,
|
| + self._cpp_namespaces[dependency_namespace]))
|
| + return c
|
| +
|
| + def _NamespaceTypeDependencies(self):
|
| dependencies = set()
|
| for function in self._namespace.functions.values():
|
| for param in function.params:
|
| - dependencies |= self._TypeDependencies(param)
|
| - dependencies |= self._TypeDependencies(function.callback.param)
|
| + dependencies |= self._PropertyTypeDependencies(param)
|
| + for param in function.callback.params:
|
| + dependencies |= self._PropertyTypeDependencies(param)
|
| for type_ in self._namespace.types.values():
|
| for prop in type_.properties.values():
|
| - dependencies |= self._TypeDependencies(prop)
|
| + dependencies |= self._PropertyTypeDependencies(prop)
|
|
|
| - dependency_namespaces = set()
|
| + dependency_namespaces = dict()
|
| for dependency in dependencies:
|
| - dependency_namespace = self._type_namespaces[dependency]
|
| - if dependency_namespace != self._namespace:
|
| - dependency_namespaces.add(dependency_namespace)
|
| -
|
| - includes = Code()
|
| - for dependency_namespace in sorted(dependency_namespaces):
|
| - includes.Append('#include "%s/%s.h"' % (
|
| - dependency_namespace.source_file_dir,
|
| - self._cpp_namespaces[dependency_namespace]))
|
| - return includes
|
| + namespace = self._type_namespaces[dependency]
|
| + if namespace != self._namespace:
|
| + if not dependency_namespaces.get(namespace):
|
| + dependency_namespaces[namespace] = []
|
| + dependency_namespaces[namespace].append(dependency)
|
| + return dependency_namespaces
|
|
|
| - def _TypeDependencies(self, prop):
|
| + def _PropertyTypeDependencies(self, prop):
|
| """Recursively gets all the type dependencies of a property.
|
| """
|
| deps = set()
|
| @@ -128,8 +159,8 @@ class CppTypeGenerator(object):
|
| if prop.type_ == PropertyType.REF:
|
| deps.add(prop.ref_type)
|
| elif prop.type_ == PropertyType.ARRAY:
|
| - deps = self._TypeDependencies(prop.item_type)
|
| + deps = self._PropertyTypeDependencies(prop.item_type)
|
| elif prop.type_ == PropertyType.OBJECT:
|
| for p in prop.properties.values():
|
| - deps |= self._TypeDependencies(p)
|
| + deps |= self._PropertyTypeDependencies(p)
|
| return deps
|
|
|