Chromium Code Reviews| Index: tools/json_schema_compiler/h_generator.py |
| diff --git a/tools/json_schema_compiler/h_generator.py b/tools/json_schema_compiler/h_generator.py |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..9b89641e705f5f55358ea27db5850a0ec23db25f |
| --- /dev/null |
| +++ b/tools/json_schema_compiler/h_generator.py |
| @@ -0,0 +1,211 @@ |
| +# Copyright (c) 2012 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. |
| + |
| +from model import PropertyType |
| +import code |
| +import cpp_type_generator |
| +import cpp_util |
| + |
| +class HGenerator(object): |
| + """A .h generator for a namespace. |
| + """ |
| + def __init__(self, namespace, model, cpp_type_generator): |
| + self._cpp_type_generator = cpp_type_generator |
| + self._namespace = namespace |
| + self._target_namespace = ( |
| + self._cpp_type_generator.getCppNamespaceName(self._namespace)) |
| + |
| + def generate(self): |
| + """Generates a code.Code object with the .h for a single namespace. |
| + """ |
| + c = code.Code() |
| + (c.append(cpp_util.CHROMIUM_LICENSE).append() |
| + .append(cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file) |
| + .append() |
| + ) |
| + |
| + ifndef_name = self._generateIfndefName() |
| + (c.append('#ifndef %s' % ifndef_name) |
| + .append('#define %s' % ifndef_name) |
| + .append('#pragma once') |
| + .append() |
| + .append('#include <string>') |
| + .append('#include <vector>') |
| + .append() |
| + .append('#include "base/basictypes.h"') |
| + .append('#include "base/memory/scoped_ptr.h"') |
| + .append('#include "base/values.h"') |
| + .append() |
| + .append('using base::Value;') |
| + .append('using base::DictionaryValue;') |
| + .append('using base::ListValue;') |
| + .append() |
| + ) |
| + |
| + includes = self._cpp_type_generator.generateCppIncludes() |
| + if not includes.isEmpty(): |
| + (c.concat(includes) |
| + .append() |
| + ) |
| + |
| + (c.concat(self._cpp_type_generator.getCppNamespaceStart()) |
| + .append() |
| + .append('//') |
| + .append('// Types') |
| + .append('//') |
| + .append() |
| + ) |
| + for type_ in self._namespace.types.values(): |
| + (c.concat(self._generateType(type_)) |
| + .append() |
| + ) |
| + (c.append('//') |
| + .append('// Functions') |
| + .append('//') |
| + .append() |
| + ) |
| + for function in self._namespace.functions.values(): |
| + (c.concat(self._generateFunction(function)) |
| + .append() |
| + ) |
| + (c.append() |
| + .append() |
| + .concat(self._cpp_type_generator.getCppNamespaceEnd()) |
| + .append() |
| + .append('#endif // %s' % ifndef_name) |
| + .append() |
| + ) |
| + return c |
| + |
| + def _generateType(self, type_, serializable=True): |
| + """Generates a struct for a type. |
| + """ |
| + classname = cpp_util.cppName(type_.name) |
| + c = code.Code() |
| + if type_.description: |
| + c.comment(type_.description) |
| + (c.sblock('struct %(classname)s {') |
| + .append('~%(classname)s();') |
| + .append('%(classname)s();') |
| + .append() |
| + ) |
| + |
| + for prop in type_.properties.values(): |
| + if prop.description: |
| + c.comment(prop.description) |
| + if prop.optional: |
| + c.append('scoped_ptr<%s> %s;' % |
| + (self._cpp_type_generator.getType(prop, pad_for_generics=True), |
| + prop.name)) |
| + else: |
| + c.append('%s %s;' % |
| + (self._cpp_type_generator.getType(prop), prop.name)) |
| + c.append() |
| + |
| + (c.comment('Populates a %(classname)s object from a Value. Returns' |
| + ' whether |out| was successfully populated.') |
| + .append('static bool Populate(const Value& value, %(classname)s* out);') |
| + .append() |
| + ) |
| + |
| + if serializable: |
| + (c.comment('Returns a new DictionaryValue representing the' |
| + ' serialized form of this %(classname)s object.') |
|
jstritar
2012/01/23 22:42:07
I think you should add a note to the comment sayin
calamity
2012/01/24 22:57:22
Done.
|
| + .append('DictionaryValue* ToValue() const;') |
| + ) |
| + (c.eblock() |
| + .sblock(' private:') |
| + .append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);') |
| + .eblock('};') |
| + ) |
| + c.substitute({'classname': classname}) |
| + return c |
| + |
| + def _generateFunction(self, function): |
| + """Generates the structs for a function. |
| + """ |
| + c = code.Code() |
| + (c.sblock('namespace %s {' % cpp_util.cppName(function.name)) |
| + .concat(self._generateFunctionParams(function)) |
| + .append() |
| + .concat(self._generateFunctionResult(function)) |
| + .append() |
| + .eblock('};') |
| + ) |
| + return c |
| + |
| + def _generateFunctionParams(self, function): |
| + """Generates the struct for passing parameters into a function. |
| + """ |
| + c = code.Code() |
| + |
| + if function.params: |
| + c.sblock('struct Params {') |
| + for param in function.params: |
| + if param.description: |
| + c.comment(param.description) |
| + if param.type_ == PropertyType.OBJECT: |
| + c.concat(self._GenerateType(param, serializable=False)) |
| + c.append() |
| + for param in function.params: |
| + c.append('%s %s;' % |
| + (self._cpp_type_generator.getType(param), param.name)) |
| + |
| + (c.append() |
| + .append('Params();') |
| + .append('~Params();') |
| + .append() |
| + .append('static Params* Create(const ListValue& args);') |
| + .eblock() |
| + .sblock(' private:') |
| + .append('DISALLOW_COPY_AND_ASSIGN(Params);') |
| + ) |
| + |
| + c.eblock('};') |
| + |
| + return c |
| + |
| + def _generateFunctionResult(self, function): |
| + """Generates the struct for passing a function's result back. |
| + """ |
| + # TODO(calamity): Handle returning an object |
| + c = code.Code() |
| + |
| + param = function.callback.param |
| + # TODO(calamity): Put this description comment in less stupid place |
| + if param.description: |
| + c.comment(param.description) |
| + (c.append('class Result {') |
| + .sblock(' public:') |
| + ) |
| + arg = '' |
| + # TODO(calamity): handle object |
| + if param: |
| + if param.type_ == PropertyType.REF: |
| + arg = 'const %(type)s& %(name)s' |
| + else: |
| + arg = 'const %(type)s %(name)s' |
| + arg = arg % { |
| + 'type': self._cpp_type_generator.getType(param), |
| + 'name': param.name |
| + } |
| + (c.append('static Value* Create(%s);' % arg) |
| + .eblock() |
| + .sblock(' private:') |
| + .append('Result() {};') |
| + .append('DISALLOW_COPY_AND_ASSIGN(Result);') |
| + .eblock('};') |
| + ) |
| + |
| + return c |
| + |
| + def _generateIfndefName(self): |
| + """Formats a path and filename as a #define name. |
| + |
| + e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__. |
| + """ |
| + return (('%s/%s_H__' % |
| + (self._namespace.source_file_dir, self._target_namespace)) |
| + .upper().replace('/', '_')) |
| + |