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 |