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 any_helper | 6 import any_helper |
7 import code | 7 import code |
8 import cpp_util | 8 import cpp_util |
9 import model | 9 import model |
10 import sys | 10 import sys |
11 import util_cc_helper | 11 import util_cc_helper |
12 | 12 |
13 class CCGenerator(object): | 13 class CCGenerator(object): |
14 """A .cc generator for a namespace. | 14 """A .cc generator for a namespace. |
15 """ | 15 """ |
16 def __init__(self, namespace, cpp_type_generator): | 16 def __init__(self, namespace, cpp_type_generator, referenced_schemas): |
17 self._cpp_type_generator = cpp_type_generator | 17 self._cpp_type_generator = cpp_type_generator |
18 self._referenced_schemas = referenced_schemas | |
18 self._namespace = namespace | 19 self._namespace = namespace |
19 self._target_namespace = ( | 20 self._target_namespace = ( |
20 self._cpp_type_generator.GetCppNamespaceName(self._namespace)) | 21 self._cpp_type_generator.GetCppNamespaceName(self._namespace)) |
21 self._util_cc_helper = ( | 22 self._util_cc_helper = ( |
22 util_cc_helper.UtilCCHelper(self._cpp_type_generator)) | 23 util_cc_helper.UtilCCHelper(self._cpp_type_generator)) |
23 self._any_helper = any_helper.AnyHelper() | 24 self._any_helper = any_helper.AnyHelper() |
24 | 25 |
25 def Generate(self): | 26 def Generate(self): |
26 """Generates a code.Code object with the .cc for a single namespace. | 27 """Generates a code.Code object with the .cc for a single namespace. |
27 """ | 28 """ |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
91 if type_.properties: | 92 if type_.properties: |
92 raise NotImplementedError('\n'.join(model.GetModelHierarchy(type_)) + | 93 raise NotImplementedError('\n'.join(model.GetModelHierarchy(type_)) + |
93 '\nCannot generate both functions and properties on a type') | 94 '\nCannot generate both functions and properties on a type') |
94 for function in type_.functions.values(): | 95 for function in type_.functions.values(): |
95 (c.Concat( | 96 (c.Concat( |
96 self._GenerateFunction( | 97 self._GenerateFunction( |
97 cpp_namespace + '::' + cpp_util.Classname(function.name), | 98 cpp_namespace + '::' + cpp_util.Classname(function.name), |
98 function)) | 99 function)) |
99 .Append() | 100 .Append() |
100 ) | 101 ) |
101 else: | 102 elif type_.type_ == PropertyType.OBJECT: |
102 (c.Concat(self._GeneratePropertyFunctions( | 103 (c.Concat(self._GeneratePropertyFunctions( |
103 cpp_namespace, type_.properties.values())) | 104 cpp_namespace, type_.properties.values())) |
104 .Sblock('%(namespace)s::%(classname)s()') | 105 .Sblock('%(namespace)s::%(classname)s()') |
105 .Concat(self._GenerateInitializersAndBody(type_)) | 106 .Concat(self._GenerateInitializersAndBody(type_)) |
106 .Eblock('%(namespace)s::~%(classname)s() {}') | 107 .Eblock('%(namespace)s::~%(classname)s() {}') |
107 .Append() | 108 .Append() |
108 ) | 109 ) |
109 if type_.from_json: | 110 if type_.from_json: |
110 (c.Concat(self._GenerateTypePopulate(cpp_namespace, type_)) | 111 (c.Concat(self._GenerateTypePopulate(cpp_namespace, type_)) |
111 .Append() | 112 .Append() |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
314 | 315 |
315 E.g for std::string, generate Value::CreateStringValue(var) | 316 E.g for std::string, generate Value::CreateStringValue(var) |
316 """ | 317 """ |
317 if prop.type_ == PropertyType.CHOICES: | 318 if prop.type_ == PropertyType.CHOICES: |
318 # CHOICES conversion not implemented. If needed, write something to | 319 # CHOICES conversion not implemented. If needed, write something to |
319 # generate a function that returns a scoped_ptr<Value> and put it in | 320 # generate a function that returns a scoped_ptr<Value> and put it in |
320 # _GeneratePropertyFunctions, then use it here. Look at CreateEnumValue() | 321 # _GeneratePropertyFunctions, then use it here. Look at CreateEnumValue() |
321 # for reference. | 322 # for reference. |
322 raise NotImplementedError( | 323 raise NotImplementedError( |
323 'Conversion of CHOICES to Value not implemented') | 324 'Conversion of CHOICES to Value not implemented') |
324 if prop.type_ in (PropertyType.REF, PropertyType.OBJECT): | 325 if self._IsObjectOrObjectRef(prop): |
325 if prop.optional: | 326 if prop.optional: |
326 return '%s->ToValue().release()' % var | 327 return '%s->ToValue().release()' % var |
327 else: | 328 else: |
328 return '%s.ToValue().release()' % var | 329 return '%s.ToValue().release()' % var |
329 elif prop.type_ == PropertyType.ANY: | 330 elif prop.type_ == PropertyType.ANY: |
330 return '%s.DeepCopy()' % self._any_helper.GetValue(prop, var) | 331 return '%s.DeepCopy()' % self._any_helper.GetValue(prop, var) |
331 elif prop.type_ == PropertyType.ADDITIONAL_PROPERTIES: | 332 elif prop.type_ == PropertyType.ADDITIONAL_PROPERTIES: |
332 return '%s.DeepCopy()' % var | 333 return '%s.DeepCopy()' % var |
333 elif prop.type_ == PropertyType.ENUM: | 334 elif prop.type_ == PropertyType.ENUM: |
334 return 'CreateEnumValue(%s).release()' % var | 335 return 'CreateEnumValue(%s).release()' % var |
335 elif prop.type_ == PropertyType.ARRAY: | 336 elif self._IsArrayOrArrayRef(prop): |
336 return '%s.release()' % self._util_cc_helper.CreateValueFromArray( | 337 return '%s.release()' % self._util_cc_helper.CreateValueFromArray( |
337 prop, var) | 338 self._GetRef(prop), var, prop.optional) |
338 elif prop.type_.is_fundamental: | 339 elif prop.type_.is_fundamental: |
339 if prop.optional: | 340 if prop.optional: |
340 var = '*' + var | 341 var = '*' + var |
341 return { | 342 return { |
342 PropertyType.STRING: 'Value::CreateStringValue(%s)', | 343 PropertyType.STRING: 'Value::CreateStringValue(%s)', |
343 PropertyType.BOOLEAN: 'Value::CreateBooleanValue(%s)', | 344 PropertyType.BOOLEAN: 'Value::CreateBooleanValue(%s)', |
344 PropertyType.INTEGER: 'Value::CreateIntegerValue(%s)', | 345 PropertyType.INTEGER: 'Value::CreateIntegerValue(%s)', |
345 PropertyType.DOUBLE: 'Value::CreateDoubleValue(%s)', | 346 PropertyType.DOUBLE: 'Value::CreateDoubleValue(%s)', |
346 }[prop.type_] % var | 347 }[prop.type_] % var |
347 else: | 348 else: |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
448 .Append('if (%s)' % | 449 .Append('if (%s)' % |
449 cpp_util.GetAsFundamentalValue(prop, value_var, '&temp')) | 450 cpp_util.GetAsFundamentalValue(prop, value_var, '&temp')) |
450 .Append(' %(dst)s->%(name)s.reset(new %(ctype)s(temp));') | 451 .Append(' %(dst)s->%(name)s.reset(new %(ctype)s(temp));') |
451 ) | 452 ) |
452 else: | 453 else: |
453 (c.Append('if (!%s)' % | 454 (c.Append('if (!%s)' % |
454 cpp_util.GetAsFundamentalValue( | 455 cpp_util.GetAsFundamentalValue( |
455 prop, value_var, '&%s->%s' % (dst, prop.unix_name))) | 456 prop, value_var, '&%s->%s' % (dst, prop.unix_name))) |
456 .Append('return %(failure_value)s;') | 457 .Append('return %(failure_value)s;') |
457 ) | 458 ) |
458 elif prop.type_ in (PropertyType.OBJECT, PropertyType.REF): | 459 elif self._IsObjectOrObjectRef(prop): |
459 if prop.optional: | 460 if prop.optional: |
460 (c.Append('DictionaryValue* dictionary = NULL;') | 461 (c.Append('DictionaryValue* dictionary = NULL;') |
461 .Append('if (!%(value_var)s->GetAsDictionary(&dictionary))') | 462 .Append('if (!%(value_var)s->GetAsDictionary(&dictionary))') |
462 .Append(' return %(failure_value)s;') | 463 .Append(' return %(failure_value)s;') |
463 .Append('scoped_ptr<%(ctype)s> temp(new %(ctype)s());') | 464 .Append('scoped_ptr<%(ctype)s> temp(new %(ctype)s());') |
464 .Append('if (!%(ctype)s::Populate(*dictionary, temp.get()))') | 465 .Append('if (!%(ctype)s::Populate(*dictionary, temp.get()))') |
465 .Append(' return %(failure_value)s;') | 466 .Append(' return %(failure_value)s;') |
466 .Append('%(dst)s->%(name)s = temp.Pass();') | 467 .Append('%(dst)s->%(name)s = temp.Pass();') |
467 ) | 468 ) |
468 else: | 469 else: |
469 (c.Append('DictionaryValue* dictionary = NULL;') | 470 (c.Append('DictionaryValue* dictionary = NULL;') |
470 .Append('if (!%(value_var)s->GetAsDictionary(&dictionary))') | 471 .Append('if (!%(value_var)s->GetAsDictionary(&dictionary))') |
471 .Append(' return %(failure_value)s;') | 472 .Append(' return %(failure_value)s;') |
472 .Append( | 473 .Append( |
473 'if (!%(ctype)s::Populate(*dictionary, &%(dst)s->%(name)s))') | 474 'if (!%(ctype)s::Populate(*dictionary, &%(dst)s->%(name)s))') |
474 .Append(' return %(failure_value)s;') | 475 .Append(' return %(failure_value)s;') |
475 ) | 476 ) |
476 elif prop.type_ == PropertyType.ANY: | 477 elif prop.type_ == PropertyType.ANY: |
477 if prop.optional: | 478 if prop.optional: |
478 c.Append('%(dst)s->%(name)s.reset(new Any());') | 479 c.Append('%(dst)s->%(name)s.reset(new Any());') |
479 c.Append(self._any_helper.Init(prop, value_var, dst) + ';') | 480 c.Append(self._any_helper.Init(prop, value_var, dst) + ';') |
480 elif prop.type_ == PropertyType.ARRAY: | 481 elif self._IsArrayOrArrayRef(prop): |
481 # util_cc_helper deals with optional and required arrays | 482 # util_cc_helper deals with optional and required arrays |
482 (c.Append('ListValue* list = NULL;') | 483 (c.Append('ListValue* list = NULL;') |
483 .Append('if (!%(value_var)s->GetAsList(&list))') | 484 .Append('if (!%(value_var)s->GetAsList(&list))') |
484 .Append(' return %(failure_value)s;') | 485 .Append(' return %(failure_value)s;') |
485 .Append('if (!%s)' % self._util_cc_helper.PopulateArrayFromList( | 486 .Append('if (!%s)' % self._util_cc_helper.PopulateArrayFromList( |
486 prop, 'list', dst + '->' + prop.unix_name)) | 487 self._GetRef(prop), 'list', dst + '->' + prop.unix_name, |
488 prop.optional)) | |
487 .Append(' return %(failure_value)s;') | 489 .Append(' return %(failure_value)s;') |
488 ) | 490 ) |
489 elif prop.type_ == PropertyType.CHOICES: | 491 elif prop.type_ == PropertyType.CHOICES: |
490 type_var = '%(dst)s->%(name)s_type' | 492 type_var = '%(dst)s->%(name)s_type' |
491 c.Sblock('switch (%(value_var)s->GetType()) {') | 493 c.Sblock('switch (%(value_var)s->GetType()) {') |
492 for choice in self._cpp_type_generator.GetExpandedChoicesInParams([prop]): | 494 for choice in self._cpp_type_generator.GetExpandedChoicesInParams([prop]): |
493 (c.Sblock('case %s: {' % cpp_util.GetValueType(choice)) | 495 (c.Sblock('case %s: {' % cpp_util.GetValueType( |
496 self._GetRef(choice).type_)) | |
494 .Concat(self._GeneratePopulatePropertyFromValue( | 497 .Concat(self._GeneratePopulatePropertyFromValue( |
495 choice, value_var, dst, failure_value, check_type=False)) | 498 choice, value_var, dst, failure_value, check_type=False)) |
496 .Append('%s = %s;' % | 499 .Append('%s = %s;' % |
497 (type_var, | 500 (type_var, |
498 self._cpp_type_generator.GetEnumValue( | 501 self._cpp_type_generator.GetEnumValue( |
499 prop, choice.type_.name))) | 502 prop, choice.type_.name))) |
500 .Append('break;') | 503 .Append('break;') |
501 .Eblock('}') | 504 .Eblock('}') |
502 ) | 505 ) |
503 (c.Append('default:') | 506 (c.Append('default:') |
(...skipping 21 matching lines...) Expand all Loading... | |
525 raise NotImplementedError(prop.type_) | 528 raise NotImplementedError(prop.type_) |
526 c.Eblock('}') | 529 c.Eblock('}') |
527 sub = { | 530 sub = { |
528 'value_var': value_var, | 531 'value_var': value_var, |
529 'name': prop.unix_name, | 532 'name': prop.unix_name, |
530 'dst': dst, | 533 'dst': dst, |
531 'failure_value': failure_value, | 534 'failure_value': failure_value, |
532 } | 535 } |
533 if prop.type_ not in (PropertyType.CHOICES, PropertyType.ANY): | 536 if prop.type_ not in (PropertyType.CHOICES, PropertyType.ANY): |
534 sub['ctype'] = self._cpp_type_generator.GetType(prop) | 537 sub['ctype'] = self._cpp_type_generator.GetType(prop) |
535 sub['value_type'] = cpp_util.GetValueType(prop) | 538 sub['value_type'] = cpp_util.GetValueType(self._GetRef(prop).type_) |
536 c.Substitute(sub) | 539 c.Substitute(sub) |
537 return c | 540 return c |
538 | 541 |
539 def _GeneratePropertyFunctions(self, param_namespace, params): | 542 def _GeneratePropertyFunctions(self, param_namespace, params): |
540 """Generate the functions for structures generated by a property such as | 543 """Generate the functions for structures generated by a property such as |
541 CreateEnumValue for ENUMs and Populate/ToValue for Params/Result objects. | 544 CreateEnumValue for ENUMs and Populate/ToValue for Params/Result objects. |
542 """ | 545 """ |
543 c = code.Code() | 546 c = code.Code() |
544 for param in params: | 547 for param in params: |
545 if param.type_ == PropertyType.OBJECT: | 548 if param.type_ == PropertyType.OBJECT: |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
609 if prop.type_ in (PropertyType.ENUM, PropertyType.CHOICES): | 612 if prop.type_ in (PropertyType.ENUM, PropertyType.CHOICES): |
610 if prop.optional: | 613 if prop.optional: |
611 prop_name = prop.unix_name | 614 prop_name = prop.unix_name |
612 if prop.type_ == PropertyType.CHOICES: | 615 if prop.type_ == PropertyType.CHOICES: |
613 prop_name = prop.unix_name + '_type' | 616 prop_name = prop.unix_name + '_type' |
614 c.Append('%s->%s = %s;' % ( | 617 c.Append('%s->%s = %s;' % ( |
615 dst, | 618 dst, |
616 prop_name, | 619 prop_name, |
617 self._cpp_type_generator.GetEnumNoneValue(prop))) | 620 self._cpp_type_generator.GetEnumNoneValue(prop))) |
618 return c | 621 return c |
622 | |
623 def _IsObjectOrObjectRef(self, prop): | |
624 """Determines if this property is an Object or is a ref to an Object. | |
625 """ | |
626 return self._GetRef(prop).type_ == PropertyType.OBJECT | |
627 | |
628 def _IsArrayOrArrayRef(self, prop): | |
629 """Determines if this property is an Array or is a ref to an Array. | |
630 """ | |
631 return self._GetRef(prop).type_ == PropertyType.ARRAY | |
632 | |
633 def _GetRef(self, prop): | |
Yoyo Zhou
2012/04/10 19:26:48
I'm not sure this name is clear enoguh. How about
cduvall
2012/04/12 00:41:23
This function is actually returning the whole prop
| |
634 """Returns the item a $ref is referring to. | |
Yoyo Zhou
2012/04/10 19:26:48
s/item/type/, and add a note on what it returns if
cduvall
2012/04/12 00:41:23
Done. See previous comment.
| |
635 """ | |
636 if prop.type_ != PropertyType.REF: | |
637 return prop | |
638 if prop.ref_type in self._namespace.types.keys(): | |
639 return self._namespace.types[prop.ref_type] | |
640 for namespace in self._referenced_schemas: | |
641 qualified_name = namespace + '.' + prop.ref_type | |
642 if qualified_name in self._cpp_type_generator._type_namespaces.keys(): | |
643 return (self._cpp_type_generator._type_namespaces[qualified_name] | |
Yoyo Zhou
2012/04/10 19:26:48
The _ is supposed to prefix private members, so yo
cduvall
2012/04/12 00:41:23
Done.
| |
644 .types[prop.ref_type]) | |
645 return prop | |
OLD | NEW |