| OLD | NEW |
| 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 from model import PropertyType | 5 from model import PropertyType |
| 6 import code | 6 import code |
| 7 import cpp_util | 7 import cpp_util |
| 8 import os | 8 import os |
| 9 | 9 |
| 10 class HGenerator(object): | 10 class HGenerator(object): |
| (...skipping 24 matching lines...) Expand all Loading... |
| 35 .Append('#include <vector>') | 35 .Append('#include <vector>') |
| 36 .Append() | 36 .Append() |
| 37 .Append('#include "base/basictypes.h"') | 37 .Append('#include "base/basictypes.h"') |
| 38 .Append('#include "base/memory/linked_ptr.h"') | 38 .Append('#include "base/memory/linked_ptr.h"') |
| 39 .Append('#include "base/memory/scoped_ptr.h"') | 39 .Append('#include "base/memory/scoped_ptr.h"') |
| 40 .Append('#include "base/values.h"') | 40 .Append('#include "base/values.h"') |
| 41 .Append() | 41 .Append() |
| 42 ) | 42 ) |
| 43 | 43 |
| 44 c.Concat(self._cpp_type_generator.GetRootNamespaceStart()) | 44 c.Concat(self._cpp_type_generator.GetRootNamespaceStart()) |
| 45 # TODO(calamity): These forward declarations should be #includes to allow |
| 46 # $ref types from other files to be used as required params. This requires |
| 47 # some detangling of windows and tabs which will currently lead to circular |
| 48 # #includes. |
| 45 forward_declarations = ( | 49 forward_declarations = ( |
| 46 self._cpp_type_generator.GenerateForwardDeclarations()) | 50 self._cpp_type_generator.GenerateForwardDeclarations()) |
| 47 if not forward_declarations.IsEmpty(): | 51 if not forward_declarations.IsEmpty(): |
| 48 (c.Append() | 52 (c.Append() |
| 49 .Concat(forward_declarations) | 53 .Concat(forward_declarations) |
| 50 .Append() | 54 .Append() |
| 51 ) | 55 ) |
| 52 | 56 |
| 53 (c.Concat(self._cpp_type_generator.GetNamespaceStart()) | 57 c.Concat(self._cpp_type_generator.GetNamespaceStart()) |
| 54 .Append() | 58 c.Append() |
| 55 .Append('//') | 59 if self._namespace.types: |
| 56 .Append('// Types') | 60 (c.Append('//') |
| 57 .Append('//') | 61 .Append('// Types') |
| 58 .Append() | 62 .Append('//') |
| 59 ) | |
| 60 for type_ in self._namespace.types.values(): | |
| 61 (c.Concat(self._GenerateType(type_)) | |
| 62 .Append() | 63 .Append() |
| 63 ) | 64 ) |
| 64 (c.Append('//') | 65 for type_ in self._namespace.types.values(): |
| 65 .Append('// Functions') | 66 (c.Concat(self._GenerateType(type_)) |
| 66 .Append('//') | 67 .Append() |
| 67 .Append() | 68 ) |
| 68 ) | 69 if self._namespace.functions: |
| 69 for function in self._namespace.functions.values(): | 70 (c.Append('//') |
| 70 (c.Concat(self._GenerateFunction(function)) | 71 .Append('// Functions') |
| 72 .Append('//') |
| 71 .Append() | 73 .Append() |
| 72 ) | 74 ) |
| 75 for function in self._namespace.functions.values(): |
| 76 (c.Concat(self._GenerateFunction(function)) |
| 77 .Append() |
| 78 ) |
| 73 (c.Append() | 79 (c.Append() |
| 74 .Concat(self._cpp_type_generator.GetNamespaceEnd()) | 80 .Concat(self._cpp_type_generator.GetNamespaceEnd()) |
| 75 .Concat(self._cpp_type_generator.GetRootNamespaceEnd()) | 81 .Concat(self._cpp_type_generator.GetRootNamespaceEnd()) |
| 76 .Append() | 82 .Append() |
| 77 .Append('#endif // %s' % ifndef_name) | 83 .Append('#endif // %s' % ifndef_name) |
| 78 .Append() | 84 .Append() |
| 79 ) | 85 ) |
| 80 return c | 86 return c |
| 81 | 87 |
| 82 def _GenerateEnumDeclaration(self, enum_name, prop, values): | 88 def _GenerateEnumDeclaration(self, enum_name, prop, values): |
| 89 """Generate the declaration of a C++ enum for the given property and |
| 90 values. |
| 91 """ |
| 83 c = code.Code() | 92 c = code.Code() |
| 84 c.Sblock('enum %s {' % enum_name) | 93 c.Sblock('enum %s {' % enum_name) |
| 85 if prop.optional: | 94 if prop.optional: |
| 86 c.Append(self._cpp_type_generator.GetEnumNoneValue(prop) + ',') | 95 c.Append(self._cpp_type_generator.GetEnumNoneValue(prop) + ',') |
| 87 for value in values: | 96 for value in values: |
| 88 c.Append(self._cpp_type_generator.GetEnumValue(prop, value) + ',') | 97 c.Append(self._cpp_type_generator.GetEnumValue(prop, value) + ',') |
| 89 (c.Eblock('};') | 98 (c.Eblock('};') |
| 90 .Append() | 99 .Append() |
| 91 ) | 100 ) |
| 92 return c | 101 return c |
| 93 | 102 |
| 94 def _GenerateFields(self, props): | 103 def _GenerateFields(self, props): |
| 95 """Generates the field declarations when declaring a type. | 104 """Generates the field declarations when declaring a type. |
| 96 """ | 105 """ |
| 97 c = code.Code() | 106 c = code.Code() |
| 98 # Generate the enums needed for any fields with "choices" | 107 # Generate the enums needed for any fields with "choices" |
| 99 for prop in props: | 108 for prop in props: |
| 100 if prop.type_ == PropertyType.CHOICES: | 109 if prop.type_ == PropertyType.CHOICES: |
| 101 enum_name = self._cpp_type_generator.GetChoicesEnumType(prop) | 110 enum_name = self._cpp_type_generator.GetChoicesEnumType(prop) |
| 102 c.Concat(self._GenerateEnumDeclaration( | |
| 103 enum_name, | |
| 104 prop, | |
| 105 [choice.type_.name for choice in prop.choices.values()])) | |
| 106 c.Append('%s %s_type;' % (enum_name, prop.unix_name)) | 111 c.Append('%s %s_type;' % (enum_name, prop.unix_name)) |
| 107 elif prop.type_ == PropertyType.ENUM: | |
| 108 c.Concat(self._GenerateEnumDeclaration( | |
| 109 self._cpp_type_generator.GetType(prop), | |
| 110 prop, | |
| 111 prop.enum_values)) | |
| 112 for prop in self._cpp_type_generator.GetExpandedChoicesInParams(props): | 112 for prop in self._cpp_type_generator.GetExpandedChoicesInParams(props): |
| 113 if prop.description: | 113 if prop.description: |
| 114 c.Comment(prop.description) | 114 c.Comment(prop.description) |
| 115 c.Append('%s %s;' % ( | 115 c.Append('%s %s;' % ( |
| 116 self._cpp_type_generator.GetType(prop, wrap_optional=True), | 116 self._cpp_type_generator.GetType(prop, wrap_optional=True), |
| 117 prop.unix_name)) | 117 prop.unix_name)) |
| 118 c.Append() | 118 c.Append() |
| 119 return c | 119 return c |
| 120 | 120 |
| 121 def _GenerateType(self, type_, serializable=True): | 121 def _GenerateType(self, type_): |
| 122 """Generates a struct for a type. | 122 """Generates a struct for a type. |
| 123 """ | 123 """ |
| 124 classname = cpp_util.Classname(type_.name) | 124 classname = cpp_util.Classname(type_.name) |
| 125 c = code.Code() | 125 c = code.Code() |
| 126 if type_.description: | 126 if type_.description: |
| 127 c.Comment(type_.description) | 127 c.Comment(type_.description) |
| 128 (c.Sblock('struct %(classname)s {') | 128 (c.Sblock('struct %(classname)s {') |
| 129 .Append('~%(classname)s();') | 129 .Append('~%(classname)s();') |
| 130 .Append('%(classname)s();') | 130 .Append('%(classname)s();') |
| 131 .Append() | 131 .Append() |
| 132 .Concat(self._GeneratePropertyStructures(type_.properties.values())) |
| 132 .Concat(self._GenerateFields(type_.properties.values())) | 133 .Concat(self._GenerateFields(type_.properties.values())) |
| 133 .Comment('Populates a %(classname)s object from a Value. Returns' | 134 ) |
| 134 ' whether |out| was successfully populated.') | 135 if type_.from_json: |
| 136 (c.Comment('Populates a %s object from a Value. Returns' |
| 137 ' whether |out| was successfully populated.' % classname) |
| 135 .Append('static bool Populate(const Value& value, %(classname)s* out);') | 138 .Append('static bool Populate(const Value& value, %(classname)s* out);') |
| 136 .Append() | 139 .Append() |
| 137 ) | 140 ) |
| 138 | 141 |
| 139 if serializable: | 142 if type_.from_client: |
| 140 (c.Comment('Returns a new DictionaryValue representing the' | 143 (c.Comment('Returns a new DictionaryValue representing the' |
| 141 ' serialized form of this %(classname)s object. Passes ' | 144 ' serialized form of this %s object. Passes ' |
| 142 'ownership to caller.') | 145 'ownership to caller.' % classname) |
| 143 .Append('scoped_ptr<DictionaryValue> ToValue() const;') | 146 .Append('scoped_ptr<DictionaryValue> ToValue() const;') |
| 144 ) | 147 ) |
| 145 (c.Eblock() | 148 (c.Eblock() |
| 146 .Sblock(' private:') | 149 .Sblock(' private:') |
| 147 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);') | 150 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);') |
| 148 .Eblock('};') | 151 .Eblock('};') |
| 149 ) | 152 ) |
| 150 c.Substitute({'classname': classname}) | 153 c.Substitute({'classname': classname}) |
| 151 return c | 154 return c |
| 152 | 155 |
| 153 def _GenerateFunction(self, function): | 156 def _GenerateFunction(self, function): |
| 154 """Generates the structs for a function. | 157 """Generates the structs for a function. |
| 155 """ | 158 """ |
| 156 c = code.Code() | 159 c = code.Code() |
| 157 (c.Sblock('namespace %s {' % cpp_util.Classname(function.name)) | 160 (c.Sblock('namespace %s {' % cpp_util.Classname(function.name)) |
| 158 .Concat(self._GenerateFunctionParams(function)) | 161 .Concat(self._GenerateFunctionParams(function)) |
| 159 .Append() | 162 .Append() |
| 160 .Concat(self._GenerateFunctionResult(function)) | 163 ) |
| 164 if function.callback: |
| 165 (c.Concat(self._GenerateFunctionResult(function)) |
| 161 .Append() | 166 .Append() |
| 162 .Eblock('};') | 167 ) |
| 163 ) | 168 c.Eblock('};') |
| 169 |
| 164 return c | 170 return c |
| 165 | 171 |
| 166 def _GenerateFunctionParams(self, function): | 172 def _GenerateFunctionParams(self, function): |
| 167 """Generates the struct for passing parameters into a function. | 173 """Generates the struct for passing parameters into a function. |
| 168 """ | 174 """ |
| 169 c = code.Code() | 175 c = code.Code() |
| 170 | 176 |
| 171 if function.params: | 177 if function.params: |
| 172 c.Sblock('struct Params {') | 178 (c.Sblock('struct Params {') |
| 173 for param in function.params: | 179 .Concat(self._GeneratePropertyStructures(function.params)) |
| 174 if param.type_ == PropertyType.OBJECT: | 180 .Concat(self._GenerateFields(function.params)) |
| 175 c.Concat(self._GenerateType(param, serializable=False)) | 181 .Append('~Params();') |
| 176 c.Append() | 182 .Append() |
| 177 (c.Concat(self._GenerateFields(function.params)) | 183 .Append('static scoped_ptr<Params> Create(const ListValue& args);') |
| 178 .Append('~Params();') | 184 .Eblock() |
| 179 .Append() | 185 .Sblock(' private:') |
| 180 .Append('static scoped_ptr<Params> Create(const ListValue& args);') | 186 .Append('Params();') |
| 181 .Eblock() | 187 .Append() |
| 182 .Sblock(' private:') | 188 .Append('DISALLOW_COPY_AND_ASSIGN(Params);') |
| 183 .Append('Params();') | 189 .Eblock('};') |
| 184 .Append() | |
| 185 .Append('DISALLOW_COPY_AND_ASSIGN(Params);') | |
| 186 .Eblock('};') | |
| 187 ) | 190 ) |
| 188 | 191 |
| 189 return c | 192 return c |
| 190 | 193 |
| 194 def _GeneratePropertyStructures(self, props): |
| 195 """Generate the structures required by a property such as OBJECT classes |
| 196 and enums. |
| 197 """ |
| 198 c = code.Code() |
| 199 for prop in props: |
| 200 if prop.type_ == PropertyType.OBJECT: |
| 201 c.Concat(self._GenerateType(prop)) |
| 202 c.Append() |
| 203 elif prop.type_ == PropertyType.CHOICES: |
| 204 c.Concat(self._GenerateEnumDeclaration( |
| 205 self._cpp_type_generator.GetChoicesEnumType(prop), |
| 206 prop, |
| 207 [choice.type_.name for choice in prop.choices.values()])) |
| 208 elif prop.type_ == PropertyType.ENUM: |
| 209 enum_name = self._cpp_type_generator.GetType(prop) |
| 210 c.Concat(self._GenerateEnumDeclaration( |
| 211 enum_name, |
| 212 prop, |
| 213 prop.enum_values)) |
| 214 c.Append('static scoped_ptr<Value> CreateEnumValue(%s %s);' % |
| 215 (enum_name, prop.unix_name)) |
| 216 return c |
| 217 |
| 191 def _GenerateFunctionResult(self, function): | 218 def _GenerateFunctionResult(self, function): |
| 192 """Generates functions for passing a function's result back. | 219 """Generates functions for passing a function's result back. |
| 193 """ | 220 """ |
| 194 c = code.Code() | 221 c = code.Code() |
| 195 | 222 |
| 196 c.Sblock('namespace Result {') | 223 c.Sblock('namespace Result {') |
| 197 params = function.callback.params | 224 params = function.callback.params |
| 198 if not params: | 225 if not params: |
| 199 c.Append('Value* Create();') | 226 c.Append('Value* Create();') |
| 200 else: | 227 else: |
| 228 c.Concat(self._GeneratePropertyStructures(params)) |
| 229 |
| 201 # If there is a single parameter, this is straightforward. However, if | 230 # If there is a single parameter, this is straightforward. However, if |
| 202 # the callback parameter is of 'choices', this generates a Create method | 231 # the callback parameter is of 'choices', this generates a Create method |
| 203 # for each choice. This works because only 1 choice can be returned at a | 232 # for each choice. This works because only 1 choice can be returned at a |
| 204 # time. | 233 # time. |
| 205 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params): | 234 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params): |
| 206 if param.description: | 235 if param.description: |
| 207 c.Comment(param.description) | 236 c.Comment(param.description) |
| 208 if param.type_ == PropertyType.OBJECT: | |
| 209 raise NotImplementedError('OBJECT return type not supported') | |
| 210 c.Append('Value* Create(const %s);' % cpp_util.GetParameterDeclaration( | 237 c.Append('Value* Create(const %s);' % cpp_util.GetParameterDeclaration( |
| 211 param, self._cpp_type_generator.GetType(param))) | 238 param, self._cpp_type_generator.GetType(param))) |
| 212 c.Eblock('};') | 239 c.Eblock('};') |
| 213 | 240 |
| 214 return c | 241 return c |
| 215 | 242 |
| 216 def _GenerateIfndefName(self): | 243 def _GenerateIfndefName(self): |
| 217 """Formats a path and filename as a #define name. | 244 """Formats a path and filename as a #define name. |
| 218 | 245 |
| 219 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__. | 246 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__. |
| 220 """ | 247 """ |
| 221 return (('%s_%s_H__' % | 248 return (('%s_%s_H__' % |
| 222 (self._namespace.source_file_dir, self._target_namespace)) | 249 (self._namespace.source_file_dir, self._target_namespace)) |
| 223 .upper().replace(os.sep, '_')) | 250 .upper().replace(os.sep, '_')) |
| 224 | 251 |
| OLD | NEW |