Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 from model import PropertyType | |
| 6 import code | |
| 7 import cpp_type_generator | |
| 8 import cpp_util | |
| 9 | |
| 10 class HGenerator(object): | |
| 11 """A .h generator for a namespace. | |
| 12 """ | |
| 13 def __init__(self, namespace, model, cpp_type_generator): | |
| 14 self._cpp_type_generator = cpp_type_generator | |
| 15 self._namespace = namespace | |
| 16 self._target_namespace = ( | |
| 17 self._cpp_type_generator.getCppNamespaceName(self._namespace)) | |
| 18 | |
| 19 def generate(self): | |
| 20 """Generates a code.Code object with the .h for a single namespace. | |
| 21 """ | |
| 22 c = code.Code() | |
| 23 (c.append(cpp_util.CHROMIUM_LICENSE).append() | |
| 24 .append(cpp_util.GENERATED_FILE_MESSAGE % self._namespace.source_file) | |
| 25 .append() | |
| 26 ) | |
| 27 | |
| 28 ifndef_name = self._generateIfndefName() | |
| 29 (c.append('#ifndef %s' % ifndef_name) | |
| 30 .append('#define %s' % ifndef_name) | |
| 31 .append('#pragma once') | |
| 32 .append() | |
| 33 .append('#include <string>') | |
| 34 .append('#include <vector>') | |
| 35 .append() | |
| 36 .append('#include "base/basictypes.h"') | |
| 37 .append('#include "base/memory/scoped_ptr.h"') | |
| 38 .append('#include "base/values.h"') | |
| 39 .append() | |
| 40 .append('using base::Value;') | |
| 41 .append('using base::DictionaryValue;') | |
| 42 .append('using base::ListValue;') | |
| 43 .append() | |
| 44 ) | |
| 45 | |
| 46 includes = self._cpp_type_generator.generateCppIncludes() | |
| 47 if not includes.isEmpty(): | |
| 48 (c.concat(includes) | |
| 49 .append() | |
| 50 ) | |
| 51 | |
| 52 (c.concat(self._cpp_type_generator.getCppNamespaceStart()) | |
| 53 .append() | |
| 54 .append('//') | |
| 55 .append('// Types') | |
| 56 .append('//') | |
| 57 .append() | |
| 58 ) | |
| 59 for type_ in self._namespace.types.values(): | |
| 60 (c.concat(self._generateType(type_)) | |
| 61 .append() | |
| 62 ) | |
| 63 (c.append('//') | |
| 64 .append('// Functions') | |
| 65 .append('//') | |
| 66 .append() | |
| 67 ) | |
| 68 for function in self._namespace.functions.values(): | |
| 69 (c.concat(self._generateFunction(function)) | |
| 70 .append() | |
| 71 ) | |
| 72 (c.append() | |
| 73 .append() | |
| 74 .concat(self._cpp_type_generator.getCppNamespaceEnd()) | |
| 75 .append() | |
| 76 .append('#endif // %s' % ifndef_name) | |
| 77 .append() | |
| 78 ) | |
| 79 return c | |
| 80 | |
| 81 def _generateType(self, type_, serializable=True): | |
| 82 """Generates a struct for a type. | |
| 83 """ | |
| 84 classname = cpp_util.cppName(type_.name) | |
| 85 c = code.Code() | |
| 86 if type_.description: | |
| 87 c.comment(type_.description) | |
| 88 (c.sblock('struct %(classname)s {') | |
| 89 .append('~%(classname)s();') | |
| 90 .append('%(classname)s();') | |
| 91 .append() | |
| 92 ) | |
| 93 | |
| 94 for prop in type_.properties.values(): | |
| 95 if prop.description: | |
| 96 c.comment(prop.description) | |
| 97 if prop.optional: | |
| 98 c.append('scoped_ptr<%s> %s;' % | |
| 99 (self._cpp_type_generator.getType(prop, pad_for_generics=True), | |
| 100 prop.name)) | |
| 101 else: | |
| 102 c.append('%s %s;' % | |
| 103 (self._cpp_type_generator.getType(prop), prop.name)) | |
| 104 c.append() | |
| 105 | |
| 106 (c.comment('Populates a %(classname)s object from a Value. Returns' | |
| 107 ' whether |out| was successfully populated.') | |
| 108 .append('static bool Populate(const Value& value, %(classname)s* out);') | |
| 109 .append() | |
| 110 ) | |
| 111 | |
| 112 if serializable: | |
| 113 (c.comment('Returns a new DictionaryValue representing the' | |
| 114 ' 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.
| |
| 115 .append('DictionaryValue* ToValue() const;') | |
| 116 ) | |
| 117 (c.eblock() | |
| 118 .sblock(' private:') | |
| 119 .append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);') | |
| 120 .eblock('};') | |
| 121 ) | |
| 122 c.substitute({'classname': classname}) | |
| 123 return c | |
| 124 | |
| 125 def _generateFunction(self, function): | |
| 126 """Generates the structs for a function. | |
| 127 """ | |
| 128 c = code.Code() | |
| 129 (c.sblock('namespace %s {' % cpp_util.cppName(function.name)) | |
| 130 .concat(self._generateFunctionParams(function)) | |
| 131 .append() | |
| 132 .concat(self._generateFunctionResult(function)) | |
| 133 .append() | |
| 134 .eblock('};') | |
| 135 ) | |
| 136 return c | |
| 137 | |
| 138 def _generateFunctionParams(self, function): | |
| 139 """Generates the struct for passing parameters into a function. | |
| 140 """ | |
| 141 c = code.Code() | |
| 142 | |
| 143 if function.params: | |
| 144 c.sblock('struct Params {') | |
| 145 for param in function.params: | |
| 146 if param.description: | |
| 147 c.comment(param.description) | |
| 148 if param.type_ == PropertyType.OBJECT: | |
| 149 c.concat(self._GenerateType(param, serializable=False)) | |
| 150 c.append() | |
| 151 for param in function.params: | |
| 152 c.append('%s %s;' % | |
| 153 (self._cpp_type_generator.getType(param), param.name)) | |
| 154 | |
| 155 (c.append() | |
| 156 .append('Params();') | |
| 157 .append('~Params();') | |
| 158 .append() | |
| 159 .append('static Params* Create(const ListValue& args);') | |
| 160 .eblock() | |
| 161 .sblock(' private:') | |
| 162 .append('DISALLOW_COPY_AND_ASSIGN(Params);') | |
| 163 ) | |
| 164 | |
| 165 c.eblock('};') | |
| 166 | |
| 167 return c | |
| 168 | |
| 169 def _generateFunctionResult(self, function): | |
| 170 """Generates the struct for passing a function's result back. | |
| 171 """ | |
| 172 # TODO(calamity): Handle returning an object | |
| 173 c = code.Code() | |
| 174 | |
| 175 param = function.callback.param | |
| 176 # TODO(calamity): Put this description comment in less stupid place | |
| 177 if param.description: | |
| 178 c.comment(param.description) | |
| 179 (c.append('class Result {') | |
| 180 .sblock(' public:') | |
| 181 ) | |
| 182 arg = '' | |
| 183 # TODO(calamity): handle object | |
| 184 if param: | |
| 185 if param.type_ == PropertyType.REF: | |
| 186 arg = 'const %(type)s& %(name)s' | |
| 187 else: | |
| 188 arg = 'const %(type)s %(name)s' | |
| 189 arg = arg % { | |
| 190 'type': self._cpp_type_generator.getType(param), | |
| 191 'name': param.name | |
| 192 } | |
| 193 (c.append('static Value* Create(%s);' % arg) | |
| 194 .eblock() | |
| 195 .sblock(' private:') | |
| 196 .append('Result() {};') | |
| 197 .append('DISALLOW_COPY_AND_ASSIGN(Result);') | |
| 198 .eblock('};') | |
| 199 ) | |
| 200 | |
| 201 return c | |
| 202 | |
| 203 def _generateIfndefName(self): | |
| 204 """Formats a path and filename as a #define name. | |
| 205 | |
| 206 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__. | |
| 207 """ | |
| 208 return (('%s/%s_H__' % | |
| 209 (self._namespace.source_file_dir, self._target_namespace)) | |
| 210 .upper().replace('/', '_')) | |
| 211 | |
| OLD | NEW |