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 util_cc_helper | 8 import util_cc_helper |
9 | 9 |
10 class CCGenerator(object): | 10 class CCGenerator(object): |
(...skipping 26 matching lines...) Expand all Loading... |
37 ) | 37 ) |
38 | 38 |
39 (c.Append() | 39 (c.Append() |
40 .Append('using base::Value;') | 40 .Append('using base::Value;') |
41 .Append('using base::DictionaryValue;') | 41 .Append('using base::DictionaryValue;') |
42 .Append('using base::ListValue;') | 42 .Append('using base::ListValue;') |
43 .Append() | 43 .Append() |
44 .Concat(self._cpp_type_generator.GetRootNamespaceStart()) | 44 .Concat(self._cpp_type_generator.GetRootNamespaceStart()) |
45 .Concat(self._cpp_type_generator.GetNamespaceStart()) | 45 .Concat(self._cpp_type_generator.GetNamespaceStart()) |
46 .Append() | 46 .Append() |
47 .Append('//') | |
48 .Append('// Types') | |
49 .Append('//') | |
50 .Append() | |
51 ) | 47 ) |
| 48 if self._namespace.types: |
| 49 (c.Append('//') |
| 50 .Append('// Types') |
| 51 .Append('//') |
| 52 .Append() |
| 53 ) |
52 for type_ in self._namespace.types.values(): | 54 for type_ in self._namespace.types.values(): |
53 (c.Concat(self._GenerateType(type_.name, type_)) | 55 (c.Concat(self._GenerateType(type_.name, type_)) |
54 .Append() | 56 .Append() |
55 ) | 57 ) |
56 (c.Append('//') | 58 if self._namespace.functions: |
57 .Append('// Functions') | 59 (c.Append('//') |
58 .Append('//') | 60 .Append('// Functions') |
59 .Append() | 61 .Append('//') |
60 ) | 62 .Append() |
| 63 ) |
61 for function in self._namespace.functions.values(): | 64 for function in self._namespace.functions.values(): |
62 (c.Concat(self._GenerateFunction(function)) | 65 (c.Concat(self._GenerateFunction(function)) |
63 .Append() | 66 .Append() |
64 ) | 67 ) |
65 (c.Concat(self._cpp_type_generator.GetNamespaceEnd()) | 68 (c.Concat(self._cpp_type_generator.GetNamespaceEnd()) |
66 .Concat(self._cpp_type_generator.GetRootNamespaceEnd()) | 69 .Concat(self._cpp_type_generator.GetRootNamespaceEnd()) |
67 .Append() | 70 .Append() |
68 ) | 71 ) |
69 # TODO(calamity): Events | 72 # TODO(calamity): Events |
70 return c | 73 return c |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 ) | 107 ) |
105 for prop in type_.properties.values(): | 108 for prop in type_.properties.values(): |
106 c.Concat(self._GenerateTypePopulateProperty(prop, 'dict', 'out')) | 109 c.Concat(self._GenerateTypePopulateProperty(prop, 'dict', 'out')) |
107 (c.Append('return true;') | 110 (c.Append('return true;') |
108 .Eblock('}') | 111 .Eblock('}') |
109 ) | 112 ) |
110 c.Substitute({'namespace': cpp_namespace, 'name': classname}) | 113 c.Substitute({'namespace': cpp_namespace, 'name': classname}) |
111 return c | 114 return c |
112 | 115 |
113 def _GenerateTypePopulateProperty(self, prop, src, dst): | 116 def _GenerateTypePopulateProperty(self, prop, src, dst): |
114 """Generate the code to populate a single property. | 117 """Generate the code to populate a single property in a type. |
115 | 118 |
116 src: DictionaryValue* | 119 src: DictionaryValue* |
117 dst: Type* | 120 dst: Type* |
118 """ | 121 """ |
119 c = code.Code() | 122 c = code.Code() |
120 dst_member = dst + '->' + prop.unix_name | 123 value_var = prop.unix_name + '_value' |
121 if prop.type_ == PropertyType.ARRAY: | 124 c.Append('Value* %(value_var)s = NULL;') |
122 # util_cc_helper deals with optional and required arrays | 125 if prop.optional: |
123 (c.Append('if (!%s)' % | 126 (c.Sblock( |
124 self._util_cc_helper.GetArray(prop, src, prop.name, dst_member)) | 127 'if (%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s)) {' |
| 128 ) |
| 129 .Concat(self._GeneratePopulatePropertyFromValue( |
| 130 prop, value_var, 'out', 'false')) |
| 131 .Eblock('}') |
| 132 ) |
| 133 else: |
| 134 (c.Append( |
| 135 'if (!%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s))') |
125 .Append(' return false;') | 136 .Append(' return false;') |
| 137 .Concat(self._GeneratePopulatePropertyFromValue( |
| 138 prop, value_var, 'out', 'false')) |
126 ) | 139 ) |
127 elif prop.type_ == PropertyType.CHOICES: | 140 c.Append() |
128 value_var = prop.unix_name + '_value' | 141 c.Substitute({'value_var': value_var, 'key': prop.name, 'src': src}) |
129 c.Append('Value* %(value_var)s = NULL;') | |
130 c.Append( | |
131 'if (!%(src)s->GetWithoutPathExpansion("%(key)s", &%(value_var)s))') | |
132 if prop.optional: | |
133 c.Append(' return true;') | |
134 else: | |
135 c.Append(' return false;') | |
136 c.Append() | |
137 c.Concat(self._GeneratePopulateChoices(prop, value_var, dst, 'false')) | |
138 c.Substitute({'value_var': value_var, 'key': prop.name, 'src': src}) | |
139 else: | |
140 if prop.optional: | |
141 if prop.type_.is_fundamental: | |
142 (c.Sblock('{') | |
143 .Append('%(type)s %(name)s_temp;') | |
144 .Append('if (%s)' % self._GeneratePopulatePropertyFunctionCall( | |
145 prop, src, '&%s_temp' % prop.unix_name)) | |
146 .Append(' out->%(name)s.reset(new %(type)s(%(name)s_temp));') | |
147 .Eblock('}') | |
148 ) | |
149 else: | |
150 raise NotImplementedError('Optional %s not implemented' % prop.type_) | |
151 else: | |
152 (c.Append('if (!%s)' % | |
153 self._GeneratePopulatePropertyFunctionCall( | |
154 prop, src, '&' + dst_member)) | |
155 .Append(' return false;') | |
156 ) | |
157 c.Substitute({ | |
158 'name': prop.unix_name, | |
159 'type': self._cpp_type_generator.GetType(prop) | |
160 }) | |
161 return c | 142 return c |
162 | 143 |
163 def _GeneratePopulatePropertyFunctionCall(self, prop, src, dst): | |
164 """Generates the function call that populates the given property. | |
165 | |
166 src: DictionaryValue* | |
167 dst: Property* or scoped_ptr<Property> | |
168 """ | |
169 if prop.type_.is_fundamental: | |
170 populate_line = cpp_util.GetFundamentalValue( | |
171 prop, src, prop.name, dst) | |
172 elif prop.type_ in (PropertyType.REF, PropertyType.OBJECT): | |
173 populate_line = '%(type)s::Populate(*%(src)s, %(dst)s)' | |
174 else: | |
175 raise NotImplementedError('%s populate is not implemented' % | |
176 prop.type_) | |
177 return populate_line | |
178 | |
179 def _GenerateTypeToValue(self, cpp_namespace, type_): | 144 def _GenerateTypeToValue(self, cpp_namespace, type_): |
180 """Generates a function that serializes the type into a |DictionaryValue|. | 145 """Generates a function that serializes the type into a |DictionaryValue|. |
181 """ | 146 """ |
182 c = code.Code() | 147 c = code.Code() |
183 (c.Sblock('scoped_ptr<DictionaryValue> %s::ToValue() const {' % | 148 (c.Sblock('scoped_ptr<DictionaryValue> %s::ToValue() const {' % |
184 cpp_namespace) | 149 cpp_namespace) |
185 .Append('scoped_ptr<DictionaryValue> value(new DictionaryValue());') | 150 .Append('scoped_ptr<DictionaryValue> value(new DictionaryValue());') |
186 .Append() | 151 .Append() |
187 ) | 152 ) |
188 for prop in type_.properties.values(): | 153 for prop in type_.properties.values(): |
189 c.Concat(self._CreateValueFromProperty(prop, prop.unix_name, 'value')) | 154 c.Concat(self._CreateValueFromProperty(prop, prop.unix_name, 'value')) |
190 (c.Append() | 155 (c.Append() |
191 .Append('return value.Pass();') | 156 .Append('return value.Pass();') |
192 .Eblock('}') | 157 .Eblock('}') |
193 ) | 158 ) |
194 return c | 159 return c |
195 | 160 |
196 def _CreateValueFromProperty(self, prop, var, dst): | 161 def _CreateValueFromProperty(self, prop, var, dst): |
197 """Generates code to serialize a single property in a type. | 162 """Generates code to serialize a single property in a type. |
198 | 163 |
199 prop: Property to create from | 164 prop: Property to create from |
200 var: variable with value to create from | 165 var: variable with value to create from |
201 """ | 166 """ |
202 c = code.Code() | 167 c = code.Code() |
203 if prop.optional: | 168 if prop.optional: |
204 c.Sblock('if (%s.get())' % var) | 169 c.Sblock('if (%s.get())' % var) |
205 if prop.type_ == PropertyType.ARRAY: | 170 if prop.type_ == PropertyType.ARRAY: |
206 c.Append('%s;' % self._util_cc_helper.SetArray(prop, var, prop.name, dst)) | 171 c.Append('%s;' % self._util_cc_helper.PopulateDictionaryFromArray( |
| 172 prop, var, prop.name, dst)) |
207 else: | 173 else: |
208 c.Append('%s->SetWithoutPathExpansion("%s", %s);' % | 174 c.Append('%s->SetWithoutPathExpansion("%s", %s);' % |
209 (dst, prop.name, cpp_util.CreateValueFromSingleProperty(prop, var))) | 175 (dst, prop.name, cpp_util.CreateValueFromSingleProperty(prop, var))) |
210 return c | 176 return c |
211 | 177 |
212 def _GenerateFunction(self, function): | 178 def _GenerateFunction(self, function): |
213 """Generates the definitions for function structs. | 179 """Generates the definitions for function structs. |
214 """ | 180 """ |
215 classname = cpp_util.Classname(function.name) | 181 classname = cpp_util.Classname(function.name) |
216 c = code.Code() | 182 c = code.Code() |
(...skipping 26 matching lines...) Expand all Loading... |
243 Params. | 209 Params. |
244 """ | 210 """ |
245 c = code.Code() | 211 c = code.Code() |
246 num_required = 0 | 212 num_required = 0 |
247 for param in function.params: | 213 for param in function.params: |
248 if not param.optional: | 214 if not param.optional: |
249 num_required += 1 | 215 num_required += 1 |
250 if num_required == len(function.params): | 216 if num_required == len(function.params): |
251 c.Append('if (%(var)s.GetSize() != %(total)d)') | 217 c.Append('if (%(var)s.GetSize() != %(total)d)') |
252 elif not num_required: | 218 elif not num_required: |
253 c.Append('if (%(var)s.GetSize() > %(total)s)') | 219 c.Append('if (%(var)s.GetSize() > %(total)d)') |
254 else: | 220 else: |
255 c.Append('if (%(var)s.GetSize() < %(required)d' | 221 c.Append('if (%(var)s.GetSize() < %(required)d' |
256 ' || %(var)s.GetSize() > %(total)d)') | 222 ' || %(var)s.GetSize() > %(total)d)') |
257 c.Append(' return scoped_ptr<Params>();') | 223 c.Append(' return scoped_ptr<Params>();') |
258 c.Substitute({ | 224 c.Substitute({ |
259 'var': var, | 225 'var': var, |
260 'required': num_required, | 226 'required': num_required, |
261 'total': len(function.params), | 227 'total': len(function.params), |
262 }) | 228 }) |
263 return c | 229 return c |
264 | 230 |
265 def _GenerateFunctionParamsCreate(self, function): | 231 def _GenerateFunctionParamsCreate(self, function): |
266 """Generate function to create an instance of Params given a pointer. | 232 """Generate function to create an instance of Params. The generated |
| 233 function takes a ListValue of arguments. |
267 """ | 234 """ |
268 classname = cpp_util.Classname(function.name) | 235 classname = cpp_util.Classname(function.name) |
269 c = code.Code() | 236 c = code.Code() |
270 (c.Append('// static') | 237 (c.Append('// static') |
271 .Sblock('scoped_ptr<%(classname)s::Params> %(classname)s::Params::Create' | 238 .Sblock('scoped_ptr<%(classname)s::Params> %(classname)s::Params::Create' |
272 '(const ListValue& args) {') | 239 '(const ListValue& args) {') |
273 .Concat(self._GenerateParamsCheck(function, 'args')) | 240 .Concat(self._GenerateParamsCheck(function, 'args')) |
274 .Append('scoped_ptr<Params> params(new Params());') | 241 .Append('scoped_ptr<Params> params(new Params());') |
275 ) | 242 ) |
276 c.Substitute({'classname': classname}) | 243 c.Substitute({'classname': classname}) |
277 | 244 |
278 for i, param in enumerate(function.params): | 245 for i, param in enumerate(function.params): |
279 dst = 'params->' + param.unix_name | |
280 # Any failure will cause this function to return. If any argument is | 246 # Any failure will cause this function to return. If any argument is |
281 # incorrect or missing, those following it are not processed. Note that | 247 # incorrect or missing, those following it are not processed. Note that |
282 # this is still correct in the case of multiple optional arguments as an | 248 # this is still correct in the case of multiple optional arguments as an |
283 # optional argument at position 4 cannot exist without an argument at | 249 # optional argument at position 4 cannot exist without an argument at |
284 # position 3. | 250 # position 3. |
| 251 failure_value = 'scoped_ptr<Params>()' |
285 if param.optional: | 252 if param.optional: |
286 failure_value = 'params.Pass()' | 253 arg_missing_value = 'params.Pass()' |
287 else: | 254 else: |
288 failure_value = 'scoped_ptr<Params>()' | 255 arg_missing_value = failure_value |
289 c.Append() | 256 c.Append() |
290 param_var = param.unix_name + '_param' | 257 value_var = param.unix_name + '_value' |
291 # TODO(calamity): Return error on incorrect argument type | 258 (c.Append('Value* %(value_var)s = NULL;') |
292 if param.type_ == PropertyType.ARRAY: | 259 .Append('if (!args.Get(%(i)s, &%(value_var)s) || ' |
293 # util_cc_helper deals with optional and required arrays | 260 '%(value_var)s->IsType(Value::TYPE_NULL))') |
294 (c.Append('ListValue* %(param_var)s = NULL;') | 261 .Append(' return %s;' % arg_missing_value) |
295 .Append('if (!args.GetList(%(i)d, &%(param_var)s))') | 262 .Concat(self._GeneratePopulatePropertyFromValue( |
296 .Append(' return %s;' % failure_value) | 263 param, value_var, 'params', failure_value)) |
297 .Append('if (!%s)' % self._util_cc_helper.GetArrayFromList( | 264 ) |
298 param, param_var, dst)) | 265 c.Substitute({'value_var': value_var, 'i': i}) |
299 .Append(' return %s;' % failure_value) | |
300 ) | |
301 c.Substitute({'param_var': param_var, 'i': i}) | |
302 elif param.type_ == PropertyType.CHOICES: | |
303 value_var = param.unix_name + '_value' | |
304 (c.Append('Value* %(value_var)s = NULL;') | |
305 .Append('if (!args.Get(%(i)s, &%(value_var)s))') | |
306 .Append(' return %s;' % failure_value) | |
307 .Append() | |
308 .Concat(self._GeneratePopulateChoices(param, value_var, 'params', | |
309 'scoped_ptr<Params>()')) | |
310 ) | |
311 c.Substitute({'value_var': value_var, 'i': i}) | |
312 else: | |
313 if param.optional: | |
314 dst = dst + '.get()' | |
315 else: | |
316 dst = '&' + dst | |
317 if param.type_ in (PropertyType.REF, PropertyType.OBJECT): | |
318 (c.Append('DictionaryValue* %s = NULL;' % param_var) | |
319 .Append('if (!args.GetDictionary(%d, &%s))' % (i, param_var)) | |
320 .Append(' return %s;' % failure_value) | |
321 ) | |
322 if param.optional: | |
323 c.Append('params->%s.reset(new %s());' % | |
324 (param.unix_name, cpp_util.Classname(param.name))) | |
325 (c.Append('if (!%(ctype)s::Populate(*%(var)s, %(dst)s))' % { | |
326 'var': param_var, 'dst': dst, | |
327 'ctype': self._cpp_type_generator.GetType(param) | |
328 }) | |
329 .Append(' return %s;' % failure_value) | |
330 ) | |
331 elif param.type_.is_fundamental: | |
332 if param.optional: | |
333 (c.Sblock('{') | |
334 .Append('%(type)s %(name)s_temp;') | |
335 .Append('if (%s)' % cpp_util.GetValueFromList( | |
336 param, 'args', i, '&%s_temp' % param.unix_name)) | |
337 .Append( | |
338 ' params->%(name)s.reset(new %(type)s(%(name)s_temp));') | |
339 .Eblock('}') | |
340 ) | |
341 c.Substitute({ | |
342 'name': param.unix_name, | |
343 'type': self._cpp_type_generator.GetType(param), | |
344 }) | |
345 else: | |
346 (c.Append( | |
347 'if (!%s)' % cpp_util.GetValueFromList(param, 'args', i, dst)) | |
348 .Append(' return %s;' % failure_value) | |
349 ) | |
350 else: | |
351 raise NotImplementedError('%s parameter is not supported' % | |
352 param.type_) | |
353 (c.Append() | 266 (c.Append() |
354 .Append('return params.Pass();') | 267 .Append('return params.Pass();') |
355 .Eblock('}') | 268 .Eblock('}') |
| 269 .Append() |
356 ) | 270 ) |
357 | 271 |
358 return c | 272 return c |
359 | 273 |
| 274 def _GeneratePopulatePropertyFromValue( |
| 275 self, prop, value_var, dst, failure_value, check_type=True): |
| 276 """Generates code to populate a model.Property given a Value*. The |
| 277 existence of data inside the Value* is assumed so checks for existence |
| 278 should be performed before the code this generates. |
| 279 |
| 280 prop: the property the code is populating. |
| 281 value_var: a Value* that should represent |prop|. |
| 282 dst: the object with |prop| as a member. |
| 283 failure_value: the value to return if |prop| cannot be extracted from |
| 284 |value_var| |
| 285 check_type: if true, will check if |value_var| is the correct Value::Type |
| 286 """ |
| 287 c = code.Code() |
| 288 c.Sblock('{') |
| 289 |
| 290 if check_type: |
| 291 (c.Append('if (!%(value_var)s->IsType(%(value_type)s))') |
| 292 .Append(' return %(failure_value)s;') |
| 293 ) |
| 294 |
| 295 if prop.type_.is_fundamental: |
| 296 if prop.optional: |
| 297 (c.Append('%(ctype)s temp;') |
| 298 .Append('if (%s)' % |
| 299 cpp_util.GetAsFundamentalValue(prop, value_var, '&temp')) |
| 300 .Append(' %(dst)s->%(name)s.reset(new %(ctype)s(temp));') |
| 301 ) |
| 302 else: |
| 303 (c.Append('if (!%s)' % |
| 304 cpp_util.GetAsFundamentalValue( |
| 305 prop, value_var, '&%s->%s' % (dst, prop.unix_name))) |
| 306 .Append('return %(failure_value)s;') |
| 307 ) |
| 308 elif prop.type_ in (PropertyType.OBJECT, PropertyType.REF): |
| 309 if prop.optional: |
| 310 (c.Append('DictionaryValue* dictionary = NULL;') |
| 311 .Append('if (!%(value_var)s->GetAsDictionary(&dictionary))') |
| 312 .Append(' return %(failure_value)s;') |
| 313 .Append('scoped_ptr<%(ctype)s> temp(new %(ctype)s());') |
| 314 .Append('if (!%(ctype)s::Populate(*dictionary, temp.get()))') |
| 315 .Append(' return %(failure_value)s;') |
| 316 .Append('%(dst)s->%(name)s = temp.Pass();') |
| 317 ) |
| 318 else: |
| 319 (c.Append('DictionaryValue* dictionary = NULL;') |
| 320 .Append('if (!%(value_var)s->GetAsDictionary(&dictionary))') |
| 321 .Append(' return %(failure_value)s;') |
| 322 .Append( |
| 323 'if (!%(ctype)s::Populate(*dictionary, &%(dst)s->%(name)s))') |
| 324 .Append(' return %(failure_value)s;') |
| 325 ) |
| 326 elif prop.type_ == PropertyType.ARRAY: |
| 327 # util_cc_helper deals with optional and required arrays |
| 328 (c.Append('ListValue* list = NULL;') |
| 329 .Append('if (!%(value_var)s->GetAsList(&list))') |
| 330 .Append(' return %s;' % failure_value) |
| 331 .Append('if (!%s)' % self._util_cc_helper.PopulateArrayFromList( |
| 332 prop, 'list', dst + '->' + prop.unix_name)) |
| 333 .Append(' return %s;' % failure_value) |
| 334 ) |
| 335 elif prop.type_ == PropertyType.CHOICES: |
| 336 return self._GeneratePopulateChoices(prop, value_var, dst, failure_value) |
| 337 else: |
| 338 raise NotImplementedError(prop.type_) |
| 339 c.Eblock('}') |
| 340 c.Substitute({ |
| 341 'value_var': value_var, |
| 342 'name': prop.unix_name, |
| 343 'dst': dst, |
| 344 'ctype': self._cpp_type_generator.GetType(prop), |
| 345 'failure_value': failure_value, |
| 346 'value_type': cpp_util.GetValueType(prop), |
| 347 }) |
| 348 return c |
| 349 |
360 def _GeneratePopulateChoices(self, prop, value_var, dst, failure_value): | 350 def _GeneratePopulateChoices(self, prop, value_var, dst, failure_value): |
361 """Generates the code to populate a PropertyType.CHOICES parameter or | 351 """Generates the code to populate a PropertyType.CHOICES parameter or |
362 property. | 352 property. The existence of data inside the Value* is assumed so checks for |
| 353 existence should be performed before the code this generates. |
363 | 354 |
364 value_var: Value* | 355 prop: the property the code is populating.. |
365 dst: Type* or scoped_ptr<Params> | 356 value_var: a Value* that should represent |prop|. |
366 failure_value: the value to return on failure. Check if the property is | 357 dst: the object with |prop| as a member. |
367 optional BEFORE the code generated by this method as failure_value will be | 358 failure_value: the value to return if |prop| cannot be extracted from |
368 used to indicate a parsing error. | 359 |value_var| |
369 """ | 360 """ |
370 type_var = '%s->%s_type' % (dst, prop.unix_name) | 361 type_var = '%s->%s_type' % (dst, prop.unix_name) |
371 | 362 |
372 c = code.Code() | 363 c = code.Code() |
373 c.Append('%s = %s;' % | 364 c.Append('%s = %s;' % |
374 (type_var, self._cpp_type_generator.GetChoiceEnumNoneValue(prop))) | 365 (type_var, self._cpp_type_generator.GetChoiceEnumNoneValue(prop))) |
375 c.Sblock('switch (%s->GetType()) {' % value_var) | 366 c.Sblock('switch (%s->GetType()) {' % value_var) |
376 for choice in self._cpp_type_generator.GetExpandedChoicesInParams([prop]): | 367 for choice in self._cpp_type_generator.GetExpandedChoicesInParams([prop]): |
377 current_choice = '%s->%s' % (dst, choice.unix_name) | 368 (c.Sblock('case %s: {' % cpp_util.GetValueType(choice)) |
378 if choice.type_.is_fundamental: | 369 .Concat(self._GeneratePopulatePropertyFromValue( |
379 c.Sblock('case %s: {' % { | 370 choice, value_var, dst, failure_value, check_type=False)) |
380 PropertyType.STRING: 'Value::TYPE_STRING', | 371 .Append('%s = %s;' % |
381 PropertyType.INTEGER: 'Value::TYPE_INTEGER', | 372 (type_var, |
382 PropertyType.BOOLEAN: 'Value::TYPE_BOOLEAN', | 373 self._cpp_type_generator.GetChoiceEnumValue( |
383 PropertyType.DOUBLE: 'Value::TYPE_DOUBLE' | 374 prop, choice.type_))) |
384 }[choice.type_]) | |
385 | |
386 (c.Append('%(type_var)s = %(enum_value)s;') | |
387 .Append('%s.reset(new %s());' % | |
388 (current_choice, self._cpp_type_generator.GetType(choice))) | |
389 .Append('if (!%s)' % | |
390 cpp_util.GetAsFundamentalValue( | |
391 choice, value_var, current_choice + '.get()')) | |
392 .Append(' return %s;' % failure_value) | |
393 .Append('break;') | 375 .Append('break;') |
394 .Eblock('}') | 376 .Eblock('}') |
395 ) | |
396 elif choice.type_ == PropertyType.ARRAY: | |
397 # util_cc_helper deals with optional and required arrays | |
398 (c.Sblock('case Value::TYPE_LIST: {') | |
399 .Append('%(type_var)s = %(enum_value)s;') | |
400 .Append('if (!%s)' % self._util_cc_helper.GetArrayFromList( | |
401 choice, | |
402 'static_cast<ListValue*>(%s)' % value_var, | |
403 current_choice)) | |
404 .Append(' return %s;' % failure_value) | |
405 .Append('break;') | |
406 .Eblock('}') | |
407 ) | |
408 else: | |
409 raise NotImplementedError(choice.type_) | |
410 c.Substitute({ | |
411 'type_var': type_var, | |
412 'enum_value': self._cpp_type_generator.GetChoiceEnumValue( | |
413 prop, choice.type_), | |
414 }) | |
415 if not prop.optional: | |
416 (c.Append('default:') | |
417 .Append(' return %s;' % failure_value) | |
418 ) | 377 ) |
| 378 (c.Append('default:') |
| 379 .Append(' return %s;' % failure_value) |
| 380 ) |
419 c.Eblock('}') | 381 c.Eblock('}') |
420 return c | 382 return c |
421 | 383 |
422 def _GenerateFunctionResultCreate(self, function): | 384 def _GenerateFunctionResultCreate(self, function): |
423 """Generate function to create a Result given the return value. | 385 """Generate function to create a Result given the return value. |
424 """ | 386 """ |
425 classname = cpp_util.Classname(function.name) | 387 classname = cpp_util.Classname(function.name) |
426 c = code.Code() | 388 c = code.Code() |
427 params = function.callback.params | 389 params = function.callback.params |
| 390 |
428 if not params: | 391 if not params: |
429 (c.Append('Value* %s::Result::Create() {' % classname) | 392 (c.Append('Value* %s::Result::Create() {' % classname) |
430 .Append(' return Value::CreateNullValue();') | 393 .Append(' return Value::CreateNullValue();') |
431 .Append('}') | 394 .Append('}') |
432 ) | 395 ) |
433 else: | 396 else: |
434 # If there is a single parameter, this is straightforward. However, if | 397 # If there is a single parameter, this is straightforward. However, if |
435 # the callback parameter is of 'choices', this generates a Create method | 398 # the callback parameter is of 'choices', this generates a Create method |
436 # for each choice. This works because only 1 choice can be returned at a | 399 # for each choice. This works because only 1 choice can be returned at a |
437 # time. | 400 # time. |
438 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params): | 401 for param in self._cpp_type_generator.GetExpandedChoicesInParams(params): |
439 arg = cpp_util.GetConstParameterDeclaration( | 402 # We treat this argument as 'required' to avoid wrapping it in a |
440 param, self._cpp_type_generator) | 403 # scoped_ptr if it's optional. |
| 404 param_copy = param.Copy() |
| 405 param_copy.optional = False |
441 c.Sblock('Value* %(classname)s::Result::Create(%(arg)s) {') | 406 c.Sblock('Value* %(classname)s::Result::Create(%(arg)s) {') |
442 if param.type_ == PropertyType.ARRAY: | 407 if param_copy.type_ == PropertyType.ARRAY: |
443 (c.Append('ListValue* value = new ListValue();') | 408 (c.Append('ListValue* value = new ListValue();') |
444 .Append('%s;' % self._util_cc_helper.SetArrayToList( | 409 .Append('%s;' % self._util_cc_helper.PopulateListFromArray( |
445 param, param.unix_name, 'value')) | 410 param_copy, param_copy.unix_name, 'value')) |
446 .Append('return value;') | 411 .Append('return value;') |
447 ) | 412 ) |
448 else: | 413 else: |
449 c.Append('return %s;' % cpp_util.CreateValueFromSingleProperty(param, | 414 c.Append('return %s;' % |
450 param.unix_name)) | 415 cpp_util.CreateValueFromSingleProperty(param_copy, |
451 c.Substitute({'classname': classname, 'arg': arg}) | 416 param_copy.unix_name)) |
| 417 c.Substitute({'classname': classname, |
| 418 'arg': cpp_util.GetParameterDeclaration( |
| 419 param_copy, self._cpp_type_generator.GetType(param_copy)) |
| 420 }) |
452 c.Eblock('}') | 421 c.Eblock('}') |
453 | 422 |
454 return c | 423 return c |
OLD | NEW |