Chromium Code Reviews| 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..12ebfe8d581f02488dbfc97eb1d85aeb1a8791ad 100644 |
| --- a/tools/json_schema_compiler/cpp_type_generator.py |
| +++ b/tools/json_schema_compiler/cpp_type_generator.py |
| @@ -35,32 +35,44 @@ class CppTypeGenerator(object): |
| """ |
| return self._cpp_namespaces[namespace] |
| - def GetCppNamespaceStart(self): |
| - """Get opening namespace declarations. |
| + def GetRootNamespaceStart(self): |
| + """Get opening root namespace declarations. |
| """ |
| c = Code() |
| - for n in self._root_namespace: |
| - c.Append('namespace %s {' % n) |
| - c.Append('namespace %s {' % self.GetCppNamespaceName(self._namespace)) |
| + for namespace in self._root_namespace: |
| + c.Append('namespace %s {' % namespace) |
| return c |
| - def GetCppNamespaceEnd(self): |
| - """Get closing namespace declarations. |
| + def GetRootNamespaceEnd(self): |
| + """Get closing root namespace declarations. |
| """ |
| c = Code() |
| - c.Append('} // %s' % self.GetCppNamespaceName(self._namespace)) |
| - for n in reversed(self._root_namespace): |
| - c.Append('} // %s' % n) |
| + for namespace in reversed(self._root_namespace): |
| + c.Append('} // %s' % namespace) |
| return c |
| - # TODO(calamity): Handle ANY |
| - def GetType(self, prop, pad_for_generics=False): |
| + def GetNamespaceStart(self): |
| + """Get opening self._namespace namespace declaration. |
| + """ |
| + return Code().Append('namespace %s {' % |
| + self.GetCppNamespaceName(self._namespace)) |
| + |
| + def GetNamespaceEnd(self): |
| + """Get closing self._namespace namespace declaration. |
| + """ |
| + return Code().Append('} // %s' % |
| + self.GetCppNamespaceName(self._namespace)) |
| + |
| + 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 |
|
Yoyo Zhou
2012/02/08 19:04:12
When would you not want to use this?
calamity
2012/02/09 00:56:52
Anywhere that isn't a declaration.
e.g scoped_ptr
|
| + optional. |
| """ |
| cpp_type = None |
| if prop.type_ == PropertyType.REF: |
| @@ -71,7 +83,7 @@ class CppTypeGenerator(object): |
| cpp_type = '%s::%s' % (self._cpp_namespaces[dependency_namespace], |
| prop.ref_type) |
| else: |
| - cpp_type = '%s' % prop.ref_type |
| + cpp_type = prop.ref_type |
| elif prop.type_ == PropertyType.BOOLEAN: |
| cpp_type = 'bool' |
| elif prop.type_ == PropertyType.INTEGER: |
| @@ -80,47 +92,74 @@ class CppTypeGenerator(object): |
| cpp_type = 'double' |
| elif prop.type_ == PropertyType.STRING: |
| cpp_type = 'std::string' |
| + elif prop.type_ == PropertyType.ANY: |
| + cpp_type = 'DictionaryValue' |
| elif prop.type_ == PropertyType.ARRAY: |
| - cpp_type = 'std::vector<%s>' % self.GetType( |
| + if prop.item_type.type_ in (PropertyType.REF, PropertyType.ANY, PropertyType.OBJECT): |
|
not at google - send to devlin
2012/02/06 13:14:48
Cool
Line wrapping though :)
calamity
2012/02/08 00:52:31
Done.
|
| + 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) |
| - # TODO(calamity): choices |
| + cpp_type = cpp_util.Classname(prop.name) |
| else: |
| - raise NotImplementedError |
| + raise NotImplementedError(prop.type_) |
| + |
| + if wrap_optional and prop.optional: |
| + cpp_type = 'scoped_ptr<%s> ' % cpp_type |
| + if pad_for_generics: |
| + return cpp_type |
| + return cpp_type.strip() |
| + |
| + def GenerateForwardDeclarations(self): |
| + """Returns the forward declarations for self._namespace. |
| - # Add a space to prevent operator ambiguity |
| - if pad_for_generics and cpp_type[-1] == '>': |
| - return '%s ' % cpp_type |
| - return '%s' % cpp_type |
| + Use after GetRootNamespaceStart. Assumes all namespaces are relative to |
| + self._root_namespace. |
| + """ |
| + c = Code() |
| + for namespace, types in sorted(self._NamespaceTypeDependencies().items()): |
| + c.Append('namespace %s {' % namespace.name) |
|
Yoyo Zhou
2012/02/08 19:04:12
Any possibility of nested namespaces?
calamity
2012/02/09 00:56:52
I don't think so. These should only be types (e.g
|
| + for type_ in types: |
| + c.Append('struct %s;' % type_) |
| + c.Append('}') |
| + return c |
| + |
| + def GenerateIncludes(self): |
| + """Returns the #include lines for self._namespace. |
| + """ |
| + c = Code() |
| + for dependency in sorted(self._NamespaceTypeDependencies().keys()): |
| + c.Append('#include "%s/%s.h"' % ( |
| + dependency.source_file_dir, |
| + self._cpp_namespaces[dependency])) |
| + return c |
| - def GenerateCppIncludes(self): |
| - """Returns the #include lines for self._namespace using the other |
| - namespaces in self._model. |
| + def _NamespaceTypeDependencies(self): |
| + """Returns a dict containing a mapping of model.Namespace to the C++ type |
| + of type dependencies for self._namespace. |
| """ |
| 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 |
| - |
| - def _TypeDependencies(self, prop): |
| + namespace = self._type_namespaces[dependency] |
| + if namespace != self._namespace: |
| + if not dependency_namespaces.get(namespace): |
|
Yoyo Zhou
2012/02/08 19:04:12
You could use dependency_namespaces.setdefault(nam
calamity
2012/02/09 00:56:52
Done.
|
| + dependency_namespaces[namespace] = [] |
| + dependency_namespaces[namespace].append(dependency) |
| + return dependency_namespaces |
| + |
| + def _PropertyTypeDependencies(self, prop): |
| """Recursively gets all the type dependencies of a property. |
| """ |
| deps = set() |
| @@ -128,8 +167,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 |