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 model |
8 import os | 9 import os |
9 | 10 |
10 class HGenerator(object): | 11 class HGenerator(object): |
11 """A .h generator for a namespace. | 12 """A .h generator for a namespace. |
12 """ | 13 """ |
13 def __init__(self, namespace, cpp_type_generator): | 14 def __init__(self, namespace, cpp_type_generator): |
14 self._cpp_type_generator = cpp_type_generator | 15 self._cpp_type_generator = cpp_type_generator |
15 self._namespace = namespace | 16 self._namespace = namespace |
16 self._target_namespace = ( | 17 self._target_namespace = ( |
17 self._cpp_type_generator.GetCppNamespaceName(self._namespace)) | 18 self._cpp_type_generator.GetCppNamespaceName(self._namespace)) |
(...skipping 13 matching lines...) Expand all Loading... |
31 .Append('#define %s' % ifndef_name) | 32 .Append('#define %s' % ifndef_name) |
32 .Append('#pragma once') | 33 .Append('#pragma once') |
33 .Append() | 34 .Append() |
34 .Append('#include <string>') | 35 .Append('#include <string>') |
35 .Append('#include <vector>') | 36 .Append('#include <vector>') |
36 .Append() | 37 .Append() |
37 .Append('#include "base/basictypes.h"') | 38 .Append('#include "base/basictypes.h"') |
38 .Append('#include "base/memory/linked_ptr.h"') | 39 .Append('#include "base/memory/linked_ptr.h"') |
39 .Append('#include "base/memory/scoped_ptr.h"') | 40 .Append('#include "base/memory/scoped_ptr.h"') |
40 .Append('#include "base/values.h"') | 41 .Append('#include "base/values.h"') |
| 42 .Append('#include "tools/json_schema_compiler/any.h"') |
41 .Append() | 43 .Append() |
42 ) | 44 ) |
43 | 45 |
44 c.Concat(self._cpp_type_generator.GetRootNamespaceStart()) | 46 c.Concat(self._cpp_type_generator.GetRootNamespaceStart()) |
45 # TODO(calamity): These forward declarations should be #includes to allow | 47 # TODO(calamity): These forward declarations should be #includes to allow |
46 # $ref types from other files to be used as required params. This requires | 48 # $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 | 49 # some detangling of windows and tabs which will currently lead to circular |
48 # #includes. | 50 # #includes. |
49 forward_declarations = ( | 51 forward_declarations = ( |
50 self._cpp_type_generator.GenerateForwardDeclarations()) | 52 self._cpp_type_generator.GenerateForwardDeclarations()) |
(...skipping 18 matching lines...) Expand all Loading... |
69 if self._namespace.functions: | 71 if self._namespace.functions: |
70 (c.Append('//') | 72 (c.Append('//') |
71 .Append('// Functions') | 73 .Append('// Functions') |
72 .Append('//') | 74 .Append('//') |
73 .Append() | 75 .Append() |
74 ) | 76 ) |
75 for function in self._namespace.functions.values(): | 77 for function in self._namespace.functions.values(): |
76 (c.Concat(self._GenerateFunction(function)) | 78 (c.Concat(self._GenerateFunction(function)) |
77 .Append() | 79 .Append() |
78 ) | 80 ) |
79 (c.Append() | 81 (c.Concat(self._cpp_type_generator.GetNamespaceEnd()) |
80 .Concat(self._cpp_type_generator.GetNamespaceEnd()) | |
81 .Concat(self._cpp_type_generator.GetRootNamespaceEnd()) | 82 .Concat(self._cpp_type_generator.GetRootNamespaceEnd()) |
82 .Append() | 83 .Append() |
83 .Append('#endif // %s' % ifndef_name) | 84 .Append('#endif // %s' % ifndef_name) |
84 .Append() | 85 .Append() |
85 ) | 86 ) |
86 return c | 87 return c |
87 | 88 |
88 def _GenerateEnumDeclaration(self, enum_name, prop, values): | 89 def _GenerateEnumDeclaration(self, enum_name, prop, values): |
89 """Generate the declaration of a C++ enum for the given property and | 90 """Generate the declaration of a C++ enum for the given property and |
90 values. | 91 values. |
(...skipping 11 matching lines...) Expand all Loading... |
102 | 103 |
103 def _GenerateFields(self, props): | 104 def _GenerateFields(self, props): |
104 """Generates the field declarations when declaring a type. | 105 """Generates the field declarations when declaring a type. |
105 """ | 106 """ |
106 c = code.Code() | 107 c = code.Code() |
107 # Generate the enums needed for any fields with "choices" | 108 # Generate the enums needed for any fields with "choices" |
108 for prop in props: | 109 for prop in props: |
109 if prop.type_ == PropertyType.CHOICES: | 110 if prop.type_ == PropertyType.CHOICES: |
110 enum_name = self._cpp_type_generator.GetChoicesEnumType(prop) | 111 enum_name = self._cpp_type_generator.GetChoicesEnumType(prop) |
111 c.Append('%s %s_type;' % (enum_name, prop.unix_name)) | 112 c.Append('%s %s_type;' % (enum_name, prop.unix_name)) |
| 113 c.Append() |
112 for prop in self._cpp_type_generator.GetExpandedChoicesInParams(props): | 114 for prop in self._cpp_type_generator.GetExpandedChoicesInParams(props): |
113 if prop.description: | 115 if prop.description: |
114 c.Comment(prop.description) | 116 c.Comment(prop.description) |
115 c.Append('%s %s;' % ( | 117 c.Append('%s %s;' % ( |
116 self._cpp_type_generator.GetType(prop, wrap_optional=True), | 118 self._cpp_type_generator.GetType(prop, wrap_optional=True), |
117 prop.unix_name)) | 119 prop.unix_name)) |
118 c.Append() | 120 c.Append() |
119 return c | 121 return c |
120 | 122 |
121 def _GenerateType(self, type_): | 123 def _GenerateType(self, type_): |
122 """Generates a struct for a type. | 124 """Generates a struct for a type. |
123 """ | 125 """ |
124 classname = cpp_util.Classname(type_.name) | 126 classname = cpp_util.Classname(type_.name) |
125 c = code.Code() | 127 c = code.Code() |
126 if type_.description: | 128 |
127 c.Comment(type_.description) | 129 if type_.functions: |
128 (c.Sblock('struct %(classname)s {') | 130 # Types with functions are not instantiable in C++ because they are |
129 .Append('~%(classname)s();') | 131 # handled in pure Javascript and hence have no properties or |
130 .Append('%(classname)s();') | 132 # additionalProperties. |
131 .Append() | 133 if type_.properties: |
132 .Concat(self._GeneratePropertyStructures(type_.properties.values())) | 134 raise NotImplementedError('\n'.join(model.GetModelHierarchy(type_)) + |
133 .Concat(self._GenerateFields(type_.properties.values())) | 135 '\nCannot generate both functions and properties on a type') |
134 ) | 136 c.Sblock('namespace %(classname)s {') |
135 if type_.from_json: | 137 for function in type_.functions.values(): |
136 (c.Comment('Populates a %s object from a Value. Returns' | 138 (c.Concat(self._GenerateFunction(function)) |
137 ' whether |out| was successfully populated.' % classname) | 139 .Append() |
138 .Append('static bool Populate(const Value& value, %(classname)s* out);') | 140 ) |
139 .Append() | 141 c.Eblock('}') |
| 142 else: |
| 143 if type_.description: |
| 144 c.Comment(type_.description) |
| 145 (c.Sblock('struct %(classname)s {') |
| 146 .Append('~%(classname)s();') |
| 147 .Append('%(classname)s();') |
| 148 .Append() |
| 149 .Concat(self._GeneratePropertyStructures(type_.properties.values())) |
| 150 .Concat(self._GenerateFields(type_.properties.values())) |
140 ) | 151 ) |
| 152 if type_.from_json: |
| 153 (c.Comment('Populates a %s object from a Value. Returns' |
| 154 ' whether |out| was successfully populated.' % classname) |
| 155 .Append( |
| 156 'static bool Populate(const Value& value, %(classname)s* out);') |
| 157 .Append() |
| 158 ) |
141 | 159 |
142 if type_.from_client: | 160 if type_.from_client: |
143 (c.Comment('Returns a new DictionaryValue representing the' | 161 (c.Comment('Returns a new DictionaryValue representing the' |
144 ' serialized form of this %s object. Passes ' | 162 ' serialized form of this %s object. Passes ' |
145 'ownership to caller.' % classname) | 163 'ownership to caller.' % classname) |
146 .Append('scoped_ptr<DictionaryValue> ToValue() const;') | 164 .Append('scoped_ptr<DictionaryValue> ToValue() const;') |
| 165 ) |
| 166 |
| 167 (c.Eblock() |
| 168 .Sblock(' private:') |
| 169 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);') |
| 170 .Eblock('};') |
147 ) | 171 ) |
148 (c.Eblock() | |
149 .Sblock(' private:') | |
150 .Append('DISALLOW_COPY_AND_ASSIGN(%(classname)s);') | |
151 .Eblock('};') | |
152 ) | |
153 c.Substitute({'classname': classname}) | 172 c.Substitute({'classname': classname}) |
154 return c | 173 return c |
155 | 174 |
156 def _GenerateFunction(self, function): | 175 def _GenerateFunction(self, function): |
157 """Generates the structs for a function. | 176 """Generates the structs for a function. |
158 """ | 177 """ |
159 c = code.Code() | 178 c = code.Code() |
160 (c.Sblock('namespace %s {' % cpp_util.Classname(function.name)) | 179 (c.Sblock('namespace %s {' % cpp_util.Classname(function.name)) |
161 .Concat(self._GenerateFunctionParams(function)) | 180 .Concat(self._GenerateFunctionParams(function)) |
162 .Append() | 181 .Append() |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 c = code.Code() | 217 c = code.Code() |
199 for prop in props: | 218 for prop in props: |
200 if prop.type_ == PropertyType.OBJECT: | 219 if prop.type_ == PropertyType.OBJECT: |
201 c.Concat(self._GenerateType(prop)) | 220 c.Concat(self._GenerateType(prop)) |
202 c.Append() | 221 c.Append() |
203 elif prop.type_ == PropertyType.CHOICES: | 222 elif prop.type_ == PropertyType.CHOICES: |
204 c.Concat(self._GenerateEnumDeclaration( | 223 c.Concat(self._GenerateEnumDeclaration( |
205 self._cpp_type_generator.GetChoicesEnumType(prop), | 224 self._cpp_type_generator.GetChoicesEnumType(prop), |
206 prop, | 225 prop, |
207 [choice.type_.name for choice in prop.choices.values()])) | 226 [choice.type_.name for choice in prop.choices.values()])) |
| 227 c.Concat(self._GeneratePropertyStructures(prop.choices.values())) |
208 elif prop.type_ == PropertyType.ENUM: | 228 elif prop.type_ == PropertyType.ENUM: |
209 enum_name = self._cpp_type_generator.GetType(prop) | 229 enum_name = self._cpp_type_generator.GetType(prop) |
210 c.Concat(self._GenerateEnumDeclaration( | 230 c.Concat(self._GenerateEnumDeclaration( |
211 enum_name, | 231 enum_name, |
212 prop, | 232 prop, |
213 prop.enum_values)) | 233 prop.enum_values)) |
214 c.Append('static scoped_ptr<Value> CreateEnumValue(%s %s);' % | 234 c.Append('static scoped_ptr<Value> CreateEnumValue(%s %s);' % |
215 (enum_name, prop.unix_name)) | 235 (enum_name, prop.unix_name)) |
216 return c | 236 return c |
217 | 237 |
218 def _GenerateFunctionResult(self, function): | 238 def _GenerateFunctionResult(self, function): |
219 """Generates functions for passing a function's result back. | 239 """Generates functions for passing a function's result back. |
220 """ | 240 """ |
221 c = code.Code() | 241 c = code.Code() |
222 | 242 |
223 c.Sblock('namespace Result {') | 243 c.Sblock('namespace Result {') |
224 params = function.callback.params | 244 params = function.callback.params |
225 if not params: | 245 if not params: |
226 c.Append('Value* Create();') | 246 c.Append('Value* Create();') |
227 else: | 247 else: |
228 c.Concat(self._GeneratePropertyStructures(params)) | 248 c.Concat(self._GeneratePropertyStructures(params)) |
229 | 249 |
230 # If there is a single parameter, this is straightforward. However, if | 250 # If there is a single parameter, this is straightforward. However, if |
231 # the callback parameter is of 'choices', this generates a Create method | 251 # the callback parameter is of 'choices', this generates a Create method |
232 # for each choice. This works because only 1 choice can be returned at a | 252 # for each choice. This works because only 1 choice can be returned at a |
233 # time. | 253 # time. |
234 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params): | 254 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params): |
235 if param.description: | 255 if param.description: |
236 c.Comment(param.description) | 256 c.Comment(param.description) |
| 257 if param.type_ == PropertyType.ANY: |
| 258 c.Comment("Value* Result::Create(Value*) not generated " |
| 259 "because it's redundant.") |
| 260 continue |
237 c.Append('Value* Create(const %s);' % cpp_util.GetParameterDeclaration( | 261 c.Append('Value* Create(const %s);' % cpp_util.GetParameterDeclaration( |
238 param, self._cpp_type_generator.GetType(param))) | 262 param, self._cpp_type_generator.GetType(param))) |
239 c.Eblock('};') | 263 c.Eblock('};') |
240 | 264 |
241 return c | 265 return c |
242 | 266 |
243 def _GenerateIfndefName(self): | 267 def _GenerateIfndefName(self): |
244 """Formats a path and filename as a #define name. | 268 """Formats a path and filename as a #define name. |
245 | 269 |
246 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__. | 270 e.g chrome/extensions/gen, file.h becomes CHROME_EXTENSIONS_GEN_FILE_H__. |
247 """ | 271 """ |
248 return (('%s_%s_H__' % | 272 return (('%s_%s_H__' % |
249 (self._namespace.source_file_dir, self._target_namespace)) | 273 (self._namespace.source_file_dir, self._target_namespace)) |
250 .upper().replace(os.sep, '_')) | 274 .upper().replace(os.sep, '_')) |
251 | 275 |
OLD | NEW |